尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Atlas 300V推理加速卡实战:从ONNX转换到YOLOv5部署全流程

发布时间:2026/9/26 8:45:36

资讯中心
01
ARTICLE

Atlas 300V推理加速卡实战:从ONNX转换到YOLOv5部署全流程

Atlas 300V推理加速卡实战:从ONNX转换到YOLOv5部署全流程
前阵子在一个检测项目里我拿到一张“Atlas”。项目组里有人第一反应是地图软件直到看到卡上印的昇腾标识才反应过来这是华为昇腾的AI推理产品线。更具体地说我手头这张是Atlas 300V 24G网上很多人直接问“这卡是不是运算加速卡”甚至有人以为它是显卡。这个问题其实正是很多刚接触Atlas的人最困惑的点它到底是干什么的和GPU有什么区别能不能直接跑PyTorch模型以及热搜里那句“atlas部署yolo”到底是怎么个部署法。这篇博文就把这些问题一次讲清楚从产品定位、软件栈、模型转换到YOLOv5在Atlas 300V上的完整推理流程再到部署过程中常见的坑和调优手段给准备入坑Atlas的朋友一份可以直接照做的实战记录。1. 先弄清楚Atlas到底是什么300V是运算加速卡吗1.1 Atlas不是单张卡是一条完整的AI推理产品线先纠正一个常见误区Atlas在这里不是说某一张具体的卡而是昇腾AI计算平台对外的一个产品品牌。它下面包含的东西挺多比如加速卡、推理服务器、训练服务器、开发者套件还有配套的软件栈。我做项目时经常接触到的主要是其中的推理加速卡包括Atlas 300V、Atlas 300I系列再往上还有整机形态的Atlas 800推理服务器等。很多同学一上来就想问“Atlas能不能训练模型”这个想法一开始就容易跑偏。昇腾产品线里训练和推理是分开的Atlas 300V这一档是明确面向推理场景设计的加速卡不是用来从零训练大模型的。它的定位更接近一个“把训练好的模型跑出结果”的执行单元比如视频流目标检测、OCR识别、人脸特征提取、分类服务这一类在线推理任务。搞清楚这层定位后面选型、做方案才会比较顺。另外还有个容易混淆的地方Atlas加速卡虽然长得像显卡也不是安在普通台式机上插上就能当显卡用的。它的核心计算单元叫AI Core驱动和上层接口走的是CANN这套软件栈和CUDA生态完全不兼容。所以不能简单拿“显存多大、算力多少T”去跟GPU比两者的架构、编程模型、使用方式差别非常大。1.2 Atlas 300V 24G到底算什么卡直接回答那个热搜问题是的Atlas 300V 24G是一张运算加速卡但更准确的说法是“AI推理加速卡”。它和训练显卡最大的区别在于设计目标不同训练卡追求的是灵活可编程、支持各种算子、能跑大规模反向传播而推理卡追求的是低时延、高吞吐、低功耗通常用固定shape、INT8量化等手段把性能榨干。看具体配置Atlas 300V 24G最扎眼的就是24G这是卡上的HBM高带宽内存用来存放模型权重、中间特征图和推理结果。24G能为实际项目带来什么一是可以装下更大更复杂的模型二是在做目标检测这类任务时可以把batch size调大一次喂更多张图进去提升整体吞吐三是做视频分析时一块卡可以同时跑多路视频流的推理任务。我在项目里一般习惯用npu-smi info这个命令来查看卡的信息类似GPU上nvidia-smi的用法。它能显示卡的型号、内存使用率、温度、AI Core占用率等信息。第一次拿到卡先跑一遍这个命令确认硬件被系统正常识别是排除环境问题的基础操作。为了帮还不熟悉Atlas的人快速建立认知我把Atlas 300V和常见GPU训练卡做个简单对比对比维度Atlas 300V 24G常见GPU训练卡如A100/4090主要设计目标AI推理执行训练、通用并行计算核心计算单元AI CoreCUDA Core / Tensor Core软件接口AscendCL / CANNCUDA / cuDNN模型格式OM由ONNX等转换任意框架原生权重或Engine典型部署形态服务器PCIe插卡、边缘设备工作站、数据中心性价比优势区间固定输入、批量推理、INT8/FP16灵活训练、动态网络、大模型这个表不是要分高下而是想说清楚Atlas 300V 24G是实打实的运算加速卡但它擅长的是“把训练好的模型高效跑起来”这件事而不是替代GPU去做训练。2. 为什么不能在Atlas上直接跑.pt推理链路的核心逻辑2.1 从PyTorch权重到OM模型中间隔着一个“翻译”过程很多第一次做国产化部署的同学最不能理解的就是为什么在GPU上能直接加载yolov5s.pt跑推理到了Atlas上就不行了核心原因在于.pt是PyTorch框架的序列化格式里面包含Python对象、参数、甚至部分代码结构本质上只有PyTorch能读懂。而Atlas上的AI Core不认PyTorch也不认Python它只能执行经过编译后的OM格式模型。可以这样理解.pt像是厨师手写的一份菜谱写得比较自由人能看懂但后厨的标准化设备不认识。OM格式相当于把菜谱转成了后厨设备直接执行的操作步骤卡每一步做什么、参数是什么都明确固定下来。这个“翻译”过程靠的就是CANN工具链里的ATC模型转换工具。完整的推理链路一般是这样的在GPU或CPU上用PyTorch等框架训练模型、验证精度。将训练好的模型导出为标准ONNX格式开放神经网络交换格式。使用ATC工具把ONNX模型转换成Atlas平台可执行的OM模型。在Atlas侧通过AscendCLPython里叫PyACL加载OM模型做推理执行。这个链路决定了Atlas部署工作的重心模型能不能成功转成OM、转换后精度是否掉得厉害、推理时输入输出怎么摆布才是真正需要花时间打磨的地方反而写推理代码本身只是套流程。2.2 CANN软件栈里到底是谁在干活CANN这个缩写经常在Atlas相关文档里出现全称是Compute Architecture for Neural Networks翻译过来就是神经网络计算架构。它不是单一的一个软件而是驱动、固件、运行时、算子库、工具链的一整套集合。我在实际安装时至少会涉及三个东西驱动和固件、CANN toolkit、以及配套的环境变量脚本。在这套软件栈里有两个角色最关键。第一个是ATC负责把ONNX模型转成OM模型转换时的输入shape、精度、目标芯片类型都在这一步设置。第二个是AscendCL负责程序运行时的设备管理、模型加载、内存申请、推理调用和CUDA里runtime的作用有点类似。Python环境里通过PyACL的接口来操作AscendCL。CANN还内置了大量算子库像卷积、池化、归一化、拼接、Resize这类YOLO模型里常见的算子基本上开箱即用。这也是为什么YOLOv5能在Atlas上顺利转换的原因。但如果哪天遇到一个CANN不支持的算子比如某些特殊激活函数或者自定义层转换就会报错这时就需要考虑修改网络结构、升级CANN版本或者用AOE工具做算子调优。只要心里明白这一层“算子支持度”的边界排错时就不会太慌。3. 动手部署YOLOv5在Atlas 300V上的完整实操3.1 环境准备驱动、固件、CANN一个都不能少拿到一张Atlas 300V 24G之后第一步不是急着写推理代码而是把运行环境装扎实。系统方面我用的是Ubuntu 20.04 x86版本另外有的项目在ARM服务器上跑安装包需要对应下载千万别下错架构。安装顺序有严格讲究一般是先装驱动再装固件最后装CANN toolkit。装完之后执行npu-smi info如果能刷新出卡的型号和相关信息说明驱动和固件已经正常工作了。CANN toolkit装完后还需要source一下环境变量脚本通常路径在/usr/local/Ascend/ascend-toolkit/set_env.sh。这里我特别想提醒一件坑过很多人的事昇腾软件对版本匹配极其敏感。驱动版本、固件版本、CANN版本三者之间是配套关系不能随便拿最新版来装。官方文档里有一个配套表比如CANN 7.0配哪个版本的驱动一定要查清楚。我刚开始直接装了一个最新CANN结果驱动不兼容加载模型时各种报错最后是重装了一套配套版本才解决。所以不要跳过配套表这一步。环境装好后建议先跑一遍CANN自带的Sample程序比如一个简单的图片分类示例确认整条链路能跑通。这能帮你在排查问题时快速区分是环境问题还是后续自己代码的问题。3.2 导出YOLOv5的ONNX模型留意输出节点和结构YOLOv5模型转换的第一步是把PyTorch的.pt导出成ONNX。YOLOv5官方仓库自带导出脚本直接执行python export.py --weights yolov5s.pt --include onnx --opset 12默认输入尺寸是640x640opset建议设置成12及以上太低的onnx版本在转OM时容易出兼容问题。导出后强烈建议先用onnxruntime跑一下确认模型输入输出的名字和shape。我在导出的时候遇到过不少次输出结构跟自己预期不一致的问题。以YOLOv5s为例在COCO数据集上输出层就是一个张量shape通常是[1, 25200, 85]其中855805表示中心点x、y宽度w高度h以及obj置信度80是COCO数据集类别数。如果用的是自定义数据集那85要相应改成5类别数。检查时可以用Python代码打印ONNX图的输入输出信息确保输出节点的名字和维度符合预期再去做ATC转换。还有一个容易踩的坑如果你在导出时开启了端到端NMS功能输出结构会完全不一样后面的推理代码和后处理逻辑也必须跟着改。我一般建议第一次部署先关闭NMS导出保持YOLOv5最标准的输出结构等整条链路跑通了再考虑端到端优化的可能性。3.3 ATC转换ONNX到OM的关键一步ONNX导出成功后接下来就是核心的ATC转换步骤。先把最基础的固定shape转换命令贴出来atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_bs1 \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640 \ --logerror逐一解释几个关键参数的意思。--framework5表示输入模型是ONNX格式。--soc_version表示目标芯片的型号这个参数特别容易填错需要根据你手上的卡来定。我手上的Atlas 300V系列对应的SOC版本是Ascend310P3但具体还要以CANN配套表为准填错的话转换过程会直接报芯片类型不匹配。--input_shape指定输入节点的名字和shape这里的images是ONNX模型里的输入节点名如果你的模型输入名不是这个要先在导出时确认清楚。--logerror是把日志级别调成只输出错误日志太详细的话转换过程中大量INFO信息会淹没真正的错误信息。固定shape是性能最优的选择。但如果你有动态分辨率的需求比如需要同时支持640x640和1280x1280的输入可以用动态shape方式转换atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_dynamic \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,-1,-1 \ --dynamic_dims640,640;960,960;1280,1280 \ --logerror用动态shape转换后推理时可以用不同的输入尺寸但带来的问题是输出张量大小也会跟着变化后处理需要根据实际shape动态调整buffer代码复杂度会上升。所以我的建议是优先固定shape只有需求确实需要灵活尺寸时才用动态shape。转换成功后会生成一个yolov5s_bs1.om文件同时终端会打印模型装载耗时等信息看到“success”就说明这一步过了。3.4 用PyACL写一个最小可运行的推理程序模型转换完成后终于到推理环节。在Atlas上Python推理用到的接口是PyACL它就是AscendCL的Python绑定。核心流程不算复杂初始化设备、加载模型、准备输入输出内存、执行推理、取结果最后释放资源。下面这个代码片段是我项目里实际用过的核心流程去掉了一些细节处理import acl import numpy as np def infer_once(om_path, input_np): # 1. 初始化 acl.init() acl.rt.set_device(0) context acl.rt.create_context(0) stream acl.rt.create_stream() # 2. 加载模型并获取输入输出尺寸 desc acl.mdl.create_desc() model_id acl.mdl.load_from_file(om_path.encode()) acl.mdl.get_desc(desc, model_id) input_size acl.mdl.get_input_size_by_index(desc, 0) output_size acl.mdl.get_output_size_by_index(desc, 0) # 3. 分配设备内存类型2表示普通内存 input_ptr acl.rt.malloc(input_size, 2) output_ptr acl.rt.malloc(output_size, 2) # 4. 把预处理好的numpy数据拷贝到设备端 input_np np.ascontiguousarray(input_np, dtypenp.float32) acl.rt.memcpy(input_ptr, input_size, acl.util.numpy_to_ptr(input_np), input_size, 1) # 5. 创建数据缓冲并执行推理 input_buffer acl.mdl.create_data_buffer(input_ptr, input_size) output_buffer acl.mdl.create_data_buffer(output_ptr, output_size) ret acl.mdl.execute(model_id, [input_buffer], [output_buffer]) # 6. 把设备端输出拷回host端 out_np np.zeros(output_size, dtypenp.uint8) acl.rt.memcpy(acl.util.numpy_to_ptr(out_np), output_size, output_ptr, output_size, 2) # 7. 解析输出以YOLOv5s固定shape为例 out_float out_np.view(np.float32) pred out_float.reshape(1, 25200, 85) # 8. 释放资源 acl.mdl.destroy_data_buffer(input_buffer) acl.mdl.destroy_data_buffer(output_buffer) acl.rt.free(input_ptr) acl.rt.free(output_ptr) acl.mdl.unload(model_id) acl.rt.destroy_stream(stream) acl.rt.destroy_context(context) acl.finalize() return pred这段代码里有几个细节值得专门讲一下。首先写入设备端的numpy数组必须是连续内存所以用np.ascontiguousarray包了一层其次输出数据拷回来之后view(np.float32)的正确用法是把底层二进制按float32重新解释不要用astype(np.float32)两者含义完全不同astype会做数值转换很可能直接把原始二进制数据搞乱第三acl.rt.memcpy最后一个参数1表示host到device2表示device到host方向搞反了数据就全乱了。在预处理部分YOLOv5推理前有固定步骤读取图片、BGR转RGB、letterbox等比缩放填充到640x640、归一化到0-1之间、再转成NCHW的float32数组。其中letterbox这一步直接决定了后面检测坐标能不能还原到原图上后面我会专门讲。3.5 后处理从25200个候选框到最终检测结果推理完成后模型输出的pred是[1, 25200, 85]的张量每一行是一个候选框。85列的含义是x、y、w、h、obj置信度、80个类别得分。需要说明的是YOLOv5导出的ONNX其检测层输出已经经过了sigmoid所以候选框坐标和置信度都落在0到1附近。如果你用的是其他版本或导出的模型输出范围不对后处理里可能需要手动补一个sigmoid操作。后处理的标准流程是过滤obj置信度过低的候选框。对每个类别分别做NMS非极大值抑制去掉重复框。把保留下来的候选框映射回原始图像坐标。第3步特别容易出错。因为模型输入是letterbox后的640x640图得到的坐标也是在这个尺寸下的坐标。要还原到原图需要先记住预处理时的缩放比scale和填充像素pad。假设原始图像宽为W高为Hletterbox后宽为640高为640那么scale min(640/W, 640/H)padx (640 - W * scale) / 2pady (640 - H * scale) / 2。还原公式为原图x (box_x - padx) / scale原图y (box_y - pady) / scale原图w box_w / scale原图h box_h / scale如果这个映射做错了最典型的症状就是检测框位置偏移有时候偏得不多有时候整个框跑到目标旁边。我这里就踩过坑一开始忘记保存letterbox的scale和pad参数输出的坐标全偏了排查了很久才发现是后处理坐标还原的问题。4. 常见问题排查与性能调优心得4.1 部署现场最容易遇到的几个报错整个Atlas部署过程中环境千差万别但高频问题其实就那么几类。我把项目里实测碰到的、以及和技术群朋友交流时常见的报错整理成了一张速查表方便大家对照排查。报错现象可能原因解决思路ATC转换时报错提示算子不支持错误编号不同版本各不相同ONNX版本太旧、模型使用了CANN不支持的算子、输入shape不合理提高opset版本或在PyTorch里调整网络结构避开特殊算子升级CANN版本用AOE做算子调优加载OM模型时报内存不足类错误显存被其他进程占用、batch设置过大、模型未正常释放用npu-smi info查看显存占用关掉其他进程减小batch size检查代码里是否重复加载模型推理输出全是0或NaN输入数据没有归一化、输入类型不是float32、通道顺序错误检查预处理输出确保数值范围在0-1左右类型是float32shape是NCHW检测框坐标整体偏移letterbox的scale和pad没有登记或映射公式写错在预处理阶段保留scale和pad后处理严格按公式还原推理第一次特别慢模型首次执行需要JIT编译或缓存加载正式运行前先用一张图跑几次预热后续速度会恢复正常动态shape模型的输出大小不对输出buffer按固定大小分配没有随实际shape调整用动态shape时按最大可能的shape分配buffer或改用定shape这里想再啰嗦一句如果你在ATC转换时报错第一反应不要想着绕过去而是先确认CANN版本和你导出ONNX的opset版本是否匹配。我遇到过多次类似E1001、E40001的报错提示最后都是升级CANN或者重新导出模型解决的。版本这个东西在Atlas生态里真的是决定成败的一环不要轻视。4.2 让Atlas 300V吞吐翻倍的三个调优手段模型在Atlas上能跑通之后接下来就是性能和吞吐的优化。我在实际项目里比较有效的三个手段是固定shape和batch化、多stream并发、预处理下沉。第一尽量使用固定shape并调大batch。固定shape情况下AI Core的执行调度可以做到最优动态shape会带来额外的shape推导成本对低时延要求高的服务影响很明显。同时24G显存空间比较充裕YOLOv5s这种模型完全可以把batch设成4、8甚至更高一次推理处理多张图吞吐能获得立竿见影的提升。第二利用多stream并发来处理多路请求。AscendCL里stream的概念和CUDA里的stream很类似可以理解成一组按顺序执行的队列。不需要多个模型实例在同一个模型句柄下创建多个stream把不同传入的图片分别放到不同stream里执行多路推理时互相阻塞的情况会明显变少。我在视频流检测场景里就是按摄像头路数分配stream实测整体并发能力提升了不少。第三预处理下沉到DVPP硬件模块。CANN里有个DVPP模块专门负责图像解码和缩放等预处理操作可以代替CPU做JPEG解码、resize。平时在GPU上习惯了OpenCV做预处理但在Atlas上如果走的是视频流或大批量图片场景把解码和缩放放到DVPP里能释放大量CPU开销也减少host和device之间的拷贝次数。代价是要多学一套接口上手成本有一点但收益在吞吐上非常明显。如果你只是做算法验证用OpenCV在CPU端预处理完全够用但如果你要上线一个高并发的检测服务我的建议很直接别偷懒一定要把预处理链路搞清楚能下沉到DVPP的就下沉。4.3 观察性能时到底该看哪些数优化前后怎么判断效果很多人喜欢盯着npu-smi info看AI Core利用率觉得利用率高就是性能好。这个想法不全面。AI Core利用率高只能说明计算资源在忙但过高的利用率在业务场景里也可能意味着排队严重、时延在涨。正确的做法是同时关注几个指标AI Core利用率、HBM内存占用率、单次推理时延、吞吐如每秒处理图片数。我一般会在固定输入数量下测两种batch、不同stream配置的耗时曲线找到时延和吞吐的平衡点。比如batch1时单帧时延最低但整体吞吐上不去batch8时单帧时延可能有小幅上升但吞吐可能翻好几倍。这个要根据实际业务是追求“快来一张”还是“单位时间处理更多张”来选择。测性能时还有个容易被忽略的干扰项预热。模型第一次加载和第一次执行时会有缓存构建的过程系统预热不足会导致首帧时延极高直接用这个数据做评估会严重误判。我的习惯是正式压测前先连续跑几十轮推理等npu-smi里显示AI Core占用率稳定了再开始记录数据。我个人在这个项目里最深的一个体会是Atlas部署的真正门槛其实不在写推理代码而在你对模型转换的理解、对预处理细节的把握。onnx转om能不能一把过往往决定了整个迁移排期是三天还是两周。如果你也是刚拿到Atlas卡建议先花半天把CANN自带的sample跑通确认环境没问题再上自己的模型这一步至少能帮你省掉一半的排查时间。等真正跑通之后再逐步去研究AOE算子调优、INT8量化、多路视频流服务框架整个Atlas平台能挖的东西还很多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。