CANN 调试与错误处理:问题排查指南与实战技巧
CANN 调试与错误处理指南摘要 本文总结了昇腾 NPU 开发中的常见错误与排查方法,涵盖调试环境准备、错误分类和五大典型场景解决方案。主要内容包括: 调试工具:介绍 npu-smi、ascend-historian 等关键工具的使用场景和日志目录位置 错误分类:整理运行时错误(内存分配、算子支持等)和编译错误(模型解析、shape推导等)的典型错误码及解决方法 五大实战场景: Torch-NPU
·
CANN 调试与错误处理:问题排查指南与实战技巧
遇到报错无从下手?这篇总结昇腾 NPU 开发中的常见错误与排查方法,让你快速定位问题。
调试环境准备
1.1 诊断工具清单
| 工具 | 用途 | 常用场景 |
|---|---|---|
npu-smi |
设备状态监控 | 查看 NPU 使用率、显存占用 |
ascend-historian |
训练过程采集 | 分析算子耗时、内存峰值 |
msnpureport |
异常日志导出 | 导出 NPU 侧错误详情 |
atc --log |
编译日志 | ATC 转换失败时定位问题 |
1.2 日志目录
# 运行时日志
ls /var/log/npu/
# 芯片微架构日志
ls /var/log/npu/slog/
# 训练 profile 输出
ls ~/ascend-works/logs/
常见错误分类
2.1 运行时错误
| 错误码 | 含义 | 排查方向 |
|---|---|---|
E00001 |
内存分配失败 | 显存不足,检查模型占用 |
E00005 |
算子不支持 | 检查算子类型是否在白名单 |
E00010 |
数据格式不匹配 | 检查输入 tensor 的 shape/dtype |
E00015 |
设备间通信超时 | 检查 HCCL 配置,网络是否畅通 |
2.2 编译错误
| 错误信息 | 原因 | 解决 |
|---|---|---|
Parse op failed |
ONNX 模型解析失败 | 用 onnx simplifier 预处理模型 |
Op not supported |
算子未适配 | 改用支持的算子或自定义实现 |
Shape unknown |
动态 shape 无法推导 | 固定 batch size 或设置 input_shape |
Memory overflow |
资源块过大 | 开启 reduce memory 或分图 |
场景一:Torch-NPU 训练报错
3.1 典型报错
RuntimeError: NPU error, error code: 0x9101E001
这个错误码表示数据搬运过程中发生错误,通常是 Host-Device 拷贝不匹配导致的。
3.2 排查步骤
# 1. 查看 NPU 状态
npu-smi info
# 2. 检查进程是否异常退出
ps aux | grep python
# 3. 查看设备日志
cat /var/log/npu/slog/device_log/0/*.log | tail -100
3.3 常见原因
| 场景 | 原因 | 修复方法 |
|---|---|---|
| 数据 shape 不匹配 | 输入张量维度错误 | 检查 torch.randn 初始化的 shape |
| 数据类型不匹配 | dtype 是 int32 但算子需要 float | 添加 .float() 转换 |
| batch size 过大 | 显存溢出 | 减小 batch_size 或开启 gradient accumulation |
| 设备 ID 错误 | 指定了不存在的 NPU | 改为 npu:0 或动态获取 |
3.4 代码修复示例
# 错误写法
data = torch.randn(batch_size, 3, 224, 224) # 默认 CPU
output = model(data) # 没有移到 NPU
# 正确写法
device = torch.device("npu:0")
data = torch.randn(batch_size, 3, 224, 224).to(device)
output = model(data)
场景二:ATC 模型转换失败
2.1 错误分析
atc --model=model.onnx \
--output=model \
--framework=5 \
--soc_version=Ascend910
Error: Cannot find op [CustomLayer] in opt
这种报错是 ONNX 模型中包含了自定义算子,ATC 无法识别。
2.2 解决方案
方案一:简化模型
# 用 onnx simplifier 移除自定义算子
pip install onnxsim
python -m onnxsim model.onnx model_simple.onnx
方案二:注册自定义算子
from msame.model import Model
# 创建自定义算子映射
custom_op_map = {
"CustomLayer": "AscendCustom", # 映射到 ATC 支持的算子
}
# 在转换时指定
atc --model=model.onnx \
--output=model \
--framework=5 \
--op_select_level=custom \
--custom_op_maps=custom_op_map
2.3 常见 ATC 错误
| 错误信息 | 原因 | 解决 |
|---|---|---|
Can not parse model |
ONNX 文件损坏 | 重新导出或用 netron 可视化检查 |
Input shape not match |
input_shape 与实际不符 | 设置正确的维度 1,3,224,224 |
Op kernel not found |
算子未在 NPU 实现 | 改用 ATC 支持的标准算子 |
SocVersion mismatch |
芯片型号不匹配 | 确认是 Ascend910 还是 Ascend310 |
场景三:多卡训练通信失败
3.1 HCCL 错误
[HCCL] ERROR: 0x81001 - Timeout when rank 0 tries to communicate with rank 2
这是集合通信超时,通常是某个进程卡住或网络不通。
3.2 排查命令
# 检查 NCCL 配置
export NCCL_DEBUG=INFO
python train.py 2>&1 | tee training.log
# 检查网络连通性
ping -c 3 192.168.1.101
# 查看 HCCL 日志
cat /var/log/npu/hccl/*.log
3.3 常见原因
| 原因 | 表现 | 处理 |
|---|---|---|
| 单卡进程卡死 | 某个 rank 无响应 | 重启训练或增加 timeout |
| 网卡故障 | 节点间 ping 不通 | 更换网线或检查交换机 |
| 集合通信配置错误 | allreduce 失败 | 检查 hccl.json 配置 |
| 梯度不同步 | 部分节点计算慢 | 开启 async_grad_accumulation |
3.4 hccl.json 配置示例
{
"rank_table": "/path/to/rank_table.json",
"machine_list": [
{
"devices": [
{"id": "0", "ip": "192.168.1.100"},
{"id": "1", "ip": "192.168.1.101"}
]
}
],
"timeout": 300
}
场景四:显存溢出(OOM)
4.1 错误日志
RuntimeError: NPU out of memory.
Allocated: 31.2 GB, Total: 31.4 GB
4.2 排查方法
# 查看显存占用
npu-smi q -s memory
# 使用 msnpureport 采集详细日志
msnpureport -t memory -o ./memory_report
4.3 优化策略
| 策略 | 效果 | 适用场景 |
|---|---|---|
| 减小 batch size | 显存降低 ~50% | 显存刚好不够 |
| 混合精度 FP16 | 显存降低 ~50% | 精度可接受 |
| 梯度累积 | 等效 batch 增大 | 收敛受影响 |
| ZeRO 分片 | 显存降低 ~N 倍 | 多卡训练 |
| 启用 recompute | 显存降低 ~30% | 激活值过大 |
4.4 优化代码示例
# 显存优化配置
model = model.to(torch.bfloat16)
# 启用 gradient checkpointing
model.gradient_checkpointing_enable()
# 减小 batch
batch_size = 8 # 从 16 降到 8
场景五:算子执行失败
5.1 错误日志
[ERROR] Op [Conv] execution failed. Error code: 0x8900A123
5.2 定位方法
# 开启算子级别的详细日志
export ASCEND_GLOBAL_LOG_LEVEL=3
python train.py
# 查看具体是哪个算子
grep "Op execution failed" ./ascend_log/*.log
5.3 常见原因
| 算子 | 常见问题 | 解决方案 |
|---|---|---|
| Conv | kernel size 不支持 | 改用 3x3 或 1x1 |
| MatMul | shape 不对齐 | 检查矩阵维度 |
| Softmax | axis 参数越界 | 确认 dim 范围 |
| Reshape | shape 冲突 | 检查目标 shape 可行性 |
调试技巧
6.1 断点调试
import torch.npu as npu
# 在关键位置插入调试
output = model(input_data)
print(f"Output shape: {output.shape}")
print(f"Output dtype: {output.dtype}")
print(f"NPU memory: {npu.memory_allocated() / 1e9:.2f} GB")
# 检查梯度
for name, param in model.named_parameters():
if param.grad is not None:
print(f"{name}: grad norm = {param.grad.norm()}")
6.2 日志分级
import logging
# 设置日志级别
logging.basicConfig(level=logging.DEBUG)
# 只在关键节点输出
def train_step():
logging.info(f"Step {step}, loss = {loss.item()}")
if loss.item() > 10:
logging.warning(f"Loss too high at step {step}")
6.3 自动化检测
#!/bin/bash
# NPU 健康检查脚本
echo "=== NPU Status ==="
npu-smi q -s memory
echo "=== Process List ==="
ps aux | grep python | head -5
echo "=== Recent Error Logs ==="
tail -20 /var/log/npu/slog/device_log/0/*.log
错误处理流程图
报错 → 记录错误码 → 查文档/社区 → 定位根因 → 修复/提 Issue
- 记录错误码:保留完整的错误日志
- 查文档:对照上文的错误码表定位原因
- 查社区:搜索昇腾论坛是否有类似问题
- 提 Issue:复现步骤清晰描述,发到官方仓库
相关仓库
- ascend-toolkit - 官方工具链 https://gitee.com/ascend/ascend-toolkit
- torch_npu - NPU 适配 https://gitee.com/ascend/torch_npu
- Atlas - 论坛与支持 https://bbs.huaweicloud.com/forum/forum-729
更多推荐




所有评论(0)