ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Atlas 300V 24G部署YOLOv5实战:从CANN安装到模型转换全流程

Atlas 300V 24G部署YOLOv5实战:从CANN安装到模型转换全流程 前段时间有个朋友跑来问我“Atlas 300V 24G到底算不算运算加速卡我拿它部署YOLO怎么感觉和网上教程对不上”这个问题其实特别典型很多人刚接触昇腾生态时第一反应都是“这不就是一张显卡嘛”结果一上手才发现坑比想象中多得多。先说结论Atlas 300V 24G是一张标准的AI推理加速卡能用来跑YOLO这类目标检测模型但它和NVIDIA GPU的玩法完全不同。它不是插上就能用需要装驱动、固件、CANN工具链还要把模型转成昇腾专用格式才能推理。这篇文章我就用完整跑通YOLOv5检测任务的实战过程把Atlas 300V的定位、部署流程、常见坑一次性讲清楚适合刚入手昇腾设备、或者正考虑用Atlas做业务推理的同学收藏。1. Atlas 300V 24G这块“加速卡”到底是什么定位1.1 从算力规格看它擅长干什么Atlas 300V型号里V一般指Video视频分析方向是昇腾生态里的AI推理卡24G指的是板载内存不是显存也不是普通内存而是HBM高带宽内存。这类卡在设计之初就是冲着视频流分析场景去的比如智慧园区的人脸抓拍、交通场景的车牌识别、工厂车间的安全帽检测这类“摄像头对着拍实时出结果”的业务。它的核心算力单位是TOPS也就是每秒万亿次整数运算。Atlas 300V 24G的典型规格是单卡提供几十TOPS的INT8推理算力功耗通常在70W到150W之间具体数值会因型号批次有差异以官方实际出货规格为准。这个量级的好处是单算力密度够用功耗又比动辄300W以上的训练卡低很多一台2U服务器塞两张卡做推理服务供电和散热压力都不大。我知道肯定有人会拿它和GPU比“为什么没人炒它”。原因很简单它的定位就不是通用图形计算而是给特定AI推理业务做加速。它不处理OpenGL指令不参与视频编码那块功能是编解码器负责的甚至连显示输出接口都没有。你插上它显示器也不会亮。它就是一个纯粹的计算单元把自己擅长的卷积、矩阵乘法做到极致剩下的事情交给CPU和宿主系统。1.2 它与GPU显卡的三个本质区别很多第一次接触Atlas的人会把“加速卡”自动等同于“显卡”这其实是理解整个昇腾体系的最大阻碍。至少有三个关键区别直接影响后续怎么用、怎么调优。第一编程接口完全不同。GPU这边你习惯用CUDA、cuDNNPython生态里还有现成的torch.cudaAtlas不行它的算力是通过CANN昇腾计算架构开放的核心调用方式是ACLAscend Computing Language接口。PyTorch模型通常不能直接跑到Atlas上需要先把模型导出为ONNX再用ATC工具转成昇腾的OM离线模型格式。第二数据流和内存模型不同。GPU算是“通用并行计算设备”什么数据格式都能灵活处理Atlas执行模型时有一套更严格的数据流约束比如输入Tensor在内存里的排布方式NHWC还是NCHW、归一化方式都必须在模型转换阶段用AIPP参数写清楚运行阶段再临时改是很麻烦的。第三生态位置不同。NVIDIA GPU因为有CUDA生态既能训练又能推理还能跑渲染、科学计算Atlas 300V这一档的定位就是纯推理卡你别指望拿它做模型训练。训练任务应该去找Atlas 800/900系列的训练服务器或者干脆在GPU上训好再导出到Atlas推理。注意如果你已经有一整套基于TensorRT的推理代码迁移到Atlas不是“改个后端”那么简单涉及模型转换、预处理对齐、后处理重写等一整套工程调整建议提前做好工作量评估。1.3 用npu-smi确认“这张卡真的在干活”系统和CANN装好之后第一个该做的动作就是检查卡的状态别急着跑模型。昇腾环境里有个命令叫npu-smi类似GPU场景的nvidia-smi是日常排查的必备工具。npu-smi info这个命令会列出当前机器上的昇腾设备编号、芯片温度、功耗、HBM使用率、算力使用率等信息。用它可以快速确认三件事驱动和固件是否正常加载如果设备状态那栏不是OK说明驱动装得有问题有没有其他进程占着卡推理时报“device busy”十有八九是有人在跑任务推理过程中HBM占用和算力占用是否合理如果HBM吃满但算力只有个位数多半是模型或预处理配置出了问题。我自己的习惯是把npu-smi封装成一个定时采集脚本每5秒采样一次记录到日志里。性能调优时直接用这段记录回放看算力波动曲线比开着终端盯屏幕靠谱得多。2. 为什么在Atlas上部署YOLO不能直接“pip install”2.1 从x86到昇腾一套完全不同的软件栈在GPU上部署YOLO很多人习惯的做法是“conda环境装个PyTorch再装个ultralytics下载权重直接跑”。这套逻辑在昇腾上行不通因为PyTorch默认根本没有昇腾后端你想让模型调用NPU得先搞清楚昇腾的软件栈分层。昇腾平台从下往上大致是这么几层驱动Driver和固件Firmware管住硬件设备本身安装后系统里才会出现/dev/davinci*设备节点CANN Toolkit核心计算库和工具链包括算子库、图编译引擎、推理运行时以及ATC模型转换工具推理框架/加速库比如MindX SDK、MindSpore推理接口或者直接调底层ACL接口写推理代码上层业务代码你自己的Python/C程序。也就是说同样一段YOLO推理代码在GPU上是“框架直接驱动硬件”在Atlas上是“业务代码通过ACL接口调用CANNCANN再通过驱动调度NPU”。中间多了一层这层的概念、接口、工具链都是昇腾自己的。很多新手卡在第一步是因为装驱动时没核对好系统架构。Atlas服务器的主机CPU有两种常见形态x86和鲲鹏ARM。CANN的安装包、驱动和固件的版本号都会区分“aarch64”和“x86_64”两种编译版本。你在x86机器上装了aarch64的包命令看起来像装上了一跑就报错。装之前先敲一句uname -m确认架构再找对应安装包。2.2 模型转换从ONNX到OM的完整逻辑YOLO权重文件比如yolov5s.pt在Atlas上是不能直接用的必须先转成OMOffline Model格式。转换过程用CANN自带的ATC工具完成核心是把PyTorch/TensorFlow训练出来的网络结构、权重、算子映射成昇腾硬件上能高效执行的指令序列。为什么要多这一步两个原因。一个是为了性能OM格式相当于已经把计算图做过算子融合、内存复用、指令编排等优化运行效率比“解释执行”高得多另一个是为了安全OM格式是二进制编译产物不太容易被直接解析出网络结构和权重在商业部署场景里多少算一层保护。转换流程大概是在GPU环境或者任意能跑PyTorch的环境下把PyTorch权重导出为ONNX格式把ONNX文件、输入尺寸、预处理参数喂给ATC工具ATC输出一个.om文件推理代码加载.om文件用ACL接口执行。这一步是昇腾部署最核心的环节80%的“部署失败”都发生在模型转换阶段。后文我专门用一整节讲细节。2.3 CANN版本、驱动、固件的搭配套路昇腾生态有个让新手很头疼的点CANN、驱动、固件三个东西有版本配套关系。CANN版本太新、驱动太老跑起来会莫名崩溃驱动太新、固件不匹配设备直接识别不了。官方每发布一个CANN版本都会附带一张“配套驱动固件版本表”在文档中心能查到。我的建议是完全按表格来不要自己发挥。比如CANN 7.0.0配什么驱动版本、什么固件版本表格写得很清楚照着装就对了。另一个建议是正式环境装好后把三个版本号记录下来以后升级时先备份旧版本。昇腾的驱动和固件升级不像pip那样“装了新版本还能轻松回滚”卸载和重装步骤比较繁琐弄不好会把系统搞挂所以版本管理上保守一点没有坏处。提示如果你是第一次装最省心的方式是使用官方提供的“Ascend-cann-toolkit”安装包时同时把“Ascend-driver”和“Ascend-firmware”的配套版本下齐。不要用apt源里随便拉到的老旧版本。3. 从0到1在Atlas 300V上跑通YOLOv5检测3.1 环境准备与CANN安装细节开始安装之前先梳理一下需要准备好的清单一台装有Atlas 300V的服务器x86或鲲鹏均可、Ubuntu或其他常见Linux系统、至少8GB内存、50GB空闲磁盘CANN工具链会占用不少空间。装CANN的时候有几个细节值得注意。一是安装方式推荐用“root用户安装”的toolkit包安装路径默认在/usr/local/Ascend这个路径后面配环境变量会反复用到二是安装完成后必须source一下环境变量脚本source /usr/local/Ascend/ascend-toolkit/set_env.sh这个脚本会把atc命令、CANN运行库路径、Python路径全部配好。忘了source的话后面执行atc命令会提示找不到工具。然后是Python环境。CANN的pyACL接口通常通过CANN自带的Python库暴露出来不需要额外pip install。你可以先验证一下能不能导入python3 -c import acl如果报错常见原因是环境变量没生效或者当前Python版本和CANN的适配版本不一致。CANN官方文档会写明支持哪些Python版本我用3.7和3.9都跑过基本稳定。3.2 导出ONNX容易被忽略的3个设置YOLOv5的导出脚本本身写得很完善用官方命令就能导出ONNXpython export.py --weights yolov5s.pt --include onnx --opset 12但为了让后面ATC转换更顺利有三个设置我建议手动确认别直接用默认值。第一输入尺寸固定。YOLOv5默认输入是640x640导出时可以通过--img 640指定。如果你业务里的图像尺寸会变化建议统一到固定尺寸。OM模型一旦编译完输入尺寸就定死了除非在ATC时配置动态shape否则运行时要严格对齐。第二opset版本。ONNX算子集的版本CANN的ATC工具对不同opset的支持度有差异。我用opset 12和opset 13都成功过但opset 17偶尔会遇到某些算子的兼容问题。没特殊需求就锁在12或13稳。第三输出节点。YOLOv5的ONNX输出通常是三个特征图对应不同尺度的检测结果。导出后可以用onnxruntime跑一遍确认输出shape是否符合预期。如果后面在ATC转换时想省事可以在导出时关掉一些不必要的后处理算子让输出“干净”一些。官方脚本默认导出的就是纯卷积输出的三个头这个没问题。3.3 ATC转换OM参数逐个解释用ATC工具转换模型是我在全流程里踩坑最多的环节。下面是实际用过的转换命令逐个参数解释一下。atc --modelyolov5s.onnx --framework5 \ --outputyolov5s --soc_versionAscend310 \ --input_shapeimages:1,3,640,640 \ --insert_op_confaipp.cfg \ --output_typeFP32--model指定输入ONNX文件--framework固定填5表示ONNX--output是输出的OM文件前缀--soc_version要填芯片型号。Atlas 300V的推理芯片一般对应Ascend310系列具体是Ascend310还是Ascend310P要做一下确认最简单的方式是运行npu-smi info查看芯片全称再对照CANN文档映射。--input_shape是把输入Tensor的形状写成“名字:维度”这个name必须是ONNX图里的实际输入名不是你自己随便编的。可以用Netron打开ONNX文件查看输入节点名很多转换失败都是因为名字写错了。--insert_op_conf是AIPP预处理配置文件用来把图像缩放、减均值、除以255、通道转换这些操作全部下沉到硬件里做这样推理代码里就可以省掉一批CPU操作。配置文件长这样aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_h: 640 src_image_size_w: 640 csc_switch: true rbuv_swap_switch: true min_chn_0: 0 max_chn_0: 255 min_chn_1: 0 max_chn_1: 255 min_chn_2: 0 max_chn_2: 255 }这里面的RGB888_U8、csc_switch这些参数说白了就是告诉硬件“进来的图像是8位RGB整型先把范围归一化到0~1再做后续计算”。如果AIPP配置和你训练时的数据预处理方式不一致跑出来的检测精度会明显下降这是最隐蔽的坑之一。3.4 Python推理代码完整的pyACL调用流程OM模型转换完成后接下来就是写推理代码。我用的是pyACL接口也就是CANN的Python API。整个推理流程可以拆成7步初始化、加载模型、准备输入输出内存、执行推理、取结果、后处理、释放资源。初始化部分import acl ret acl.init() ret acl.rt.set_device(0) # 使用0号设备 context acl.rt.create_context(0)加载模型model_path byolov5s.om model_id acl.mdl.load_from_file(model_path) # 返回模型ID后续推理靠它 desc acl.mdl.create_desc() acl.mdl.get_desc(desc, model_id)获取模型的输入输出尺寸信息input_size acl.mdl.get_num_inputs(desc) output_size acl.mdl.get_num_outputs(desc) # 获取输出数据的维度和数据类型后处理时要用到 output_dims acl.mdl.get_output_dims(desc, 0)分配输入输出内存。这里有两种做法最简单的是用acl.util.npu_alloc_zero或acl.rt.malloc把数据从numpy拷贝到NPU内存import numpy as np input_data preprocess(image) # 预处理后的numpy数组shape为(1,3,640,640) numpy_array np.ascontiguousarray(input_data) acl.rt.memcpy(dst_ptr, size, numpy_array.ctypes.data, size, ACL_MEMCPY_DEVICE_TO_DEVICE)这一步要特别留意ACL接口里很多函数是对指针操作的不能直接把numpy数组传给推理函数必须先拷贝到由acl.rt.malloc分配的device端内存里。执行推理acl.mdl.execute(model_id, input_data_ptr, output_data_ptr)这是一次同步推理也就是说程序会阻塞在这里直到推理完成。多路视频流场景下同步推理的吞吐量不够用需要用异步接口加Stream并发这个在第4章讲。推理完成后把输出从device拷贝回host端numpy数组output_numpy acl.util.ptr_to_numpy(output_ptr, (batch, channels, height, width), np.float32)3.5 后处理把神经网络输出变成检测框YOLOv5的输出是三个尺度的特征图每个特征图上的每个网格都预测若干个候选框。后处理要做的事就是把这三组张量解码成一堆(x1, y1, x2, y2, score, class)格式的最终检测框。如果之前没有把NMS等后处理算子放进模型这一步就只能在CPU上完成。核心代码思路如下把三个特征图分别做sigmoid得到归一化的坐标、置信度、类别概率按置信度阈值过滤掉低质量框把特征图上的网格坐标转换成原图坐标合并三个尺度的候选框做非极大值抑制NMS去掉重叠框。这一步的工程难度不高但细节很多。尤其是坐标变换一不小心就会在缩放和偏移上出错导致画出来的框和物体错位。我的建议是先拿一张有标准答案的测试图调通比如用YOLOv5官方仓库里的bus.jpg确认框的位置和分类都对再跑大批量数据。别一上来就去跑监控视频出错了都不知道是模型问题还是后处理问题。4. 踩坑实录与性能调优经验4.1 高频报错与排查速查表下面这些报错我基本都遇到过整理成表方便你直接对照报错信息原因排查方向“acl init failed”驱动没正常加载或权限不足检查/dev/davinci0是否存在确认用户属于HwHiAiUser组“model load failed”OM模型与芯片型号不匹配核对ATC的-soc_version是否与设备一致“ATC Model convert failed”ONNX里有不支持的算子检查opset版本尝试导出时简化图结构“input shape mismatch”输入数据shape与模型定义不符检查预处理后numpy的shape和--input_shape是否一致“insufficient memory”设备内存不足或未释放用npu-smi看HBM占用检查是否有残留进程“ge runtime error”CANN版本与驱动不匹配对照官方配套版本表重新安装推理速度很慢可能是CPU复制的开销过大用AIPP把预处理下沉到硬件用异步推理减少等待这些报错里最让人抓狂的是“ATC convert failed”报错日志会刷一大堆算子信息。说实话新手很难一眼看出问题。我常用的笨办法是把ONNX的opset从高往低一个版本一个版本试试到能转换为止。虽然不优雅但对付个别不兼容算子确实有效。4.2 精度对不上的排查思路很多人在Atlas上跑YOLO发现检测框要么偏了要么明明有物体却检测不到。最先怀疑的绝不是模型坏了而是预处理环节和训练时不一致。具体来说常见原因有这些图像缩放方式不一致。YOLOv5的letterbox预处理会把长边缩放到640短边等比缩放后填充灰边。如果你推理代码里用的是直接resize图像被拉伸变形检测精度自然下降颜色通道顺序不一致。OpenCV读图是BGR模型训练时用RGB转换环节搞错了颜色信息就是错乱的AIPP里的归一化参数和训练时不匹配比如训练时除以255后做了标准化AIPP配置里却只做了0到1的缩放输出解析时坐标没有按原图尺度反算导致框画错位置。排查方法也简单先跑一张已知结果的图把预处理后的Tensor存成npy文件和GPU环境里跑ONNX时用到的预处理输出对比。数字完全对得上再怀疑后面对不上问题一定出在预处理或AIPP配置。这种“逐阶段对比”的思路放之四海而皆准。4.3 提升推理吞吐的三板斧Atlas 300V这类推理卡刚开始跑通时大家都会觉得“没那么快啊”。项目里来了一路1080p视频流CPU占用还飙到70%。原因往往不是硬件不行而是代码把硬件用得太寒碜。真正把吞吐拉起来的是这三个方向第一用异步推理加Stream并发。ACL支持创建多个Stream不同Stream可以并发执行。单路视频用同步接口问题不大多路视频时一定要用acl.rt.create_stream把每路视频的推理请求分发到不同Stream上。任务之间不用互相干等流水线才能转起来。第二把预处理和后处理下沉或并行。AIPP把图像缩放和归一化下沉到硬件之后CPU这边就少了一大块工作。后处理虽然没法下沉但完全可以在等NPU算下一帧的时候用另一个线程做当前帧的NMS实现CPU与NPU重叠执行。第三用好DVPP做硬解码。如果输入源是视频文件或RTSP流H.264/H.265解码交给DVPP硬件模块别用FFmpeg在CPU上软解。一条1080p视频流软解就要吃掉不少CPU到了8路、16路跟本扛不住。用DVPP硬解后CPU占用会断崖式下降这是Atlas做视频分析业务时必走的一条路。提示性能调优不要靠猜先用npu-smi定时采样看算力占比。如果NPU算力已经到80%以上优化方向应该转向减少CPU瓶颈如果NPU算力只有20%不说CPU却在忙那问题多半在预处理或解码侧。最后再分享一个我自己的习惯跑通一次Atlas上的YOLO部署之后我养成一个固定动作把每一步用到的版本号、配置文件、命令都沉淀成一份可重复执行的Markdown文档连同ONNX原始文件、OM转换产物、测试图一起归档。昇腾这套工具链版本迭代快今天跑通的命令换了版本可能就变了。有了归档至少换机器重装时不用再从零摸索。如果你手头也有一张Atlas 300V或者正打算用昇腾设备做目标检测希望这篇内容能帮你少踩几个坑。先跑通小模型再逐层深入这条路是完全可以走通的。
返回列表