ARTICLE DETAIL

资讯详情

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

昇腾Atlas 300V 24G部署YOLOv5全流程:从ONNX到ATC转换到ACL推理

昇腾Atlas 300V 24G部署YOLOv5全流程:从ONNX到ATC转换到ACL推理 前两天群里又有人问“Atlas 300V 24G到底是不是运算加速卡” 紧跟着就是一串问题能不能跑YOLO部署流程和N卡一样吗性能到底行不行这类问题我几乎每周都能看到。很多人第一次接触昇腾Atlas时下意识会拿NVIDIA那套经验去套结果在驱动、模型转换、推理接口上卡得怀疑人生。Atlas并不是一张“换了牌子的GPU”它是基于达芬奇架构的AI专用处理器整个软件栈和CUDA体系完全不一样。这篇文章我从“Atlas 300V 24G是什么卡”这个基础问题聊起然后完整走一遍在Atlas上部署YOLO的流程包括环境准备、ONNX导出、ATC转换、ACL推理以及我在实际部署中踩过的坑。适合准备上手昇腾推理卡、或者已经在用但被各种报错折磨的同学看完你应该能对整套流程有个清晰的判断。1. Atlas到底有哪些卡300V 24G算什么定位1.1 先理清Atlas家族再谈部署答案是是运算加速卡但它是面向推理场景的运算加速卡不是训练卡。很多人一说“加速卡”就默认它该像GPU一样既能训练又能推理这个认知偏差是后续所有困惑的根源。Atlas产品线分工其实很清晰我直接列个表卡型定位典型场景侧重点Atlas 300T训练卡模型训练、微调大算力、高内存带宽Atlas 300I推理卡通用AI推理高吞吐、低延迟Atlas 300V视频图像推理卡视频流/图像分析推理 硬件解码Atlas 200 DK开发者套件学习、原型验证低功耗、便携Atlas 300V Pro增强版视频推理卡多路视频结构化高密度视频解码Atlas 300V 24G这种卡从规格命名就能看出它的基因300V是产品系列24G是内存容量Pro后缀代表增强版。它的核心设计目标不是跑训练任务而是把训练好的模型拿来做高并发的视频流推理所以卡上除了AI算力单元还集成了视频解码能力可以硬解多路视频流。这意味着你做个视频目标检测系统从视频流拉流、解码、缩放、模型推理、输出检测框整条链路都能在这张卡上闭环不需要额外占用GPU做解码。1.2 为什么有人会把它误认成“训练卡”核心原因是参数表里的TOPS值很唬人。Atlas 300V Pro标注的INT8算力能到140 TOPS不同版本有差异这个数字比很多桌面级GPU的FP32算力还高。但注意单位TOPS是整数运算能力而且是INT8低精度下的理论峰值和GPU标称的FP32 TFLOPS根本不是一个衡量口径。AI推理场景里模型量化成INT8后精度损失可控、吞吐大幅提升所以推理卡厂家都喜欢强调INT8算力而训练需要FP16/FP32的高精度计算对精度和动态范围的要求完全不同。另一个混淆点在于Atlas 300V确实有24GB的大显存很多人看到“大显存”就下意识觉得“能塞大模型、能训练”。实际上推理卡的显存主要用来缓存模型权重和中间特征图24GB对YOLO这类检测模型来说属于“绰绰有余”一张卡能塞好几个模型做多模型并发而不是为了跑大批量训练。1.3 那它到底能不能训练能跑但别指望效率。如果你非要在Atlas 300V上跑PyTorch的YOLO训练脚本现实是官方主推的昇腾训练栈MindSpore或者PyTorch适配框架对训练场景做了大量优化但推理卡在驱动和固件层面限制了反向传播、动态shape等训练必需特性的性能。我见过有人在300V上硬跑小batch的YOLOv5训练能跑起来loss也在降但速度比同价位训练卡差一个数量级属于“能用但毫无意义”的范畴。所以结论放到前面Atlas 300V 24G是专业的AI推理加速卡尤其擅长视频图像场景。你要做模型推理部署选它没问题你要做训练去租云GPU或者上Atlas 300T这类训练卡。2. 在Atlas上部署YOLO为什么不能照搬N卡的流程2.1 昇腾软件栈和CUDA体系完全不同NVIDIA的部署逻辑是PyTorch/TensorFlow训练好模型导出ONNX再用TensorRT优化成engine文件最后在GPU上跑。昇腾的逻辑在宏观上类似但每一层都换了名字和实现方式驱动固件相当于N卡的驱动负责让操作系统识别NPU设备一般用npu-smi info查看设备状态。CANN昇腾的计算架构你可以理解成“CUDA cuDNN”的合体。它提供底层算子库、图编译引擎、运行时环境所有上层框架都跑在CANN之上。ATC工具模型转换工具相当于TensorRT的角色。把ONNX/PB等格式的模型转换成昇腾NPU可执行的.om格式文件转换过程中会做算子融合、内存复用、格式转换等优化。推理框架官方有AscendCL简称ACL和MindSpore Lite两条路。ACL是底层C/C/Python接口控制力最强MindSpore Lite封装更友好适合快速上手。这套体系里最核心、也最容易被忽略的一点是PyTorch的.pt权重文件不能直接在NPU上跑。NPU不认识PyTorch的算子你必须先导出ONNX再通过ATC转成om格式。而且不是所有ONNX算子昇腾都支持遇到不支持的算子需要改图或者用“自定义算子”绕过去。这一点和TensorRT处理不支持的层时非常像。2.2 YOLO模型选型v5还是v8昇腾推理场景下我首推YOLOv5原因很简单YOLOv5的ONNX导出机制非常成熟一条命令就能导出带NMS和不带NMS两种版本修改输入输出也方便。模型结构固定昇腾社区和厂商官方样例基本都是基于YOLOv5做的适配遇到问题能找到大量参考。理论上YOLOv8也支持但YOLOv8的输出结构不同后处理逻辑要重写部署成本高一些而且某些特殊算子比如DFL相关的解码操作在ATC转换时需要额外处理。如果项目刚起步直接选YOLOv5s作为基座部署通了再考虑换成v8或者更大的模型。模型精度和速度的取舍在昇腾上和其他平台一样s模型对300V这种卡来说属于“轻松拿捏”m和l模型也能跑到不错的性能x模型就要考虑显存和延迟了。2.3 部署总流程和性能预期完整的部署链路是准备好权重官方权重或者自己训练好的。导出ONNX固定输入shape。写AIPP预处理配置可选。ATC把ONNX转成om。写推理程序加载om跑前处理、推理、后处理。性能和精度验证。关于性能预期我先给一个估算思路查你卡的有效INT8算力查模型在目标分辨率下的计算量YOLOv5s在640x640下大约16GFLOPs前向计算量然后用“有效算力 ÷ 单帧计算量”算出理论帧率再乘一个20%~40%的实际利用率系数。比如一张140 TOPS INT8的300V卡理论帧率能到8000FPS以上但实际内存带宽、算子调度、后处理都会拖后腿跑个几百FPS才是正常的。别相信任何厂商宣传的“峰值性能”以你自己实测为准。3. 完整实操Atlas 300V 24G上跑通YOLOv53.1 环境准备驱动、固件、CANN一次装明白昇腾的安装有个特点版本匹配比什么都重要。驱动、固件、CANN版本之间都有明确的配套关系版本错配轻则功能异常重则NPU直接无法初始化。基础环境建议用Ubuntu 20.04或22.04内核版本不要乱升级。需要安装的内容有三块驱动安装后执行npu-smi info能看到卡的信息。固件紧跟着驱动装顺序不能反。CANN toolkit安装后执行source /usr/local/Ascend/ascend-toolkit/set_env.sh来加载环境变量。CANN安装包运行后是交互式安装我建议用命令行参数静默安装chmod x Ascend-cann-toolkit_8.0.RC1_linux-aarch64.run ./Ascend-cann-toolkit_8.0.RC1_linux-aarch64.run --install --quiet装完以后务必做两件事一是确认npu-smi info能正常显示卡的信息二是确认which atc能找到转换工具。如果atc路径不对检查环境变量ASCEND_HOME_PATH有没有正确指向toolkit安装目录。新版的CANN可能还涉及Python环境版本的问题建议直接用Python 3.8或3.9太高或太低都可能遇到Python接口编译不通过的情况。如果你用conda先建一个干净的专用环境再装依赖避免系统环境相互污染。3.2 从YOLOv5导出ONNX在操作这一步之前先明确输入尺寸和batch值。部署推理卡上最常见的配置是固定batch为1、固定输入尺寸640x640。固定shape的好处是ATC转换时优化更加激进内存能提前规划好运行性能稳定。使用YOLOv5官方代码导出git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt python export.py --weights yolov5s.pt --include onnx --opset 11 --batch-size 1导出后可以再用onnxsim做一遍图精简减少冗余节点pip install onnxsim onnx python -m onnxsim yolov5s.onnx yolov5s_sim.onnx这里有个经验点导出时保持输入名称为images、输出名称默认即可后面写ATC命令时要知道输入节点的名字。如果你改过模型的输入层记得先用下面这个命令查看ONNX的输入输出定义python -c import onnx; monnx.load(yolov5s.onnx); print([i.name for i in m.graph.input], [o.name for o in m.graph.output])3.3 AIPP配置与ATC模型转换这是昇腾部署里最需要耐心的一步。先解释一下AIPP是什么它是NPU上的图像预处理单元可以在模型推理前自动完成归一化、减均值、图像缩放等操作把本来要在CPU上做的预处理下沉到NPU减少数据搬运。YOLOv5的标准预处理是图片缩放填充到640x640、像素值除以255归一化。由于我们导出ONNX时模型本身没有包含归一化所以要么在Python前处理里做要么交给AIPP。我建议交给AIPP因为省事而且快。写一个aipp.cfgaipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 crop: false mean_chn_0: 0 mean_chn_1: 0 mean_chn_2: 0 min_chn_0: 0.003921569 min_chn_1: 0.003921569 min_chn_2: 0.003921569 }这里min_chn填的是1/255等效于除以255归一化。input_format: RGB888_U8表示输入图像是RGB格式、每个通道8位。如果你的图片是BGR改成BGR888_U8即可。接下来执行ATC转换atc --modelyolov5s_sim.onnx \ --framework5 \ --outputyolov5s_bs1 \ --input_shapeimages:1,3,640,640 \ --soc_versionAscend310P3 \ --insert_op_confaipp.cfg \ --output_typeFP16 \ --logerror参数含义--framework55代表ONNX格式。--input_shape要和ONNX导出时的输入定义一致。--soc_version这个一定要填对你卡对应的芯片型号。320T、300V系列一般是Ascend310P3等310系列型号但具体以官方文档和npu-smi info显示的信息为准。填错了ATC会直接报错。--output_typeFP16算力卡跑FP16通常比FP32快内存占用也小一半。如果你后面要做INT8量化这一步可以不用指定。转换成功后目录下会生成yolov5s_bs1.om这就是NPU上直接跑的模型文件。3.4 编写推理程序ACL加载模型与后处理运行推理我用的是AscendCL的Python接口好处是接口直白不容易被框架封装的黑盒坑到。核心流程分五步初始化ACL和设置设备。加载om模型。准备输入输出内存。执行推理。后处理拿到检测框。先看初始化和加载的骨架代码import acl import numpy as np import cv2 # 初始化 acl.init() acl.rt.set_device(0) context, ret acl.rt.create_context(0) # 加载模型 model_id, ret acl.mdl.load_from_file(yolov5s_bs1.om) model_desc acl.mdl.create_desc() acl.mdl.get_desc(model_desc, model_id) # 获取模型输入输出的尺寸和个数 input_size acl.mdl.get_num_inputs(model_desc) output_size acl.mdl.get_num_outputs(model_desc) # 根据模型定义申请内存这里省略了获取dims的代码实际需要从model_desc读取宽高 input_data np.zeros((1, 3, 640, 640), dtypenp.uint8) # 注意AIPP配置下的输入是U8图像预处理部分注意AIPP模式下我们要喂给模型的是还没有归一化的原始RGB数据归一化由AIPP完成但letterbox缩放得自己写def letterbox(img, new_shape(640, 640)): shape img.shape[:2] r min(new_shape[0] / shape[0], new_shape[1] / shape[1]) new_unpad int(round(shape[1] * r)), int(round(shape[0] * r)) dw, dh (new_shape[1] - new_unpad[0]) / 2, (new_shape[0] - new_unpad[1]) / 2 img cv2.resize(img, new_unpad, interpolationcv2.INTER_LINEAR) top, bottom int(round(dh - 0.1)), int(round(dh 0.1)) left, right int(round(dw - 0.1)), int(round(dw 0.1)) img cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value(114, 114, 114)) return img, r, dw, dh执行推理时把预处理后的图像数据拷贝到模型输入内存调用acl.mdl.execute# 简化版把输入数据拷入设备内存 # 实际工程中需要先创建acl.rt.memcpy或使用acl.util.numpy_to_ptr input_ptr acl.util.numpy_to_ptr(input_data) acl.rt.memcpy(input_device_ptr, input_size, input_ptr, input_size, acl.rt.MEMCPY_HOST_TO_DEVICE) # 执行推理 ret acl.mdl.execute(model_id, input_device_ptr, input_size, output_device_ptr, output_size) # 把输出拷贝回host acl.rt.memcpy(output_data_ptr, output_size, output_device_ptr, output_size, acl.rt.MEMCPY_DEVICE_TO_HOST)上面这段是骨架逻辑真实代码里内存申请、release、错误处理都要写完整否则会有内存泄漏。如果觉得ACL接口太繁琐可以用厂商开源的acllite封装库它对图像和模型做了二次封装代码量能减少一半适合快速验证。推理输出的原始结果是模型吐出的张量YOLOv5的输出形状一般是[1, 25200, 85]25200是三个尺度下的候选框总数85是cx, cy, w, h, obj_conf, 80类cls_conf。后处理要做的事情用obj_conf阈值比如0.25过滤低置信度框。用NMS非极大值抑制去掉重复框。把框坐标按letterbox的缩放比例和padding映射回原图。这部分直接参考YOLOv5官方utils/general.py里的non_max_suppression函数改成用numpy实现即可。我实际跑下来YOLOv5s在640x640、batch 1、FP16模式下300V 24G单卡跑到两位数到上百FPS是正常的具体帧率跟CANN版本和算子优化程度关系很大。如果你是拿视频流做检测可以考虑增加batch或者用多路异步推理来提高吞吐这比单纯追求单帧延迟更有意义。3.5 从FP16到INT8想要更高吞吐就量化FP16跑通只是第一步。300V这种推理卡的优势区间在INT8把模型量化到INT8之后吞吐能再上一个台阶代价是精度会有一定损失。昇腾做INT8量化的工具叫AMCTAscend Model Compression Toolkit官方文档里的流程是准备校准数据集 - 用AMCT对ONNX模型做量化感知训练或训练后量化 - 导出量化模型 - ATC转成om。训练后量化是最省事的方式重点就是准备好校准集。经验是校准集选取要有代表性覆盖你要检测的目标类别和场景一般几百张就够了。我见过有人拿一堆和业务场景完全不相关的图片做校准结果量化后精度掉了十来个点换了一套贴近场景的校准集之后精度损失立刻回到了1~2个点以内。所以校准集的质量远比数量重要。4. 部署路上的高频坑从转换到推理4.1 模型转换阶段的问题ATC报错E40001之类的算子不支持错误是最常见的。这类问题的本质是ONNX里的某个算子在当前CANN版本的昇腾算子库里没有实现。我的排查思路是先确定是哪个算子然后看能不能通过修改模型结构绕开比如把某些在CPU上做更划算的算子比如NMS移到后处理而不是死磕在模型里。Soc version填错导致转换失败也很常见。这里有个细节不同卡可能对应同一个soc版本号但反过来同一个卡的不同固件版本也可能影响ATC的适配。最靠谱的方式是不猜直接用npu-smi info查看芯片型号再去对照官方文档确认soc_version的写法。AIPP配置不对模型输出全乱。输入是BGR结果按RGB处理了、尺寸没对上、load_start_pos配错都会导致识别结果一片混乱。排查时先把AIPP去掉走纯Python预处理确认模型推理本身没问题然后再逐步把预处理移到AIPP这样能快速定位问题在哪一侧。4.2 推理运行阶段的问题初始化报错acl.rt.set_device失败大概率是驱动和CANN版本不匹配或者当前用户没有权限访问设备。先执行npu-smi info确认设备状态正常再检查CANN版本和驱动版本是否在官方配套表里。推理结果全是0或者NaN先看输入数据对不对再看模型转换时--output_type设置有没有问题。FP16推理时如果模型里有数值敏感的层可能出现精度溢出这时候可以改回FP32跑一下对比。显存不足HBM/内存分配失败300V有24GB按理说不容易爆。如果爆了检查是不是一个进程加载了太多模型或者连续推理的中间结果没有被及时释放。ACL的acl.rt.destroy_context和acl.rt.reset_device一定要在程序退出前调用否则二次加载模型时可能踩到内存碎片问题你会在反复启停服务一段时间后突然发现内存分配失败重启进程又好了。这种隐蔽问题最好一开始就把资源释放写规范。性能远低于预期先排除是不是跑在CPU回退路径上。YOLOv5这类模型如果中间有算子没放到NPU上执行ACL会自动回退到CPU此时性能会一落千丈。判断方式很简单看推理日志里有没有warning级别的“operator fallback”之类的提示或者拿官方样例模型和自己转的模型跑同样输入对比速度。另一个常见因素是输入图像过大导致resize耗时过高300V的硬解码和AIPP能力要充分利用不要在CPU端做大量图像缩放。4.3 常见问题速查表现象可能原因解决思路atc命令找不到环境变量没加载source set_env.sh检查ASCEND_HOME_PATHnpu-smi看不到卡驱动未装好或权限不足重启、检查用户组、重新安装匹配版本模型转换报算子不支持算子库版本低/模型结构特殊升级CANN、替换算子、后处理外移推理输出错乱AIPP配置错误/图像格式错先移除AIPP对照测试显存不断上涨资源未释放规范调用acl.rt.destroy_*接口INT8量化掉点严重校准集不具备代表性换成贴近真实场景的数据集最后再分享一个心得我在不同型号的昇腾卡上踩了一圈坑之后最大的体会是——别把Atlas当成“能跑的GPU”要把它当成一套独立的推理平台来设计。从选型开始就明确你是要做训练还是推理推理就老老实实走ONNX到ATC的转换链路预处理能下沉AIPP就下沉后处理能外移就外移评估性能时用INT8算力做理论估算再实测验证。这套方法论不仅在300V上成立你后续换到300I、200 DK甚至厂商发布的任何新款推理卡都能快速迁移过去。如果你刚拿到一张300V 24G今天就可以按这个流程走一遍。第一次跑通之后你会发现昇腾的部署链路没有传说中那么玄乎就是个从PyTorch到ONNX再到om的“翻译优化”过程。把这套流程吃透后面接自己的业务模型就只是换个权重文件的事。
返回列表