Autudl華為昇騰系列NPU簡介和部署推理yolo11 yolov8 yolov5分割模型

0.配置Autudl

????????下面圖片是我所租的昇騰卡和具體環境版本,太具體的就不說了,有需要的話我單獨出一期Autudl租顯卡的教程,主要是為了學習昇騰環境如何運行Yolo系列模型。

0.1華為昇騰芯片(Ascend)簡介

1.Ascend 310(?邊緣推理 SoC)

? ? ?在僅 8?W 的功耗下,支持 FP16 達 8?TOPS,INT8 達 16?TOPS。
? ? ? 支持多通道高清視頻處理:最高可實現 16 路 1080p H.264/H.265 解碼、1 路 1080p 視頻編碼,以及 JPEG/PNG 編解碼功能。
? ? ? ? 內含 2 個 Da?Vinci Max AI 核心、8 個 ARM Cortex?A55 CPU 核心和 8?MB 片上緩存。

2.Ascend 910(數據中心級訓練 NPU)

? ? ? ? 于 2019 年發布,代號 Ascend?Max,基于 Da?Vinci 架構,擁有 32 個 Da?Vinci Max AI 核心,FP16 達 256?TFLOPS,INT8 達 512?TOPS。
? ? ? ? 配備高帶寬互聯(NoC Mesh 1024 位,HBM2E 帶寬 1.2?TB/s,350?W 功耗)

3.Ascend 910C(2025 年主打產品)

? ? ? ? 基于 SMIC 的 7?nm (N+2) 工藝,采用雙 910B Die 封裝設計,擁有約 53 億晶體管。
? ? ? ? 實現 FP16 約 800?TFLOPS 性能,搭載高達 128?GB 的 HBM3 存儲(領先于 NVIDIA H100 的 80?GB)。推測性能約為 NVIDIA H100 推理性能的 60%

0.2MindSpore框架

????????MindSpore 是華為自主研發的全場景 AI 計算框架,覆蓋云、邊、端多種部署環境。向上支持自然語言處理、計算機視覺、科學計算等多類 AI 應用,向下通過 CANN 對接昇騰 AI 處理器,實現軟硬件協同優化。
? ? ? ? ?提供端到端的模型開發能力,包括數據處理、模型構建、訓練、推理與部署,內置自動并行、算子融合、混合精度等優化機制,顯著提升性能與算力利用率。其功能定位類似于 TensorFlow 或 PyTorch,在昇騰生態中承擔核心 AI 框架的角色。

0.3CANN計算架構(Compute Architecture for Neural Networks)

????????華為面向AI場景推出的異構計算架構 CANN,作為昇騰AI處理器的軟件驅動與算子加速平臺,向上兼容多種主流AI框架(如 MindSpore、PyTorch、TensorFlow 等),向下對接昇騰系列AI處理器的算子庫、運行時與調度層,發揮承上啟下的關鍵作用。CANN 屏蔽了底層硬件差異,使開發者能夠在不關心硬件細節的情況下無縫使用主流深度學習框架進行模型開發與部署。

? ? ? ? 同時,CANN 針對多樣化的應用場景提供多層次編程接口(如算子級、圖級、應用級),支持用戶快速構建和優化基于昇騰平臺的AI應用與業務,顯著提升模型的執行效率與硬件算力利用率,其功能定位類似于 NVIDIA 的 CUDA 平臺。

總結:CANN用來屏蔽底層硬件差異,使得用戶能夠無縫使用Pytorch等主流深度學習框架進行開發

?作流程:ONNX ATC 轉換 ACLruntime 調? 推理結果

1配置環境

1.1創建一個yolo環境并進入

conda create -n yolo11 python=3.10 
conda activate yolo11

?1.2安裝yolo所需要的庫

pip install ultralytics

1.3安裝ais_bench推理工具,和aclruntime

根據自己使用的python、版本系統和架構選擇具體的whl文件

tools: Ascend tools - Gitee.comhttps://gitee.com/ascend/tools/tree/master/ais-bench_workload/tool/ais_bench#%E4%B8%8B%E8%BD%BDwhl%E5%8C%85%E5%AE%89%E8%A3%85

?下載到本地后,安裝兩個whl文件

1.3.1安裝ais_bench

pip install ais_bench-0.0.2-py3-none-any.whl -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

1.3.2安裝aclruntime

pip install aclruntime-0.0.2-cp310-cp310-linux_aarch64.whl

后面啟動可能會報一些錯誤,讓ai解決一下,很好解決

NEW_LIB=~/autodl-tmp/libstdcpp_arm64/usr/lib/aarch64-linux-gnu/libstdc++.so.6
ln -sf /usr/lib/aarch64-linux-gnu/libstdc++.so.6 /root/miniconda3/lib/libstdc++.so.6

2準備源碼和模型

模型可以是自己的,也可以從官網上下載

2.1下載源碼

https://github.com/ultralytics/ultralytics

2.2下載模型權重

Ultralytics YOLO11 - Ultralytics YOLO 文檔

3轉換模型

3.1將.pt格式轉換為.ONNX格式

from ultralytics import YOLO# Load a model
model = YOLO(r"/home/ultralytics-main/runs/train/yolo11n/weights/best.pt")# Export onnx,一定要設置opset=11 不然會報錯
model.export(format="onnx",opset=11)

3.1.1查看ONNX?絡結構和輸?輸出shape

Netron

進入網站后,上傳ONNX模型文件

3.2將.ONNX格式轉換為.om格式?

atc \--model=/root/autodl-tmp/ultralytics-main/runs/train/exp4/weights/best.onnx \--framework=5 \--output=yolo11s \--input_format=NCHW \--input_shape="images:1,3,640,640" \--soc_version=Ascend910B2

參數分別是:
--model 需要轉換模型的路徑

--framework 框架,ONNX就用5

--output ?輸出.om文件的名字

--input_shape 模型的輸入shape,640 640是訓練時圖片的大小,根據需要修改

--soc_version NPU的型號

根據下面的指令查詢npu型號后,替換910B2

npu-smi info   #用這個指令可以查詢npu型號

4.推理源碼

ultralytics路徑下創建run_seg.py

將下述代碼復制進去

import argparse
import time 
import cv2
import numpy as np
import osfrom ais_bench.infer.interface import InferSessionclass YOLO:"""YOLO segmentation model class for handling inference"""def __init__(self, om_model, imgsz=(640, 640), device_id=0, model_ndtype=np.single, mode="static", postprocess_type="v8", aipp=False):"""Initialization.Args:om_model (str): Path to the om model."""# 構建ais_bench推理引擎self.session = InferSession(device_id=device_id, model_path=om_model)# Numpy dtype: support both FP32(np.single) and FP16(np.half) om modelself.ndtype = model_ndtypeself.mode = modeself.postprocess_type = postprocess_typeself.aipp = aipp self.model_height, self.model_width = imgsz[0], imgsz[1]  # 圖像resize大小def __call__(self, im0, conf_threshold=0.4, iou_threshold=0.45):"""The whole pipeline: pre-process -> inference -> post-process.Args:im0 (Numpy.ndarray): original input image.conf_threshold (float): confidence threshold for filtering predictions.iou_threshold (float): iou threshold for NMS.Returns:boxes (List): list of bounding boxes."""# 前處理Pre-processt1 = time.time()im, ratio, (pad_w, pad_h) = self.preprocess(im0)pre_time = round(time.time() - t1, 3)# 推理 inferencet2 = time.time()preds = self.session.infer([im], mode=self.mode)  # mode有動態"dymshape"和靜態"static"等det_time = round(time.time() - t2, 3)# 后處理Post-processt3 = time.time()if self.postprocess_type == "v5":boxes, segments, masks = self.postprocess_v5(preds,im0=im0,ratio=ratio,pad_w=pad_w,pad_h=pad_h,conf_threshold=conf_threshold,iou_threshold=iou_threshold,)elif self.postprocess_type == "v8":boxes, segments, masks = self.postprocess_v8(preds,im0=im0,ratio=ratio,pad_w=pad_w,pad_h=pad_h,conf_threshold=conf_threshold,iou_threshold=iou_threshold,)else:boxes=[], segments=[], masks=[]post_time = round(time.time() - t3, 3)return boxes, segments, masks, (pre_time, det_time, post_time)# 前處理,包括:resize, pad, 其中HWC to CHW,BGR to RGB,歸一化,增加維度CHW -> BCHW可選擇是否開啟AIPP加速處理def preprocess(self, img):"""Pre-processes the input image.Args:img (Numpy.ndarray): image about to be processed.Returns:img_process (Numpy.ndarray): image preprocessed for inference.ratio (tuple): width, height ratios in letterbox.pad_w (float): width padding in letterbox.pad_h (float): height padding in letterbox."""# Resize and pad input image using letterbox() (Borrowed from Ultralytics)shape = img.shape[:2]  # original image shapenew_shape = (self.model_height, self.model_width)r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])ratio = r, rnew_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))pad_w, pad_h = (new_shape[1] - new_unpad[0]) / 2, (new_shape[0] - new_unpad[1]) / 2  # wh paddingif shape[::-1] != new_unpad:  # resizeimg = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)top, bottom = int(round(pad_h - 0.1)), int(round(pad_h + 0.1))left, right = int(round(pad_w - 0.1)), int(round(pad_w + 0.1))img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114))  # 填充# 是否開啟aipp加速預處理,需atc中完成if self.aipp:return img, ratio, (pad_w, pad_h)# Transforms: HWC to CHW -> BGR to RGB -> div(255) -> contiguous -> add axis(optional)img = np.ascontiguousarray(np.einsum('HWC->CHW', img)[::-1], dtype=self.ndtype) / 255.0img_process = img[None] if len(img.shape) == 3 else imgreturn img_process, ratio, (pad_w, pad_h)# YOLOv5/6/7通用后處理,包括:閾值過濾與NMS+masks處理def postprocess_v5(self, preds, im0, ratio, pad_w, pad_h, conf_threshold, iou_threshold, nm=32):"""Post-process the prediction.Args:preds (Numpy.ndarray): predictions come from ort.session.run().im0 (Numpy.ndarray): [h, w, c] original input image.ratio (tuple): width, height ratios in letterbox.pad_w (float): width padding in letterbox.pad_h (float): height padding in letterbox.conf_threshold (float): conf threshold.iou_threshold (float): iou threshold.nm (int): the number of masks.Returns:boxes (List): list of bounding boxes.segments (List): list of segments.masks (np.ndarray): [N, H, W], output masks."""# (Batch_size, Num_anchors, xywh_score_conf_cls), v5和v6_1.0的[..., 4]是置信度分數,v8v9采用類別里面最大的概率作為置信度scorex, protos = preds[0], preds[1]  # 與bbox區別:Two outputs: 檢測頭的輸出(1, 8400*3, 117), 分割頭的輸出(1, 32, 160, 160)# Predictions filtering by conf-thresholdx = x[x[..., 4] > conf_threshold]# Create a new matrix which merge these(box, score, cls, nm) into one# For more details about `numpy.c_()`: https://numpy.org/doc/1.26/reference/generated/numpy.c_.htmlx = np.c_[x[..., :4], x[..., 4], np.argmax(x[..., 5:-nm], axis=-1), x[..., -nm:]]# NMS filtering# 經過NMS后的值, np.array([[x, y, w, h, conf, cls, nm], ...]), shape=(-1, 4 + 1 + 1 + 32)x = x[cv2.dnn.NMSBoxes(x[:, :4], x[:, 4], conf_threshold, iou_threshold)]# 重新縮放邊界框,為畫圖做準備if len(x) > 0:# Bounding boxes format change: cxcywh -> xyxyx[..., [0, 1]] -= x[..., [2, 3]] / 2x[..., [2, 3]] += x[..., [0, 1]]# Rescales bounding boxes from model shape(model_height, model_width) to the shape of original imagex[..., :4] -= [pad_w, pad_h, pad_w, pad_h]x[..., :4] /= min(ratio)# Bounding boxes boundary clampx[..., [0, 2]] = x[:, [0, 2]].clip(0, im0.shape[1])x[..., [1, 3]] = x[:, [1, 3]].clip(0, im0.shape[0])# 與bbox區別:增加masks處理# Process masksmasks = self.process_mask(protos[0], x[:, 6:], x[:, :4], im0.shape)# Masks -> Segments(contours)segments = self.masks2segments(masks)return x[..., :6], segments, masks  # boxes, segments, maskselse:return [], [], []def postprocess_v8(self, preds, im0, ratio, pad_w, pad_h, conf_threshold, iou_threshold):x, protos = preds[0], preds[1]  # x: (1, 37, 8400), protos: (1, 32, 160, 160)# 統一為 (8400, 37)if x.ndim == 3:if x.shape[1] < x.shape[2]:    # (1, 37, 8400)x = np.einsum('bcn->bnc', x)[0]  # -> (8400, 37)else:                          # (1, 8400, 37)x = x[0]else:raise ValueError(f'unexpected pred0 shape: {x.shape}')# 動態確定 nm(此模型就是 32)nm = protos.shape[1] if (protos.ndim == 4 and protos.shape[1] in (16, 32, 64)) else 32# 取類別分支并按需做 sigmoidcls_blob = x[:, 4:-nm]  # 維度應為 (8400, num_classes);你的模型 num_classes=1if cls_blob.size and (cls_blob.max() > 1 or cls_blob.min() < 0):cls_scores = 1.0 / (1.0 + np.exp(-cls_blob))else:cls_scores = cls_blobif cls_scores.size == 0:return [], [], []scores = cls_scores.max(axis=-1)clses  = cls_scores.argmax(axis=-1)keep = scores > conf_thresholdif not np.any(keep):return [], [], []# 拼接為統一數組x = np.c_[x[keep, :4], scores[keep], clses[keep], x[keep, -nm:]]  # [cx,cy,w,h,score,cls, 32-vec]# === NMS 前先把 cx,cy,w,h -> x,y,w,h(左上+寬高)===tlwh = np.c_[x[:, 0] - x[:, 2] / 2,x[:, 1] - x[:, 3] / 2,x[:, 2],x[:, 3]]idxs = cv2.dnn.NMSBoxes(tlwh.tolist(), x[:, 4].astype(float).tolist(),conf_threshold, iou_threshold)if len(idxs) == 0:return [], [], []idxs = np.array(idxs).reshape(-1)x = x[idxs]# 轉回 xyxy 并映射回原圖x[..., [0, 1]] -= x[..., [2, 3]] / 2x[..., [2, 3]] += x[..., [0, 1]]x[:, :4] -= [pad_w, pad_h, pad_w, pad_h]x[:, :4] /= min(ratio)x[:, [0, 2]] = x[:, [0, 2]].clip(0, im0.shape[1])x[:, [1, 3]] = x[:, [1, 3]].clip(0, im0.shape[0])# 處理 maskmasks = self.process_mask(protos[0], x[:, 6:], x[:, :4], im0.shape)segments = self.masks2segments(masks)return x[:, :6], segments, masks@staticmethoddef masks2segments(masks):"""It takes a list of masks(n,h,w) and returns a list of segments(n,xy) (Borrowed fromhttps://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L750)Args:masks (numpy.ndarray): the output of the model, which is a tensor of shape (batch_size, 160, 160).Returns:segments (List): list of segment masks."""segments = []for x in masks.astype('uint8'):c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]  # CHAIN_APPROX_SIMPLE  該函數用于查找二值圖像中的輪廓。if c:# 這段代碼的目的是找到圖像x中的最外層輪廓,并從中選擇最長的輪廓,然后將其轉換為NumPy數組的形式。c = np.array(c[np.array([len(x) for x in c]).argmax()]).reshape(-1, 2)else:c = np.zeros((0, 2))  # no segments foundsegments.append(c.astype('float32'))return segmentsdef process_mask(self, protos, masks_in, bboxes, im0_shape):c, mh, mw = protos.shapemasks = np.matmul(masks_in, protos.reshape((c, -1))).reshape((-1, mh, mw))  # [n, mh, mw]# ★ 先 sigmoid,把線性疊加的 logits 轉成概率masks = 1.0 / (1.0 + np.exp(-masks))masks = np.transpose(masks, (1, 2, 0))                  # -> [mh, mw, n]masks = np.ascontiguousarray(masks)masks = self.scale_mask(masks, im0_shape)               # -> [H, W, n]masks = np.einsum('HWN -> NHW', masks)                  # -> [n, H, W]masks = self.crop_mask(masks, bboxes)                   # 裁剪到框內return masks > 0.5@staticmethoddef scale_mask(masks, im0_shape, ratio_pad=None):"""Takes a mask, and resizes it to the original image size. (Borrowed fromhttps://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L305)Args:masks (np.ndarray): resized and padded masks/images, [h, w, num]/[h, w, 3].im0_shape (tuple): the original image shape.ratio_pad (tuple): the ratio of the padding to the original image.Returns:masks (np.ndarray): The masks that are being returned."""im1_shape = masks.shape[:2]if ratio_pad is None:  # calculate from im0_shapegain = min(im1_shape[0] / im0_shape[0], im1_shape[1] / im0_shape[1])  # gain  = old / newpad = (im1_shape[1] - im0_shape[1] * gain) / 2, (im1_shape[0] - im0_shape[0] * gain) / 2  # wh paddingelse:pad = ratio_pad[1]# Calculate tlbr of masktop, left = int(round(pad[1] - 0.1)), int(round(pad[0] - 0.1))  # y, xbottom, right = int(round(im1_shape[0] - pad[1] + 0.1)), int(round(im1_shape[1] - pad[0] + 0.1))if len(masks.shape) < 2:raise ValueError(f'"len of masks shape" should be 2 or 3, but got {len(masks.shape)}')masks = masks[top:bottom, left:right]masks = cv2.resize(masks, (im0_shape[1], im0_shape[0]),interpolation=cv2.INTER_LINEAR)  # INTER_CUBIC would be betterif len(masks.shape) == 2:masks = masks[:, :, None]return masks@staticmethoddef crop_mask(masks, boxes):"""It takes a mask and a bounding box, and returns a mask that is cropped to the bounding box. (Borrowed fromhttps://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L599)Args:masks (Numpy.ndarray): [n, h, w] tensor of masks.boxes (Numpy.ndarray): [n, 4] tensor of bbox coordinates in relative point form.Returns:(Numpy.ndarray): The masks are being cropped to the bounding box."""n, h, w = masks.shapex1, y1, x2, y2 = np.split(boxes[:, :, None], 4, 1)r = np.arange(w, dtype=x1.dtype)[None, None, :]c = np.arange(h, dtype=x1.dtype)[None, :, None]return masks * ((r >= x1) * (r < x2) * (c >= y1) * (c < y2))if __name__ == '__main__':# Create an argument parser to handle command-line argumentsparser = argparse.ArgumentParser()parser.add_argument('--seg_model', type=str, default=r"yolov8s-seg.om", help='Path to OM model')parser.add_argument('--source', type=str, default=r'images', help='Path to input image')parser.add_argument('--out_path', type=str, default=r'results', help='結果保存文件夾')parser.add_argument('--imgsz_seg', type=tuple, default=(640, 640), help='Image input size')parser.add_argument('--classes', type=list, default=['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light','fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow','elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee','skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard','tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich','orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed','dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven','toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'], help='類別')parser.add_argument('--conf', type=float, default=0.7, help='Confidence threshold')parser.add_argument('--iou', type=float, default=0.7, help='NMS IoU threshold')parser.add_argument('--device_id', type=int, default=0, help='device id')parser.add_argument('--mode', default='static', help='om是動態dymshape或靜態static')parser.add_argument('--model_ndtype', default=np.single, help='om是fp32或fp16')parser.add_argument('--postprocess_type', type=str, default='v8', help='后處理方式, 對應v5/v8兩種后處理')parser.add_argument('--aipp', default=False, action='store_true', help='是否開啟aipp加速YOLO預處理, 需atc中完成om集成')args = parser.parse_args()# 創建結果保存文件夾if not os.path.exists(args.out_path):os.mkdir(args.out_path)print('開始運行:')# Build modelseg_model = YOLO(args.seg_model, args.imgsz_seg, args.device_id, args.model_ndtype, args.mode, args.postprocess_type, args.aipp)color_palette = np.random.uniform(0, 255, size=(len(args.classes), 3))  # 為每個類別生成調色板for i, img_name in enumerate(os.listdir(args.source)):try:t1 = time.time()# Read image by OpenCVimg = cv2.imread(os.path.join(args.source, img_name))# 檢測Inferenceboxes, segments, _ , (pre_time, det_time, post_time) = seg_model(img, conf_threshold=args.conf, iou_threshold=args.iou)print('{}/{} ==>總耗時間: {:.3f}s, 其中, 預處理: {:.3f}s, 推理: {:.3f}s, 后處理: {:.3f}s, 識別{}個目標'.format(i+1, len(os.listdir(args.source)), time.time() - t1, pre_time, det_time, post_time, len(boxes)))# Draw rectangles and polygonsim_canvas = img.copy()# 在繪制循環里加健壯性判斷for (*box, conf, cls_), segment in zip(boxes, segments):# segment 可能為空或很短;也可能是 float,需要轉 int32if segment is None or len(segment) < 3:continueseg = np.round(segment).astype(np.int32).reshape(-1, 1, 2)  # -> Nx1x2, int32# 先畫邊,再填充cv2.polylines(img, [seg], True, (255, 255, 255), 2)cv2.fillPoly(im_canvas, [seg], (255, 0, 0))# 畫 bbox 和標簽x1, y1, x2, y2 = map(int, box[:4])cls_i = int(cls_)cv2.rectangle(img, (x1, y1), (x2, y2), color_palette[cls_i], 1, cv2.LINE_AA)label = args.classes[cls_i] if 0 <= cls_i < len(args.classes) else f'cls{cls_i}'cv2.putText(img, f'{label}: {conf:.3f}', (x1, max(0, y1 - 9)),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_palette[cls_i], 2, cv2.LINE_AA)# Mix imageimg = cv2.addWeighted(im_canvas, 0.3, img, 0.7, 0)cv2.imwrite(os.path.join(args.out_path, img_name), img)except Exception as e:print(e)

5.啟動命令?

python ~/autodl-tmp/ultralytics-main/run_seg.py   \
--seg_model /root/autodl-tmp/ultralytics-main/yolo11n-seg1.om   \
--source /root/autodl-tmp/ultralytics-main/test   \
--classes [person]  \
--postprocess_type v8

--classes 是模型檢測標簽名

--source 推理文件所在文件夾

--det_model om模型參數路徑

--postprocess_type yolov8 v9 v11都用v8,使用的yolov5的話改為yolov5

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92871.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92871.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92871.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是JSP和Servlet以及二者的關系

JSP&#xff08;JavaServer Pages&#xff09; 是“HTML 里寫 Java”的模板技術&#xff0c;最終會被容器轉換成 Servlet。Servlet 是“Java 里寫 HTML”的 Java 類&#xff0c;直接繼承 javax.servlet.http.HttpServlet&#xff0c;用來接收/響應 HTTP 請求。Servlet 是什么 純…

【WonderTrader源碼詳解 1】【環境搭建 2】【編譯安裝WonderTrader】

一、引言 本篇來講述如何搭建 wondertrader 和 wtpy 二、wondertrader 2.1 源碼下載 # /home/leo/sda_1.6TBgit clone https://gitee.com/wondertrader/wondertrader.gitgit clone https://gitee.com/wondertrader/wtpy.git2.2 源碼編譯 cd /home/leo/sda_1.6TB/wondertrader/s…

hutool 作為http 客戶端工具調用的一點點總結

場景一&#xff1a;客戶端timeout 的時間給的很短//100毫秒 private static final int HTTP_TIMEOUT_MS 1 * 100; response HttpUtil.createPost(patrolresultconfirmUrl).body(JSONObject.toJSONString(search)).header("Authorization", token).timeout(HTTP_TI…

基于MongoDB/HBase的知識共享平臺的設計與實現

標題:基于MongoDB/HBase的知識共享平臺的設計與實現內容:1.摘要 在當今信息爆炸的時代&#xff0c;知識的有效共享和管理變得愈發重要。本研究的目的是設計并實現一個基于MongoDB/HBase的知識共享平臺&#xff0c;以滿足大規模知識數據的存儲、高效查詢和快速共享需求。方法上&…

PHP數組操作:交集、并集和差集

1. 交集&#xff08;Intersection&#xff09;交集是指兩個集合中都存在的元素。$array1 [1, 2, 3, 4]; $array2 [3, 4, 5, 6];$intersection array_intersect($array1, $array2); print_r($intersection); // 輸出: Array ( [2] > 3 [3] > 4 )2. 并集&#xff08;Uni…

Qt 常用控件 - 7

Text Edit&#xff08;多行輸入框&#xff09;QTextEdit 表示多行輸入框&#xff0c;也是一個富文本 & markdown 編輯器&#xff0c;能在內容超出范圍時自動提供滾動條。QTextEdit&#xff1a;不僅僅能表示純文本&#xff0c;還可以表示 htnl 和 markdownQPlainTextEdit&am…

JDK、eclipse的安裝,配置JDK、Tomcat并使用eclipse創建項目

目錄一、JDK的安裝1. 安裝JDK2. 配置環境變量3. 檢查jdk是否已安裝二、eclipse的安裝1. 解壓安裝2. 設置字體大小3. 設置拼寫提示三、tomcat安裝四、創建項目1. 第一次創建一個普通的java項目2. 第一次創建一個java web項目擴展&#xff1a;運行項目報Tomcat端口占用&#xff0…

Iptables 詳細使用指南

目錄 1. 工作原理? 2. 核心架構&#xff08;四表五鏈&#xff09; 2.1 四張表&#xff08;優先級從高到低&#xff09; 2.2 五條內置鏈&#xff08;數據包流向&#xff09; 3. Iptables規則 3.1 規則的匹配條件與目標動作 常見匹配條件&#xff08;用于篩選數據包&…

Vue 服務端渲染(SSR)詳解

Vue SSR是一種在服務端將 Vue 應用渲染成 HTML 字符串&#xff0c;然后直接發送到客戶端的技術。相比傳統的客戶端渲染&#xff0c;Vue SSR 能帶來更好的 SEO 性能和更快的首屏加載時間。下面我們從零到一&#xff0c;結合項目源碼&#xff0c;詳細講解如何實現一個 Vue SSR 項…

機器翻譯:需要了解的數學基礎詳解

文章目錄一、概率論與統計學1.1 基本概念1.2 在機器翻譯中的應用二、線性代數2.1 基本概念2.2 在機器翻譯中的應用三、微積分3.1 基本概念3.2 在機器翻譯中的應用四、信息論4.1 基本概念4.2 在機器翻譯中的應用五、數值優化5.1 優化問題形式化5.2 優化算法5.3 正則化技術六、圖…

藍橋杯手算題和雜題簡易做法

一、巧用Excel Excel在解決某些數學問題時非常高效&#xff0c;特別是涉及表格計算、簡單統計和可視化分析時。 門牌制作 這道題是一道基礎題&#xff0c;只需要判斷每個數字有幾個2&#xff0c;然后在加起來即可&#xff0c;但是還有更簡單的方法&#xff0c;先通過編譯器&…

5. 緩存-Redis

文章目錄前言一、 介紹1. 簡介2. 核心特點二、 應用場景1. 應用場景2. 數據類型作用場景三、 性能特性1. 內存2. 高性能數據結構3. 單線程、多路復用四、 異步持久化機制1. RDB&#xff08;Redis Database&#xff09;2. AOF&#xff08;Append-Only File&#xff09;3. 持久化…

如何理解Tomcat、Servlet、Catanalina的關系

目錄 背景&#xff1a; 結論&#xff1a; 好文-【拓展閱讀】&#xff1a; 象漂亮更新動力&#xff01; 背景&#xff1a; 學習Java的Servlet時&#xff0c;常常說Tomcat是一個容器&#xff0c;我們寫ServletA,ServletB,Tomcat容器在啟動的時候會讀取web.xml或者我們程序中的…

Hive的并行度的優化

對于分布式任務來說&#xff0c;任務執行的并行度十分重要。Hive的底層是MapReduce&#xff0c;所以Hive的并行度優化分為Map端優化和Reduce端優化。(1)、Map端優化Map端的并行度與Map切片數量相關&#xff0c;并行度等于切片數量。一般情況下不用去設置Map端的并行度。以下特殊…

Vue.js 響應接口:深度解析與實踐指南

Vue.js 響應接口&#xff1a;深度解析與實踐指南 引言 隨著前端技術的不斷發展&#xff0c;Vue.js 作為一種流行的前端框架&#xff0c;已經成為了眾多開發者的首選。Vue.js 的響應式系統是其核心特性之一&#xff0c;它允許開發者輕松實現數據的雙向綁定。而響應接口則是Vue.j…

高精度藍牙定位:技術、應用與未來發展

一、高精度藍牙定位概述在當今科技飛速發展的時代&#xff0c;定位技術的精度和可靠性變得越來越重要。高精度藍牙定位作為一種新興的定位技術&#xff0c;正逐漸嶄露頭角。藍牙技術是一種支持設備短距離通信&#xff08;一般10m內&#xff09;的無線電技術&#xff0c;能在包括…

C# 基于halcon的視覺工作流-章29-邊緣提取-亞像素

C# 基于halcon的視覺工作流-章29-邊緣提取-亞像素 本章目標&#xff1a; 一、1edges_sub_pix&#xff1b; 二、threshold_sub_pix&#xff1b;本實例實現過程與章28基本相同&#xff0c;不同處在于提取的邊緣是亞像素&#xff0c;精度較高&#xff0c;本文僅介紹不同之處&#…

如何實現PostgreSQL的高可用性,包括主流的復制方案、負載均衡方法以及故障轉移流程?

前言 實現 PostgreSQL 的高可用性&#xff08;High Availability, HA&#xff09;是一個系統工程&#xff0c;需要結合復制技術、連接路由&#xff08;負載均衡&#xff09;、自動故障轉移&#xff08;Failover&#xff09;以及監控告警。以下是主流方案和關鍵流程的詳細說明&a…

Apache Ignite 生產級的線程池關閉工具方法揭秘

Apache Ignite 中用于 安全、可靠地關閉線程池&#xff08;ExecutorService&#xff09; 的關鍵邏輯。我們來一步步深入理解它的設計思想和實現細節。&#x1f9f1; 一、核心方法&#xff1a;U.shutdownNow(...) public static void shutdownNow(Class<?> owner, Nullab…

Unity:GUI筆記(一)——文本、按鈕、多選框和單選框、輸入框和拖動條、圖片繪制和框繪制

寫在前面&#xff1a;寫本系列(自用)的目的是回顧已經學過的知識、記錄新學習的知識或是記錄心得理解&#xff0c;方便自己以后快速復習&#xff0c;減少遺忘。主要是唐老師的課程。一、重要參數、文本、按鈕GUI相關代碼需要寫在private void OnGUI()中。該函數每幀執行&#x…