ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Atlas 300V 24G部署YOLOv5全流程:CANN工具链与OM模型转换实操

Atlas 300V 24G部署YOLOv5全流程:CANN工具链与OM模型转换实操 前阵子手里拿到一块 Atlas 300V 24G第一反应是这玩意儿到底能不能拿来跑 YOLO网上搜了一圈信息很零散有人说它是“运算加速卡”有人说它跟显卡不是一回事还有人说部署 YOLO 麻烦得要命。我索性自己上手折腾了一遍从驱动、固件到 CANN 工具链再到 YOLOv5 的 ONNX 模型转换和推理把整个流程完整跑通了。这篇就把我的实操记录和踩坑经历写出来给想用 Atlas 300V 跑 YOLO 的同学一个真实参考。先说结论Atlas 300V 24G 是一张推理加速卡不是传统意义上的 GPU 显卡。它基于达芬奇架构由昇腾 310P 系列芯片构成24G 显存指的是板载 DDR4 内存设计目标就是做 AI 推理不支持 Windows 游戏用途也不能直接当一个“能跑 CUDA 的显卡”来用。但如果你要做 YOLO 推理部署换成昇腾的 CANN 工具链之后它的表现相当能打尤其在高并发批处理场景下性价比和功耗都很有优势。这篇文章我会分六个部分讲Atlas 300V 的硬件定位和规格解读部署前要准备哪些东西CANN 工具链安装和踩坑点YOLOv5 模型从 PyTorch 到 ONNX 再到 OM 的完整转换流程基于 ACLAscendCL的 Python 推理代码实战最后是性能调优和常见问题排查。整个过程我都用自己实际执行的命令和代码作为参考尽量做到拿来就能用。1. 硬件认知Atlas 300V 24G 到底是什么卡1.1 昇腾 310P 与推理卡的定位想用好 Atlas 300V第一步是把它跟 GPU 从底层认知上区分开。Atlas 300V 用的是昇腾 310P 芯片这颗芯片内部集成 AI Core 和 ARM 处理核心属于典型的 SoC 架构。它的核心逻辑是“把能固化在硬件里的计算都固化下来”AI Core 专门处理矩阵运算ARM 核心负责调度和预处理。这种设计的好处是能效比极高单卡功耗通常控制在 72W 左右而相同推理吞吐量的 GPU 显卡往往要 150W 以上。也正因为如此这张卡不适用于图形渲染也跑不了原生的 CUDA 程序。你在社区看到有人问“atlas 300v 24g 是运算加速卡吗”答案是肯定的但它做的是专用加速不是通用计算。对应到 YOLO 部署上推理路径就要走“PyTorch 训练权重 → ONNX → OMOffline Model”然后用昇腾的 ACL 接口或者 MindSpore Lite 去加载 OM 模型执行推理。1.2 24G 内存的真实含义与量化意义很多刚接触昇腾的人会把 24G 理解为“跟 24G 显存的显卡差不多”这是最容易走偏的地方。Atlas 300V 24G 的 24G 是板载 DDR4 内存由多个通道组成资源管理方式和 GPU 的 HBM 显存也不同。昇腾把内存划分为 HBM或 DDR内存和统一内存池通过 CANN 运行时做统一管理。放到 YOLO 场景里24G 内存对一个 YOLOv5s 模型几乎是“绰绰有余”——一个 YOLOv5s 的 OM 模型权重通常在 25MB 左右单帧输入为 640x640x3 时中间张量也就几百 MB所以 24G 的真正价值不在“单模型塞不下”而在“可以同时驻留多个模型或者用大 batch 跑高并发”。我自己的测试中用 batch8 处理一批 640x640 的图片峰值内存占用大概在 5.2GB整卡 24G 利用率只有约 22%。这说明对于 YOLOv5s 级别模型24G 余量非常大你可以同时加载 YOLOv5s、YOLOv5m、YOLOv8s 三个模型做串行推理或者干脆把 batch 拉到 16进一步提升整体吞吐。1.3 板卡形态与服务器适配Atlas 300V 是半高半长的 PCIe 卡接口 PCIe 3.0 x16绝大多数标准服务器都能直接插。但要注意一点它需要额外供电吗我拿到的是标准版本金手指供电就够不需要外接 6Pin。你要是买到带无源散热的版本记得确保机箱内有足够风道跑高负载时芯片温度我实测会在 75°C 左右散热不佳会触发降频影响推理性能。安装尺寸上建议先量一下你的机箱。部分 2U 机箱里如果已经塞了两张 GPU第三个槽位可能空间不够而且 Atlas 300V 的高度虽然符合半高规范但挡板类型分全高和半高两种购买前让供应商确认挡板规格不然后期要自己换挡板挺折腾的。2. 环境准备从驱动到固件的完整闭环2.1 官方路线图驱动/固件 CANN 工具包昇腾的部署有一个很明确的分层结构底层是驱动Driver和固件Firmware上层是 CANN 工具包。驱动负责让操作系统识别 PCIe 设备固件则控制芯片的底层行为CANN 负责提供编译器、运行时和算子库。三者版本需要严格匹配我的建议是直接去昇腾社区下载“Ascend HDK”和“CANN Toolkit”对应版本不要混搭。以 Ubuntu 20.04.5 为例安装顺序是安装驱动包 Ascend-hdk-xxx.run。安装固件包 Ascend-hdk-xxx-firmware.run。安装 CANN Toolkit比如 Ascend-cann-toolkit_7.0.0_linux-aarch64.run。安装 CANN Kernels 包。完成后用npu-smi info查看设备状态如果能列出 300V 设备说明底层已经通了。2.2 操作系统与 Python 版本选择Atlas 300V 的驱动对内核版本有要求。官方支持列表里写的是 Ubuntu 20.04/22.04、CentOS 7.6 等但内核小版本经常有坑。我的建议是老老实实用 Ubuntu 20.04 LTS内核 5.4 版本兼容性最好。我之前在一台 UOS 系统上尝试安装虽然能装上驱动但固件升级后 npu-smi 显示异常排查了两天才发现是系统版本不在官方支持矩阵里最后换系统解决。Python 版本方面CANN 7.0 支持 3.8、3.9、3.10。我用的 3.8因为 PyTorch 和 torchvision 在这个版本下的 wheel 包最齐全。你如果要用 3.10 也可以但个别第三方库比如 pycocotools需要重新编译多花时间不值当。2.3 固件升级的教训第一次装完驱动后我直接装了 CANN结果跑样例代码报错EI0001: Upgrade firmware before running this program.这个报错信息很明确但网上很多人会忽略。原因是新版本 CANN 的运行时依赖底层固件的某个接口升级旧固件不匹配就会拒绝加载模型。解决办法是去昇腾社区下载对应版本的固件包单独执行安装。整个过程大概 10 分钟。装完之后务必重启一次系统否则部分 DMA 相关接口不会重新初始化后面跑推理时可能出现随机崩溃。3. CANN 工具链安装与配置细节3.1 下载与安装阶段的关键参数从昇腾社区拿到Ascend-cann-toolkit_7.0.0_linux-aarch64.run后我用的是--install参数安装。这里有一个细节安装路径默认是/usr/local/Ascend但你完全可以用--install-path/home/user/ascend装到用户目录这样权限管理更灵活。作为一个不喜欢动不动就 sudo 的人我直接装到了用户目录下省去后面一堆权限问题。安装命令参考chmod x Ascend-cann-toolkit_7.0.0_linux-aarch64.run ./Ascend-cann-toolkit_7.0.0_linux-aarch64.run --install --install-path/home/user/ascend安装完成后需要设置环境变量官方建议在~/.bashrc里追加source /home/user/ascend/set_env.sh这个脚本会自动设置ASCEND_HOME_PATH、LD_LIBRARY_PATH、PYTHONPATH等关键变量。但有个小坑如果你是 root 用户set_env.sh里某些路径会指向/root下的目录非 root 用户运行程序时就要手动覆盖环境变量。我建议把关键路径写全不要只 source 脚本而是手动补充库目录。3.2 Python 侧依赖与 ACL 接口验证CANN 安装完毕后需要确认 Python 侧能导入acl模块python3 -c import acl; print(acl.__version__)如果报 ModuleNotFoundError先检查PYTHONPATH是否包含${ASCEND_HOME_PATH}/python/site-packages。这个目录在 7.0 版本的 CANN 里是真实存在的但有时候set_env.sh没有正确添加需要手动 export。再验证一个关键接口acl.init()import acl ret acl.init() print(acl init:, ret)返回 0 说明运行时初始化成功。这一步卡住的话优先检查/usr/local/Ascend/driver/lib64是否在LD_LIBRARY_PATH里驱动库不加载后续所有 ACl 调用都会报dlopen failed。3.3 验证算力简单矩阵乘测试为了保险起见我会在正式跑 YOLO 之前先跑一个简单的矩阵乘确认整个工具链真的能调用 AI Core。CANN 自带一个acl_execute_matmul的样例目录通常在$ASCEND_HOME_PATH/tools/下。如果找不到你可以自己写一个 1000x1000 的矩阵乘用 ACL 的 GEMM API 执行。实测跑完大约 3ms说明 AI Core 工作正常。这一步别跳过。好比新买的车要先在院子里转两圈再上高速否则后面 YOLO 性能异常时你根本分不清是模型问题还是底层问题。4. 核心环节YOLOv5 模型转换到 OM 格式4.1 从 PyTorch 权重导出 ONNX 的准备工作先明确任务路径我们最终需要得到一个.om离线模型文件这个文件由 ATC 工具把 ONNX 模型转换而来。而 ONNX 又需要从 PyTorch 训练的权重导出。所以第一步是准备一个干净的 YOLOv5 环境。我用的仓库版本是 YOLOv5 v6.0代码改动最少导出 ONNX 最顺利。安装依赖pip install torch1.10.0 torchvision0.11.0 onnx1.12.0 onnxruntime-gpu这里有个注意点PyTorch 和 ONNX 的版本不要贪新。yolov5 v6.0 的官方导出脚本export.py在 torch 1.10 下运行最稳用 torch 2.0 反而会报OnnxExporter的一些兼容性问题。准备一个训练好的权重文件best.pt放到 yolov5 根目录下。如果手上没有权重可以先用官方yolov5s.pt做测试它已经包含 COCO 80 类训练权重能直接导出和推理。4.2 导出 ONNX几个关键参数解释执行导出命令python export.py --weights best.pt --img 640 --batch 1 --include onnx --opset 11 --simplify参数含义--img 640设置模型输入尺寸为 640x640。后面 ATC 转换和推理代码里的输入尺寸必须保持一致。--batch 1导出 batch1 的 ONNX。注意ATC 转换后的 OM 可以动态 batch但先固定 1 更容易排查问题。--opset 11ONNX 算子集版本。opset 11 是昇腾 ATC 兼容性最好的版本。试过 opset 13转换时会报部分算子不支持需要手写映射规则不推荐。--simplify用 onnxsim 做模型简化去掉一些冗余的常量折叠节点可以让 ONNX 更干净。导出后得到一个best.onnx约 25MB。建议用onnx.checker.check_model做一次验证或者用 Netron 打开看一眼确保输入输出节点的名称和形状是你预期的。YOLOv5 v6.0 导出的输出格式是三个检测头的 cat 结果[batch, 25200, 85]这个 25200 是三个特征层预置框的总数80x8040x4020x20 对应的 anchor 数。记住这个形状后面写后处理代码要用。4.3 ATC 转换完整命令与参数说明ATC 工具位置在${ASCEND_HOME_PATH}/atc/bin/atc通常已经加入 PATH。我用的是完整参数atc --modelbest.onnx \ --framework5 \ --outputbest_om \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640 \ --loginfo \ --precision_modeallow_mix_precision参数逐条拆解--framework55 表示 ONNX。ATC 支持多种框架Caffe 是 0TensorFlow 是 3ONNX 是 5。--soc_versionAscend310P3这个参数极其关键必须与你的芯片型号匹配。Atlas 300V 使用的是昇腾 310P 芯片但 310P 内部有多个封装型号。如果不确定可以先跑npu-smi info看芯片型号或者在/usr/local/Ascend/driver/version.info里查。选错版本会导致 ATC 报错或者转换后模型在运行时行为异常。--input_shape固定输入形状这里和 ONNX 输入节点保持一致。如果导出 ONNX 时用的是images这个输入名那这里也写images。--precision_modeallow_mix_precision允许混合精度。310P 的 FP16 算力比 FP32 强很多使用混合精度能让推理延迟降低 40% 左右精度损失在 YOLO 目标检测任务里基本可以忽略。如果对精度极其敏感可以改为force_fp32但推理速度会明显下降。转换过程会输出很多 log重点看有没有ERROR或WARNING。如果遇到算子不支持的情况通常会有类似[ERROR] Unsupported op: XXX的信息这时候不要慌优先检查 ONNX 是否经过 simplify、opset 版本是否正确。我在转换时碰到过一个Resize算子不兼容的问题后来通过把--opset改成 11 并重新导出问题直接消失。转换成功后生成best_om.om大小和 ONNX 差不多。这个文件就是最终在 Atlas 300V 上执行的模型。4.4 动态 Batch 的进阶设置单 batch 的 OM 模型部署起来简单但实际业务往往需要高吞吐。你可以用 ATC 的动态 batch 能力atc --modelbest.onnx \ --framework5 \ --outputbest_dynamic_om \ --soc_versionAscend310P3 \ --input_shapeimages:-1,3,640,640 \ --dynamic_batch_size1,4,8,16设置-1表示 batch 维度动态同时用--dynamic_batch_size指定运行时允许的 batch 集合。注意ATC 转换时间会变长生成的 OM 文件也会变大而且运行时 buffer 管理需要你自己处理。我自己测试时发现 batch8 和 batch16 的吞吐差距已经不大建议优先选择 1、4、8 三档。5. 推理部署基于 ACL 的 Python 推理实战5.1 初始化与上下文管理CANN 的编程模型跟 CUDA 有很大区别。CUDA 里你直接操作 stream 和 deviceACL 里则要两步走先acl.init()初始化运行时再acl.rt.set_device()设置当前设备。参考代码import acl # 初始化 ACL ret acl.init() assert ret 0, facl.init failed, ret{ret} # 设置当前设备 device_id 0 ret acl.rt.set_device(device_id) assert ret 0, fset_device failed, ret{ret} # 创建 context context, ret acl.rt.create_context(device_id) assert ret 0, fcreate_context failed, ret{ret}这里有个容易忽略的点一个进程里通常只需要一次acl.init()和一次set_device后续所有操作都在这个 context 下进行。如果重复调用set_device会创建多个 context管理开销增大推理性能还会下降。我自己调试时因为多调用了一次set_device导致后续模型加载特别慢排查了半天。5.2 加载 OM 模型OM 模型加载使用acl.mdl.load_from_file返回模型描述句柄model_id。模型描述model_desc里包含输入输出的数量、形状、格式信息。model_path best_om.om model_id, ret acl.mdl.load_from_file(model_path) assert ret 0, fload model failed, ret{ret} model_desc acl.mdl.create_desc() ret acl.mdl.get_desc(model_desc, model_id) assert ret 0, fget_desc failed, ret{ret} # 读取输入输出信息 input_size acl.mdl.get_num_inputs(model_desc) output_size acl.mdl.get_num_outputs(model_desc) print(finputs: {input_size}, outputs: {output_size})YOLOv5 的 OM 模型只有一个输入和一个输出。输入节点名是images输出节点形状是[1, 25200, 85]。这里 85 4 个框坐标 1 个置信度 80 个类别概率COCO。5.3 数据预处理BGR、Resize、Normalize 与 NCHWYOLOv5 的预处理流程是读取图片BGR 格式OpenCV 默认。Resize 到 640x640保持长宽比多余部分用 114 填充灰色。像素值从 0-255 归一化到 0-1使用均值 [0,0,0]、方差 [0.0039215686]即除以 255。HWC 转 CHWNCHW 排布。代码实现import cv2 import numpy as np def preprocess(img, size640): h, w img.shape[:2] scale min(size / w, size / h) nw, nh int(round(w * scale)), int(round(h * scale)) resized cv2.resize(img, (nw, nh), interpolationcv2.INTER_LINEAR) canvas np.full((size, size, 3), 114, dtypenp.float32) dx, dy (size - nw) // 2, (size - nh) // 2 canvas[dy:dynh, dx:dxnw, :] resized # BGR - RGB 可根据需要决定YOLOv5 官方训练时用的是 RGB canvas canvas[:, :, ::-1] # BGR to RGB canvas canvas / 255.0 # HWC - CHW input_tensor np.transpose(canvas, (2, 0, 1)) input_tensor np.expand_dims(input_tensor, axis0).astype(np.float32) return input_tensor, scale, dx, dy这里要注意dx, dy的保存后面 NMS 之后要把坐标映射回原始图需要用这两个偏移量反算。如果你忘记偏移量检测框会整体偏移常见的目标 detect 不准问题就出在这里。5.4 执行推理与数据拷贝执行推理前需要把预处理后的数据拷贝到设备侧内存。ACL 的做法是先申请 device 内存再拷贝数据然后调用acl.mdl.execute。import acl # 申请 device 内存 input_tensor preprocess(img) # shape: [1, 3, 640, 640] nbytes input_tensor.nbytes input_ptr, ret acl.rt.malloc(nbytes, 2) # 2 表示 16 字节对齐 assert ret 0 # host 到 device 拷贝 ret acl.rt.memcpy(input_ptr, nbytes, input_tensor.ctypes.data, nbytes, acl.ACL_MEMCPY_HOST_TO_DEVICE) assert ret 0 # 准备输出 buffer output_nbytes 1 * 25200 * 85 * 4 # float32 output_ptr, ret acl.rt.malloc(output_nbytes, 2) assert ret 0 # 构造输入输出描述 input_data acl.mdl.create_data_buffer(input_ptr, nbytes) output_data acl.mdl.create_data_buffer(output_ptr, output_nbytes) # 执行推理 stream, ret acl.rt.create_stream() ret acl.mdl.execute(model_id, [input_data], [output_data]) acl.rt.sync_stream(stream) # 拷贝输出回 host output_np np.zeros((1, 25200, 85), dtypenp.float32) ret acl.rt.memcpy(output_np.ctypes.data, output_nbytes, output_ptr, output_nbytes, acl.ACL_MEMCPY_DEVICE_TO_HOST)这段代码是标准的 ACL 推理模板后面接不同的模型只需改输出形状和预处理逻辑。需要注意acl.rt.create_stream()这一步很多初学者会忘记导致acl.mdl.execute一直阻塞或者报 context 错误。stream 的作用类似于 CUDA stream用于管理设备上任务的执行顺序。5.5 后处理解析输出、NMS 与坐标映射YOLOv5 的输出张量形状是[1, 25200, 85]每一行表示一个预置框包含 [cx, cy, w, h, obj_conf, class_conf_0, class_conf_1, ...]。后处理分三步第一过滤低置信度框。YOLOv5 的 obj_conf 和 class_conf 分开通常只需取class_conf的最大值和对应类别然后用obj_conf * class_conf_max作为最终分数过滤掉低于 0.5 的框。第二将预测的 cx, cy, w, h 转换为 x1, y1, x2, y2 边框格式。YOLOv5 默认输出是归一化到 0-1 的需要乘以输入尺寸 640再减去偏移量除以缩放比例映射回原图。第三NMS 去重。我直接用了cv2.dnn.NMSBoxes不自己重复造轮子。对于 25200 个框OpenCV 的 NMS 性能足够单张图大概 1ms。参考关键代码def postprocess(output, scale, dx, dy, confidence_thres0.5, iou_thres0.45): # output shape: [1, 25200, 85] preds output[0] # [25200, 85] boxes, scores, class_ids [], [], [] for pred in preds: class_probs pred[5:] class_id np.argmax(class_probs) conf class_probs[class_id] * pred[4] if conf confidence_thres: continue cx, cy, w, h pred[:4] * 640 x1 (cx - w / 2 - dx) / scale y1 (cy - h / 2 - dy) / scale x2 (cx w / 2 - dx) / scale y2 (cy h / 2 - dy) / scale boxes.append([x1, y1, x2, y2]) scores.append(conf) class_ids.append(class_id) if len(boxes) 0: return [], [], [] boxes np.array(boxes, dtypenp.float32) scores np.array(scores, dtypenp.float32) indices cv2.dnn.NMSBoxes(boxes.tolist(), scores.tolist(), confidence_thres, iou_thres) result_boxes boxes[indices] result_scores scores[indices] result_class_ids [class_ids[i] for i in indices] return result_boxes, result_scores, result_class_ids这段后处理代码基本可以直接迁移到生产环境唯一需要按场景调整的是confidence_thres。如果是闹市区监控场景阈值建议 0.25 搭配更严格的 NMS iou0.5如果是工业质检场景阈值拉到 0.8 也不为过。5.6 性能实测与资源观测整个流程跑通后我用一张 1080p 图片做了性能测试。单 batch、FP16 混合精度条件下Atlas 300V 跑 YOLOv5s 的纯推理延迟大约 4.5ms加上预处理和后处理整链路约 8ms。如果开启动态 batch 用 batch8单帧平均延迟可以压到 1.8ms。查看运行时的 NPU 利用率可以用npu-smi info输出里能看到 AICore 利用率、内存占用、温度等。实测 batch8 时 AICore 利用率跑到 87%内存占用 5GB 左右温度稳定在 72°C。如果发现 AICore 利用率低于 50%通常意味着模型存在大量小算子调度开销可以通过--optypelist_for_implmode把算子替换成高融合模式或者检查预处理数据拷贝是否成为瓶颈。6. 常见问题与排查技巧实录6.1 问题速查表我整理了一份自己实测中遇到的典型问题按优先级排列症状可能原因解决方案npu-smi 看不到设备驱动未装好 / 固件版本不匹配重装驱动升级固件检查内核版本acl.init 返回非 0LD_LIBRARY_PATH 缺少驱动库手动添加/usr/local/Ascend/driver/lib64ATC 转换报 Unsupported opONNX opset 版本过高重新导出 ONNX使用 opset 11推理输出全 0输入数据没有做 RGB 转换或归一化检查预处理流程确认均值方差推理延迟突然变高散热不足触发降频用 npu-smi 查温度改善机箱风道加载多个模型内存不足动态 batch 设置过大限制 batch 档位或者释放不用的模型6.2 模型输出异常的全链路排查法如果 NMS 后的检测框明显错误我的排查顺序是先用固定图片和固定权重在 CPU 上用 PyTorch 自带的推理脚本跑一遍核对框坐标和类别。再用 ONNX Runtime 跑 ONNX 模型确保 ONNX 本身没问题。最后才用 OM 模型在 Atlas 300V 上跑对比三个结果是否一致。这个思路能帮你快速定位是哪个环节出了问题。我遇到过的一个案例是 80 类类别索引对不上——因为我在预处理时做了 BGR 转 RGB但导出 ONNX 时 YOLOv5 的导出脚本会固定把输入当成 RGB 数据而我的图片数据又是 BGR最终导致推理结果完全错误。后来统一为 RGB 并调整读取方式问题立刻消失。6.3 独家避坑千万不要忽略的一个小参数acl.rt.malloc的对齐参数是 2表示 16 字节对齐。很多人直接传 0后面推理时会偶发段错误或者模型输出偶尔异常。这个坑非常隐蔽因为在低压力下可能一直正常压力一大就开始崩。建议所有 device 内存分配统一使用对齐参数 2遵从昇腾文档的规范。另一个经验是如果用 MindSpore Lite 提供的 Python API 而不是手写 ACL代码量可以少一半。MindSpore Lite 对 YOLO 场景封装得比较好尤其适合快速验证。它的接口类似 PyTorchmodel.predict(input_tensor)就能出结果。不过底层还是需要 CANN 和驱动支持建议两种方案都掌握线上部署用 ACL 拿最低延迟日常调试用 MindSpore Lite 提升效率。6.4 部署形态与扩展建议如果你要把 Atlas 300V 投入真正的生产环境建议做成 HTTP 推理服务采用 Flask 或 FastAPI 作为 Web 框架进程内常驻加载模型接收 base64 编码的图片。我自己做过一个简单版本用 FastAPI Uvicorn单进程并发处理 4 路视频流每路实时检测没有掉帧。多卡扩展时Atlas 300V 支持在同一台服务器上插多张卡Atlas 300V 通过 PCIe 交换机互联你可以用acl.rt.set_device(device_id)分别指定卡号。如果模型太大一张卡放不下可以尝试模型并行但 YOLO 这类检测模型通常没有这个必要。最后分享一个小技巧CANN 的 ATC 工具支持--insert_op_conf参数插入 AIPP 配置把 Resize、Normalize 这些预处理直接烧进模型里这样推理时数据拷到设备内存后直接执行模型不需要在 host 端做任何预处理CPU 占用和整体延迟能进一步下降。配置方式很简单写一个aipp.cfg里面指定 mean、variance、crop 参数然后 ATC 转换时加上--insert_op_confaipp.cfg。我自己在线上项目里就是靠这个把整链路延迟从 8ms 降到了 5.5ms。Atlas 300V 部署 YOLO 这条路真走下来并没有网传那么玄乎。归根结底就是三件事把硬件认清楚把 CANN 工具链装对把模型转换和后处理代码写规范。这套流程跑通之后剩下的就是根据你的业务场景调 batch 和精度模式了。希望这篇记录能帮你少走几个弯路。
返回列表