msProbe PyTorch 场景快速入门¶
1. 概述¶
msProbe(MindStudio Probe)是 AI 模型精度调试工具。本文以 ResNet-50 模型训练为例,演示 NPU/GPU 数据采集、精度比对及分级可视化构图比对的完整流程,帮助您掌握数值溢出、Loss 异常、模型不收敛等典型精度问题的排查方法与分析思路。
体验地图(核心操作约需 10 分钟)
| 步骤 | 环节 | 核心工具 | 操作耗时 | 原理学习 |
|---|---|---|---|---|
| 1 | 环境准备 | CANN 容器 | 5 min | 5 min |
| 2 | NPU 数据采集 | PrecisionDebugger | 1 min | 10 min |
| 3 | GPU 标杆采集 | PrecisionDebugger | 0.5 min | 5 min |
| 4 | 精度比对 | msProbe compare | 1 min | 10 min |
| 5 | 可视化构图比对 | graph_visualize / TensorBoard | 2 min | 10 min |
👉 本教程基于 PyTorch 框架。如需在 MindSpore 场景下使用,请参阅《MindSpore 场景精度调试工具快速入门》。
2. 操作步骤¶
2.1 环境准备(必做)¶
🛑 本节为强制前置步骤!跳过本节可能导致后续多项操作失败。
本教程的 NPU 侧操作仅支持在标准化 CANN 容器中执行,不支持直接在裸机、虚拟机或其他非标准容器环境中执行。
2.1.1 前置条件¶
开始前,请确认服务器满足以下要求:
| 项目 | 要求 | 验证方法 |
|---|---|---|
| 硬件算力 | Linux 服务器配备至少 1 张 NPU 卡,驱动与固件已安装 | 执行 npu-smi info,确认 NPU 卡状态正常 |
| 容器运行 | 已安装并运行 Docker(建议版本 ≥ 18.0) | 执行 docker ps,无报错即表示服务正常启动 |
| 脚本执行 | 宿主机已安装 Python 3 | 在宿主机执行 python3 -V,有版本信息输出即表示已安装 |
| 网络通信 | 已安装 curl(任意版本) | 执行 curl -V,有版本信息输出即表示已安装 |
👉 确认前置条件满足后,若环境具备公网访问能力,本章 NPU 侧命令可全程直接 Copy/Paste 执行,无需手动输入或拼接,以避免因输入错误导致命令执行失败。
2.1.2 宿主机:自动识别并配置镜像环境变量¶
在宿主机执行以下命令(该命令依次完成:读取 NPU PCI ID,匹配镜像版本,写入环境变量供后续流程使用):
source /dev/stdin <<< "$(dev_id=$(lspci -n -D | grep -o '19e5:d[0-9a-f]\{3\}' | head -n1 | cut -d: -f2); case "$dev_id" in 'd500' ) echo "export MY_STUDY_VAR_CANN_IMAGE=swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.0.0-310p-openeuler24.03-py3.11-devel; export MY_CHIP_NAME=310P";; 'd802' ) echo "export MY_STUDY_VAR_CANN_IMAGE=swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.0.0-910b-openeuler24.03-py3.11-devel; export MY_CHIP_NAME=910B";; 'd803' ) echo "export MY_STUDY_VAR_CANN_IMAGE=swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.0.0-a3-openeuler24.03-py3.11-devel; export MY_CHIP_NAME=A3";; 'd806' ) echo "export MY_STUDY_VAR_CANN_IMAGE=swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.0.0-950-openeuler24.03-py3.11-devel; export MY_CHIP_NAME=950";; * ) echo "unset MY_STUDY_VAR_CANN_IMAGE MY_CHIP_NAME; echo >&2; echo -e '\033[31m[FAIL] Get device ID: $dev_id. Learning is not supported in the current environment.\033[0m' >&2";; esac)"
[ -n "$MY_STUDY_VAR_CANN_IMAGE" ] && echo -e "\e[32m[PASS] Successfully identified chip [$MY_CHIP_NAME] and auto-selected image:\n $MY_STUDY_VAR_CANN_IMAGE\e[0m"
[!NOTE]说明
命令原理
通过
lspci获取 NPU 的 PCI ID,自动匹配 CANN 官方镜像,并将镜像地址赋给环境变量MY_STUDY_VAR_CANN_IMAGE,供后续使用。
所有镜像均来自华为云 AscendHub 上发布的 CANN 官方镜像。如需了解镜像详情,请参阅 CANN 官方镜像仓库。
若命令执行后输出 [PASS],则表示执行成功;若输出 [FAIL],可能原因如下:
- 硬件不在本教程支持范围内:本学习环境仅支持昇腾 310P、A2、A3 及 950 系列产品,请切换至兼容的硬件环境后重试;
- 底层环境异常:未安装
lspci,或当前用户无法通过lspci -n -D查询 NPU PCI ID,请联系环境管理员确认底层环境。
2.1.3 宿主机:拉取镜像¶
在宿主机执行:
若因处于企业内网导致拉取失败,请参考 第 3.1 节 的解决方案。
2.1.4 宿主机:下载容器启动脚本¶
在宿主机执行:
cd ~ && curl -fLO --retry 3 https://inst.obs.cn-north-4.myhuaweicloud.com/env/ctr_in.py && chmod +x ctr_in.py
若因网络限制无法下载,请参考 第 3.2 节 的解决方案。
2.1.5 宿主机:启动容器¶
在宿主机执行以下命令,并根据终端提示确认容器创建信息:
预期结果:终端显示类似以下的 root Shell 提示符,表示容器已成功启动并进入容器:
若提示错误或出现容器选择界面,请返回 第 2.1.2 节,确认命令输出 [PASS],再重新启动容器。
2.1.6 容器内:安装 Python 依赖和 msProbe¶
在容器内执行以下命令:
pip3 install networkx==3.6.1 pillow==12.2.0
pip3 install https://inst.obs.cn-north-4.myhuaweicloud.com/env/mirror/$(arch)/download.pytorch.org/whl/cpu/torch-2.7.1%2Bcpu-cp311-cp311-manylinux_2_28_$(arch).whl
pip3 install https://gitcode.com/Ascend/pytorch/releases/download/v26.0.0-pytorch2.7.1/torch_npu-2.7.1.post4-cp311-cp311-manylinux_2_28_$(arch).whl
pip3 install torchvision==0.22.1 --index-url https://download.pytorch.org/whl/cpu
pip3 install -U mindstudio-probe
若因处于企业内网导致安装失败,请参考 第 3.3 节 的解决方案。
2.1.7 容器内:检查环境安装正确性¶
安装完成后执行环境检查命令:
python3 -c 'import torch, torch_npu; assert torch.npu.is_available(), "NPU is unavailable"; import msprobe; print("PyTorch:", torch.__version__)' && msprobe --help >/dev/null && tensorboard --help >/dev/null && echo -e "\e[32m[PASS] NPU environment, msProbe and TensorBoard check passed.\e[0m"
若显示 [PASS],表示 NPU 环境、Python 依赖、msProbe 和 TensorBoard 均已正常配置,可以继续进行下一步操作。
2.2 在 NPU 环境采集待调试数据¶
2.2.1 准备采集配置¶
在容器内执行以下命令,将采集配置写入 ~/config.json:
cat > ~/config.json << EOF
{
"task": "statistics",
"dump_path": "${HOME}/msprobe_dump_npu",
"rank": [],
"step": [0, 1],
"level": "mix",
"async_dump": false,
"statistics": {
"scope": [],
"list": [],
"data_mode": ["all"],
"summary_mode": "statistics"
}
}
EOF
本配置采集第 0、1 两个训练迭代中 Module 和 API 层级的前向、反向输入输出统计量。采集结果可同时用于精度比对和分级可视化构图比对。由于 task 设置为 statistics,仅保存 Tensor 统计量,不保存完整的 Tensor 数据,可降低磁盘占用。
2.2.2 准备模型训练代码¶
在容器内执行以下命令,将训练代码写入 ~/precision_sample.py。脚本使用固定随机数据训练 ResNet-50 模型,并通过 PrecisionDebugger 采集精度数据。该模型包含卷积、归一化、激活、残差连接、池化和全连接等典型结构:
cat > ~/precision_sample.py << 'EOF'
import os, argparse, torch, torch.nn as nn
from torch.utils.data import DataLoader
import torchvision.datasets as datasets, torchvision.models as models, torchvision.transforms as transforms
try:
import torch_npu
from torch_npu.contrib import transfer_to_npu
except ImportError:
pass
from msprobe.pytorch import PrecisionDebugger, seed_all
seed_all(seed=1234, mode=True)
parser = argparse.ArgumentParser()
parser.add_argument('--gpu', default=0, type=int)
args = parser.parse_args()
device = torch.device(f'cuda:{args.gpu}')
torch.cuda.set_device(args.gpu)
model = models.resnet50().to(device)
criterion = nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
train_loader = DataLoader(datasets.FakeData(1281167, (3, 224, 224), 1000, transforms.ToTensor()), batch_size=32, shuffle=True, num_workers=4, pin_memory=True)
val_loader = DataLoader(datasets.FakeData(50000, (3, 224, 224), 1000, transforms.ToTensor()), batch_size=32, shuffle=False, num_workers=4, pin_memory=True)
debugger = PrecisionDebugger(config_path=os.path.expanduser("~/config.json"))
global_step = 0
total_epochs = 2
total_steps = total_epochs * len(train_loader)
for epoch in range(total_epochs):
model.train()
for i, (images, target) in enumerate(train_loader):
debugger.start(model)
images, target = images.to(device, non_blocking=True), target.to(device, non_blocking=True)
loss = criterion(model(images), target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
debugger.stop()
if global_step % 10 == 0:
print(f"Current Step: {global_step} (Progress: {global_step / total_steps:.2%})\tLoss: {loss.item():.4e}")
debugger.step()
global_step += 1
model.eval()
correct, total = 0, 0
with torch.no_grad():
for images, target in val_loader:
images, target = images.to(device, non_blocking=True), target.to(device, non_blocking=True)
correct += model(images).argmax(dim=1).eq(target).sum().item()
total += target.size(0)
print(f" * Finished Epoch Pool - Evaluation Acc@1: {100.0 * correct / total:.3f}%")
scheduler.step()
EOF
2.2.3 启动训练和采集¶
在容器内执行以下命令:
默认使用 0 号卡。若该卡不可用或需指定其他卡,请将
--gpu 0中的数字替换为目标卡 ID。
当日志输出如下信息时,表明 step0/step1 精度数据采集已完成。此时后续训练迭代(step 2、3、4 等)仍会继续执行,可按 Ctrl + C 安全终止进程以节省时间,提前终止不会影响已采集的 step0/step1 数据完整性:
2026-07-15 02:08:30 (2596) [INFO] dump.json is at /root/msprobe_dump_npu/step1.
2026-07-15 02:08:31 (2596) [INFO] ****************************************************************************
2026-07-15 02:08:31 (2596) [INFO] * msprobe ends successfully. *
2026-07-15 02:08:31 (2596) [INFO] ****************************************************************************
[!NOTE]说明
日志输出与手动终止原理
脚本启动后即开始训练,由于config.json中配置"step": [0, 1],msProbe 仅在第 0、1 个训练迭代触发采集并输出相关日志;从第 2 个迭代起,msProbe 停止采集,终端仅输出训练脚本自身的日志(如Current Step: 10 (Progress: 0.01%))。此时 step0 与 step1 的精度数据已完整落盘,可安全终止训练进程。
2.2.4 查看采集结果¶
运行以下命令,自动定位第 0 个训练迭代(step0)生成的 dump.json 并查看目录结构:
NPU_DUMP_JSON=$(find "${HOME}/msprobe_dump_npu/step0" -type f -name dump.json | head -n 1)
echo "${NPU_DUMP_JSON}"
tree -L 3 "${HOME}/msprobe_dump_npu"
若成功输出 dump.json 路径,则表明数据采集正常。
单卡训练中,精度数据通常保存在 proc{pid} 目录;多卡训练则保存在 rank{id} 目录。常见结构如下:
msprobe_dump_npu
├── step0
│ └── proc{pid}
│ ├── construct.json
│ ├── dump.json
│ └── stack.json
└── step1
└── proc{pid}
├── construct.json
├── dump.json
└── stack.json
| 文件 | 说明 |
|---|---|
construct.json |
记录 Module 层级关系信息 |
dump.json |
包含 Module 和 API 在前向、反向过程中的输入输出统计量及溢出信息,是后续精度比对的核心输入 |
stack.json |
记录 API 调用栈信息,用于从可疑 API 回溯至训练代码 |
2.3 在 GPU 环境采集标杆数据¶
本快速入门旨在体验 msProbe 核心功能,自行采集 GPU 数据对理解工具价值有限,建议直接使用预置示例数据:
cd ~
git clone --depth 1 --single-branch https://gitcode.com/Ascend/msprobe.git
cp -rf ~/msprobe/examples/quick_start/gpu_dump ~/msprobe_dump_gpu
[!NOTE]说明
预置 GPU 数据已覆盖典型精度问题特征,可将您的体验时间大幅缩短,聚焦于 msProbe 核心分析能力而非环境搭建。
如您想体验 GPU 采集数据过程,请参考 第 4 章 中的提示自主探索操作。
2.4 NPU 与 GPU 精度比对¶
2.4.1 准备比对数据¶
在 NPU 容器内执行以下命令,重新定位双端数据路径:
NPU_DUMP_JSON=$(find "${HOME}/msprobe_dump_npu/step0" -type f -name dump.json | head -n 1)
GPU_DUMP_JSON=$(find "${HOME}/msprobe_dump_gpu/step0" -type f -name dump.json | head -n 1)
echo "NPU: ${NPU_DUMP_JSON}"
echo "GPU: ${GPU_DUMP_JSON}"
确认两个变量均输出实际的 dump.json 路径后再继续执行比对。
2.4.2 执行精度比对¶
在 NPU 容器内执行以下命令:
若输出如下信息,则表明比对成功:
************************************************************************************
* msprobe compare ends successfully. *
************************************************************************************
2.4.3 查看精度比对结果¶
执行以下命令查看生成的结果文件:
单卡场景会生成 compare_result_{timestamp}.csv(或 xlsx 格式),该文件列出参与比对的 API、数据类型、Tensor 形状、统计量误差、比对结论和错误信息等:
图 1 精度比对结果文件内容示例
查看结果时,建议按以下顺序分析:
- 筛选异常:根据
Result列筛选未通过的 API; - 排查错误:查看
Err_Message,判断是否存在 API 未匹配、数据类型或形状不一致等问题; - 比对统计:针对已匹配但精度差异较大的 API,对比 Max、Min、Mean、L2 Norm 等统计量及相对误差;
- 回溯代码:结合
NPU_Stack_Info或 NPU 侧stack.json,定位可疑 API 对应的训练代码。
更多指标定义和结果解读方法,请参见《精度比对结果分析》。
2.5 分级可视化构图比对¶
分级可视化构图比对会还原两侧模型的 Module 和 API 层级结构,并将精度差异映射到图节点上,适合从整体模型结构逐层定位可疑节点。
2.5.1 生成双图比对文件¶
在 NPU 容器内执行以下命令:
msprobe graph_visualize -tp "${HOME}/msprobe_dump_npu" -gp "${HOME}/msprobe_dump_gpu" -o "${HOME}/graph_visualize_output"
执行完成后查看输出结果:
输出目录中将生成如下文件:
若提示模型结构为空,请确认 NPU 和 GPU 采集配置中的 level 均为 mix 或者均为 L0,并检查两侧 construct.json 文件内容是否为空。
2.5.2 启动 TensorBoard¶
在 NPU 容器内执行以下命令:
终端将输出类似如下访问地址(主机名和端口以实际日志为准):
在浏览器中访问 http://服务器IP:6006/。若因防火墙限制导致无法直接访问,可通过 VS Code 端口转发或 SSH 端口转发访问,具体方法请参考 第 5.3 节。
2.5.3 查看可视化比对结果¶
成功打开 TensorBoard 后,可看到如下双图比对结果:
图 2 NPU 与 GPU 分级可视化构图比对
建议按以下顺序分析:
- 确认数据:在数据选择区确认所选 NPU 数据、GPU 数据、训练迭代(Step)及进程相互对应;
- 逐级展开:从模型顶层逐级展开 Module,优先关注颜色较深或标记为精度可疑的节点;
- 搜索定位:利用节点搜索功能,快速定位精度比对结果文件中发现的可疑 API;
- 分析偏差:选中节点后对比两侧统计量、精度指标及调用栈,判断首个显著偏差位置。
更多节点匹配、精度筛选、溢出检测和跨套件比对方法,请参见《PyTorch 场景分级可视化构图比对》。
2.6 后续进阶路径¶
恭喜您完成 msProbe 快速入门体验,您已掌握 msProbe 的基础使用方法。如需深入了解其功能用法,请参考:
3. 附录 A:内网环境无公网访问权限的应对方案¶
3.1 Docker 镜像在隔离内网的获取方法¶
方案一:配置 Docker 代理直接拉取
适用于大多数 Linux 发行版且 Docker 版本 ≥ 18.0 的环境(不保证所有场景兼容)。若遇异常,请结合实际情况调整。
编辑 Docker 服务代理配置文件 /etc/systemd/system/docker.service.d/http-proxy.conf,内容示例如下(请根据实际环境替换用户名、密码、代理地址及端口):
[Service]
Environment="HTTP_PROXY=http://username:password@proxy.example.com:8080"
Environment="HTTPS_PROXY=http://username:password@proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
保存后重载并重启 Docker 服务:
随后即可正常执行 docker pull。
方案二:离线导入 CANN 镜像
如果代理方案不可行,请先在内网 NPU 服务器上执行 第 2.1.2 节,并记录 MY_STUDY_VAR_CANN_IMAGE 的完整值。然后登录一台具备公网访问能力且 CPU 架构相同的中转机,将下方 CANN_IMAGE 的值替换为刚才记录的镜像地址并执行命令:
将 cann.tar 通过 U 盘等方式传输至内网服务器后,在内网服务器执行以下命令加载:
加载完成后,继续完成 第 3.2 节,再返回 第 2.1.5 节 启动容器。如果已切换宿主机 Shell,请重新执行第 2.1.2 节中的命令以恢复镜像环境变量。
3.2 传输容器启动脚本¶
在可访问当前网页的浏览器中输入如下链接,下载 ctr_in.py 脚本文件,并将其手动复制至内网服务器的 ~/ 目录:
复制完成后,在内网服务器的宿主机上执行:
确认 ctr_in.py 存在且具有执行权限后,返回 第 2.1.5 节 启动容器。
3.3 离线安装 Python 依赖¶
优先使用内网 pip 源安装依赖。若没有可用的内网软件源,请在具备公网访问能力、与内网 NPU 服务器的 CPU 架构和 Python 版本均相同的中转环境中,按以下方式下载所需安装包:
将 offline_wheels 目录传输到内网服务器并复制到容器的用户主目录,然后在容器内执行:
安装完成后,返回 第 2.1.7 节 执行验证命令,无需再次执行联网安装命令。
4. 附录 B:在 GPU 环境下训练模型并采集数据¶
若需自行采集,请确保 GPU 环境已安装与 NPU 环境版本一致的 PyTorch,并安装 msProbe:
在 GPU 环境执行以下命令创建采集配置:
cat > ~/config.json << EOF
{
"task": "statistics",
"dump_path": "${HOME}/msprobe_dump_gpu",
"rank": [],
"step": [0, 1],
"level": "mix",
"async_dump": false,
"statistics": {
"scope": [],
"list": [],
"data_mode": ["all"],
"summary_mode": "statistics"
}
}
EOF
参照 第 2.2.2 节 将训练代码写入 ~/precision_sample.py,随后启动训练与数据采集:
采集完成后,执行以下命令打包数据,以便传输至 NPU 容器:
5. 常见问题(FAQ)¶
5.1 退出容器后如何重新进入?¶
在宿主机上选择以下任一方法重新进入容器:
方法一(推荐):使用容器启动脚本
根据提示选择目标容器;若仅有一个可进入的容器,脚本会自动进入该容器。
方法二:使用 Docker 原生命令
请将 alice_YYMMDD_HHMMSS 替换为实际容器名称。可先执行 docker ps 查看正在运行的容器及其名称。
5.2 执行 Docker 命令时提示 permission denied 如何处理?¶
当前用户可能未加入 Docker 用户组。可使用 root 权限在宿主机执行:
执行后需退出当前用户会话并重新登录,或执行以下命令使用户组变更立即生效:
完成后执行 docker ps 验证 Docker 命令是否可正常使用。不建议以 root 用户身份进行日常操作。Docker 用户组具有较高的系统权限,请仅将可信用户加入该用户组。
5.3 TensorBoard 端口被防火墙拦截时如何访问?¶
当服务器防火墙限制直接访问 TensorBoard 端口时,可使用 VS Code 端口转发 或 SSH 本地端口转发。这两种方式仅需 SSH 端口连通,无需额外开放 6006 端口。
方法一:VS Code 端口转发(推荐)¶
若已使用 VS Code Remote-SSH 连接服务器,可通过图形化界面快速完成端口映射:
-
中止上面启动的 TensorBoard 进程,改为在 VS Code 远程终端中启动 TensorBoard:
-
VS Code 通常会自动检测终端中的端口监听信息并在右下角弹出提示,直接点击链接即可访问;
- 若没有弹出提示,也可以点击 VS Code 底部面板的 “端口 (Ports)” 选项卡,选择 “转发端口”,输入
6006并确认; - 转发成功后,点击列表中生成的 “本地地址” 链接(如
http://localhost:6006),即可在本地浏览器中直接访问。
方法二:SSH 命令行端口转发¶
若未使用 VS Code,可通过原生 SSH 命令建立隧道:
-
在本地终端(Windows PowerShell / CMD / Linux / macOS)执行以下命令,按提示输入密码:
请将
your_username和192.168.1.1替换为实际的用户名和服务器 IP,并保持该 SSH 会话处于连接状态。 -
在本地浏览器中打开:

