1. Atlas 300V 24G到底是什么?先说结论
先说重点:Atlas 300V 24G是一块推理加速卡,不是训练卡。它基于华为昇腾310P芯片,板载24GB显存,主要用在边缘侧和数据中心的视频分析、目标检测、图像分类这类推理场景。和训练卡相比,它主打的是“高能效比”和“低成本部署”,不是用来从头训练模型的。
“atlas部署yolo”这个热搜词其实暴露了大家最关心的需求:我手上有一块Atlas 300V 24G加速卡,怎么把PyTorch训练的YOLO模型跑起来?这个问题我在实际项目里踩过不少坑,从最开始的模型转换失败,到后面推理性能调优,花了不少时间才把整套流程跑通。这篇文章把我验证过的完整链路写出来,包括硬件选型逻辑、CANN环境搭建、ONNX转OM的详细参数、推理代码的骨架,以及最常遇到的报错和解决办法。
适合谁看?如果你手头正好有Atlas 300V 24G的卡,或者正在评估要不要采购这块卡来做YOLO推理,又或者你用的是其他Atlas系列卡想要参考部署流程,这篇文章都能帮你少走弯路。我自己是把YOLOv5和YOLOv8都在这块卡上完整部署过的,下面讲的内容全部来自实际操作,不是纸面推测。
2. Atlas 300V 24G硬件定位与选型思考
2.1 昇腾310P芯片的核心参数
Atlas 300V 24G的核心是昇腾310P芯片,这颗芯片在昇腾家族里的定位很清晰:面向推理场景。对比一下昇腾910系列是给训练用的,310系列是给推理用的,而310P是310的增强版本。
具体到Atlas 300V这张卡有几个关键参数值得关注:
- 芯片:昇腾310P,8个AI Core,频率1.0GHz左右
- 显存:24GB LPDDR4X,带宽204GB/s
- 算力:INT8精度下约140 TOPS,FP16约70 TFLOPS
- 功耗:最大72W,无主动散热设计的话需要机箱风道配合
- 接口:PCIe 4.0 x16,兼容x8插槽(带宽减半)
这里要特别强调一下,24GB显存是这块卡最大的卖点。市面上同价位的推理卡一般只有8GB或者16GB显存,24GB意味着你可以同时加载更多路视频流,或者跑更大的模型。我实测过用Batch Size 4跑YOLOv5s,显存占用大约6GB,还有大量余量可以开更多路并发。如果是YOLOv8m这种更大的模型,24GB也完全扛得住。
2.2 为什么选择Atlas系列做YOLO推理
我之前用GPU做推理部署,后来换成Atlas 300V,核心驱动是成本和功耗。一张主流推理GPU动辄几千上万,功耗200W起步,而Atlas 300V的功耗只有72W,整机可以做得更小更省电。在客户现场那种机柜空间有限、电源余量不足的场景下,这种优势非常明显。
另外一个重要因素是解码能力。Atlas 300V支持硬件视频解码,可以同时解码一路4路1080P视频流(H.264/H.265),这意味着视频流分析场景可以省掉CPU解码的资源消耗。我用FFmpeg推流实测过,单纯做视频解码,CPU占用率几乎可以忽略不计,这对跑实时视频分析非常有帮助。
当然Atlas的劣势也客观存在:一是生态没有CUDA那么成熟,很多模型转换要自己动手改算子;二是调试工具链不如NVIDIA全家桶那么顺手;三是社区资料相对少。但如果你的场景是固定的YOLO模型、固定的推理链路,这些劣势都可以通过一次性的工程投入来弥补。
2.3 和GPU部署YOLO的横向对比
从部署流程的角度做一个直观对比:
| 对比项 | Atlas 300V 24G | NVIDIA T4 | NVIDIA 3080 |
|---|---|---|---|
| 显存 | 24GB | 16GB | 10GB |
| 功耗 | 72W | 70W | 320W |
| INT8算力 | 约140 TOPS | 约65 TOPS | 约89 TOPS |
| 模型格式 | OM(需转换) | TensorRT Engine | TensorRT Engine |
| 视频解码 | 硬件支持 | 不支持(部分版本支持) | 不支持 |
| 开发门槛 | 较高 | 中等 | 中等 |
| 单卡价格区间 | 中等 | 较高 | 中等 |
说实话,单看推理性能,Atlas 300V的INT8算力指标并不差,配合硬件解码能力,在视频分析场景下甚至比T4更有优势。但开发门槛确实高一些,主要卡在模型转换和算子适配这一步。下面对这部分重点展开。
3. 部署环境搭建与CANN工具链准备
3.1 宿主机环境要求
在开始部署之前,先确认你的宿主机满足基本要求。我自己用的是一台x86服务器,Ubuntu 20.04系统,内核版本5.4。CANN对系统有明确的要求,不满足会直接安装失败或者运行报错,浪费很多时间。
推荐环境配置:
- 操作系统:Ubuntu 18.04/20.04 x86_64,或者CentOS 7.6以上
- CPU:x86架构,ARM架构也可以但坑更多,新手不推荐
- 内存:至少16GB,建议32GB以上
- 磁盘:至少50GB空闲空间(CANN工具包加模型转换缓存很占空间)
- 网络:能访问外网下载依赖包
- 驱动:需要安装Atlas相关的驱动和固件,版本要匹配
一个特别容易踩的坑是内核版本和驱动不匹配。Atlas的驱动对内核有编译依赖,如果你自己编译过内核或者升级过内核,驱动装不上是常有的事。最简单的办法是用Ubuntu 20.04原版内核,不要自己折腾。
3.2 CANN工具包安装与版本选择
CANN(Compute Architecture for Neural Networks)是Atlas卡的软件栈,相当于CUDA toolkit的角色。安装CANN之前必须先装好驱动和固件,顺序不能乱。
安装步骤简述:
- 下载驱动、固件和CANN工具包,注意版本号必须配套。以CANN 7.0.0为例,对应驱动版本是24.1.rc1左右,具体以官方兼容性列表为准。
- 在BIOS中开启以上IOMMU、以上Resizable BAR等选项(不同主板叫法不同,一般出厂默认开启)
- 安装驱动:
chmod +x Ascend-hdk-*.run ./Ascend-hdk-*.run --install- 安装CANN工具包:
chmod +x Ascend-cann-toolkit_7.0.0_linux-x86_64.run ./Ascend-cann-toolkit_7.0.0_linux-x86_64.run --install- 设置环境变量:
source /usr/local/Ascend/ascend-toolkit/set_env.sh版本匹配这个问题我吃了不少苦头。有一次我偷懒用了不配套的驱动+CANN组合,结果运行推理时直接报“device open failed”,排查了一天才发现是固件版本太旧。以后建议直接去昇腾社区查兼容性列表,下载“驱动+固件+CANN”三件套配套版本,一次性装好。
3.3 确认设备状态
安装完成后,用命令确认设备是否被正常识别:
npu-smi info正常输出会显示芯片信息、显存信息、温度等。如果能看到类似这样的输出就说明基本OK:
+---------------+-----------------+--------------------------------------------------+ | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page) | | Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) | +===============+=================+==================================================+ | 310P | OK | 12.8 43 0 / 0 | | 0 | 0000:01:00.0 | 0 0 / 24576 0 / 24576 | +---------------+-----------------+--------------------------------------------------+看到“OK”和24576MB(24GB)显存信息,说明设备正常。如果命令找不到,先检查驱动是否装好,用dmesg | grep ascend查看内核日志有没有报错。注意驱动安装后需要重启系统才能生效,新装驱动后别急着跑命令,先重启一遍。
4. YOLO模型转换全流程:从PyTorch到OM格式
4.1 模型转换的整体思路
Atlas卡不能直接运行PyTorch的.pt模型,也不能直接跑ONNX模型,必须转换成华为的OM格式。转换工具是ATC(Ascend Tensor Compiler)。
模型转换的完整链路是:
PyTorch .pt -> ONNX -> OM每一步都有可能出问题。PyTorch转ONNX这一步一般比较顺利,但ONNX转OM这一步经常报算子不支持。我的经验是,尽量用YOLOv5官方的export.py导出ONNX,YOLOv8用ultralytics包自带的导出功能,不要自己手写转换脚本,否则踩坑概率倍增。
4.2 PyTorch模型导出为ONNX
以YOLOv5为例,官方仓库就带了导出脚本:
python export.py --weights yolov5s.pt --include onnx --opset 11这里有几个关键参数要注意:
--opset 11:ONNX算子集版本,CANN对opset 11支持最好。不要用opset 12以上,否则有些算子不兼容。--batch-size 1:先按batch size 1导出,后续在ATC转换时再动态指定,这样灵活性更高。- 导出前建议把模型放到eval模式,避免BN层的行为差异。
导出完成后可以用Netron可视化工具打开ONNX文件,确认模型结构完整。重点看输出节点是不是有三个(YOLOv5是三个不同尺度的输出),每个输出节点的维度是不是合理。我看过一些模型在导出时输出节点名字被改掉导致后续ATC转换找不到节点,所以导出后先检查一次再走下一步。
4.3 ATC转换为OM格式
导出ONNX后,用ATC工具转换成OM格式。这是整个流程中最容易让人崩溃的一步,我把我验证过可用的命令贴出来:
atc --model=yolov5s.onnx \ --framework=5 \ --output=yolov5s_bs1 \ --input_shape="images:1,3,640,640" \ --insert_op_conf=aipp.cfg \ --output_type=FP16 \ --input_format=NCHW \ --soc_version=Ascend310P3 \ --core_type=AiCore参数说明:
--framework=5:5表示ONNX,这个值不能变。--input_shape:指定输入shape。YOLOv5的输入是images这个名字,batch size设为1。如果你的输入节点名不是images,先用Netron看一下实际的输入名再改。--insert_op_conf:AIPP配置文件,用于图像预处理(resize、归一化、颜色空间转换)。这个文件很关键,后面单独讲。--output_type=FP16:输出精度用FP16。如果你后续在代码里要自己处理输出,统一用FP32也可以,但显存占用会更高。--soc_version=Ascend310P3:芯片型号。如果你拿不准自己的芯片是哪个版本,在npu-smi info里看,或者执行/usr/local/Ascend/ascend-toolkit/latest/bin/atc --help查看支持的版本列表。
4.4 AIPP配置文件写法和避坑
AIPP(AI Preprocessing)是Atlas硬件预处理模块,它可以把图像预处理(缩放、裁剪、减均值、除以标准差)直接下沉到硬件上执行,避免在CPU或AI Core上做重复计算。配置文件是.cfg格式的文本文件,下面是我用的一个完整示例:
aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 crop: true load_start_pos_h: 0 load_start_pos_w: 0 crop_size_w: 640 crop_size_h: 640 resize: true resize_output_w: 640 resize_output_h: 640 csc_switch: true rbuv_swap_switch: true 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 }这里面最容易被忽略的是src_image_size_w/h。它指的是输入到AIPP模块的原始图像尺寸,不是模型输入尺寸。如果你在推理代码里已经把图像resize到了640x640再送进去,这个值就填640;如果你送原图(比如1280x720),这里就要填1280和720,让AIPP做resize和crop。
另外var_reci_chn是像素归一化的倒数。YOLO训练时一般用0-1归一化,也就是除以255,所以这里的值是1/255 = 0.003921569。如果你的模型训练时用的是0.003921569,这里就填这个;如果是减均值除标准差那种归一化方式,要用min_chn和var_reci_chn配合来实现。
4.5 OM模型精度校验
转换完成后不要直接上生产环境,先用一张测试图校验精度。我通常的做法是:
- 用原PyTorch模型跑一张图,得到检测框和类别。
- 用Atlas推理跑同一张图,得到检测结果。
- 对比两者的置信度分数和框坐标,误差应该在1%以内。
如果发现精度对不上,优先排查以下方向:
- AIPP的归一化参数是否和训练时一致。我遇到过一次用YOLOv8s,训练时归一化用0-1,但AIPP里忘了除以255,结果所有框的置信度都很低。
output_type选FP16时精度会损失一丢丢,如果误差在可接受范围内就不用管。- 检查输入图像通道顺序,YOLO训练一般用RGB,如果AIPP配置里
rbuv_swap_switch没设对,BGR和RGB通道反了,检测框全乱——这个错误表现是目标完全检测不到,或者检测到一堆错误目标。
5. 推理代码实现:用AscendCL跑YOLO
5.1 AscendCL的核心概念
OM模型转换好之后,推理代码使用AscendCL(Ascend Computing Language)API,它和CUDA的Runtime API地位类似。
AscendCL编程有几个核心概念:
- Device(设备):对应一块Atlas卡
- Context(上下文):类似进程的上下文环境
- Stream(流):任务执行的队列
- aclmdl(模型):加载到设备上的OM模型
- aclDataBuffer:数据缓冲区,输入输出数据都在这里
程序的整体流程是:
初始化Device -> 加载OM模型 -> 创建输入输出Buffer -> 准备输入数据 -> 执行推理 -> 获取输出 -> 后处理 -> 释放资源5.2 Python推理代码骨架
我习惯用Python先快速验证流程,确认没问题后再用C++做性能优化。下面是一个可以直接跑的Python推理代码骨架:
import numpy as np import acl from PIL import Image # 初始化 ret = acl.init() ret = acl.rt.set_device(0) # 创建上下文 context, ret = acl.rt.create_context(0) # 加载模型 model_path = b"./yolov5s_bs1.om" model_id, ret = acl.mdl.load_from_file(model_path) # 获取模型输入输出信息 input_desc = acl.mdl.get_input_desc(model_id) output_desc = acl.mdl.get_output_desc(model_id) input_size = acl.mdl.get_input_size_by_index(model_id, 0) output_size = acl.mdl.get_output_size_by_index(model_id, 0) # 创建数据缓冲区 input_data = np.zeros((1, 3, 640, 640), dtype=np.float16) output_data = np.zeros((1, 25200, 85), dtype=np.float16) # 准备输入(这里假设图像已经预处理为640x640的RGB float16数组) image = Image.open("test.jpg").resize((640, 640)) image_np = np.array(image).astype(np.float16) / 255.0 image_np = np.transpose(image_np, (2, 0, 1)) # HWC -> CHW input_data[0] = image_np # 创建acl数据缓冲区 input_buffer = acl.rt.create_buffer(input_data.tobytes(), input_size) output_buffer = acl.rt.create_buffer(output_data.tobytes(), output_size) # 执行推理 ret = acl.mdl.execute(model_id, [input_buffer], [output_buffer]) # 从输出缓冲区读取数据 output_ptr = acl.rt.get_data_buffer(output_buffer) output_data = np.frombuffer(output_ptr, dtype=np.float16).reshape((1, 25200, 85)) # 后处理:Decode + NMS boxes, scores, class_ids = yolo_postprocess(output_data[0], conf_thres=0.25, iou_thres=0.45) # 释放资源 acl.rt.destroy_buffer(input_buffer) acl.rt.destroy_buffer(output_buffer) acl.mdl.unload(model_id) acl.rt.destroy_context(context) acl.rt.reset_device(0) acl.finalize()有几个关键点需要特别说明:
acl.rt.create_buffer创建的input_buffer需要传递数据的字节流,格式必须是bytes,所以要用.tobytes()转换。- 输入数据的dtype必须和ATC转换时的
--input_format和--output_type对应。如果ATC时用了FP16,这里的dtype就是float16;如果用了FP32,就是float32。这个不匹配会导致推理结果全是不对的值,而且是那种很难排查的“看起来正常但全部检测不到”的情况。 - 输出尺寸25200是YOLOv5s的anchor数量(640x640输入时,3个尺度分别有80x80+40x40+20x20=8400个格子,每个格子3个anchor,总共25200)。如果你的模型不同,这个数要自己算。
5.3 后处理Decode + NMS的逻辑
YOLO的输出是raw预测值,要先decode成边界框,再做NMS。decode逻辑如下(YOLOv5为例):
def yolo_postprocess(pred, conf_thres=0.25, iou_thres=0.45): """ pred: ndarray shape (25200, 85) xywh + obj_conf + class_conf -> xyxy + class_id """ # 提取边信息 boxes = pred[:, :4] # cx, cy, w, h (相对于640x640的像素值) obj_conf = pred[:, 4] # objectness cls_conf = pred[:, 5:] # 80个类的分数 # 过滤低置信度 score = obj_conf * cls_conf.max(axis=1) # 最终置信度 = obj_conf * max(cls_conf) mask = score > conf_thres boxes = boxes[mask] score = score[mask] cls_ids = cls_conf[mask].argmax(axis=1) # 转换坐标格式 cx,cy,w,h -> x1,y1,x2,y2 x1 = boxes[:, 0] - boxes[:, 2] / 2 y1 = boxes[:, 1] - boxes[:, 3] / 2 x2 = boxes[:, 0] + boxes[:, 2] / 2 y2 = boxes[:, 1] + boxes[:, 3] / 2 boxes = np.stack([x1, y1, x2, y2], axis=1) # NMS按类别执行 final_boxes = [] final_scores = [] final_cls_ids = [] for cls_id in np.unique(cls_ids): mask = cls_ids == cls_id cls_boxes = boxes[mask] cls_scores = score[mask] keep = nms(cls_boxes, cls_scores, iou_thres) final_boxes.extend(cls_boxes[keep]) final_scores.extend(cls_scores[keep]) final_cls_ids.extend([cls_id] * len(keep)) return np.array(final_boxes), np.array(final_scores), np.array(final_cls_ids)如果你用的是YOLOv8,输出不是这种25200x85的结构,而是3个不同shape的输出,decode方式也不一样,后面会专门讲。
5.4 YOLOv8在Atlas上的差异处理
YOLOv8和YOLOv5在Atlas上部署有几个关键差异:
第一个是输出格式不同。YOLOv8去掉了objectness,每个anchor直接预测类别,所以输出是(1, 84, 8400)这种结构(4个坐标 + 80个类别)。AT C转换时不需要特殊处理,但后处理代码要改。
YOLOv8的decode方式(简化版本):
def yolo_v8_postprocess(pred, conf_thres=0.25, iou_thres=0.45): """ pred: ndarray shape (84, 8400) 坐标是cx,cy,w,h,相对原图尺寸的比值 """ pred = pred.transpose(1, 0) # 变成 (8400, 84) boxes = pred[:, :4] cls_conf = pred[:, 4:] scores = cls_conf.max(axis=1) cls_ids = cls_conf.argmax(axis=1) mask = scores > conf_thres boxes = boxes[mask] scores = scores[mask] cls_ids = cls_ids[mask] # cxcywh -> xyxy,乘以原图尺寸 boxes[:, 0] = (boxes[:, 0] - boxes[:, 2] / 2) * 640 boxes[:, 1] = (boxes[:, 1] - boxes[:, 3] / 2) * 640 boxes[:, 2] = (boxes[:, 2] + boxes[:, 2] / 2) * 640 boxes[:, 3] = (boxes[:, 3] + boxes[:, 3] / 2) * 640 # 执行类别NMS ...第二个是模型导出。YOLOv8用ultralytics库导出ONNX时要加参数:
yolo export model=yolov8s.pt format=onnx opset=11 imgsz=640导出后同样用Netron检查输出节点,确认输出维度是(1, 84, 8400)。
第三个是精度对齐。YOLOv8训练时图像归一化到0-1,但推理时还需要做letterbox预处理,AIPP里要配置letterbox的填充值。YOLOv8默认用114做填充(RGB三通道都是114),AIPP不支持自定义填充值,所以我在实践中的做法是不做letterbox,直接把原图resize到640x640。这样会损失一点精度,但在大多数场景下检测效果还可以接受。如果要完全对齐训练时的精度,只能在代码里用CPU做letterbox,再把预处理后的图喂给模型,稍微牺牲一点性能。
6. 性能优化与常见问题排查实录
6.1 性能瓶颈分析和优化手段
部署完成后,性能优化是不可避免的环节。我实测过YOLOv5s在单张Atlas 300V 24G上的推理耗时,FP16精度下,单张图片的模型推理耗时大约在3-5ms。这个数据仅供参考,因为耗时和输入分辨率、模型复杂度、batch size都有关系。
提升吞吐量有以下几个方向:
- 加大Batch Size:把多张图合成一个batch推理,可以有效提高硬件利用率。但注意batch size变化需要重新用ATC转换模型,
input_shape里改成对应的batch值。实测bs4比bs1吞吐量提升60%左右,bs8反而提升不大了,因为AI Core已经接近饱和。 - 使用Stream并发:AscendCL支持多Stream并行执行。把不同路的视频分析放到不同Stream里,可以提高整体利用率。但要注意线程安全问题,Python里用ThreadPoolExecutor来管理多个Stream比较简单。
- 减少数据拷贝:输入数据从CPU到NPU有拷贝开销,尽量保持数据在NPU端。如果做视频分析,解码后的帧直接走DVPP硬件处理链,避免CPU介入。
- AIPP下沉预处理:把resize、归一化都配到AIPP里,省掉CPU预处理时间。
6.2 常见报错速查表
下面整理了我部署过程中遇到的高频报错,附上解决办法。
| 报错信息 | 原因分析 | 解决办法 |
|---|---|---|
E10001: Failed to open device | 驱动未装好或设备被占用 | 检查npu-smi info是否能识别设备,重启系统后再试 |
E40001: Invalid parameter | ATC转换参数错误 | 检查soc_version、input_shape,确认输入节点名 |
E40006: Unsupported op | ONNX里有CANN不支持的算子 | 升级CANN版本,或者在导出时指定opset 11,尝试简化模型结构 |
ACL_ERROR_RT_PARAM_INVALID | 输入输出的shape或dtype不对 | 核对ATC转换时的--input_shape和代码里创建的array维度是否一致 |
| 推理结果全零/置信度全低 | 输入数据没正确写入缓冲区,或归一化参数错误 | 打印输入buffer内容对比预期值,检查AIPP配置 |
| 输出数据乱码 | dtype不一致,代码用了float32但模型output_type是FP16 | 统一dtype,ATC转换和代码里保持一致 |
6.3 一个印象深刻的排查案例
有一次我把YOLOv5s部署到客户现场,模型转换完成后在本机跑一切正常,但复制到客户机器上推理结果全错。一开始怀疑是模型拷贝损坏,但md5校验没问题;怀疑是CANN版本不一致,检查了也一样。
排查了大半天,最后发现是AIPP配置里的resize行为导致的。客户那边要求的输入源是1280x720的原始分辨率,我在配置AIPP时写了src_image_size_w: 1280, src_image_size_h: 720,AIPP自动resize到640x640。但本机测试的时候,我用的测试图是608x608的,src_image_size写的是608,所以两边行为不一样。
这个问题的本质是:AIPP的src_image_size必须和实际送入模型的前置图像尺寸一致,否则AIPP不会按预期执行resize。从那以后我做了个约定:所有部署文档里必须明确写明“送入AIPP的图像尺寸是多少”,避免不同数据源导致的隐性差异。
6.4 关于24GB显存的实际使用心得
最后聊聊显存。24GB显存听起来很大,但用起来也没那么“随便造”。OM模型本身的权重占用其实不大,YOLOv5s的OM模型大概150MB左右,真正吃显存的是推理时的输入输出缓冲区和多路并发的显存开销。
我实际测试过一路1080P视频流(解码+推理)占用的显存大约1GB左右,所以24GB理论上支持24路并发。但实际跑的时候,CPU解码、内存带宽、PCIe带宽都可能成为瓶颈,并不是显存够就能无限扩并发。建议根据实际业务场景压测出一个安全的并发数,一般建议留20%的显存余量给系统缓冲和偶发内存泄漏。
另外,Atlas卡的显存是由芯片统一管理的,不像GPU有显存碎片问题那么严重,但如果长期运行反复加载模型,建议定时重启释放资源。我在一个7x24小时运行的推理服务里遇到过显存逐渐增长的情况,最终定位是模型加载和释放过程中有少量内存泄漏,代码里加上定时重启进程后解决了。
7. 部署完成后,我个人的几点体会
在整个Atlas 300V 24G + YOLO的部署过程中,我最大的感受是:这套方案适合业务逻辑固定、包含大量视频流、有真实成本压力的生产场景。Atlas卡的性价比在硬件指标上非常能打,但开发调试的时间成本也确实比GPU生态高。如果你有足够的耐心去啃文档、排查算子兼容性,最终得到的是一套功耗低、体积小、单卡并发能力强的推理方案。
最后分享一个小技巧:CANN的日志是排查问题时最好的朋友。默认日志级别比较高,很多有用的调试信息都看不到。在推理代码初始化时加一行环境变量设置,把日志级别调低,问题定位会快很多:
export ASCEND_GLOBAL_LOG_LEVEL=1 # 0 DEBUG, 1 INFO, 2 WARNING, 3 ERROR同时,ATC转换时的--log=debug参数会输出大量的转换细节,特别是算子映射过程,遇到算子不支持的报错时,配合日志看是哪个算子、在哪一层出现的,再针对性地做模型修改或算子替换,效率会高很多。希望大家部署顺利,少踩我踩过的坑。