昇腾NPU调试排障手册——从“报错了“到“修好了“的完整流程
昇腾NPU调试排障手册——从"报错了"到"修好了"的完整流程
·

调试昇腾NPU上的问题比调试普通Python代码更复杂,因为错误可能发生在任何一层:PyTorch适配器层、CANN算子层、HCCL通信层、ACL驱动层、固件层。掌握系统化的调试方法,能把排查时间从几天缩短到几小时。
一、错误分类与快速定位
昇腾的错误码通常以 6位数字 开头,不同前缀代表不同层级的问题。
1. 错误码速查表
ERROR_CATEGORIES = {
# ACL运行时错误 (100000-199999) - 显存/资源管理
"ACL_ERROR_MEMORY": {
"range": (100000, 109999),
"examples": ["100001", "100002"],
"cause": "内存分配失败/显存不足 (OOM)",
"solution": "减少Batch Size / 开启ZeRO-3 / 检查内存泄漏",
},
"ACL_ERROR_RESOURCE": {
"range": (110000, 119999),
"examples": ["110001"],
"cause": "资源耗尽(流/事件/Stream未释放)",
"solution": "检查是否忘记 `torch.npu.synchronize()` 或手动释放Tensor",
},
# HCCL通信错误 (200000-299999) - 多卡通信
"HCCL_ERROR_TIMEOUT": {
"range": (200000, 209999),
"examples": ["200001", "200002"],
"cause": "多卡通信超时 (网络抖动/配置错误)",
"solution": "增加 HCCL_CONNECT_TIMEOUT / 检查网卡物理连接",
},
"HCCL_ERROR_RANK": {
"range": (210000, 219999),
"examples": ["210001"],
"cause": "Rank配置错误/节点ID冲突",
"solution": "检查环境变量 RANK/WORLD_SIZE / 确认 hccn_tool 状态",
},
# ATC编译错误 (300000-399999) - OM模型转换
"ATC_ERROR_OP_NOT_SUPPORT": {
"range": (300000, 309999),
"examples": ["300001"],
"cause": "ONNX算子不支持/融合失败",
"solution": "查看 `op_not_support.log` / 使用 `--disable_fusion` 降级编译",
},
"ATC_ERROR_SHAPE": {
"range": (320000, 329999),
"examples": ["320001"],
"cause": "Shape不匹配/动态Shape配置错误",
"solution": "在ATC命令中指定 `--dynamic_shape_inputs`",
},
# 算子执行错误 (400000-499999) - 计算逻辑
"OP_ERROR_COMPUTE": {
"range": (400000, 409999),
"examples": ["400001"],
"cause": "算子计算溢出/除零/NaN",
"solution": "检查输入数据范围 / 调整精度 (FP16->BF16)",
},
# 环境/驱动错误 (600000+) - 底层基础
"ENV_ERROR_DRIVER": {
"range": (600000, 609999),
"examples": ["600001"],
"cause": "驱动/固件版本不匹配",
"solution": "升级固件至推荐版本 (参考 CANN 兼容性矩阵)",
},
}
2. 自动化诊断脚本
将你的报错日志复制到一个文本文件 error_log.txt,运行以下脚本自动分析:
import re
def diagnose_error_log(log_content):
"""从日志内容中提取并分析错误"""
error_codes = re.findall(r'(?:ACL|HCCL|ATC|ERROR)[\s:]*(\d{6})', log_content)
diagnosis = []
for code in set(error_codes):
if int(code) >= 100000 and int(code) < 700000:
diagnosis.append(f"检测到错误码: {code}")
if 100000 <= int(code) < 200000:
diagnosis.append(" -> 疑似内存/资源问题 (OOM或泄漏)")
elif 200000 <= int(code) < 300000:
diagnosis.append(" -> 疑似通信问题 (网络或配置)")
elif 300000 <= int(code) < 400000:
diagnosis.append(" -> 疑似模型编译问题 (算子不支持)")
elif 400000 <= int(code) < 500000:
diagnosis.append(" -> 疑似计算逻辑问题 (NaN/Overflow)")
else:
diagnosis.append(" -> 疑似环境问题 (驱动/固件)")
else:
diagnosis.append(f"未知错误码: {code}")
return "\n".join(diagnosis)
# 使用示例
# log = open('error_log.txt').read()
# print(diagnose_error_log(log))
二、环境问题排查 (Step-by-Step)
大多数“跑不起来”的问题都源于环境配置。请按顺序执行以下检查。
Step 1:检查驱动和固件版本 (最关键)
# 1. 查看驱动版本
npu-smi info -t version
# 2. 查看固件版本 (必须与驱动匹配!)
cat /etc/ascend/{version,info}.json 2>/dev/null || npuinfo
# 常见匹配关系 (以CANN 7.0为例):
# Driver: 23.0.x -> Firmware: 1.85.x
# Driver: 6.3.x -> Firmware: 1.73.x
# 如果看到 "Firmware version incompatible" (600001),请升级固件:
source /usr/local/Ascend/ascend-toolkit/set_env.sh
npu-firmware-upgrade
Step 2:验证CANN与PyTorch版本
# 1. 检查CANN组件
ls -la /usr/local/Ascend/ascend-toolkit/latest/
# 2. 检查Python包
pip list | grep -E "(cann|torch-npu|acl)"
# 3. Python内部验证
python3 << 'EOF'
import torch
import torch_npu
print(f"PyTorch: {torch.__version__}")
print(f"Torch-NPU: {torch_npu.__version__}")
print(f"NPU Available: {torch.npu.is_available()}")
print(f"NPU Count: {torch.npu.device_count()}")
if torch.npu.is_available():
try:
x = torch.randn(1).npu()
print("NPU Tensor Creation: OK")
except Exception as e:
print(f"NPU Tensor Creation Failed: {e}")
else:
print("NPU Not Available! Check driver installation.")
EOF
Step 3:权限与设备可见性
# 1. 检查设备节点权限
ls -la /dev/davinci*
# 预期输出应包含 user 权限,若无则需添加用户组
sudo usermod -aG hwloc $USER
newgrp hwloc # 刷新组权限
# 2. 检查驱动模块是否加载
lsmod | grep ascend
# 如果没有输出,尝试重启服务:
sudo systemctl restart ascend-driver
Step 4:NUMA绑定优化 (性能相关)
如果程序能跑但速度慢,可能是CPU与NPU不在同一个NUMA节点。
# 查看NPU所在的NUMA节点
npu-smi info -q | grep numa
# 启动程序时绑定到对应节点
numactl --cpunodebind=0 --membind=0 python3 train.py
三、内存问题排查 (OOM & Leak)
1. 实时显存监控
import torch
def check_memory():
if torch.npu.is_available():
allocated = torch.npu.memory_allocated() / (1024**3)
reserved = torch.npu.memory_reserved() / (1024**3)
print(f"Allocated: {allocated:.2f} GB")
print(f"Reserved: {reserved:.2f} GB")
print(f"Peak: {torch.npu.max_memory_allocated() / (1024**3):.2f} GB")
if reserved > allocated + 1:
print("⚠️ 警告: Reserved远大于Allocated,可能存在显存碎片!")
print("建议: 定期调用 torch.npu.empty_cache()")
else:
print("NPU not available")
# 在训练循环中定期调用
check_memory()
2. 常见OOM解决方案
| 现象 | 原因 | 解决方案 |
|---|---|---|
| 训练启动即OOM | 初始显存占用过大 | 减小 batch_size / 启用 gradient_checkpointing |
| 训练中途OOM | 激活值累积过多 | 开启 activation_checkpointing / 减小 seq_len |
| 推理OOM | KV Cache过大 | 减小 max_seq_len / 使用 int8 量化 |
| 频繁OOM但显存未满 | 显存碎片化 | 设置 ASCEND_RT_MEMORY_REUSE=1 / 重启进程 |
3. 内存泄漏检测
import gc
import torch
def leak_detector(model, data_loader):
for i, (input, label) in enumerate(data_loader):
# 强制垃圾回收
gc.collect()
torch.npu.empty_cache()
output = model(input)
loss = criterion(output, label)
loss.backward()
if i % 10 == 0:
print(f"Step {i}: Allocated={torch.npu.memory_allocated()/1e9:.2f}GB")
optimizer.step()
optimizer.zero_grad()
# 关键:确保没有引用残留
del input, label, output, loss
四、通信与分布式调试 (HCCL)
多机多卡训练时,HCCL 是最常见的故障点。
1. 常见HCCL错误
- 200001 (Timeout): 网络不通或某台机器挂掉。
- 解决:
export HCCL_CONNECT_TIMEOUT=600(延长至10分钟)。
- 解决:
- 210001 (Rank Mismatch): 环境变量配置不一致。
- 解决: 确保所有节点
RANK,WORLD_SIZE,MASTER_ADDR,MASTER_PORT完全一致。
- 解决: 确保所有节点
- 通信带宽低: 实际速度远低于理论值。
- 解决: 检查
hccn_tool状态,确认 RoCE/IB 网络正常。
- 解决: 检查
2. 网络连通性测试
# 1. 单机内测试
hccl_tool --test
# 2. 跨节点测试 (在所有节点上同时ping)
ping -c 3 <peer_ip>
# 3. 带宽测试 (需要安装iperf3)
iperf3 -c <peer_ip> -t 10 -J | jq '.end.sum_received_bytes'
3. 调试技巧:单卡隔离法
如果多卡报错,先尝试单卡运行,排除代码逻辑问题:
# 只使用第一张卡
export ASCEND_RT_VISIBLE_DEVICES=0
python train.py
如果单卡正常,再逐步增加卡数,定位是哪两张卡之间出了问题。
五、算子与编译问题 (ATC/Op)
1. ATC编译失败排查
如果 atc 命令报错 300001 (Op Not Support):
# 1. 查看详细日志
less atc_output/op_not_support.log
# 2. 临时禁用融合 (降低难度)
atc --model=model.onnx \
--disable_fusion=true \
...
# 3. 自定义算子
如果确实是新算子,需要编写 C++ 自定义算子插件并注册。
2. 算子性能瓶颈
使用 msprof 分析哪个算子最慢:
# 开启Profiling
export MS_PROFILE=1
# 运行推理
python inference.py
# 生成报告
msprof --mode=trace --output=profile.prof ./inference.py
msprof --input=profile.prof --output=report.html
六、终极排查清单 (Checklist)
在提交Issue或寻求官方支持前,请准备好以下信息:
- 硬件信息:
npu-smi info -t version截图。 - 软件版本: CANN版本、PyTorch版本、固件版本。
- 错误日志: 完整的
stderr输出,特别是最后10行。 - 复现步骤: 最小可复现代码 (Minimal Reproducible Example)。
- 环境配置: 相关的
export环境变量列表。 - 网络拓扑: 如果是多机,说明互联方式 (RoCE/IB)。
七、总结
- 先看驱动: 600001 错误最常见,先升级固件。
- 再看显存: OOM 是第二大杀手,优先减小 Batch/SeqLen。
- 后看通信: 多卡问题先测网络,再调参数。
- 善用工具:
npu-smi,msprof,hccl_tool是三大神器。
记住:昇腾的报错信息有时比较晦涩,不要只看最后一行,往前翻几行寻找 Error Code 才是破局的关键。
更多推荐

所有评论(0)