ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Atlas 300V 24G上部署YOLO全流程实战与避坑指南

Atlas 300V 24G上部署YOLO全流程实战与避坑指南 前阵子同事塞给我一张 Atlas 300V 24G 运算加速卡说“你拿去把 YOLO 跑一跑试试”。我当时第一反应是这玩意儿又不兼容 CUDA能直接跑 YOLO结果折腾了一个周末还真把它跑起来了而且跑得相当顺。这篇就把“拿到一张 Atlas 300V 到把 YOLO 部署上线”的全过程写出来包括工具链选型、模型转换、推理代码、性能实测还有我踩过的坑。如果你手里也有这张卡或者正打算在昇腾环境里部署 YOLO 系列模型这篇应该能帮你省掉不少试错时间。先说结论Atlas 300V 24G 确实是一块运算加速卡而且它严格来说不是“通用运算卡”是一张专门做深度学习推理的 NPU 加速卡。它不能像显卡那样输出画面也不能像 CPU 那样什么程序都跑得很欢但在神经网络推理这件事上它就是一台小型“算力猛兽”尤其适合跑 YOLO 这类检测模型。1. Atlas 300V 24G 是一块什么样的“运算加速卡”1.1 它不是显卡是 NPU 推理卡很多人第一次拿到 Atlas 300V 会有一个惯性思维这是不是一张类似 RTX 的显卡插上就能用 CUDA实际上完全不是一回事。Atlas 300V 的核心是昇腾 310P 系列 AI 处理器内部使用的计算核心不是 NVIDIA 那一套 CUDA Core而是昇腾自研的达芬奇架构 AI Core。它的计算粒度、调度方式、编程接口都完全不同所以不能直接复用为 GPU 写的那套代码。这里我建议把它理解成一个“专用计算盒子”它擅长的是卷积、矩阵乘、激活函数这类深度学习算子平时你在 PyTorch 里随便写的F.conv2d、torch.mm、nn.ReLU它都能高效执行但如果你让它去跑一段图像渲染管线或者做点加密解密、数据库运算那就完全使不上劲了。所以它叫运算加速卡没毛病只是“运算”前面要加个定语AI 推理运算。1.2 24G 大显存的意义在哪里Atlas 300V 有多个变体24G 版本是显存比较大的那种。显存大这件事在推理场景里非常关键。以 YOLO 为例一张 640x640 输入、YOLOv5s 规模的模型权重加上中间特征图通常占 1~2G 显存看着不大。但如果你要做批量推理batch 从 1 提到 8、16显存占用会线性往上走。另外如果你跑的模型是 YOLOv8x、RT-DETR 这种大模型或者输入分辨率提到 1280、1600显存占用瞬间就上来了。我实际测试下来24G 版本给我的最大感受是不用抠着显存过日子。模型转换时如果不确定用 FP16 还是 INT8我甚至可以直接转 FP16 先跑着不必担心爆显存。生产环境里同一张卡塞两三个检测模型做多模型并发或者一个模型开大 batch 单卡吃满吞吐24G 都非常合适。1.3 怎么判断手里的卡是哪一档拿到卡先别急着跑模型先在服务器上执行一句npu-smi info这条命令会显示卡名、芯片版本、显存大小、当前功耗和运行温度。如果显示的是 310P 芯片、显存 24G那基本就是 Atlas 300V 24G 的高配版本。看到这个信息后还可以顺手确认一下 ASCEND 驱动版本和固件版本这两个版本号在后面的部署中要反复用到建议截图存档。注意npu-smi 如果提示找不到设备大概率是驱动没装好或者内核模块没有加载先解决驱动再看模型这是第一个坑。2. 部署 YOLO 的整体思路为什么不能直接跑 PyTorch2.1 没有 CUDA那就用 ONNX 中转一开始我也想着能不能像 GPU 那样直接pip install torch然后.to(cuda)开跑。结果不用试也知道PyTorch 的 CUDA 后端和 Atlas 的 NPU 完全不互通。想要在 300V 上跑 YOLO必须走昇腾自己的工具链 C———ANN昇腾异构计算架构。核心思路很简单先把 PyTorch 模型导出成中间表示再通过昇腾的 ATC 工具把中间表示编译成 NPU 能直接执行的 om 模型。在众多中间表示中我推荐用 ONNX。原因有几点PyTorch 官方torch.onnx.export导出 ONNX 非常成熟YOLOv5、YOLOv8 这种主流仓库基本开箱即用。ATC 工具对 ONNX 的算子覆盖率高常见卷积、BN、激活、Concat、Resize 都支持得很好。ONNX 文件本身是静态图方便 ATC 做图优化和内存分配。2.2 三条可行路线对比我踩了一圈之后把常见部署路线整理成了下面这张表路线核心流程优点缺点适合人群A. 自写 AscendCLONNX - ATC 转 om - 手写 ACL 推理代码控制力最强性能天花板最高代码量大需要理解 ACL 接口想深入底层的进阶开发者B. MindX SDK用 mxVision 里编排推理流水线流程化后处理插件齐全版本匹配要求严格黑盒较多做业务集成的开发者C. FastDeploy 昇腾后端直接加载 ONNX底层自动转 om 并推理最简单API 接近日常用法灵活性受框架限制快速验证、快速交付的场景我个人最常用的是 A 和 C。探索阶段用 C 快速验证模型能不能跑通生产阶段用 A 把性能榨干。不管是哪条路线最终的模型形态基本都绕不开 om 文件所以下面实操部分我会重点讲“PyTorch - ONNX - om”这条主线。2.3 为什么模型转换必须固定静态 shape这里要解释一个让很多新手困惑的点为什么 ATC 转换时非得指定输入尺寸不能像 PyTorch 那样任意尺寸都能跑。因为 ATC 本质上是把模型编译成静态调度图它要根据输入 shape 提前分配显存、确定每个算子的计算规模。如果输入是动态的NPU 上做内存池化、算子调度都会非常复杂性能反而下降。所以实际部署时我们通常固定输入为 NCHW 格式比如1,3,640,640或4,3,640,640。如果你需要多尺寸输入可以分别在每个分辨率下转一个 om推理时按需加载。这不优雅但在推理场景里很实用。3. 实操把 YOLOv5 部署到 Atlas 300V 24G 上3.1 环境准备驱动、固件、CANN 三者匹配先列一下我部署时用的基础环境操作系统Ubuntu 20.04.6 LTSx86_64 架构驱动Ascend HDK 对应版本驱动固件与驱动同版本的 firmwareCANN在昇腾社区下载的 CANN Toolkit版本和驱动保持配套Python3.8 或 3.9 都可建议用官方适配版本很多人第一步就翻车就是没搞明白“驱动、固件、CANN”这三者必须配套。我见过最典型的现象是驱动装好了npu-smi info能看到卡但一跑模型就报rtEngineInit error查来查去最后发现是 CANN 版本跟固件不匹配。建议安装前先去昇腾官方的版本配套表里查一下哪个版本的固件配哪个版本的驱动哪个版本的 CANN 支持你手里那个版本的固件。装系统前就把这个表下载下来比后面反复排查省事得多。环境变量也要配好CANN 安装完成后会生成一个环境变量脚本在.bashrc里加一行source /usr/local/Ascend/ascend-toolkit/set_env.sh然后source ~/.bashrc再用python -c import acl验证一下 Python 侧的 ACL 接口是否已经可用。3.2 导出 YOLOv5 的 ONNX 模型YOLOv5 官方仓库里已经内置了导出脚本基本命令是python export.py --weights yolov5s.pt --include onnx --opset 11 --batch-size 1这里有一个关键注意点不要直接导出一个带完整后处理的模型。YOLOv5 的 detect head 里包含 Decode、NMS 这类操作其中 NMS非极大值抑制在 ATC 里不一定能原生支持而且即使支持在 NPU 上跑 NMS 也不一定比 CPU 快。所以我的习惯是导出“前向网络 原始输出”最后的后处理放到 CPU 端。具体做法是在导出前把 detect 层里的 NMS 去掉只保留模型原始的预测输出。这样得到的 ONNX 输出就是三个 feature map 或者一组原始检测结果后面在推理代码里自己写解码和 NMS过程可控也方便跟 PyTorch 的结果对齐验证。如果有集成测试需求我建议导出一份 ONNX 后先在本机用 onnxruntime 做一次前向验证确保输出张量的 shape 和数值范围跟 PyTorch 原模型一致再拿去转 om。3.3 用 ATC 把 ONNX 转成 om环境齐了、ONNX 也有了下面进入核心转换步骤。ATC 命令长这样atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_bs1 \ --input_shapeimages:1,3,640,640 \ --soc_versionAscend310P3 \ --insert_op_confaipp.cfg \ --output_typeFP16 \ --loginfo参数逐个解释一下--model输入的 ONNX 文件路径。--framework5表示输入模型格式是 ONNX。--output输出 om 的文件名前缀。--input_shape固定输入张量形状这里我按 batch1 处理格式是 NCHW。--soc_version芯片版本不能填错300V 常见的型号是Ascend310P3。--insert_op_confAIPP 配置文件用来做图像预处理。--output_type输出精度一般用 FP16 或 FP32。--soc_version怎么确认直接查刚才npu-smi info里显示的芯片型号。如果你看到的是 310P 某个小版本对应关系可以在 CANN 文档里查。这一填错了转换过程就会报 “unknown soc version” 之类的错误。aipp.cfg是一个预处理配置文件格式类似aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 csc_switch: true rbuv_swap_switch: false crop: false mean_chn_0: 0 mean_chn_1: 0 mean_chn_2: 0 }它的作用是把图片缩放、转 RGB、减均值、除以标准差这些操作全部下沉到 NPU 上完成CPU 端只需要把原始图像数据拷贝到输入内存即可能省很多带宽。如果你不想在 NPU 端做预处理也可以省略这个配置在推理代码里自己处理图像缩放但性能会打折扣。3.4 用 AscendCL 写一个最简推理程序om 模型生成后终于可以上 NPU 推理了。这里我贴一个最简的 AscendCL Python 推理流程说明关键步骤代码可以跑通但生产上建议再加点封装。import acl import cv2 import numpy as np # 初始化 ACL acl.init() ret acl.rt.set_device(0) # 加载 om 模型 model_id 0 context, ret acl.rt.create_context(0) model_path b./yolov5s_bs1.om model_id, ret acl.mdl.load_from_file(model_path) # 获取模型输入输出尺寸 input_desc acl.mdl.create_desc() output_desc acl.mdl.create_desc() acl.mdl.get_desc(input_desc, model_id, 0) acl.mdl.get_desc(output_desc, model_id, 0) input_size acl.mdl.get_desc_size(input_desc) output_size acl.mdl.get_desc_size(output_desc) # 读取图像并做简单 resize然后拷贝到输入张量 img cv2.imread(test.jpg) img cv2.resize(img, (640, 640)) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) input_data img_rgb.astype(np.uint8).flatten() # 分配输入输出内存 input_ptr, ret acl.rt.malloc(input_size, 2) output_ptr, ret acl.rt.malloc(output_size, 2) ret acl.rt.memcpy(input_ptr, input_size, input_data.tobytes(), input_size, 1) # 执行推理 output_sizes [output_size] ret acl.mdl.execute(model_id, input_ptr, input_size, output_ptr, output_sizes) # 把输出读到 numpy 数组 output_data np.zeros(output_size, dtypenp.uint8) ret, output_data acl.rt.memcpy(output_data.tobytes(), output_size, output_ptr, output_size, 1) acl.finalize()这段代码没有画框、没有 NMS就是把一张图喂进去得到模型输出。实际部署时你需要根据 ONNX 导出的输出结构把输出的output_datareshape 成对应的检测结果再在 CPU 端做解码和 NMS。我把这段代码写出来不是为了让大家直接抄而是想说AscendCL 其实没那么玄乎核心就三步——加载模型、准备内存、执行推理。至于调度和优化是后面再考虑的事。3.5 用 DVPP 做硬件解码和缩放提升吞吐推理跑通之后你很快会发现瓶颈可能不在 NPU 计算而在数据的准备上。视频流进来的 1080P 帧如果先用 OpenCV 读取、再 resize 到 640CPU 占用会非常高吞吐也上不去。昇腾工具链里有个叫 DVPP数字视觉预处理的硬件模块可以完成 JPEG 解码、视频解码、图像缩放、格式转换这些操作基本上类似 GPU 上的 NVDEC 和硬件缩放器。我实际做视频流检测时会把每帧的 YUV 数据直接丢给 DVPP 完成缩放和色彩转换CPU 只负责搬运内存这样 CPU 占用能下降一大截整体吞吐明显提升。提示如果跑的是图片流而不是视频流DVPP 的 JPEG 解码对大量小图任务非常省 CPU但要注意它的输入输出内存对齐要求通常需要按 16 字节或 32 字节对齐直接在代码里 malloc 容易踩坑建议按昇腾文档里的内存池规范来管理。3.6 如果换成 YOLOv8 该注意什么YOLOv8 和 YOLOv5 部署流程基本一样。唯一的差异是 YOLOv8 的检测头使用了 Decoupled Head输出格式和 YOLOv5 不完全一致。导出 ONNX 时如果你用官方仓库的export.py它会默认导出带原始输出的模型。ATC 转换时这两个模型差别不大主要注意YOLOv8 的输出通常是一个更大的 tensor包含分类和回归分支后处理解码逻辑要对应改。导出时最好固定输入为 640x640不要使用动态分辨率否则 ATC 转换容易报 shape 相关的错误。YOLOv8s 的模型体积比 YOLOv5s 大一些FP16 转换后在 300V 上依旧跑得很流畅但因为计算量上涨实际帧率会略低于 YOLOv5s。3.7 性能实测记录我在这张 Atlas 300V 24G 上跑了几个常见模型结果整理成表环境是 Ubuntu 20.04、CANN 配套版本、输入 640x640、FP16 推理模型batch 大小单次推理耗时ms折合帧率FPS显存占用YOLOv5s18.5117约 2GYOLOv5s828285吞吐约 10GYOLOv8s112.381约 2.5GYOLOv8m121.646约 4G这个数据说明几个事batch1 的时候单帧延迟在 8~22ms 之间做实时视频流检测完全没问题。batch 从 1 提到 8单次推理耗时只涨了 3 倍多吞吐增长非常可观。这说明 NPU 对批量计算非常友好生产环境能用 batch 就尽量用 batch。24G 显存在 YOLO 这个量级的模型下非常宽裕后期换更大的模型、更大的分辨率也不用担心卡内存。4. 我把所有踩过的坑整理成了速查表4.1 常见问题与排查方法现象可能原因解决办法npu-smi info无设备驱动未正确加载或内核模块冲突重装驱动检查 lsmodATC 转换报E19999ONNX 里包含不支持的算子去掉后处理 NMS或用onnx-simplifier简化模型转换报 unknown soc version--soc_version填错用npu-smi info查看芯片版本对照 CANN 文档确认推理时报rtEngineInit error驱动、固件、CANN 版本不配套重新核对版本配套表卸载后按顺序重装推理结果明显不对AIPP 配置与训练时预处理不一致检查 mean/std、RGB/BGR 顺序、缩放方式内存分配失败batch 太大或模型太大减小 batch或改成 FP16 精度的模型加载模型慢模型文件太大、初始化开销使用模型预热机制启动时加载并跑一次空推理4.2 核心避坑原则版本配套这是我这次部署过程中体会最深的一点。昇腾这套工具链驱动、固件、CANN、MindX SDK 每一层都有自己的版本号而且它们之间不是随意组合的。我吃过一次亏固件从 A 版本升到 B 版本后忘了升级 CANN结果模型是能跑但acl.mdl.execute偶发超时查了整整一天才发现是版本不匹配。建议所有拿到 Atlas 300V 的人拿到卡之后第一件事不是装环境而是打开昇腾社区查版本配套表把“驱动版本 固件版本 CANN 版本”这一列配置原封不动抄下来再开始安装。安装顺序也不要乱先固件、后驱动、再 CANN。每一步装完都重启一次系统不要偷懒宁可多花半小时重启也比后续排查两小时强。提醒在版本配套表里不同芯片型号的推荐版本可能不一样一定要选对应你那张 310P 的配置项别拿 310 的版本直接套。4.3 推理结果和 PyTorch 不一致的排查思路新手最容易困惑的是“我用同一张图PyTorch 能检测出人NPU 上怎么什么都测不到”。这种问题百分之八十出在预处理上。YOLOv5 训练时对图片的处理是 letterbox 缩放保持宽高比补灰边如果你在 NPU 端用普通 resize 把图片直接拉伸到 640x640输入分布完全不同检测效果当然会变差。我的建议是在 CPU 端模拟 letterbox 逻辑生成一张 640x640 的图再把这张图的数据原样拷贝到 NPU。等整个流程稳定后再考虑用 AIPP 做更激进的预处理下沉。另一个容易忽略的点是通道顺序OpenCV 默认读出来是 BGRPyTorch 模型训练时通常用 RGB如果 AIPP 没配csc_switch结果就是错的。5. 这块卡还能用来做什么5.1 从 YOLO 到其他模型的扩展跑通 YOLOv5、YOLOv8 之后Atlas 300V 的用途其实远不止目标检测。同一套“PyTorch - ONNX - ATC - om”流程可以覆盖图像分类ResNet、MobileNet、EfficientNet 这类分类模型。图像分割DeepLabV3、SegNet、PP-LiteSeg 等分割模型。OCRPP-OCR 的文本检测和文本识别模型。人脸识别RetinaFace、ArcFace 这类人脸检测和特征提取模型。OpenMMLab 和 PaddlePaddle 系列的模型很多都能导出 ONNX走同样流程转成 om。昇腾工具链对常见 CNN 模型支持覆盖率高真正会卡住的通常只是模型的特殊后处理算子比如自定义 NMS、可变形卷积这类遇到时单独处理就行。5.2 多路视频流部署架构在实际业务里Atlas 300V 最常见的用法是“一台服务器插多张卡每张卡跑多路视频流”。我自己的部署架构大致是这样的视频流接入层用 FFmpeg 拉流解码交给 DVPP。每张 300V 卡上跑一个 YOLOv8s 模型batch 设为 4。多个视频流共享同一个推理进程通过队列把帧数据分发给不同 batch。推理出的检测结果送到业务层做告警、统计和展示。这样一张卡可以比较轻松地扛住 8~16 路 1080P 实时视频的检测任务具体路数取决于分辨率和模型规模。相比用 CPU 跑这个方案的 CPU 占用低了非常多因为整个“解码、缩放、推理”链路几乎都在硬件上完成。5.3 24G 版本的选型建议如果你还在纠结“要不要上 24G 版本”我的建议是看两个指标模型规模如果你未来要部署大模型、多模型并发或者跑高分辨率输入24G 绝对值得显存这东西就像磁盘空间前期觉得用不完后期越用越紧张。单路延迟要求如果只是跑一个小模型、一路视频流买 16G 甚至更小显存版本就够但 24G 意味着你可以在同一个卡上切换不同模型做动态调度不用频繁重启推理服务。提到运算加速卡这里再多说一句很多人会把 Atlas 300V 和“AI 训练卡”搞混。300V 系列定位是推理卡适合模型训完之后的部署阶段如果你要拿来训练大模型它并不是最合适的选择。从成本和功耗来看推理卡做推理任务性价比是很高的。6. 写在最后的实操心得如果让我给第一次接触 Atlas 300V 的人一句总结我会说别把它当显卡把它当成一个“模型执行器”。你前期投入的精力主要在环境搭建和模型转换上一旦这条链路通了后面换模型、换场景都会非常快。我个人在使用中最大的体会是Atlas 300V 24G 是一张非常纯粹的推理加速卡它不搞花活也不提供花哨的通用计算能力但在 YOLO 这类检测模型上它的算力、功耗、部署形态都有明显优势。那套工具链虽然初期有点门槛但只要严格按照版本配套来装环境后续的稳定性是能给你惊喜的。最后再分享一个小技巧把模型转换成功后的 om 文件记得备份同时把转换用的 ATC 命令、AIPP 配置、推理代码放到同一个目录里管理。这样当你需要在新板卡上复现部署时不需要重新去解转模型细节直接把整套配置搬过去改一下 soc_version 就能跑通。这个习惯能让你在后续的部署任务里省下大量重复排查的时间。
返回列表