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
  1. 记录错误码:保留完整的错误日志
  2. 查文档:对照上文的错误码表定位原因
  3. 查社区:搜索昇腾论坛是否有类似问题
  4. 提 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
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐