最近这半年我基本每天都在跟 Atlas 平台打交道,前前后后折腾了 Atlas 300V 24G 推理卡、CANN 工具链、模型转换、推理服务上线,可以说把这条链路从无到有彻底摸了一遍。经常有人在群里问“Atlas 300V 24G 是运算加速卡吗”,也经常有人问“Atlas 上能不能跑 YOLO”,这两个问题恰好是我一直在做的事。这篇就当是给自己这半年的一个记录,也给正准备入坑 Atlas 的朋友做一个参考。
先说结论:Atlas 300V 24G 确实是一块标准的 AI 推理加速卡,而且在它上面部署 YOLO 系列模型,尤其是 YOLOv5、YOLOv8 这类检测模型,是完完全全可行的。但整个过程跟 CUDA 生态那套“装好驱动、拉个镜像、直接跑”的体验不太一样,有一些 Atlas 特有的坑和细节,比如模型格式转换、芯片型号匹配、AIPP 配置、动态 Shape 处理这些。如果没人提醒,你可能会在第一步就卡住很久。
下面我把整个 Atlas 部署 YOLO 的核心链路拆开讲清楚。
1. Atlas 平台的整体认知:从“一张加速卡”到“一套软硬栈”
1.1 Atlas 300V 24G 到底是什么:算力规格与定位
先解决最简单但也最容易搞混的问题:Atlas 300V 24G 是不是一块运算加速卡?是,但它是推理卡,不是训练卡。这两个概念的区别很关键。
Atlas 300V 24G 是基于昇腾 310P 系列芯片打造的 AI 推理加速卡,板载 24GB 显存(实际可用约 22~23GB),支持 FP16、INT8 等低精度推理。很多人看到“24G”就下意识拿它跟 RTX 3090、A10 这些 GPU 比,其实定位完全不一样。3090 可以训练可以推理,但 Atlas 300V 24G 的设计目标就是“高吞吐、低功耗、低成本”地把已经训练好的模型跑起来。它面向的场景是视频分析、图像分类、目标检测这类线上推理业务,而不是用来从头训练一个 YOLO 模型。
拿我手头这块卡举例,单槽位、被动散热、功耗我记得在 70W 左右,比动辄 300W 的 GPU 省电太多。但省电不意味着不能打,在 INT8 精度下,YOLOv5s 跑 640x640 输入的推理延迟能压到 15~25ms 左右,这个数字在真实业务里已经相当能打了。
记住一个核心区别:Atlas 300V 24G 适合“把模型跑起来”,不适合“把模型训出来”。搞清楚这点,后面很多选型问题就都不会跑偏。
1.2 从硬件到软件:CANN、MindStudio、Ascend CLI 的完整软件栈
很多第一次接触 Atlas 的人会被一串缩写搞晕:CANN、MindSpore、MindStudio、OM、ATC、Ascend CLI、DVPP、AIPP…… 这都是啥?
我拿 NVIDIA 生态做个类比,你一下就懂了。
CUDA 是英伟达全家桶的底层,CANN 就是昇腾的底层。CANN(Compute Architecture for Neural Networks)是华为昇腾 AI 处理器的异构计算架构,相当于“昇腾的 CUDA”。所有上层的推理框架、工具链,最终都是通过 CANN 去调用昇腾芯片的算力。
ATC 工具是模型转换工具,全称 Ascend Tensor Compiler。它负责把你手上的 ONNX、TensorFlow、MindSpore 模型转成昇腾的离线模型格式 OM。OM 格式可以理解为昇腾的“TensorRT engine”或者“TorchScript”,是经过图优化、算子融合、量化之后的推理文件,部署时直接加载即可。
MindStudio 是集成开发环境,有点像 Visual Studio + TensorBoard 的混合体,可以在里面做模型转换、调试、性能分析。但说实话,我在生产环境里用得不多,更多的时候是直接在命令行用 atc、npu-smi 这些工具干活。用习惯了你会发现,命令行才是运维和部署的主战场。
还有几个关键组件:Driver 和 Firmware 负责让操作系统识别并驱动昇腾芯片;npu-smi 命令类似 nvidia-smi,用来查看芯片状态、显存占用、温度;DVPP 是昇腾的硬图像处理单元,可以做缩放、裁剪、格式转换,把图片预处理从 CPU 卸载到硬件上。
这套软件栈的逻辑其实很清晰:模型用 ONNX 或 MindSpore 训练好,用 ATC 转成 OM,推理程序通过 CANN 的 Python/C++ API 加载 OM 并执行推理,DVPP 帮你在硬件层面做图像预处理。一旦你把每个组件负责什么搞清楚,整套东西就不神秘了。
| 昇腾组件 | 类比 NVIDIA 生态 | 职责 |
|---|---|---|
| CANN | CUDA | 底层异构计算架构,统一调度芯片算力 |
| Driver/Firmware | NVIDIA Driver | 让操作系统识别并驱动昇腾设备 |
| ATC 工具 | TensorRT 的 trtexec | 将 ONNX/TF 模型转换为 OM 离线模型 |
| OM 格式 | TensorRT Engine | 昇腾芯片直接加载执行的推理模型格式 |
| npu-smi | nvidia-smi | 查看芯片、显存、温度、算力占用 |
| MindStudio | TensorBoard + 调试器 | 图形化开发、调试、性能分析工具链 |
| DVPP | NPP / CV-CUDA | 硬件级图像预处理:缩放、裁剪、色域转换 |
| AIPP | TensorRT 的预处理配置 | 将归一化、RGB/BGR 转换等融合进模型转换阶段 |
2. 为什么用 Atlas 跑 YOLO:场景选型与部署思路
2.1 YOLO 部署的主流路线对比
先明确一点:YOLO 是目前最流行的目标检测模型之一,也是 Atlas 用户问得最多的模型类型。什么智慧工地安全帽检测、工厂违规行为识别、道路交通流量分析、园区安防监控,这些业务十有八九最后都会落到“跑一个 YOLO 模型”。
部署 YOLO 的路线有很多种。如果你有 NVIDIA 显卡,最简单的是用 TensorRT 加速,再用 Triton 或者自己写个 FastAPI 服务把模型包起来。这条路太成熟了,网上教程一堆,基本不会踩大坑。
但如果你的硬件选型是昇腾,事情就变得稍微有趣一点。Atlas 上跑 YOLO 的主流路线有三条:
第一条,用 MindSpore 框架直接加载 YOLO 模型,再导出 OM 推理。这条路适合从零开始用昇腾全家桶的团队,但如果你手里的 YOLO 是 PyTorch 训练的,还需要先做权重迁移,麻烦。
第二条,通过 ONNX 中转。PyTorch 训练出的 YOLO 模型先导出 ONNX,再用 ATC 工具把 ONNX 转成 OM。这是目前最通用、最省事的路线,也是我推荐大多数人走的路线。因为 ONNX 是中间格式,跟框架解耦,导出和转换过程中可控性最强,出问题也好排查。
第三条,直接用社区开源的昇腾版本 YOLO,比如某些厂商已经适配好的模型库。这条路最省事,但容易遇到“能跑的模型跟你业务不匹配”的问题,还得重新训练、重新适配,绕一圈又回到第二条路。
我个人的结论很明确:对于绝大多数团队来说,PyTorch -> ONNX -> OM 是最佳路径。原因为在后面展开。
2.2 为什么 ONNX 中转是“捷径”:模型转换的核心逻辑
从我实操经验来看,PyTorch 训练的 YOLO 模型 -> ONNX -> OM 这条链路,最大的优势是“卡点可控”。
PyTorch 模型直接转 OM 不是不行,但昇腾官方对 MindSpore 的支持最完善,PyTorch 需要先经历一次模型迁移。如果你的 YOLO 是从 ultralytics 仓库加载的,那里面大量算子是针对 PyTorch 动态图优化的,直接转昇腾格式会出现各种各样的算子兼容问题。而 ONNX 作为中间格式,相当于做了一个“标准化”处理,把 PyTorch 的动态图逻辑固化成了静态的计算图描述。
换成大家更容易理解的说法:PyTorch 模型像是一个“活的厨师”,你告诉他菜谱,他现场决定先切菜还是先热锅;ONNX 像是一张“写好的流程图”,每一步干什么全部定死。昇腾芯片在执行推理时需要的就是后者——一张完全确定的计算图,这样它才能做算子融合、内存复用、静态调度这些优化。
所以我的建议是:在用 ATC 转 OM 之前,先保证导出的 ONNX 模型是正确的、稳定的。导 ONNX 这一步的坑有时候比 ATC 转换本身还多。比如 YOLOv5 的导出代码里有个--grid参数,导出的模型是带网格输出的版本,不带的话后处理要自己写;又比如某些版本的 YOLOv8 导出 ONNX 后输出的 shape 是动态的,如果不固定 batch size 和输入分辨率,ATC 转换时会报错。
2.3 Atlas 在真实业务场景里的优劣势:什么时候选它
Atlas 300V 24G 真正的优势场景是“视频流大数据分析”,尤其是多路视频并行解码 + 推理 + 结构化输出的场景。
举个例子,一个智慧园区有 200 路摄像头,每路都需要做安全帽检测,要求实时分析。NVIDIA 方案下你可能会配两台 T4 服务器,或者一台 A10 服务器,成本不低。Atlas 300V 24G 的优势在于单卡 24G 大显存,加上昇腾的 DVPP 硬件解码能力,单卡可以轻松处理几十路 1080P 视频流,整体功耗还低。
但 Atlas 也有明显的短板。一是生态不如 CUDA 丰富,很多开源项目没有官方昇腾支持,需要自己适配;二是算力上限在那里,不适合跑超大模型,比如 YOLOv8x、YOLOX-L 这类重模型,推理延迟会明显升高。如果你需要跑大模型或追求极致的灵活性,还是老老实实用 CUDA 生态。
所以我一般建议别人做选型时问自己三个问题:模型是不是 YOLO 级别的中小型模型?业务是不是视频/图像批处理类推理?对功耗和成本是否敏感?如果三个都满足,Atlas 300V 24G 是非常有竞争力的选择。
3. 实操:Atlas 300V 24G 上部署 YOLO 的全流程记录
3.1 环境准备与驱动安装要点
这部分我记录的是自己在 Ubuntu 20.04 上的完整安装过程。硬件是 Atlas 300V 24G 推理卡,系统是 Ubuntu 20.04.6 LTS,内核版本 5.4。
第一步,确认硬件被系统识别。插上卡后,用lspci | grep -i ascend能看到昇腾设备。如果能识别到设备,说明物理连接没问题。然后安装固件和驱动。昇腾社区提供的是 Ascend-cann-toolkit、Ascend-cann-nna、Ascend-cann-kernels 等安装包,再加上 driver 和 firmware,加起来有好几个 GB。
我的安装顺序是这样的:
# 1. 安装驱动和固件 ./Ascend-hdk-310p-npu-driver_*.run --full --install ./Ascend-hdk-310p-npu-firmware_*.run --full --install # 2. 安装 CANN 工具包 ./Ascend-cann-toolkit_*.run --install # 3. 设置环境变量 source /usr/local/Ascend/ascend-toolkit/set_env.sh这一步有几个非常关键的细节:
- 版本必须匹配。驱动、固件、CANN 三者的版本要一致或兼容。昇腾的安装包里都会标注兼容版本号,我见过太多人因为驱动和 CANN 版本不一致,卡在 ATC 转换阶段报“跨芯片类型不支持”这类莫名其妙的错误。建议装之前先看官方文档的版本配套表。
- 安装过程不要用 sudo。准确说是不要用 sudo 执行 Ascend-cann-toolkit 的安装脚本,它会写入当前用户目录下的隐藏配置。直接用普通用户跑
.run文件,它默认会装到/usr/local/Ascend/ascend-toolkit。 - 装完驱动后用
npu-smi info验证。正常能看到一张昇腾 310P 卡,显存 24GB,温度 40 度上下。如果 npu-smi 报错,多半是驱动没装好。
+-------------------------------------------------------------------------------------------+ | npu-smi 24.0.rc1 Version: 24.0.rc1 | +============================+==============================================================+ | NPU Name | 24G | 内存 | 温度 | ... | +============================+==============================================================+ | 0 310P | 23079 | 42 | ... | +----------------------------+--------------------------------------------------------------+看到 310P 字样,说明环境基本就绪。
3.2 ONNX 模型转 OM:ATC 关键参数与避坑细节
环境就绪之后,最核心的一步就是模型转换。我以 YOLOv5s 为例,先把 PyTorch 模型导出成 ONNX,然后转成 OM。
第一步,导出 ONNX。在 ultralytics 的 YOLOv5 仓库下,官方提供了导出脚本。建议直接固定输入尺寸,比如 640x640,不需要动态。
python export.py --weights yolov5s.pt --include onnx --img-size 640 640 --batch-size 1这条命令会在同目录生成 yolov5s.onnx。导出后建议用onnx-simplifier做一次简化,把冗余节点清掉,能显著降低后续 ATC 转换失败的概率。
python -m onnxsim yolov5s.onnx yolov5s_sim.onnx第二步,用 ATC 把 ONNX 转成 OM。我最常用的是这一条命令:
atc --model=yolov5s_sim.onnx --framework=5 \ --output=yolov5s_om \ --soc_version=Ascend310P3 \ --input_shape="images:1,3,640,640" \ --insert_op_conf=aipp.cfg \ --output_type=FP16这里有几个参数我得重点解释:
--framework=5表示输入模型为 ONNX,固定值,不要改。--soc_version=Ascend310P3表示芯片型号。这个参数极其重要,一旦写错,转换出来的 OM 在芯片上会直接加载失败,报E13885之类错误。查询当前芯片型号用npu-smi info就够,310P 系列有多个变体,400I、300I、300V 对应的 SoC 版本号不同,建议确认清楚。--input_shape指定模型输入形状。如果你的模型导出时是动态 Shape,这里必须显式固定,否则 ATC 会报input shape not assigned。--insert_op_conf=aipp.cfg是 AIPP 配置文件,用来把预处理放到硬件上完成。下面详细说。--output_type=FP16指定模型输出精度。推理场景推荐 FP16,精度损失小,速度比 FP32 快。
说到 AIPP,这是昇腾平台跟 CUDA 平台差异最大的一环。CUDA 生态里常用的做法是,预处理用 Python/OpenCV 做,比如 Resize、Normalize、通道变换。但在 Atlas 上,你可以把这一步“编译”进模型里,推理时硬件直接对原始图像做预处理,省掉 CPU 的开销。
我的 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 min_chn_0: 0 min_chn_1: 0 min_chn_2: 0 var_reci_chn_0: 0.003921569 var_reci_chn_1: 0.003921569 var_reci_chn_2: 0.003921569 }这个配置做的事情是:输入 RGB888 格式的 640x640 图像,在硬件里直接做归一化(除以 255,也就是乘 1/255)。如果你的训练预处理里有均值/方差标准化,同样可以在这里配好。
这里有个很隐蔽的坑:YOLOv5 训练时用的图像增强是 Letterbox,也就是把原始图等比缩放后填充到 640x640,而 AIPP 做的是直接 Resize。如果不加处理,推理效果会明显下降。解决办法有两种:一种是在外部代码里先把图像做完 Letterbox 再传给模型,此时 AIPP 的src_image_size应该和模型输入一致;另一种是使用图像缩放算子把 Letterbox 逻辑也塞进模型前处理。我实践中更推荐外部代码做 Letterbox,简单可控。
完整的转换日志最后一行如果看到ATC run success,说明 OM 生成成功。接下来就可以用om_validate或者实际推理验证。
3.3 推理代码与性能验证:Python 接口实操
模型转好后,你需要写推理代码。昇腾提供了 Python 版推理接口,如果你本身有 Python 开发经验,上手很快。
我贴一个最精简的 YOLOv5 推理示例,加载 OM 模型,输入一张图片,拿到检测结果:
import numpy as np import cv2 from tqdm import tqdm from ais_bench.infer.interface import InferSession # 加载 OM 模型 session = InferSession(0, "yolov5s_om.om") # 读取图像并预处理 img = cv2.imread("demo.jpg") img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.resize(img, (640, 640)) img = img.astype(np.float32) / 255.0 img = np.transpose(img, (2, 0, 1)) img = np.expand_dims(img, axis=0) # 推理 outputs = session.infer(feeds=[img]) # 拿到模型输出 predictions = outputs[0] print(predictions.shape)InferSession是昇腾自带的高层推理接口,底层基于 CANN 的 ACL API,省去了手动管理acl.mdl的各种麻烦。如果你不想直接用这个,也可以在 CANN toolkit 里找到aclrts和pyacl库来调用。
推理拿到原始张量之后,还需要做 YOLO 的经典后处理:解码、置信度过滤、NMS。这一步跟模型导出方式强相关。如果你的 ONNX 是带--grid参数导出的,输出层已经包含了解码后的坐标(类似1,25200,85的结构),后处理只需要做阈值过滤和 NMS。如果你的模型输出还是三个不同尺度的特征图(1,255,80,80这种),后处理要额外写解码。
这里重点说一下性能验证。转好 OM 后,可以先做一个简单的延迟测试:
npu-smi info查看芯片占用率,主要看算力利用率。更精确的性能评估可以用昇腾自带的msame工具:
msame --model yolov5s_om.om --input demo.bin --output ./out --loop 100msame一次跑 100 次,统计平均延迟,这个数据比你自己在 Python 里计时更接近真实线上性能。我用 YOLOv5s + 640x640 + FP16 测下来的数据是,单张推理耗时 20ms 左右,对应的帧率 50 FPS 上下;换 INT8 量化后能压到 12ms 左右,但精度会损失一点。
3.4 实战案例:一条烟盒检测服务的完整部署记录
前面讲的都是单点工具,我再串一条真实场景的完整链路。我之前帮朋友做一个“香烟陈列检测”的小服务,输入一张货架照片,检测里面每一包烟的位置和朝向。模型用的是 YOLOv8n,训练集 8000 张图,业务要求是单张推理延迟低于 30ms。
流程是这样的:
- 用 ultralytics 训练好 YOLOv8n,pt 权重;
- 导出 ONNX:
yolo export model=yolov8n.pt format=onnx imgsz=640; - 用 onnxsim 简化;
- ATC 转 OM,
--soc_version=Ascend310P3 --input_shape="images:1,3,640,640" --output_type=FP16; - 写推理服务,用 FastAPI 包一层,内部调用 InferSession 加载 OM;
- 同时用多进程 + 绑核的方式压测,确认并发 5 个请求时 P99 延迟低于 60ms。
最终上线后,单卡跑了 3 个模型实例:烟盒检测、朝向分类、清晰度判断,整体算力占用 70% 左右,功耗没超过 60W。相比之前用的 GPU 方案,这个功耗和成本表现让我非常满意。
4. 常见问题排查与性能优化实录
4.1 ATC 转换阶段的经典报错与处理
我把这些坑归类成速查表,读者朋友可以直接照着排查:
| 报错信息 | 原因 | 解决方法 |
|---|---|---|
E10005: input op is empty | ONNX 模型输入名称和 input_shape 不匹配 | 检查 ONNX 的输入名称,用onnx.load打印 graph input 名,改成实际名称 |
E10020: Unsupported op | 模型里的某个算子昇腾不支持 | 先 onnxsim 简化;再不行就把该算子替换成等价实现 |
E10001: soc version not support | --soc_version写错 | 用npu-smi info查看实际芯片型号,改成正确版本 |
E19999: inner error | 差分、动态 shape 等复杂原因 | 先固定所有输入 shape,关闭动态维度,再逐个排查 |
| CRC check failed 或 load model failed | OM 文件与芯片不匹配 | 回退到 ATC 转换步骤检查 soc_version 和 output_type |
我印象最深的一次是,转 YOLOv8s 的时候一直报Unsupported op,后来发现是某个版本的 ultralytics 导出的 ONNX 里带了GridSample算子,昇腾老版本 CANN 不支持。升级 CANN 到新版本就解决了。所以如果你的模型比较新,先看看 CANN 版本是不是太老。
4.2 推理阶段的常见坑:显存、输入输出、图像格式
模型成功加载后,真正的坑才开始。我把自己遇到过的典型推理期问题列出来:
第一个是显存不足的问题。Atlas 300V 24G 看着显存很大,但如果同时加载多个读模型、开多进程推理,很容易 OOM。现象是推理时报错,或者 ACLLite 返回 507018 之类的错误码。我建议按“单进程单模型”的方式组织代码,一个进程持有一个模型实例,避免多个进程重复加载同一份 OM。
第二个是输出张量的 Shape 不符合预期。YOLOv8 导出的 ONNX 输出 Shape 是1,84,8400还是1,8400,84,不同版本不一样。如果你发现后处理拿不到正确坐标,先打印 outputs[0].shape 确认,再调整后处理代码,不用硬猜。
第三个是图像格式问题。AIPP 配置里写了RGB888_U8,但 OpenCV 默认读出来的是 BGR。如果不做通道转换,模型推理效果会一团糟。很多人调试半天找不到原因,最后发现只是通道顺序错了。
第四个是AI CPU算子占用过高的问题。有的算子无法在昇腾的 AI Core 上执行,会自动跑到 CPU 上,导致推理时间暴涨。你可以用 profiling 工具查算子执行时间,如果发现大量算子跑在 AI CPU,就需要修改模型结构。我遇到过模型里有个Sigmoid算子没有在融合中被优化,改成在推理代码里做后处理,速度立刻翻倍。
4.3 性能优化三板斧:AIPP、DVPP、INT8量化
性能优化这块,我总结下来就是三板斧:AIPP、DVPP、INT8量化。
- AIPP把归一化、减均值、通道转换塞进模型,减少 CPU 工作量。这个前面说过,不重复。
- DVPP是昇腾的硬件图像处理单元,可以把 Resize、Crop、色彩空间转换这些操作从 CPU 卸载到硬件上。实际操作上,将图片送入推理前用 DVPP 做缩放,比 OpenCV 的 resize 在 CPU 上跑快一大截。尤其在高并发视频流场景,这步优化能省下很可观的 CPU 资源。
- INT8 量化是延迟最激进的优化手段。我个人建议用官方 AMCT 工具做量化校准,而不是直接转 INT8。校准集最好使用真实业务数据的子集,几百张图就够。量化后跑一轮验证,观察 mAP 下降是否在可接受范围,再看延迟收益。
它们之间的优先关系是:先用 AIPP 把预处理省掉,再用 DVPP 把图像缩放省掉,最后才考虑 INT8 量化。因为量化对精度的破坏是不可逆的,能不动尽量不动。
4.4 关于开发调试效率的几个习惯
最后分享几个我调试昇腾程序时积累的习惯,这些细节很多人不写,但实际影响很大。
第一,日志一定要开。CANN 的日志默认好像是不打印的,你要设置环境变量把日志打开:
export ASCEND_GLOBAL_LOG_LEVEL=1 export ASCEND_SLOG_PRINT_TO_STDOUT=1这样报错时会输出比较详细的日志,定位问题会快很多。调试完记得改回默认级别。
第二,先用最简单的小模型验证环境,再跑 YOLO。别一上来就转 YOLOv5s,先用一个官方的 ResNet50 例子把整个环境链路跑通,确认驱动、CANN、ATC、推理接口都没问题。如果 ResNet50 能跑通,那 YOLO 的问题就只可能在模型转换和后处理;如果连 ResNet50 都跑不通,先把环境搞定再说。
第三,注意 Python 环境和 CANN 的 SDK 路径。很多人装了 CANN 之后,忘了在代码里引用对应的 Python 包的路径。建议在每次打开终端时都执行source /usr/local/Ascend/ascend-toolkit/set_env.sh,或者写进.bashrc。如果没配环境变量,Python 里 import 昇腾模块时会直接报 ModuleNotFoundError。
第四,用msame验证模型延迟一定要用真机,不要依赖简要指标,也不要只做单次推理。我习惯跑 100 次循环,取 P50 和 P99 两个值,这样对真实性能的判断更可靠。
5. 我的实操体会与扩展建议
最后说点更宏观的东西。Atlas 这套生态,初看确实让人困惑——为什么不能像 CUDA 一样省心?但实际用下来,它的逻辑是清楚的,只是跟 CUDA 的“自由组合”思路不同,昇腾更讲究“标准链路”。一旦你把 ONNX -> ATC -> OM -> CANN 推理这条链路走顺,其实非常高效。
我个人在实际操作中的体会是,Atlas 300V 24G 最大的价值不是单卡算力有多强,而是在 24G 显存和 70W 功耗这个约束下,给了你一个非常极致的“单位功耗吞吐比”。做视频分析、批量推理这类业务时,这个特性带来的成本优势是 GPU 方案很难匹敌的。
再分享一个小技巧:如果你要跑的模型不止一个,尽量把它们合并成一个大 ONNX 再转 OM,或者用多进程分别加载各自的 OM。前者省显存,后者提高并发,两者结合效果更好。我现在跑的两个检测模型就是用多进程方案,单卡同时处理两个业务互不干扰。
如果你正准备部署 YOLO 到 Atlas,我的建议是:先买一块 300V 24G(或者去云上租一块试试),然后把官方文档里的 ResNet50 范例完整跑通,再对照我前面写的步骤操作 YOLO。整个过程最顺利的可能一天就能跑通,但如果你能把自己踩过的坑记录下来,对整个团队都会很有价值。