ARTICLE DETAIL

资讯详情

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

Atlas 300V部署YOLO全流程:从硬件选型到模型转换与推理调优

Atlas 300V部署YOLO全流程:从硬件选型到模型转换与推理调优 前阵子遇到好几拨朋友来问同一个事手头有块Atlas的卡到底能不能拿来跑YOLO以及那个“Atlas 300V 24G”是不是大家常说的运算加速卡。我一开始还觉得奇怪后来一聊才发现好多人是第一次接触昇腾这套东西拿到卡之后直接照着GPU那套思路去弄结果卡在环境、模型转换这些地方半天搞不定反过来怀疑是卡有问题。其实不是卡不行是这套工具链的上手方式跟CUDA那一套差别挺大。这篇就围绕Atlas部署YOLO这件事把从硬件选型、环境搭建到模型转换、推理落地、问题排查的整个流程捋一遍希望能帮准备入坑的朋友少走点弯路。1. Atlas 300V 24G到底是什么卡适合干什么活1.1 从“运算加速卡”这个疑问说起先说结论Atlas 300V 24G确实是运算加速卡而且是一块专门为AI推理设计的加速卡。它属于华为昇腾系列核心是昇腾AI处理器算力单位不是咱们熟悉的TFLOPS而是TOPS INT8。24G指的是板载显存容量这个容量在推理卡里算是比较大的主要解决的是“大模型放不下”或者说“多路视频流并发不够”的问题。很多人第一次看到“Atlas 300V”这个名字容易把它跟英伟达的显卡搞混觉得是不是类似RTX 3090那种既能渲染又能跑CUDA的卡。这里得说清楚Atlas 300V系列定位是纯推理卡它的强项是跑已经训练好的模型做高吞吐、低延迟的批量推理不是用来训模型的。训练还得靠GPU或者专门的训练卡推理场景才是Atlas的主场。那它跟常规的GPU比有什么优势一个是能效比高同样的功耗下能处理的并发路数更多适合机房大规模部署另一个是板载显存大24G这个规格在跑YOLOv8、YOLOv5这类目标检测模型的时候非常舒服尤其是做视频流分析一个模型实例可以同时处理几十路视频显存不会成为瓶颈。再一个就是国产化栈的适配很多项目对于芯片自主可控有要求Atlas就是冲着这个需求来的。1.2 Atlas产品线的几个常见形态Atlas这个产品线其实挺复杂的我接触到的就有好几种形态简单梳理一下方便大家对号入座Atlas 200 DK开发者套件巴掌大一块板子适合做边缘计算原型验证功耗很低但算力也相对有限。Atlas 300I Pro / 300V ProPCIe插卡插在服务器上用的像是给服务器加装了一块AI推理单元。300I是推理卡300V也是推理卡但两者的定位略有区别300V更侧重视频分析场景解码能力更强。Atlas 800 推理服务器整机形态里面预装了好几张Atlas卡适合集中式部署比如智慧园区、安防监控的中心端。咱们这里说的“Atlas 300V 24G”指的通常就是300V系列里24G显存版本的PCIe推理卡。这种卡在市面上流通量不小很多项目用它在边缘侧或者中心侧跑YOLO。1.3 YOLO这类模型为什么需要大显存搞目标检测的都知道YOLO系列模型本身并不大YOLOv8s也就20多MB的权重文件按理说8G显存都绰绰有余。那24G的意义在哪核心在“并发”两个字。实际项目里一张推理卡不可能只跑一路视频。假设一路1080P视频流做实时检测YOLOv8s在Atlas上的单路推理延迟大约在10到20毫秒之间算下来一路视频占用的推理资源其实很低。这时候我们往往会让同一张卡同时处理多路视频显存里要同时放下多路视频帧的输入、中间特征图、输出结果缓存以及模型本身的权重。路数一多显存占用就上去了。24G能非常从容地支撑几十路视频并发这就是它最大的价值。另外还有一个场景新版本的YOLO模型加了Transformer模块或者项目里要同时跑检测加分割、检测加关键点多个模型对显存的需求也会明显上涨。24G这种大显存规格意味着灵活度更高不太需要频繁地去抠显存用量。2. 从零搭建Atlas推理环境的实操记录2.1 昇腾部署绕不开的软件栈Driver、Firmware、CANN拿到Atlas 300V 24G这张卡之后第一步不是装PyTorch而是先把底层的软件栈搭起来。昇腾这套东西跟CUDA不太一样它把驱动、固件、运行时环境分了三层Driver驱动负责操作系统跟硬件之间的通信装完之后系统里会出现一个设备节点类似/dev/davinci0。Firmware固件有些版本需要单独升级跟驱动配套使用。CANN昇腾计算语言对标的是CUDA。里面包含了运行时、图编译引擎、算子库、推理接口等等是连接上层框架PyTorch、MindSpore和底层硬件的关键。建议装的时候先到昇腾社区官网确认一下操作系统版本跟软件版本的配套关系。官方给了一个兼容性列表比如Ubuntu 20.04 / 22.04、openEuler、CentOS都有对应的支持版本。这里提醒一句尽量别用太冷门的操作系统否则后续编译算子的时候会遇到很多莫名其妙的依赖问题。2.2 安装步骤与验证方法以Ubuntu 22.04 CANN 7.0为例安装步骤大致是这么几步安装驱动。下载驱动包后运行安装脚本chmod x Ascend-hdk-*.run ./Ascend-hdk-*.run --install安装固件同样用.run文件安装。装完之后用npu-smi info查看卡的状态如果能看到类似-----------------------------------的健康信息列表说明驱动和固件都正常工作了。这一步非常重要相当于CUDA里的nvidia-smi看不到卡信息就需要排查驱动安装问题。安装CANN工具包chmod x Ascend-cann-toolkit_*.run ./Ascend-cann-toolkit_*.run --install装完之后设置环境变量source /usr/local/Ascend/ascend-toolkit/set_env.sh验证CANN是否可用。最简单的办法是跑一个官方自带的样例程序比如在/usr/local/Ascend/ascend-toolkit/latest/tools目录下用msopstool或者跑一段ACL的示例代码。初次接触的话我推荐直接用npu-smi info先确认设备状态再找一个小模型走一遍转换加推理的全流程只要能通说明软件栈基本没问题了。2.3 容器化部署的经验补充很多实际项目里服务器上不止一个人用环境乱来乱去容易互相干扰。我的建议是能上容器就上容器。昇腾官方提供了带CANN的容器镜像基于镜像起一个容器把宿主机的设备映射进去就行。docker run -it --name atlas-dev \ --device/dev/davinci0 \ --device/dev/davinci_manager \ --device/dev/hisi_hdc \ --device/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ ascendhub.huawei.com/public/ascend-ubuntu:22.04 \ /bin/bash有个细节需要注意容器里的CANN版本最好跟宿主机的驱动版本兼容否则设备映射进去之后容器内调用接口会报版本不匹配的错误。我习惯在宿主机上装好驱动容器内只装CANN这样两边版本可以灵活搭配方便复用同一个宿主机跑多个不同CANN版本的项目。3. PyTorch的YOLO模型怎么搬到Atlas上跑3.1 模型转换的整体思路pt - onnx - om在Atlas上跑YOLO有个绕不开的环节模型转换。PyTorch训练的.pt权重不能直接在昇腾上跑需要先转成ONNX再用ATC工具把ONNX转成昇腾的.om格式。OM是昇腾的离线模型格式里面不仅有网络结构还包含了算子映射和融合之后的可执行指令。转换链路是PyTorch .pt - ONNX .onnx - OM .om经常有人问为什么不能直接加载.pt跑原因很简单昇腾的算子执行逻辑跟GPU不一样它需要经过构图、算子调度、内存规划这一整套编译流程OM就是编译之后的产物。这个流程虽然多了一步但也带来了一个好处模型一旦转成OM后续每次加载都不需要重新构图启动速度快推理性能也更稳定。3.2 用ATC工具做转换的关键参数ATCAscend Tensor Compiler是CANN里负责模型转换的工具。以YOLOv8s为例转换命令大概是这样的atc --modelyolov8s.onnx \ --framework5 \ --outputyolov8s_bs1 \ --input_shapeimages:1,3,640,640 \ --soc_versionAscend310P3 \ --insert_op_confaipp.cfg这里几个参数逐个说一下--framework55代表ONNX模型格式这个参数别写错。--input_shape固定输入尺寸。YOLOv8默认输入是640x640batch size这里先设成1。如果后续要多路并发且需要灵活batch可以开启动态batch后面会细说。--soc_version指定芯片型号Atlas 300V 24G对应的芯片平台一般是Ascend310P3具体可以用npu-smi info查看芯片信息来确认。这个参数很重要选不对会导致后续推理报错或者算子编译不充分。--insert_op_conf插入AIPP预处理配置。这一步容易忽略但它直接影响推理结果是否准确。AIPP就是在硬件上进行图像预处理比如缩放、减均值、除方差、色域转换等于把原来在Python里做的那些预处理下沉到硬件上降低主机侧CPU开销。3.3 AIPP配置与预处理对齐的细节很多人在模型转换之后、推理之前最容易出问题的就是预处理没对齐。PyTorch训练YOLO的时候预处理一般是读取图像 - resize到640x640 - 转RGB - 转成Tensor - /255归一化。Atlas的AIPP配置也要按照完全一样的逻辑来写aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 crop: false resize: true resize_w: 640 resize_h: 640 csc_switch: true rbuv_swap_switch: false min_chn_0: 0.0 min_chn_1: 0.0 min_chn_2: 0.0 var_reci_chn_0: 0.00392156862745098 var_reci_chn_1: 0.00392156862745098 var_reci_chn_2: 0.00392156862745098 }这里var_reci_chn是归一化系数的倒数对应Python里的1/255。csc_switch: true表示做色域转换把RGB数据转成模型需要的格式。如果输入端是BGR则需要把rbuv_swap_switch设为true。预处理逻辑不一致最典型的表现就是推理出来的框位置是刘海上加刘海完全不对。4. 推理代码该怎么写跟GPU版有什么差异4.1 ACL推理的基本流程模型转换好之后就进入推理编写阶段。昇腾的推理接口叫ACLAscend Computing Language使用流程可以归纳为五步初始化acl.init()然后设置设备acl.rt.set_device(0)。加载模型acl.mdl.load_from_file(yolov8s_bs1.om)得到模型ID。准备输入输出根据模型描述里的输入尺寸申请device内存把输入数据拷贝过去。执行推理调用acl.mdl.execute同步或异步方式执行。获取结果从输出内存里取回检测结果再做后处理NMS、坐标解析。这整个流程跟CUDA里用TensorRT做推理的思路很接近但接口风格完全不一样第一次写的人需要适应一下。4.2 一个可运行的YOLOv8推理示例这里给一个简化的示例展示如何在Atlas上用Python接口加载OM模型并做推理推理。以YOLOv8的输出为例输出张量维度一般是1,84,840080类COCO场景下需要做转置然后再解析。import acl import numpy as np # 初始化 ret acl.init() ret acl.rt.set_device(0) context, ret acl.rt.create_context(0) # 加载模型 model_path yolov8s_bs1.om model_id, ret acl.mdl.load_from_file(model_path) model_desc acl.mdl.create_desc() ret acl.mdl.get_desc(model_desc, model_id) # 获取输入输出尺寸 input_size acl.mdl.get_input_size_by_index(model_desc, 0) output_size acl.mdl.get_output_size_by_index(model_desc, 0) # 申请device内存 input_data np.random.randn(1, 3, 640, 640).astype(np.float32) input_ptr acl.util.numpy_to_ptr(input_data) device_input, ret acl.rt.malloc(input_size, 2) acl.rt.memcpy(device_input, input_size, input_ptr, input_size, 1) device_output, ret acl.rt.malloc(output_size, 2) # 执行推理 ret acl.mdl.execute(model_id, [device_input], [device_output]) # 取回结果 output_data np.zeros(output_size, dtypenp.uint8) host_output_ptr acl.util.numpy_to_ptr(output_data) acl.rt.memcpy(host_output_ptr, output_size, device_output, output_size, 2) # 解析输出 output_arr np.frombuffer(output_data, dtypenp.float32) output_arr output_arr.reshape((1, 84, 8400)) # 具体维度以模型输出为准 # 后续解析逻辑与GPU版一致需要转置为 1,8400,84再做阈值过滤 NMS # 释放资源 acl.rt.free(device_input) acl.rt.free(device_output) acl.mdl.destroy_desc(model_desc) acl.mdl.unload(model_id) acl.rt.destroy_context(context) acl.finalize()需要注意以上代码为了可读性省略了异常处理实际项目中ret一定要逐行检查。acl.rt.memcpy的kind参数1表示Host到Device2表示Device到Host这个很容易搞反。4.3 数据预处理与后处理对齐推理代码本身不复杂真正复杂的是前后处理。GPU上用PyTorch推理的时候预处理和后处理都是Python代码灵活但是慢。到了Atlas上尤其跑高并发场景最好把预处理交给AIPP后处理尽量用向量化操作或者C扩展实现。后处理这块YOLOv8的输出是1,84,8400需要先把维度转成1,8400,84前4个值是cx, cy, w, h第5个是置信度后面是各类别得分。常规做法是去掉置信度低于阈值的框。用置信度乘各类别得分得到最终得分取最高分类别。对每个类别做NMS去掉重叠框。这里有个细节OM模型的输出数据排布跟ONNX不一定完全一致。ONNX输出可能是1,84,8400但ATC转换过程中可能会做算子融合和内存重排所以代码里最好先把原始输出打印出来看一下维度再解析不要想当然。5. 性能调优与常见问题排查5.1 常见报错速查表昇腾这套东西错误信息很多时候不太直观报错了看不懂特别容易劝退。我把实际踩过的几个典型问题整理一下现象可能原因解决办法acl.mdl.load_from_file报错找不到设备驱动没装好或者容器没映射设备先用npu-smi info确认设备是否可见检查容器启动参数模型加载成功但推理结果全为0AIPP预处理与训练时不一致检查输入是RGB还是BGR归一化系数是否设置正确转换时报Unsupport opONNX里有昇腾不支持的算子查看具体算子名称尝试升级CANN版本或手工替换算子推理延迟比预期高很多batch size太小模型没有充分使用硬件尝试加大batch或使用动态batch用多路视频流并发测试报E13114类似错误码显存不足降低batch size或者换用更轻量的模型版本5.2 性能瓶颈定位Atlas的性能调优思路跟GPU有很大不同。GPU上很多时候瓶颈在数据传输上Atlas也一样有这个问题但更需要注意的是“算子下发”的开销。Atlas 300V这类推理卡一次推理需要把多个算子串起来执行如果算子粒度太细比如模型里有大量小算子那么推理引擎在调度上的开销会变得很明显。这时候可以试试ATC转换时的--enable_small_channel1参数对通道数较小的特征图做优化或者开--optypelist_for_implmode指定使用高算力算子实现。不过最有效的还是从源头上选一个更高效的模型结构。还有一个容易被忽略的点数据从H2D到D2H的拷贝频率。如果你在Python端循环里每一帧推理都做一次内存申请和释放性能肯定上不去。正确的做法是初始化时就把输入输出的device内存申请好推理循环里只做拷贝和执行。5.3 动态batch与多路视频流的推荐配置实际项目里Atlas 300V 24G跑YOLO最典型的场景就是多路视频流分析。如果每一路视频单独用一个模型实例那内存和算力都会浪费。更推荐的做法是开动态batch把多路视频的帧拼成一个batch送进去推理。ATC转换时这样设atc --modelyolov8s.onnx \ --framework5 \ --outputyolov8s_dynamic \ --input_shapeimages:-1,3,640,640 \ --dynamic_batch_size1,2,4,8 \ --soc_versionAscend310P3 \ --insert_op_confaipp.cfg动态batch设置之后推理时每次可以按当前实际的路数动态决定batch大小比如当前有4路视频帧到了就凑成4张图送进去有8路就凑成8张。这样比固定batch1的推理方式吞吐量能提升好几倍。实际操作中还有一个心得最好在应用层做一个轻量级的帧队列把各路视频的帧统一调度攒够batch再送推理。攒批时间不能太长否则单路视频的延迟就上去了。我一般用10到20毫秒的窗口既保证实时性又能尽量凑满一个batch。5.4 显存与内存优化的一些建议24G显存看着很大但如果代码写得糙照样能被吃满。优化显存占用有两条路一是减小输入尺寸把分辨率从640x640降到480x480或者416x416虽然精度会掉一点但对很多场景完全够用二是在后处理的时候及时释放中间变量尤其在使用Python接口时numpy数组如果不主动释放会一直占着内存。另外Atlas 300V 24G有视频解码单元如果项目里需要做视频流解码可以直接调用昇腾的DVPP数字视觉预处理模块把解码、缩放、色域转换都放到硬件上完成。这套接口学习曲线稍微陡峭一些但一旦用熟整个视频分析链路的CPU占用能大幅下降。我头一回把解码从FFmpeg换到DVPP之后CPU占用直接从80%降到了30%以内效果极其明显。一些更实际的经验最后说一点个人体会。Atlas部署YOLO这套流程说难不难说简单也不简单。最磨人的不是某个单个步骤而是整个链条里环环相扣的版本匹配问题。操作系统版本、驱动版本、固件版本、CANN版本、甚至Ubuntu内核版本任何一个环节不一致都可能导致莫名其妙的报错。我建议新手拿到卡之后第一步什么都不用做先老老实实照着官方文档的推荐组合把环境装好然后跑通官方自带的样例确认全链路没问题再开始折腾YOLO。另外对于那个“是不是运算加速卡”的问题再重申一遍Atlas 300V 24G是标准的AI推理加速卡不是GPU也不能直接拿来当显卡输出画面。它的加速能力体现在AI模型的推理计算上尤其是视觉类模型。如果你手头的项目是目标检测、图像分类、语义分割这类推理任务它是个性价比不错的选项但如果你想拿来做通用并行计算或者模型训练那就找错方向了。踩过几次坑之后我现在做Atlas上的部署验证都会先建一个固定版本的开发容器把驱动之外的软件全部塞进容器里环境做坏了直接删掉重建十分钟就能恢复。这个习惯帮我省了非常多的时间。如果你刚开始接触Atlas我强烈建议你也用这个方式至少能让“环境问题”和“代码问题”分开排查不至于混在一起一查就是半天。
返回列表