ARTICLE DETAIL

资讯详情

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

Atlas 300V 24G实战:从零部署YOLO目标检测全流程

Atlas 300V 24G实战:从零部署YOLO目标检测全流程 提到Atlas这个词数据库圈子的人会先想到PowerDesigner里的中间件工具但在AI推理场景下搜到它八成指的是昇腾的Atlas系列加速卡。最近好几个搞视觉的同学在后台问我同一个问题Atlas 300V 24G到底算不算一张正经的运算加速卡能不能拿来部署YOLO如果真要把手头的YOLO模型搬到这个卡上从零到能出检测结果需要走哪些路这篇文章我就把这套流程完整拆开讲一遍包括Atlas 300V的硬件定位、CANN环境搭建、ONNX转OM模型、推理脚本编写、性能调优以及我在实际部署中踩过的各种坑。内容尽量按“看完就能照着做”的标准来写适合刚拿到昇腾卡、准备做目标检测推理的新手也适合已经在用Atlas但没系统梳理过部署流程的朋友。1. 先别急着跑代码Atlas 300V 24G到底是张什么卡1.1 为什么大家老在问“它是不是运算加速卡”先说结论是的Atlas 300V 24G就是一张运算加速卡而且是一张专门为AI推理设计的加速卡。很多人看到“300V”这个命名会懵因为Atlas系列里有300I、300V、310P、910B等各种型号不提前做功课很容易搞混。Atlas 300V和训练卡最大的区别在于定位。训练卡通常要跑大规模分布式训练对算力、显存带宽、集群通信都有极高要求而Atlas 300V系列更强调单卡推理性能、能效比、以及单卡可以承载的模型规模。24G显存这个配置在推理卡里算相当给力像我实际部署中把一个YOLOv5s模型转成INT8后多batch推理完全够用甚至同时常驻好几个模型都没问题。另外要注意Atlas 300V有Pro版和标准版的区分。Pro版一般是低功耗被动散热设计24G和12G两个规格标准版是主动散热24G和48G两个规格。评论里有人在问“300V 24G靠不靠谱”我的看法是如果你要做边缘侧目标检测、摄像头视频流分析这类的推理任务24G版本在大多数场景下是溢出的15W到70W的功耗范围也能匹配不同的工控机部署环境。1.2 Atlas系列选型300I、300V到底怎么分我做选型对比时习惯用一张表把关键差异列出来方便判断自己手里的卡属于哪一类型号芯片典型显存散热方式典型场景Atlas 300I ProAscend 310P8GB主动散热轻量推理、边缘盒Atlas 300V ProAscend 310P12GB / 24GB被动散热低功耗视频分析Atlas 300V 标准版Ascend 910B系列24GB / 48GB主动散热中型推理服务器Atlas 800 训练服务器Ascend 910系列单卡32GB以上主动散热模型训练如果你的卡是24G显存、插在一个带风扇的卡槽里、跑起来整机功耗明显上升大概率是Atlas 300V标准版。这里有个判断技巧用npu-smi工具看芯片类型如果显示的是Ascend 910B3或者910B4那就是标准版如果显示Ascend 310P那就是300V Pro。选型这件事给我的经验是不要只看显存更要看芯片代际和软件生态适配。310P的卡和910B的卡在CANN的算子支持、模型转换策略上有些细微差别但好在昇腾的CANN工具链把大部分差异都屏蔽掉了同一个OM模型在两种卡上都能跑只是性能和精度表现会有区别。2. 部署环境准备给Atlas安一个“家”2.1 三件套先行驱动、固件、CANN工具包拿到Atlas卡之后第一步永远不是写代码而是把运行环境收拾干净。昇腾的推理环境主要分三部分Driver驱动、Firmware固件、CANN Toolkit。这三者必须配套安装版本不一致会出现各种各样莫名其妙的问题。我建议的安装顺序是先安装Driver和Firmware重启一次机器用npu-smi确认卡已经被识别再安装CANN Toolkit安装包可以从昇腾社区的软件仓库下载选择对应的操作系统版本和架构。这里特别提醒Atlas 300V的驱动分为x86_64和aarch64两个版本如果是ARM服务器下载的时候千万别选错否则安装过程会直接报错。Driver安装命令一般是root权限下执行run包chmod x Ascend-hdk-*.run ./Ascend-hdk-*.run --full安装完成后用npu-smi info检查设备状态能看到类似下面的输出说明驱动已经正常识别-------------------------------------------------------------------------------------- | NPU Name | HBM Size | Health | -------------------------------------------------------------------------------------- | 300V | 24GB | OK | --------------------------------------------------------------------------------------CANN Toolkit的安装更简单同样是.run包执行后按提示输入相关路径即可。装完之后需要把环境变量写入~/.bashrc常见的变量是这些export ASCEND_HOME/usr/local/Ascend/ascend-toolkit/latest export LD_LIBRARY_PATH$ASCEND_HOME/runtime/lib64:$ASCEND_HOME/compiler/lib64:$LD_LIBRARY_PATH export PATH$ASCEND_HOME/compiler/bin:$ASCEND_HOME/atc/bin:$PATH2.2 Ubuntu和openEuler系统选哪个更省心我一开始用的是Ubuntu 20.04整个流程走得很顺后来在一台openEuler 22.03的机器上又部署了一遍发现步骤上基本一致只有几个依赖包需要额外处理。从实际体验来说Ubuntu的社区资料更多遇到问题好排查。但如果你要上生产环境尤其是不太想折腾GCC版本的场景openEuler反而更贴近昇腾的默认支持列表。选系统时建议先查一下CANN版本对应的支持矩阵别拿一个过新的系统版本去装旧CANN那样纯属给自己找麻烦。另外有两个系统层面的小坑我在这里先埋个伏笔后面第四章会细说Ubuntu 22.04默认的Python版本是3.10但有些CANN版本的Python接口只测试到3.8或3.9需要自己建虚拟环境。openEuler默认没有安装cmake和gcc-g编译ACLite依赖的时候会报找不到头文件。3. 一步步把YOLO部署到Atlas 300V上3.1 先从ONNX开始模型导出这一步别偷懒Atlas不能直接跑PyTorch的.pt权重需要先转换成ONNX再由ATC工具转成昇腾的OM格式。整个过程最关键的其实是ONNX导出这一步很多转换失败问题都出在这里。我用YOLOv5举例导出ONNX的标准做法是在YOLOv5源码目录下执行python export.py --weights yolov5s.pt --include onnx --opset 11 --batch-size 1这里有两个参数特别重要opseth和batch-size。ATC对ONNX的算子版本有一定支持范围opset11是比较稳妥的选择而batch-size建议固定为1先跑通整个链路后续再优化动态batch。导出完成后先别急着转OM先用onnxruntime在本地跑一张测试图确认ONNX模型本身没有导出问题。这一步能省掉后面一大半排查时间。如果onnxruntime推理出来的结果和PyTorch原始结果差异很大那说明导出时可能有算子没映射好先解决这个问题再上Atlas。3.2 ATC转换从ONNX到OM的必经之路拿到导出成功的ONNX后就可以用ATC工具做模型转换了。ATC的全称是Ascend Tensor Compiler它负责把ONNX、TensorFlow的PB、MindSpore等格式的模型编译成昇腾专用的OM模型。我常用的转换命令是这样atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_aipp \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640 \ --insert_op_confaipp.cfg \ --output_typeFP32参数说明一句话总结framework5表示输入是ONNXsoc_version指定芯片型号310P芯片写Ascend310P3910B系列写Ascend910B3具体可以查CANN文档input_shape固定模型输入尺寸这里对应YOLOv5的640x640输入insert_op_conf用来插入AIPP预处理配置可以把图像缩放、减均值、标准化这些操作直接搬到硬件上做AIPP配置在日常部署中很常用我用过的简单配置长这样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: false mean_chn_0: 0 mean_chn_1: 0 mean_chn_2: 0 }插入AIPP后原始图像可以直接以JPEG或二进制格式送入硬件预处理单元CPU端的预处理负载几乎降为零。3.3 写一个最小可运行的推理脚本模型转换完成后就可以用Python写推理脚本了。最直接的方式是用昇腾官方提供的AscendCL接口手动管理内存和模型执行。下面是一个去掉异常处理的极简版本重点展示整个推理生命周期import acl import numpy as np # 初始化 ret acl.init() ret acl.rt.set_device(0) context, ret acl.rt.create_context(0) # 加载模型 model_id, ret acl.mdl.load_from_file(yolov5s_aipp.om) # 获取模型输入输出维度 desc acl.mdl.create_desc() ret 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) # 申请输入输出内存 input_data, ret acl.rt.malloc(input_size, 2) output_data, ret acl.rt.malloc(output_size, 2) # 读图像并做预处理这里假设已经把图像转成了模型需要的ND格式 img_bytes open(test.bin, rb).read() ret acl.rt.memcpy(input_data, input_size, img_bytes, len(img_bytes), 1) # 执行推理 ret acl.mdl.execute(model_id, input_data, input_size, output_data, output_size) # 取出输出 out_np acl.util.ptr_to_numpy(output_data, (output_size // 4,), 2) print(inference done, output shape:, out_np.shape) # 释放资源 acl.rt.free(input_data) acl.rt.free(output_data) acl.mdl.unload(model_id)实际项目中我不会直接用这么底层的接口更多会基于ACLite自己封装一层把图像解码、缩放、padding都包进去。但对第一次上手的人来说看懂这段代码的价值在于理解昇腾推理的核心流程初始化、加载模型、申请内存、拷入输入、执行、取输出、释放。把这条主链路跑通后面所有复杂功能都只是在这个框架上打补丁而已。推理输出拿到手之后还需要做解码和NMS后处理。YOLO的原始输出一般是一个大数组需要按anchor数量和类别数做reshape再过滤低置信度检测框。这部分逻辑和GPU上完全一样不需要因为换了推理卡就改动算法逻辑。4. 性能调优从“能跑”到“跑得快”4.1 用benchmark工具快速摸清卡的脾气模型部署到Atlas之后第一件事不是直接上业务代码而是先摸清当前配置下的性能基线。昇腾CANN自带一个叫benchmark的工具可以让你不用写任何业务代码就完成模型的纯推理压测。基本用法如下benchmark -om_pathyolov5s_aipp.om \ -batch_size1 \ -input_shapeactual_input_1:1,3,640,640 \ -loop_count100 \ -warmup_count10benchmark运行结束后会输出平均耗时、每秒执行次数等关键指标。这里忠告一句第一轮跑出来的数字别急着拿去写报告先检查几个前提否则数据不可信warmup轮数够不够建议至少10轮是否绑定了CPU核心建议用taskset绑定到靠近NPU的物理核系统是否处于空载状态避免其他进程抢占CPU资源我在实际项目里发现一个现象同一份OM模型AIPP启不启用性能波动幅度能到30%以上。原因在于AIPP把图像预处理从CPU卸载到了硬件模块CPU端省下来的时间全变成了端到端的收益。如果你的业务对延迟敏感AIPP一定要开。4.2 精度和性能打架时怎么办部署YOLO时经常会遇到精度不达标的情况。比如原始PyTorch模型的mAP是0.5转换到OM之后掉到0.45差距可能出在两个地方。第一个是模型转换时的精度损失。如果ONNX导出的算子是FP32转换时选择FP16精度会有一定的数值精度变化。大部分模型下降到FP16问题不大但遇到数值敏感的网络还是要对比一下FP32和FP16的输出差异。解决办法是在ATC转换时用output_typeFP32的选项或者对敏感层单独保留高精度。第二个是AIPP配置和训练时预处理不一致。YOLOv5训练时用的是RGB顺序、归一化到0-1区间如果你的AIPP里mean和std设置和训练时不统一检测精度会明显下降。一个典型的错误就是BGR和RGB搞反了检测框位置没问题但类别置信度全部错乱。所以AIPP的配置要反复核对训练代码里的预处理参数。如果精度和性能实在无法兼得还可以考虑用AMCT工具做INT8量化。这个过程需要准备一批校准数据集让工具统计激活值的范围然后生成量化后的OM模型。INT8量化后的性能提升非常明显但精度需要自己评估。我的经验是目标检测模型做INT8量化置信度阈值要适当调低一点因为少量检测框的置信度会被压低。5. 常见问题与排查实录5.1 驱动和CANN版本不匹配最常见的启动杀手这是Atlas部署里出现频率最高的问题没有之一。症状是跑任何推理程序都会报错有的报“acl init failed”有的报“runtime error”但npu-smi看起来一切正常。排查路径很固定# 查看驱动版本 npu-smi info # 查看CANN版本 cat /usr/local/Ascend/ascend-toolkit/latest/version.cfg拿到两个版本后去昇腾社区的版本配套表里核对。我记得之前遇到过一台机器装了6.3.RC3的CANN但驱动版本对应的是7.0的配套分支结果所有推理程序都无法创建context。解决办法就是重装驱动或者把CANN降级让两者回到配套状态。我后来学乖了每次部署前先把Driver版本、Firmware版本、CANN版本这三行信息保存在一个文本里贴在机器上以后排查问题时可以少走很多弯路。5.2 24G显存不够用的真相模型常驻和动态加载Atlas 300V 24G虽然显存不小但踩过一次显存不足的坑后我明白了一个道理显存管理的首要原则是让模型常驻而不是频繁加载释放。在刚开始写推理服务时我图省事每次请求来了都重新加载一遍模型推理完立刻释放。结果在并发请求多的时候整个进程直接报“out of memory”。原因很简单模型加载本身需要额外的workspace内存加载释放反复操作内存碎片越积越多最后把24G都耗尽了。正确做法是进程启动时把模型加载到显存推理时只做数据搬入搬出服务退出时才卸载模型。如果同时要管理多个模型最好用一个显存管理模块统一分配不要让每个线程各管各的。另外如果模型确实大到24G装不下优先考虑模型分片或者改用INT8版本。YOLO这类检测模型INT8后体积能缩小一半还多精度损失通常在可接受范围内。显存不够用的时候永远别直接加batch size硬撑掉精度得不偿失。5.3 YOLO特有的后处理坑解密输出的组织方式很多人在Atlas上跑通YOLO后都会卡在后处理阶段拿到的输出数组和预期的检测结果对不上。这里的问题是不同版本的YOLO在导出ONNX时输出层的组织方式不同。以YOLOv5为例如果export.py加了--end2end参数输出会是一个已经做过NMS的Tensor如果没加输出就是三个不同尺度的特征图需要自己decode。在Atlas上建议导出时直接使用端到端版本把NMS也一起编进模型里。这样推理输出的就是过滤后的检测框省去写decode和NMS的麻烦。但端到端输出也有代价NMS里的IoU阈值、置信度阈值被固定在了模型里运行时想调整只能重新转模型。我的建议是开发阶段用带后处理的模型快速验证部署阶段用端到端模型上线两边各留一个版本。5.4 排查问题用的几个救命命令最后整理几个排查时最常用的命令平时没事多敲一敲真出问题时能省大量时间# 查看NPU设备状态和健康信息 npu-smi info # 查看CANN日志应用层报错基本在这 tail -f ~/ascend/log/plog/*.log # 查看系统日志中NPU相关错误 dmesg | grep -i npu # 查看环境变量是否正确加载 env | grep ASCEND如果应用卡死优先看plog下的日志错误信息会比Python traceback详细得多。搞不定的时候把plog日志连同npu-smi输出一起发到社区论坛一般半天内就能找到答案。在整个部署过程中我最大的感受是昇腾卡和GPU的思路并不完全一样不能照搬CUDA生态下的部署经验。但只要你愿意花时间把CANN的整套工具链理清楚从模型转换到推理性能调优每一步其实都有非常成熟的路径可以走。Atlas 300V 24G作为一张推理卡在成本、功耗、显存三者之间找到了一个很合适的平衡点尤其适合目标检测这类常见的视觉业务。最后再分享一个小技巧第一次上手时别追求一步到位先用最小模型跑通整个链路再逐步把AIPP、多batch、INT8量化这些进阶功能加上去。把链路掌握熟练之后你会发现Atlas的推理部署没有想象中那么神秘踩过的坑越多后面就越顺。
返回列表