ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Atlas 300V 24G能否作为运算加速卡?YOLO模型部署实战解析

Atlas 300V 24G能否作为运算加速卡?YOLO模型部署实战解析 1. 整体设计与思路拆解1.1 先说结论Atlas 300V到底是什么如果你最近在查AI推理加速相关的东西大概率会碰到“Atlas”这个词。尤其是Atlas 300V 24G这款卡很多人第一反应是这货是不是类似RTX 4090那种显卡能不能直接拿来部署YOLO目标检测模型先说结论Atlas 300V是一款昇腾系列NPU推理卡不是传统意义上的GPU但它的确属于“运算加速卡”这个范畴。它专门为AI推理场景设计算力表现上以INT8和FP16为主不像显卡那样擅长图形渲染。也就是说你拿它当游戏显卡用肯定不行但如果目的是跑YOLO、跑ResNet、跑OCR这类深度学习推理任务它完全能胜任而且在功耗、稳定性、部署形态上有自己的优势。我最早接触Atlas平台是因为一个边缘计算项目需要在机房部署多个视频流检测服务原本打算用GPU方案但考虑到功耗和供货周期最后换成了Atlas 300V。实话实说刚开始确实不习惯因为整个软件栈跟CUDA生态完全是两套逻辑踩了不少坑。这篇博文就基于我的实际使用经验把“Atlas 300V能不能跑YOLO、怎么跑、坑在哪里”一次说清楚。1.2 为什么会有“Atlas 300V 24G是不是运算加速卡”这种疑问这个疑问的来源主要有两个。第一Atlas这个产品线覆盖范围比较广有服务器侧的Atlas 800训练服务器、Atlas 300I系列推理卡、Atlas 300V系列视频分析卡还有边缘计算盒子和模组。很多人第一次看到“Atlas 300V 24G”这个名字分不清楚它跟训练卡、跟GPU之间的区别甚至有人以为它是显卡。第二24G这个显存容量在GPU领域基本是中高端训练卡的水平比如RTX 3090就是24G。看到这个数字自然会产生“是不是对标3090”的联想。但实际上Atlas 300V的24G是NPU的缓存内存用于存放模型权重和中间特征图传输带宽和访问方式都跟GPU显存有差异不能直接用“显存大性能强”的GPU逻辑来衡量。真实情况是Atlas 300V 24G的定位是视频分析场景下的高性能推理加速卡单卡能够支持几十路1080P视频的实时分析。它内部包含多个AI Core计算单元配合DVPP图像预处理模块在处理视频流目标检测任务时效率很高。1.3 部署YOLO选Atlas而不是GPU的四个理由我在决定用Atlas之前对比过几套方案包括NVIDIA的Tesla T4、RTX 4000系列以及Atlas 300V。对比下来Atlas在四个方面有明显吸引力。第一是功耗控制。Atlas 300V的典型功耗在70W左右满载也就不到100W而Tesla T4功耗是70W到90W但T4供货量少价格高。RTX系列虽然性价比高但民用卡的稳定性和长时间运行寿命在机房环境里不如专业推理卡。第二是解码能力。Atlas 300V自带硬件视频解码模块H.264/H.265视频流可以直接通过DVPP硬件解码不需要额外占用AI Core资源。这个特性在做实时视频流检测时特别有用。GPU方案通常需要单独用NVDEC或者FFmpeg软解软解会占CPU资源NVDEC的并发路数还要看具体型号。第三是数据安全要求。在某些政企、金融、运营商场景里面国产化推理卡是硬性要求没得选。Atlas 300V在供应链和生态适配方面比较有保障。第四是长期运行稳定性。Atlas的散热设计和无风扇被动散热版本非常适合机房7x24小时运行。我自己实测连续跑了一周多没有出现掉卡或者性能衰减的问题。不过也要把丑话说在前面如果你只是为了个人学习或者跑个demo验证一下模型效果我建议直接用GPU省心太多。Atlas的软件生态虽然这几年进步明显但跟CUDA相比还是有不小差距需要花时间去适应。2. 核心细节解析与实操要点2.1 先搞懂Atlas的软件栈再动手不然寸步难行Atlas平台跟CUDA生态最大的区别在于它的整个软件体系以CANNCompute Architecture for Neural Networks为核心。你可以把CANN理解为昇腾平台的“CUDA”但它不仅有驱动和运行时还提供了算子库、图编译引擎、推理引擎等一整套工具链。CANN下面是昇腾NPU硬件抽象层通过AscendCLAscend Computing Language接口对外提供统一API调用能力。AscendCL的作用类似于CUDA Runtime API负责内存管理、模型加载、推理执行等基础操作。再往上有MindSpore框架的昇腾后端、MindX SDK推理套件以及华为官方提供的模型转换工具ATC。部署YOLO的完整链路是这样的PyTorch训练模型 ↓ 导出ONNX模型 ↓ ATC工具转换成OM格式 ↓ AscendCL或MindX SDK加载OM模型推理 ↓ 推理结果后处理NMS等这里面最关键也最容易出问题的一步就是ONNX转OM。GPU平台可以直接用TensorRT加速PyTorch导出的ONNX但Atlas只认OM格式必须经过ATC转换。ATC转换的过程本质上是把ONNX的计算图映射到昇腾NPU支持的算子集合上面如果模型里用到了一些昇腾算子库还不支持的算子转换就会报错。2.2 模型转换的底层逻辑为什么不能直接跑PyTorch模型很多人刚接触Atlas时都会问为什么PyTorch训练好的pth模型不能直接加载运行原因在于NPU跟GPU的指令集和计算架构完全不同GPU上的算子经过CUDA优化NPU上则需要专门的算子指令才能高效执行。ATC工具做的事情就是把ONNX图中的每个算子逐一映射到昇腾AI Core支持的算子并生成一个高度优化过的OM模型文件。举个例子YOLOv5s模型里面常见的算子包括Conv、BatchNorm、SiLU、Concat、Resize、Sigmoid等。其中Conv和BatchNorm这类基础算子在昇腾上支持得很完善转换时基本没有问题。但一些特殊版本的自定义算子、或者某些ONNX导出选项导致的冗余算子就可能在转换时报“Unsupported Op”之类的错误。我在转换一个改过的YOLOv5模型时就踩过算子不支持的坑。后来排查发现问题出在模型里用了一个动态尺寸的Resize节点ATC转换时无法确定输出尺寸。解决方法是固定模型输入尺寸比如固定成640x640并在导出ONNX时设置opset版本为11以上。2.3 三种部署姿势按需选择Atlas上运行YOLO模型的姿势主要有三种从底层的灵活度到上层的易用性递增。第一种是直接调用AscendCL接口类似于用CUDA Runtime API手写推理代码。这种方式的优点是可以精细控制内存分配和推理流程性能上限最高缺点是代码量大需要手动管理输入输出内存、请求队列、流同步等开发效率低。第二种是使用MindSpore框架的昇腾后端直接用Python写推理脚本。这种方式比较适合本来就熟悉MindSpore的开发者加载OM模型、准备数据、执行推理都比较方便。但对于PyTorch用户来说还需要额外学习MindSpore的API习惯。第三种是使用MindX SDK推理套件。MindX SDK把模型加载、推理、前后处理封装成了插件化流程可以通过配置文件串联起来用户只需要写很少的代码。这种方式最适合快速落地YOLO推理服务也是我目前在项目中主要用的方案。它的缺点是封装层级高遇到问题排查起来比较费劲但胜在开发效率高。3. 实操过程与核心环节实现3.1 环境准备清单在开始之前先确认硬件和软件环境。我下面列一个参考组合实测可以正常跑通YOLOv5s模型的转换和推理。硬件方面一台x86服务器操作系统为Ubuntu 20.04或22.04一张Atlas 300V 24G推理卡通过PCIe插槽连接服务器内存建议32G以上硬盘预留至少20G空间软件方面昇腾CANN Toolkit版本为6.1及以上MindX SDK或AscendCL开发包Python 3.8或3.9PyTorch用于导出ONNX模型CUDA仅用于GPU上导出ONNX不参与Atlas部署安装CANN Toolkit的过程比较繁琐官网提供了安装脚本按顺序执行即可。需要注意的一点是安装完成后必须source环境变量脚本否则命令行里找不到atc、msame这些工具。source /usr/local/Ascend/ascend-toolkit/set_env.sh安装完成后可以用npu-smi工具查看NPU设备信息检查驱动是否正常。npu-smi info如果能看到设备列表并且状态为OK说明硬件和驱动基本没问题。接下来就可以开始模型转换了。3.2 从PyTorch导出ONNX模型我以YOLOv5s为例说明操作流程。首先准备一份YOLOv5代码仓库在能够正常加载权重的环境中执行导出脚本。python export.py --weights yolov5s.pt --include onnx --opset 11 --img-size 640 640导出时需要注意几个关键参数。opset版本建议选择11或12太高或太低都可能影响ATC转换。输入尺寸固定为640x640不要用动态尺寸否则后续在ATC里配置动态shape会很麻烦。导出后的ONNX模型可以先在Python侧的onnxruntime上跑一次验证输出结果是否正常。这一步很有必要可以提前发现导出是否成功避免后面转换OM后才发现问题排查起来更耗时。3.3 使用ATC工具将ONNX转换为OM拿到onnx文件后执行ATC转换命令。atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640 \ --output_typeFP32 \ --precision_modeforce_fp16参数说明model输入的ONNX模型路径framework5表示输入模型格式为ONNXoutput输出OM模型名称soc_version芯片版本。Atlas 300V对应的是Ascend310P系列具体可以用npu-smi info查看或用ascend-dmi工具确认input_shape输入张量名称和形状名称必须跟ONNX模型的输入名一致最好在导出前用参数指定--dynamic为Falseprecision_modeforce_fp16强制使用FP16精度。这个选项能显著提升推理速度但极端情况下会对精度产生轻微影响泛化能力敏感的模型建议先测一下一个容易忽略的点是ONNX模型输入节点的名称可能是images也可能是input具体取决于YOLOv5仓库代码里使用的名称。转换前建议写个小脚本打印一下输入节点的名字不然input_shape填错ATC转换会直接报错。3.4 MindX SDK推理代码实现转换完OM模型后就可以在MindX SDK中搭建推理流程了。MindX SDK的做法是先定义一个pipeline配置文件声明流中包含哪些插件模块例如视频解码插件、图像缩放插件、模型推理插件、后处理插件。下面是一个简化版pipeline配置pipeline: imagedecoder: plugin: mxpi_imagedecoder props: input_format: RGB imageresize: plugin: mxpi_imageresize props: resize_width: 640 resize_height: 640 modelinference: plugin: mxpi_tensorinfer props: modelPath: ./yolov5s.om deviceId: 0 imagepostprocess: plugin: mxpi_objectpostprocess props: postprocessConfigPath: ./yolov5_postprocess.config配置文件里要根据实际模型的后处理要求填写类别数、anchor尺寸、置信度阈值等参数。这一块没有统一标准模板必须根据自己训练的YOLO版本去调整。如果是官方YOLOv5s模型可以直接参考社区里的公开配置。接下来用Python调用SDK。from mindx.sdk import base base.init(mxVision) stream base.create_stream(pipeline.yaml) # 读取一张图片 image base.data_utils.read_image(test.jpg) tensor base.Tensor(image, dtypeuint8) # 输入到流中 result stream.infer(tensor)整个调用过程不算复杂。推理结果返回后需要解析每个人的坐标、类别和置信度再将坐标映射回原始图像尺寸。3.5 性能实测数据我自己用Atlas 300V 24G跑YOLOv5s固定输入640x640FP16精度单路推理实测处理纯推理部分大约在每秒35到45帧之间。如果加上视频解码、缩放、后处理整体端到端处理1080P视频流大约能做到每秒25到30帧左右足够覆盖大多数实时分析场景。作为对比同样条件下用RTX 3060跑YOLOv5s纯推理速度大约是60到70帧。Atlas在绝对速度上确实比不过同价位GPU但在多路视频流并发场景下Atlas的优势会体现出来。因为DVPP硬件解码不占AI Core资源跑8路、16路视频流时GPU方案的CPU占用率会明显上升而Atlas可以做到CPU占用率很低。不过要注意Atlas 300V的INT8性能比FP16更好如果有明确的精度容忍度建议改用INT8量化模型推理吞吐量还能再提升不少。4. 常见问题与排查技巧实录4.1 模型转换失败算子不支持怎么办这是最常遇到的问题。ATC转换报错信息通常会在日志里明确指出来是哪个算子的哪个属性不支持但有时候报错信息很绕不是直接告诉你算子名字。优先排查方向有三个。第一检查ONNX模型是否包含动态维度。固定输入尺寸重新导出ONNX。第二检查算子版本兼容性。某些YOLO改进版本里会用到自定义模块比如SPPF、C3TR、注意力机制相关算子这些在导出ONNX后可能是以比较底层的方式表示的。遇到这种情况可以先把对应模块的代码简化或者替换成原生支持的算子。第三升级CANN版本。昇腾算子库更新很快很多新算子是在新版本里追加的。我遇到过有一个模型在老版本CANN上无法转换升级到7.0 RC版本后直接通过。如果还是不行就需要检查ONNX模型的静态图是否存在不合理的地方比如输入输出名称不一致、shape信息缺失等。可以用以下脚本快速检查模型结构。import onnx model onnx.load(yolov5s.onnx) print(model.graph.input) print(model.graph.output)4.2 推理结果不正确坐标偏移或者检测不到物体这类问题大概率出在前处理和输入格式上。YOLO模型输入图像一般需要做letterbox处理将原始图像等比缩放到640x640四周填充灰色像素。如果省略了这一步直接把图片resize到640x640推理精度会明显下降尤其是小目标检测效果惨不忍睹。MindX SDK的imageresize插件默认是直接拉伸resize不是letterbox。这一点要特别注意需要自己写一个插件或者在resize前加上padding处理。我刚开始跑的时候没注意这个细节检测结果完全错乱后来对比了onnxruntime的推理结果才定位到问题。另外输入图像的通道顺序也容易踩坑。PyTorch模型默认输入是RGB但是OpenCV读出来的是BGR。如果忘记做通道转换模型的检测结果会整体偏离或者出现大量漏检。4.3 推理时内存不足程序崩溃Atlas 300V虽然显存有24G但NPU内存管理跟GPU不太一样。如果在同一时间内频繁创建和销毁推理上下文内存碎片化会越来越严重最终导致分配失败。解决方法是复用一个推理上下文不要每次推理都重新创建。MindX SDK的Stream模式本身就做了内存池管理正常情况下不会出现持续上涨的问题。但如果自己用AscendCL裸调就需要手动管理内存复用。另外多路视频流并发时要注意每个流对应的输入buffer和输出buffer是否及时释放。最简单粗暴的办法是设置一个合理的batch大小比如每4帧推理一次再配合消息队列做缓冲避免峰值请求一下子把所有内存打满。4.4 关于“Atlas 300V 24G是运算加速卡吗”的最终解答这个问题其实没有标准答案取决于你的判断维度。从功能角度说它确实是用来加速AI计算的硬件设备加解密、图像处理、视频分析、自然语言处理这些推理任务都能跑称之为“运算加速卡”没有毛病。但它不是通用运算加速卡。它不能跑CUDA程序不能跑任意Python代码也不能直接当作GPU去并行计算。它的核心价值在于深度神经网络推理特别是视频流场景下的目标检测、图像分类、语义分割这类任务。如果你手里已经有CUDA写的YOLO推理程序想在Atlas上直接跑只有一条路重新走一遍模型转换和代码适配流程没有捷径。这也提醒我们在选型时不要只看硬件指标还得把软件的适配成本算进去。写在后面一点个人经验用Atlas 300V跑通YOLO整体流程其实比想象中要花时间。尤其是从GPU生态切换过来的人一开始会很不适应工具链的成熟度和社区文档的丰富度都跟CUDA生态有差距。但一旦把模型转换和SDK流程跑通之后常规的YOLO推理部署就是走流程了没有特别多玄学的东西。我的建议是如果你只是学习或者做原型验证优先用GPU效率高得多。如果你有明确的部署场景比如长时间运行、多路视频流、机房环境不合适、或者有国产化要求那Atlas 300V值得纳入考虑。买卡之前先拿官方工具箱或者测试环境把模型转换流程跑通一遍确认算子都能支持再决定是否下单这样能最大程度避免硬件到了但模型跑不起来的尴尬局面。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进