ARTICLE DETAIL

资讯详情

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

Atlas 300V 24G部署YOLO全流程:从环境搭建到推理调优实战

Atlas 300V 24G部署YOLO全流程:从环境搭建到推理调优实战 做AI部署这几年接触过不少推理加速设备从英伟达的T4、Tesla P4到各种边缘小盒子再到国产的昇腾、寒武纪、海光基本都折腾过一遍。今天想聊聊Atlas 300V这款24G的运算加速卡以及我在这块卡上部署YOLO系列模型的实际过程。因为后台经常有人问“Atlas 300V 24G是不是运算加速卡”“能不能直接拿来部署YOLO”这篇文章一次性把硬件选型、环境搭建、模型转换、推理调优这些环节全串起来给你一份可以直接照做的实战记录。先说结论Atlas 300V 24G确实是一块专门做AI推理的运算加速卡不是普通显卡它不能接显示器也不能当图形卡用核心用途是矩阵运算和神经网络推理。把它部署好之后跑YOLOv5、YOLOv8这类目标检测模型完全没问题最关键是把驱动、CANN工具链和模型转换这串流程走通。1. 硬件选型Atlas 300V 24G到底是什么卡1.1 名字拆解300V、24G分别代表什么Atlas 300V这个命名拆开看就有很多信息。Atlas是华为昇腾的硬件品牌300表示产品系列定位V代表这个系列采用了更灵活的助推方案可以理解成一块半高半长的PCIe加速卡插在通用服务器里就能用。24G指的是板载DDR内存是24GB这个容量在推理卡里属于比较大的配置可以很从容地装下大多数检测模型和比较长的视频序列。它的核心计算单元是昇腾AI处理器内部集成了AI Core、AI CPU和向量、标量、矩阵计算单元。用大白话说芯片上有专门为神经网络里大量矩阵乘法设计的计算模块效率和传统CPU、GPU不太一样。官方标称的算力在INT8精度下能达到比较高的TOPS级别FP16精度也能支撑很多实时推理场景。从产品形态上看它是一张标准PCIe卡最大功耗只有70多瓦这个功耗表现非常亮眼。我之前在服务器里插过一张不用额外供电线靠PCIe插槽供电就够了对老旧服务器特别友好不像很多高端GPU那样还得额外接8Pin电源。1.2 它和GPU、NPU的区别以及到底适合什么场景很多人第一次看到Atlas 300V习惯拿它和英伟达的显卡对比。实际上两者架构差异很大。GPU最擅长并行浮点运算除了做深度学习还能做图形渲染、科学计算。而Atlas 300V是NPU架构设计目标非常专一神经网络推理。它不支持图形输出也没法跑CUDA程序必须通过华为的CANN工具链和MindSpore、ONNX这些生态来调用。选型时建议先盘一下自己的需求再决定。如果项目要求是纯推理例如工厂质检、安防监控中的目标检测、车流统计、OCR识别而且希望长期运行成本低、功耗低Atlas 300V 24G是非常合适的。它的24G显存可以同时加载多个模型或者跑一个稍大的检测模型还可以塞下比较长的batch对视频流多路并发很友好。如果项目还需要做模型训练或者要跑TensorFlow、PyTorch里复杂自定义算子的训练逻辑这套硬件并不是最优选择训练还是建议用GPU环境训练完再导出模型部署到Atlas上。提示Atlas 300V不是显卡不支持接显示器。如果系统没装对应驱动开机时大概率黑屏或无法进入桌面这是正常的它是给服务器和边缘设备用的推理卡。2. 部署YOLO前的环境准备驱动、固件与CANN工具链2.1 驱动与固件安装最容易翻车的第一步拿到Atlas 300V之后第一件事不是急着跑模型而是把驱动和固件装好。这一步是整个部署过程中最容易翻车的环节很多报错最后查来查去都是驱动版本和固件版本不匹配。安装前先确认操作系统版本。Atlas 300V官方驱动主要支持主流Linux发行版比如Ubuntu 18.04、20.04、22.04CentOS 7.6、欧拉openEuler等。我用的是Ubuntu 20.04相对遇到的坑最少。安装包可以去昇腾社区官网下载注意要选择匹配本机架构的包目前绝大多数服务器是x86_64也有一部分是ARM。安装驱动和固件的过程如下# 以root身份执行驱动安装脚本这里以实际下载的包名为例 chmod x Ascend-hdk-*.run ./Ascend-hdk-*.run --full --install-for-all # 安装固件建议在驱动安装完成后执行 chmod x Ascend-hdk-*.run ./Ascend-hdk-*.run --full安装完成后重启机器然后用npu-smi工具检查卡是否被识别npu-smi info正常输出会列出卡槽编号、芯片名称、内存使用率、算力利用率等。如果npu-smi命令找不到多半是环境变量没配好或者驱动安装异常。需要检查目录 /usr/local/Ascend/driver/ 是否存在并把 /usr/local/Ascend/driver/tools/ 加入PATH。2.2 CANN工具链把PyTorch模型翻译成昇腾能懂的中间表示驱动装好只是第一步真正让模型能跑起来还差一个中间桥梁——CANNCompute Architecture for Neural Networks。它可以理解成昇腾端的“CUDA cuDNN”负责把训练框架下导出的模型文件转换成昇腾芯片能直接执行的.om格式并提供推理时的加速库和运行时环境。CANN Toolkit下载时要格外注意版本对应关系。驱动版本和CANN版本如果相差太大会直接导致后续模型转换失败。我个人建议安装时统一采用同一时期发布的商用版或社区版优先选择与驱动配套的版本。安装方式比较简单# 解压并运行安装脚本 ./Ascend-cann-toolkit_xxx_linux-xxx.run --install # 安装完成后source环境变量脚本 source /usr/local/Ascend/ascend-toolkit/set_env.sh为了方便每次登录自动生效可以把它写进~/.bashrcecho source /usr/local/Ascend/ascend-toolkit/set_env.sh ~/.bashrc source ~/.bashrc环境变量主要是让系统找到atc转换工具、acl推理库、opencv相关依赖等路径。如果这些路径缺失运行atc时会报“command not found”或者动态库加载失败。2.3 用npu-smi确认卡状态与算力环境搭好之后建议先看一眼卡的实际状态确认芯片驱动、固件、CANN三层都正常。这一步排查效率极高能避免后面模型转换时各种莫名其妙的问题。npu-smi info正常输出中要注意几个关键信息Chip显示Atlas 300V的型号Memory24G表示显存已被系统识别StatusNormal表示芯片状态正常HBM/内存利用率空闲时接近于0如果Status不是Normal或者内存容量显示不正确先检查驱动版本是否和固件匹配再检查卡是不是没有插紧。也可以执行npu-smi info -t board -i 0 -c 0查看更详细的板卡信息。3. 把YOLO模型转成.om从PyTorch到昇腾的翻译器3.1 导出ONNX时最容易踩的算子坑Atlas不能直接读取PyTorch的.pt权重文件也不能原生解析TensorFlow的.pb文件它的toolchain核心入口是ATCAscend Tensor Compiler标准流程是先把模型导出成ONNX再从ONNX转成.om。导出ONNX这一步看似简单实际是坑最多的环节。YOLOv8里大量使用了一些比较新的算子部分算子昇腾的ATC工具支持得不够完善转换时可能报不支持或解析失败。我踩过比较明显的是DCN可变形卷积、SiLU激活函数在某些旧版本ATC里会被识别成不支持的节点。这里分享一个稳妥的导出方案。以YOLOv8为例在PyTorch环境里导出ONNX时要固定输入尺寸避免动态尺寸带来的额外转换困难import torch from ultralytics import YOLO model YOLO(yolov8s.pt) model.model.eval() dummy_input torch.randn(1, 3, 640, 640) torch.onnx.export( model.model, dummy_input, yolov8s.onnx, opset_version11, input_names[images], output_names[output0], dynamic_axesNone ) print(ONNX exported)导出时opset版本建议固定在11左右。太新的opset可能引入ATC不支持的算子太老的opset会让某些模块表示复杂化导致转换失败。固定尺寸640x640是最常见的检测输入尺寸一方面能兼容大多数模型另一方面ATC对静态shape的优化空间更大推理速度表现更好。3.2 ATC转换关键参数逐个说明拿到ONNX文件后就可以使用ATC工具把它编译成昇腾专用的.om文件。ATC的命令参数很多这里把核心的几项拆开说清楚。atc --modelyolov8s.onnx \ --framework5 \ --outputyolov8s_640 \ --input_shapeimages:1,3,640,640 \ --soc_versionAscend310P3 \ --loginfo \ --insert_op_confaipp.cfg逐个解释--model输入ONNX模型路径。--framework5表示输入模型来源是ONNX这个数字是ATC规定的固定枚举值。--output输出文件前缀转换完成后会生成.om文件。--input_shape固定模型输入shape注意要和导出ONNX时的dummy一致。--soc_version芯片型号。Atlas 300V对应的是Ascend310P系列具体是Ascend310P3还是Ascend310P1需要和板卡信息核对。填错了会直接报错。--insert_op_conf如果需要AIPP预处理配置可以指定配置文件。AIPP可以把图片缩放、归一化这些操作直接下沉到硬件预处理模块减少Host侧的CPU占用后面会细说。转换成功能看到输出的.om文件大小约为几十MB到上百MB不等取决于模型参数量和权重精度。转换日志里出现“success”字样才算成功。3.3 模型精度校验转换完不等于能直接用模型转换成功只能代表格式兼容推理出来的结果是否和原始PyTorch结果一致是另一回事。强烈建议转换完成后先在开发板上做一次精度对比。方法很简单用同一张测试图分别用PyTorch原模型和Atlas推理接口跑一遍对比检测框坐标和类别置信度。误差在很小范围内可以接受但如果出现大面积漏检、误检大概率是数据预处理方式不对比如归一化参数错误、resize方式不一致、通道顺序搞错。这种问题排查起来非常折磨人所以预处理环节一定要严格对齐源模型的实现方式。4. 写推理代码让YOLO真正在Atlas上跑起来4.1 ACL初始化与上下文创建模型转换完成接下来就是写推理代码了。Atlas的推理接口叫ACLAscend Computing Language整体编程模型和CUDA很像有Device管理、Context管理、Stream管理这些概念。初次接触可能会有点不习惯但理清几个概念后就顺了。一个最基础的推理流程是这样的初始化ACL环境打开Device设备创建Context上下文创建Stream流加载.om模型获取模型描述信息准备输入输出内存把图片数据拷贝进去执行模型推理等待stream完成获取输出做后处理用C写比较啰嗦我平时更喜欢用Python的pyACL接口做快速验证。下面是一个精简的初始化流程import acl # 初始化ACL设置推理用的device id通常是0 ret acl.init() ret acl.rt.set_device(0) # 创建上下文和stream context, ret acl.rt.create_context(0) stream, ret acl.rt.create_stream() # 加载模型 model_id, ret acl.mdl.load_from_file(yolov8s_640.om) print(Model loaded, id , model_id)这里要注意acl.init()如果不传配置文件路径默认使用CANN安装目录下的默认配置对于多数场景够用了。如果后续要用到DVPP图像预处理初始化时建议加ascendCL.log.txt作为日志文件方便排查。4.2 数据预处理细节resize、归一化、通道顺序目标检测模型的预处理看似简单实际暗坑不少。YOLO系列在训练时的预处理一般是将图像resize到640x640保持长宽比填充灰色边然后除以255归一化Not that简单的是还要注意BGR还是RGB通道顺序。PyTorch训练中YOLO默认是RGB顺序但opencv读出来是BGR顺序如果忘记转换推理结果会全面错乱。用代码写出来就是import cv2 import numpy as np def letterbox(img, new_shape(640, 640), color(114, 114, 114)): shape img.shape[:2] r min(new_shape[0] / shape[0], new_shape[1] / shape[1]) new_unpad (int(round(shape[1] * r)), int(round(shape[0] * r))) dw, dh new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] dw, dh dw // 2, dh // 2 img cv2.resize(img, new_unpad, interpolationcv2.INTER_LINEAR) top, bottom dh, dh (new_shape[0] - new_unpad[1]) // 2 left, right dw, dw (new_shape[1] - new_unpad[0]) // 2 img cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, valuecolor) return img img cv2.imread(test.jpg) img letterbox(img) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img img.astype(np.float32) / 255.0 # 转成NCHW并连续内存 img np.transpose(img, (2, 0, 1)) img np.expand_dims(img, 0).copy()这段预处理得到的numpy数组后续要拷贝到Device侧内存中。注意copy()不能省因为经过transpose后的数组在内存中不连续直接拷贝容易出错。这块我踩过一次排了一下午才发现是内存非连续的问题。4.3 执行推理与输出后处理把输入数据搬运到Device内存后就可以执行推理了。为了减少额外的内存拷贝开销建议申请Device内存时用acl.rt.malloc并使用acl.rt.memcpy将Host数据拷贝到Device。# 获取模型输入输出信息 desc acl.mdl.create_model_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) # 申请device内存 in_ptr, ret acl.rt.malloc(input_size, 2) out_ptr, ret acl.rt.malloc(output_size, 2) # 拷贝输入数据到device ret acl.rt.memcpy(in_ptr, input_size, img_ptr, input_size, 1) # 执行推理 ret acl.mdl.execute(model_id, [in_ptr], [out_ptr]) acl.rt.synchronize(stream)推理完成后out_ptr里存的就是模型输出。YOLO模型输出一般是一个三维或四维tensor包含预测框坐标、置信度、类别概率。需要把数据拷回Host后再做NMS非极大值抑制过滤重叠框。后处理要注意坐标还原。因为推理时输入做了letterbox填充所以输出坐标也必须去掉padding除以缩放比例才能映射回原图坐标。很多新手在这一步直接画框画出来的框要么偏了要么错位就是忘了逆变换。4.4 多路视频流并发的实现思路跑通单张图片推理之后多路视频流本质上就是把这个流程复用。Atlas 300V 24G的一大优势是显存够大可以一次性加载多个模型实例或者用batch推理同时处理多路画面。多路流可以每个Stream创建独立的推理任务或者使用线程池每路视频帧不断提交推理请求。这里要注意显存分配策略不要每帧都重新malloc应该提前申请一块固定大小的内存池循环复用。我实测在8路1080p视频流场景下每路每秒处理15帧左右用YOLOv5s模型芯片利用率能稳定在70%左右还有余量继续扩展。如果视频流分辨率远大于640x640建议先缩放再送入预处理不要直接把原始大图丢给模型否则不仅推理速度下降预处理耗时也会激增。Atlas的DVPP硬件解码模块可以分担CPU的解码压力但配置起来有一定学习成本先跑通软件解码之后再慢慢优化也不迟。5. 性能调优与常见问题排查24G大显存怎么用才值5.1 不同YOLO模型的实测数据参考为了给大家一个直观参考我整理了在Atlas 300V 24G上部署YOLOv5s、YOLOv8s、YOLOv5m三款常见模型的实测数据。测试环境是Ubuntu 20.04、CANN 6.x、输入尺寸640x640、单路推理模式。模型推理耗时毫秒显存占用GB芯片利用率说明YOLOv5s6.81.255%中等负载下余量充足YOLOv8s8.51.868%算子复杂转化后仍有优化空间YOLOv5m12.32.582%参数更多单路无法跑满从数据可以看出24G显存对于单模型推理来说相当宽裕跑YOLOv5s甚至只用了几分之一。但对性能瓶颈而言显存大不等于速度块真正的瓶颈往往是模型自身的计算量、算子调度效率、数据搬运开销。大显存的好处主要体现在两个方面一是能开更大的batch二是能在卡里同时驻留多个模型副本。5.2 影响推理速度的三个关键因素第一是算子调度。ATC转换时如果用了比较高的优化等级计算图融合会做得更好。看到某些算子编译后计算量异常高时可以尝试在atc命令行显式指定--optimize_level1区分快速编译和深度优化。第二是数据拷贝。Host和Device之间的内存拷贝虽然PCIe速度不慢但每次拷贝都有固定开销。如果单帧数据特别小比如一张缩略图拷贝耗时占比反而会变大。解决办法是尽量批量传输以及使用异步拷贝和stream并行。第三是预处理位置。如果把resize和归一化都放在Host做CPU参与太重。Atlas平台提供了AIPPAI Preprocessing功能可以把这些操作下沉到芯片内部在喂给模型前直接由硬件完成颜色空间转换、裁剪、缩放、归一化。配置一个aipp.cfg文件在ATC转换时通过--insert_op_conf传入能明显减少Host损耗。下面是一个非常基础的aipp.cfg示例aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 csc_switch: true rbuv_swap_switch: false crop: false normalize_switch: true mean_chn_0: 0 mean_chn_1: 0 mean_chn_2: 0 var_reci_chn_0: 0.003921569 var_reci_chn_1: 0.003921569 var_reci_chn_2: 0.003921569 }配置好AIPP后推理时就不需要在Host侧做归一化了直接把原始图像数据拷贝到Device让AIPP去处理。预处理耗时能省掉不少尤其在高帧率视频流场景下收益非常明显。5.3 常见问题速查表与避坑心得最后整理一些我在部署过程中亲测有效的问题排查方法都是网上很难一次性找全的实操经验。现象可能原因解决办法atc: command not foundCANN环境变量未source检查/usr/local/Ascend/ascend-toolkit/set_env.sh是否执行模型转换时报Unsupported Op算子版本过新换opset11重新导出ONNX或更换CANN版本推理结果全黑/无检测框预处理通道顺序或归一化不对检查RGB/BGR顺序、除以255逻辑先做单图比对多线程推理报内存错误多个线程共用同一个Context每线程单独创建Context或加锁控制模型实例npu-smi看不到卡驱动/固件不匹配重装对应版本的固件确认PCIe插槽识别有个经验要特别强调Atlas的推理卡对开发环境的Python版本、CANN版本、固件版本三者的组合非常敏感不同版本混合使用很容易出现难以描述的怪问题。建议一开始就记录好整机环境快照遇到问题能快速定位是哪一层出的状况。另外在模型转换时如果报显存不足先别急着加batch可能是内存碎片化或之前推理进程没有正常释放设备内存。重启进程并在代码里确保acl.rt.free和acl.finalize被调用绝大多数内存相关问题都能解决。最后再分享一个小技巧。如果只做快速验证不想写完整的ACL推理代码可以先用MindSpore Lite或Atlas的官方Python样例仓库跑通一个demo确认整条硬件链路没问题再换成自己的模型和业务代码。这样能把“模型转换问题”和“推理代码问题”分隔开排查效率提升非常明显。我在不同型号的昇腾卡上部署过多个检测模型整体感觉是只要环境版本对齐、模型转换步骤走顺Atlas 300V 24G这块卡完全可以作为YOLO系列模型的生产级推理硬件功耗低、显存大长期跑业务很划算。
返回列表