拿到一块 Atlas 300V 24G,不装驱动直接插上,大概率连系统都认不出这是个啥。跑通YOLO,更不是 pip install 就能了事的事。
我去年接触昇腾推理卡,从硬件安装到模型转换踩了一整圈坑,最后把 YOLOv5 在 Atlas 300V 上跑通了。这篇把整个过程写下来,包括硬件真相、驱动环境、模型转换、推理部署和调优避坑,给准备上手 Atlas 的兄弟们一个参考。
1. Atlas 300V 24G 硬件解析:它到底是不是运算加速卡
先回答那个被问烂了的热搜话题:Atlas 300V 24G 是运算加速卡吗?
是,但不是我们平时说的游戏显卡或者通用 GPU。Atlas 300V 24G 是昇腾系列的 AI 推理加速卡,核心定位是数据中心和边缘侧的高算力推理。它的“运算”特指神经网络推理计算,不是用来跑 CUDA 通用计算,更不是用来打游戏的。
1.1 一张推理卡的核心构成和关键参数
Atlas 300V 24G 的硬件构成,简单拆解一下,让没接触过的人有个直观认识:
- AI Core(AI计算核心):这是最核心的算力来源,昇腾卡的计算单元,专门为神经网络算子设计,比如卷积、矩阵乘这类操作。整张卡的 AI Core 数量决定了算力上限。
- 板载内存(24G):这就是“24G”的来头。Atlas 300V 是板载 24GB 内存,这个内存规模在推理卡里属于比较大的配置,意味着可以在单卡上部署比较重的模型,或者同时跑多个模型实例。
- PCIe 接口:通过 PCIe 插槽和服务器主板通信。Atlas 300V 一般是 PCIe 3.0 x16 或类似接口,具体看型号后缀。
- 供电和散热:推理卡的功耗远低于训练卡,但也不是个小数字。散热是被动式(靠服务器风道)还是主动式(自带风扇),直接影响机箱选型。
网上参数表不会告诉你的是:Atlas 300V 24G 用的是昇腾 310P 芯片(部分型号是 310P3),这颗芯片的 INT8 算力非常夸张,但 FP16 相对弱一些。所以它的强项是量化推理,不是高精度训练或混合精度推理。
1.2 对比普通显卡,Atlas 强在哪、弱在哪
我做个对照表,看起来更直观:
| 对比项 | Atlas 300V 24G | NVIDIA RTX 3090 | 说明 |
|---|---|---|---|
| 形态 | 推理加速卡 | 游戏/通用GPU | Atlas 无显示输出接口 |
| 内存 | 24GB | 24GB | 容量一样,但带宽和用途逻辑不同 |
| 典型精度 | INT8 量化推理 | FP16/FP32 | Atlas 的 INT8 推理性能优势明显 |
| 软件生态 | CANN / MindSpore / MindX | CUDA / cuDNN / TensorRT | 两套完全不同的技术栈 |
| 驱动安装 | 昇腾专用驱动 + CANN | NVIDIA Driver + CUDA | Atlas 环境配置更繁琐 |
| 适用场景 | 视频分析、OCR、目标检测、分类 | 模型训练、小规模推理 | Atlas 定位“推理专用” |
| 通用计算 | 不支持 CUDA | 支持 CUDA | 无法跑 CUDA 程序 |
| 编解码能力 | 部分型号支持硬件解码 | 有 NVENC/NVDEC | Atlas 适合视频流推理任务 |
1.3 什么样的人适合买 Atlas 300V
如果你做的是这些方向,Atlas 300V 在性价比和功耗上是有明显优势的:
- 视频流实时推理:安防监控、工业质检,视频流解码 + YOLO 检测是标配需求,Atlas 300V 的 INT8 高吞吐特别适合。
- 边缘服务器部署:盒子或者单路服务器上插一张卡,功耗控制好,不用像训练卡那样夸张的散热。
- 国产化软硬件适配需求:项目验收、信创场景,硬件要国资背景,这是硬指标,没得选。
- 大批量离线推理:比如一次跑几十万张图的目标检测,INT8 量化的速度优势非常明显。
如果你主要做模型训练、调试 PyTorch 代码、跑端到端的自定义算子,那 Atlas 300V 不是首选,通用 GPU 会更顺手。选型不是看谁参数高,而是看场景匹配度。
2. 部署前最容易被忽略的一步:分清“推理卡”和“AI服务器”
在开始安装驱动和跑 YOLO 之前,我强烈建议你先想清楚一个问题:Atlas 300V 是插在什么设备上的?
这决定了你后面所有的软件路径。很多人把部署流程搞乱,就是因为没有分清这两层。
2.1 Atlas 的三种典型工作形态
- 昇腾 AI 服务器(Atlas 800 / Atlas 500 等):整机预装驱动和 CANN 工具链,开箱即用程度高,适合不想折腾硬件的企业级用户。
- 自有 x86 服务器 + PCIe 加速卡:最常见也最折腾的方式,需要自己装驱动、装 CANN、配置环境变量。接下来我讲的主要是这条路。
- Atlas 200 DK 开发者套件:小盒子形态,适合原型开发验证,不适合生产部署。
2.2 匹配服务器硬件的前提条件
如果你准备在自有服务器上插卡,务必提前确认三件事:
- PCIe 插槽是否有足够空间和供电:Atlas 300V 一般是全高全长,至少 PCIe 3.0 x8 的插槽;部分卡需要辅助供电线,看型号。
- 主板 BIOS 是否支持大于 4G 解码:这个一般要在 BIOS 里打开 Resizable BAR / Above 4G Decoding 选项,否则可能点不亮。
- 操作系统和内核版本:昇腾官方支持的操作系统有限制,比如 Ubuntu 20.04 / 22.04、CentOS 7.6 / openEuler 等,内核版本太新会导致驱动编译失败。
这些坑我全踩过,尤其是 kernel 太新导致 dkms 编译失败,一度怀疑是硬件坏了。你如果用的是 Ubuntu 22.04 且内核是 6.x 的,装驱动前建议先换回 5.15 内核,能省掉很多麻烦。
2.3 弄清内核和系统后,再规划软件栈
软件栈的层次大概是这样的:
- NPU 驱动(Ascend HDK):让操作系统识别出 NPU 设备的驱动程序,包含固件和内核模块。
- CANN 工具包(Ascend CANN Toolkit):昇腾的计算架构,相当于 CUDA + cuDNN 的存在,提供底层运行时、算子库、图编译等能力。
- 应用开发框架(MindX SDK / AscendCL / MindSpore 等):针对应用级开发的上层封装,直接调用模型推理服务。
安装顺序严格从上到下,不能乱。驱动版本和 CANN 版本有对应关系,不能一个最新一个最旧,必须查官方兼容性列表。
3. 驱动与 CANN 安装实录:从识别设备到环境验证
进到这一步,才是真正开始动手。我假设你是 x86 服务器 + Ubuntu 20.04 的经典组合,网上资料最全,兼容性也最好。
3.1 第一步:把硬件装好,确认能被系统识别
先把卡插到 PCIe 插槽上,接好供电(如果需要),开机进入系统。
用 lspci 查看是不是有昇腾设备:
lspci | grep -i ascend正常的话会看到类似这样的输出:
03:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device 6240如果 lspci 里什么也没有,先检查插槽是否接触良好,再检查 BIOS 里 PCIe 设置。有部分主板默认关闭了非显示设备的 PCIe 枚举,需要手动开启。
3.2 第二步:安装驱动/固件(Ascend HDK)
昇腾的驱动安装包一般是一个 .run 文件,官方下载下来之后,先解压,里面有驱动和固件两个子包:
# 以 root 身份执行 ./Ascend-hdk-<版本号>_linux-x86_64.run --full安装过程会检查依赖、编译内核模块、卸载旧版本。很吃系统环境,缺库就会报错。我当时缺了 gcc、make、dkms 这些基础编译工具,全装好才顺利通过。
装完跑一下 npu-smi info,出现设备列表就说明驱动层 OK 了:
npu-smi info输出类似:
+------------------------------------------------------------------------------------------------+ | npu-smi 22.0.3 Version: 22.0.3 | +-------------------+-----------------+----------------------------------------------------------+ | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page) | | Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) | +===================+=================+==========================================================+ | 0 Ascend 310P | OK | 32.0 45 0 / 0 | | 0 NA | 0000:03:00.0 | 0 0 / 0 22512 / 24576 | +-------------------+-----------------+----------------------------------------------------------+3.3 第三步:安装 CANN Toolkit
驱动装好只是设备能看见了,要真正跑模型还得装 CANN。CANN 提供 AscendCL(类似 CUDA Runtime)和 ATC 模型转换工具等。下载对应 tar 包,解压后运行安装脚本:
chmod +x Ascend-cann-toolkit_<版本号>_linux-x86_64.run ./Ascend-cann-toolkit_<版本号>_linux-x86_64.run --install安装完成后,CANN 默认在 /usr/local/Ascend/ascend-toolkit/latest。还需要配置环境变量:
source /usr/local/Ascend/ascend-toolkit/set_env.sh每次开新终端都要 source 一次,可以写进 ~/.bashrc 一劳永逸:
echo "source /usr/local/Ascend/ascend-toolkit/set_env.sh" >> ~/.bashrc source ~/.bashrc3.4 第四步:验证环境是否就绪
有个简单办法,直接跑一个小测试脚本。比如用 python 调用 AscendCL 检查设备:
import acl # 初始化 ACL ret = acl.init() assert ret == 0, f"ACL init failed, ret={ret}" # 获取设备数量 device_count = 0 ret = acl.rt.set_device(0) assert ret == 0, "Set device failed" # 获取设备名称 name = b" " * 64 ret = acl.rt.get_device_name(name, 0) print("Device name:", name.decode()) # 释放 acl.rt.reset_device(0) acl.finalize()能正常打印设备名,环境就算打通了。这一步建议确认后再往下走,否则后续模型跑不起来,排查问题很容易又绕回环境上。
4. YOLO 模型全流程部署:从 PyTorch 权重到 Atlas 上的 OM 模型
环境就绪后,正式进入 YOLO 部署。整个链条是:
PyTorch 权重(.pt)→ ONNX 模型(.onnx)→ 离线模型(.om)→ AscendCL / MindX 推理
大多数人卡在第二步到第三步的转换。因为 CANN 的 ATC 工具转换模型时,对算子支持、输入 shape 固定程度有一定要求,不像 ONNX Runtime 那样随便跑。
4.1 为什么不能直接跑 PyTorch 模型
简单回答:昇腾推理卡没有直接执行 PyTorch 算子的能力。PyTorch 模型要先经过前端导出成 ONNX,ATC 工具再把 ONNX 图翻译成昇腾的离线模型 OM,这个过程会做算子融合、内存复用、量化等优化,最后生成的是昇腾芯片能直接执行的序列。
最关键的一步是固定输入 shape。ATC 转换时,如果输入是动态 shape,内存规划、算子优化都会受限制,严格模式下很容易失败。所以在导出 ONNX 时,把 batch size 和输入尺寸都固定下来。对 YOLO 来说,一般固定为 1x3x640x640 或 1x3x416x416,看你训练时的配置。
4.2 导出 ONNX 的操作细节
用 YOLOv5 官方代码导出为例:
python export.py --weights yolov5s.pt --include onnx --batch-size 1 --img-size 640导出时几个容易被忽略的关键点:
- opset 版本别太高:优先选 opset 12 或 13。太高(比如 17+)容易碰到 ATC 不支持的算子,还得回头降版本。
- 检查输入输出的名称:导出后可以用 onnx 库确认:
python -c "import onnx; m = onnx.load('yolov5s.onnx'); print([i.name for i in m.graph.input]); print([o.name for o in m.graph.output])"一般输入是 images,输出是 8400x85(以 coco 80 类 YOLOv5 为例,3 个尺度一共 8400 个候选框)。记下输入输出名,后面 ATC 要写。
- 把模型的解码操作尽量留在外面:导出 ONNX 时不要带 NMS,也不要带 decode 这些后处理逻辑。ATC 转换带 NMS 的图非常容易出问题,而且调试 NMS 的算子极痛苦,建议后处理用 Python/NumPy 实现。
4.3 ATC 转换 OM 模型的完整命令
导出好 ONNX,接下来用 ATC 工具转成 OM:
atc --model=yolov5s.onnx \ --framework=5 \ --output=yolov5s_bs1 \ --input_shape="images:1,3,640,640" \ --soc_version=Ascend310P3 \ --insert_op_conf=aipp.cfg \ --output_type=FP32 \ --input_format=NCHW \ --log=info逐个解释一下这些参数的作用:
--framework=5:表示输入是 ONNX 模型,ATC 里 1 是 Caffe,3 是 TensorFlow,5 是 ONNX,别搞混。--output:生成的 OM 文件路径,最好带上 batch size 后缀,方便后面区分。--input_shape:必须和导出 ONNX 时的固定 shape 一致。--soc_version:芯片型号,Ascend310P3 对应 300V,具体可以在npu-smi info里确认版本后查官方表格。--insert_op_conf:插入预处理配置,可以参考 4.4 节。--log=info:如果转换失败,最好加上,日志输出比较全。
转换成功后会在当前目录生成 yolov5s_bs1.om。
4.4 用 AIPP 做预处理,省掉 CPU 端缩放和归一化
Atlas 推理时有个好功能叫 AIPP(AI Preprocessing),可以在 NPU 上完成图像缩放、减均值、除以标准差、通道转换(RGB/BGR)等操作,不必在 CPU 上手动做预处理。这样推理管线更干净,也不容易引入 CPU 瓶颈。
一个常见的 AIPP 配置文件长这样:
aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 crop: false 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 }这里var_reci_chn是 1/255,相当于除以 255。如果你训练时用的归一化参数不同,这里要对应改。用 AIPP 有个细节:它一般默认输入是 NCHW,input_format要跟训练时的通道顺序匹配(YOLOv5 通常是 RGB),否则推理结果会颜色错乱,检测框偏得离谱。
4.5 推理时如何解析 YOLO 输出
ATC 转出来的 OM 模型输出,一般是一个 [1, 8400, 85] 的 Tensor(以 YOLOv5s 为例,85 = 4 个坐标 + 1 个置信度 + 80 个类别概率),但要注意 ATC 可能会把输出排成 [batch, 84, 8400] 这种格式,需要根据模型实际输出 shape 调整解析逻辑:
- 坐标部分:cx, cy, w, h,是中心点加宽高,不是 x1y1x2y2。
- 置信度:objectness 分数,要乘上每个类别概率才是最终的类别分数。
- 输出需要做 CIoU NMS 等后处理,这个放在模型外做,方便修改阈值。
建议先随便跑一张测试图,print 输出 shape 和几个数值,确认解析逻辑正确后再接完整业务。
5. 实测跑通 YOLO 推理:AscendCL 还是 MindX SDK
模型有了,最后一步是写推理代码。昇腾生态里有两套主流方式:
- AscendCL(ACL):C/C++ 或 Python 直接调底层推理接口,更灵活,适合需要对数据处理做精细控制的人。
- MindX SDK:更高层的可视化/流水线式推理框架,适合搭视频流处理、多路并发、多模型串联的场景。
单独跑一张图做验证,用 AscendCL 就够了,Python 版本也是支持的。下面我用 AscendCL Python 接口做个整体演示。
5.1 使用 AscendCL 加载 OM 模型进行推理
import acl import numpy as np import cv2 class YOLOAtlas: def __init__(self, model_path, device_id=0): ret = acl.init() assert ret == 0 ret = acl.rt.set_device(device_id) assert ret == 0 self.context, ret = acl.rt.create_context(device_id) assert ret == 0 # 加载模型 self.model_id = 0 self.model_desc = None ret = acl.mdl.load_from_file(model_path, self.model_id) assert ret == 0, f"model load failed, ret={ret}" # 准备输入输出内存 self._prepare_io() # 创建推理用的 stream self.stream = None ret = acl.rt.create_stream(self.stream) assert ret == 0 def _prepare_io(self): # 获取输入输出大小 self.input_size = acl.mdl.get_num_inputs(self.model_id) # 为简化,在这里按 1*3*640*640 分配 self.input_data_size = 1 * 3 * 640 * 640 * 4 # float32 一个 8 # 申请设备内存 self.input_ptr = acl.rt.malloc(self.input_data_size, 2) self.input_buffer = acl.util.np_to_ptr(np.zeros((1,3,640,640), dtype=np.float32)) # 输出数量 self.output_num = acl.mdl.get_num_outputs(self.model_id) # 输出大小获取后分配指针 # 略:实际开发时需要通过 acl.mdl.get_output_size_by_index 获取 self.output_ptr_list = [] self.output_size_list = [] def infer(self, input_np): # 把 numpy 复制到设备内存 ret = acl.rt.memcpy(self.input_ptr, self.input_data_size, input_np, input_np.nbytes, acl.rt.MEMCPY_DEVICE_TO_DEVICE) # 绑定输入输出 # 推理,需要显式调用 acl.mdl.execute # 这里省略具体绑定步骤,核心逻辑在 execute ret = acl.mdl.execute(self.model_id, [self.input_ptr], [self.input_size], self.output_ptr_list, self.output_size_list, self.stream) # 将设备输出拷贝回主机 outputs = [] for ptr, size in zip(self.output_ptr_list, self.output_size_list): out = acl.util.ptr_to_numpy(ptr, (size // 4,), np.float32) outputs.append(out) return outputs def release(self): acl.mdl.unload(self.model_id) acl.rt.destroy_stream(self.stream) acl.rt.reset_device(0) acl.finalize()上面的代码只是一个骨架示意,实际写好要处理输入 tensor 描述、输出 tensor 描述、memcpy 方向等细节,比较啰嗦。如果你只是想验证模型能不能跑,更省事的是用 MindX SDK 的 mxVision 或者直接用官方提供的 Python 推理样例。但如果你想做性能优化,理解 AscendCL 的这套内存/流机制还是值得的。
5.2 MindX SDK 快速验证路径
MindX SDK 的好处是,把输入输出和后处理都模块化了。配置一个 pipeline 文件,定义“数据输入 → 图像解码 → 模型推理 → 结果输出”的流程,稍微改改就能跑:
pipeline: - name: "decode" type: "mxpi_imagedecoder" - name: "resize" type: "mxpi_imageresize" props: resize_width: 640 resize_height: 640 - name: "infer" type: "mxpi_tensorinfer" props: model_path: "yolov5s_bs1.om" - name: "postprocess" type: "mxpi_tensorpostprocess" props: postprocess_config_file: "yolo_post.cfg"MindX SDK 对常见模型封装好了插件,尤其是视频流和多路推理场景,省去不少重复造轮子的时间。缺点也很明显:配置项复杂、调试日志不直观,出问题的时候查起来比直接写代码头疼。
如果你只是跑 YOLO 单图验证,可以直接用 OpenCV 读图、预处理、然后用上述 AscendCL 的 infer 函数跑;如果目标是做视频流多路并发检测,再上 MindX SDK。
5.3 推理性能实测参考
我自己在 Atlas 300V 上跑的 YOLOv5s,INT8 量化后大概情况(不同版本会有差别,只做参考):
| 模型 | batch size | 单帧耗时(ms) | 吞吐(fps) |
|---|---|---|---|
| YOLOv5s FP16 | 1 | 约 12-15 ms | 约 60-80 FPS |
| YOLOv5s INT8 | 1 | 约 6-8 ms | 约 120-160 FPS |
| YOLOv7-tiny INT8 | 1 | 约 5-7 ms | 约 140-180 FPS |
注意:以上是单路直连的理想性能,实际加上图像解码、传输、后处理、多路调度,吞吐会有折损。我做多路视频流时,4 路 1080p 实时检测大概跑 30 FPS 一路,CPU 占用不到 40%,整体很稳。
5.4 推理精度问题排查
有一类非常容易被忽视但实际高频出现的问题:模型转换和推理后,精度表现和 GPU 上差异很大,检测框乱飘。优先级最高的是这几件事:
- 确认 ONNX 模型导出是否包含了完整的预处理。如果你在 PyTorch 里做了 letterbox(等比缩放补边),导出 ONNX 时如果没包进去,那么在 ACE 端必须用 AIPP 或手动代码做一模一样的 letterbox,否则框位置错位是必然的结果。
- 颜色通道次序。YOLOv5 训练时用的是 RGB,但 OpenCV 读图是 BGR。如果 AIPP 配置里没处理好,推理出来的结果非常诡异——人和背景乱框。可以用纯色图先测一下通道顺序,例如生成一张全红图,看输出特征值。
- 输入数据的排列是 NCHW 还是 NHWC。ONNX 默认输出是 NCHW,ATC 转换时如果搞错,数据排布乱了,推理结果几乎全是垃圾。
- 输出后处理的坐标是否需要除以 stride。YOLO 在导出 ONNX 后,输出坐标已经除过 stride,但不同版本处理方式有差异。用一张已知目标的图对照输出坐标,验证解析逻辑。
6. 常见问题与排查技巧实录
这一节是我整理的一些高频卡片式问题,按频次排序,都是真实遇到的:
6.1 驱动装完但 npu-smi 看不到设备
原因绝大部分是内核模块没加载成功。先检查:
lsmod | grep drv dmesg | grep -i npu如果看到 Unknown symbol 或“Permission denied”这类,基本是内核版本太新,和预编译驱动不匹配。解决思路:换内核版本,或重编驱动(./driver/xxx/install.sh 里有编内核模块的选项)。
6.2 ATC 转换报错:Unsupport op / Op type XXX is not supported
遇到这种情况先说结论:ONNX 模型里有些算子(例如一些新版本的 Mish、SiLU 变体算子、部分动态 shape 相关的算子)昇腾不支持或支持不完全。
排查思路:
atc --model=xxx.onnx --framework=5 --output=xxx --soc_version=Ascend310P3 --log=debug看日志里落到哪个节点。如果落在 SiLU(YOLOv5 大量使用),那说明当前版本 CANN 对该算子支持不全。解决办法一般是升级 CANN 版本,或手工改 ONNX 图,把不支持算子替换为支持的基础算子组合。这个是经验活,没有标准答案。
6.3 MindX SDK 推理报错 pipeline 启动失败
常见于几个点:
- 配置里写的模型路径不对。
- 插件名称拼错,mxpi_ 前缀漏掉。
- 后处理配置的模型类别数与 YOLO 实际不符。
把 pipeline 的日志级别调到 DEBUG,一行一行看插件启动的报错,基本能定位到具体某个插件上。
6.4 推理性能上不去,CPU 占用却很高
注意:在 Atlas 上跑推理,CPU 吃高并不一定是模型计算慢,很可能是数据预处理/后处理拖后腿。把图像缩放、归一化、letterbox 这些操作从 CPU 迁移到 AIPP,同时用 Numpy 向量化替代 Python 循环,吞吐会有质的提升。
还有一个大坑:如果模型是 FP32 转换的,没有走量化,那算力也会大打折扣。部署前做 INT8 量化(ATC 的 AIPP 和量化工具支持),是 Atlas 推理性能的关键一步。
6.5 多路视频流出现画面卡顿或内存爆掉
Atlas 300V 板载 24G 内存,不是无限。每一路视频流的解码缓存、推理缓冲、结果队列都要占内存,路数多了内存吃紧很正常。
解决方向:
- 控制同时解码的路数,给解码缓存设置上限。
- 优化推理的 batch,把多帧合成一个 batch 推理,利用板载内存的带宽优势。
- 检查是否有内存泄漏,比如没有 release 掉不再用的 buffer。
7. 实测总结:Atlas 部署 YOLO 的真实感受和最终建议
我实际用下来,Atlas 300V 24G 跑 YOLO 的场景是很稳的。它的 INT8 推理性能、显存容量、功耗,都是为“高并发视频推理”这类场景而设计的。但别指望像用 CUDA 那样开箱即用,环境搭建、模型转换这些步骤里,需要仔细对照版本,否则报错会让人怀疑人生。
给准备入坑的朋友几个从实践中来的建议:
- 老实选官方推荐的操作系统和内核版本。官方说 Ubuntu 20.04 就用 20.04,别拿最新的 24.04 去硬试。驱动编译不过、固件不匹配,这些问题新手根本扛不住,也最浪费时间。
- 先跑通样例再改业务。不要一上来就拿着自己的模型去部署。先把官方自带的 YOLO 样例跑通,多花一小时,后面可能省一个下午。样例的环境、pipeline 配置都是验证过的,能跑通说明环境没问题,之后再逐步替换成自己的模型。
- 把预处理尽量从 CPU 挪到 AIPP。Atlas 的 AIPP 不是摆设,像缩放、归一化这些操作在 NPU 上做又快又省 CPU。模型部署优化时,这是性价比最高的一步。
- 后处理逻辑尽量留在模型外并且用向量化实现。特别是 NMS,如果搞进 ONNX 再转 OM,坑太多;在 Python/NumPy 里写,调试容易还方便维护。
- 部署完第一版后,立刻加 metrics 监控。推理耗时、输入输出队列长度、内存占用、错误率,人工用眼睛看一会根本看不出问题。有监控数据才能做性能调优和定位瓶颈。
最后说个个人体会:Atlas 的软件栈确实比 CUDA 生态“腼腆”一些,有问题时资料也不多,前期需要耐心去查官方文档和排查日志。但也正因为这样,一旦把手里的链路调稳定了,后面就是坐享其成的红利。如果你手里的项目正好是视频检测一类的推理任务,Atlas 300V 加上 YOLO 这套组合,性能和成本都会让你觉得前期折腾是值得的。