CANN runtime 维测功能组件在故障定位与性能剖析中的应用
CANN runtime 的维测功能组件(adump、msprof、log)构成了一个立体化、多层次的可观测性体系。它不仅支持传统的日志记录,更通过精准数据 Dump、硬件级性能采样、设备状态直连等手段,将“黑盒”AI加速过程变为“白盒”。这种设计极大降低了开发者在复杂异构环境下的调试成本,尤其在大模型、多卡训练等高价值场景中,其价值尤为凸显。
前言
CANN(Compute Architecture for Neural Networks)作为一套面向 AI 加速硬件的全栈异构计算平台,其 runtime 层不仅承担任务调度、内存管理、设备控制等核心职责,还集成了强大的维测功能组件(Diagnostics and Measurement Components)。这些组件为开发者提供了从模型精度异常、算子崩溃到系统级性能瓶颈的端到端可观测能力,是保障 AI 应用稳定高效运行的关键基础设施。
一、维测功能组件的整体架构与定位
根据 runtime/README.md 的描述,维测功能组件包含以下三个核心子系统:
- adump:提供单算子或整网模型的输入/输出数据 Dump 能力,用于精度比对与异常定位;
- msprof:性能调优工具,采集 AI 任务执行过程中的关键性能指标(如指令周期、内存带宽、Cache 命中率);
- log:日志记录与设备侧状态导出模块,包含
msnpureport命令行工具,支持查询设备日志、错误码、寄存器状态等。
这些模块均以内嵌形式集成于 runtime 核心库中,并通过统一的配置接口(如环境变量、API 参数)激活,无需修改用户业务代码即可启用。
注:尽管维测功能依赖底层驱动支持,但本文聚焦于 runtime 仓库自身实现,不涉及 driver 层细节。
二、adump:精度问题的“显微镜”
当 AI 模型在目标硬件上出现精度下降或数值异常时,adump 模块可精确捕获指定算子或整个网络的中间张量数据,供开发者与 CPU/GPU 参考结果进行比对。
2.1 触发机制与配置方式
adump 支持两种触发模式:
- 主动 Dump:通过 API 或配置文件指定要 Dump 的算子名称、Tensor 名称;
- 异常 Dump:当 runtime 捕获到硬件异常(如非法地址访问、浮点溢出)时,自动 Dump 异常算子的输入/输出及 Workspace 数据。
配置主要通过环境变量完成:
export ASCEND_SLOG_PRINT_TO_STDOUT=1
export DUMP_MODE="all" # all / specific
export DUMP_OP_NAME="MatMul_0" # 若为 specific 模式
export DUMP_PATH="/home/user/dump"
2.2 数据格式与存储结构
Dump 数据以 Protobuf + NPY 混合格式存储,兼顾结构化元信息与高效数值存储:
dump/
├── model_name/
│ ├── graph_0/
│ │ ├── op_MatMul_0/
│ │ │ ├── input_0.npy
│ │ │ ├── output_0.npy
│ │ │ └── tiling_info.pb
│ │ └── ...
│ └── dump_config.json
其中 tiling_info.pb 记录了算子分块(Tiling)策略,对理解 NPU 上的执行逻辑至关重要。
2.3 源码实现:拦截算子执行路径
adump 的核心在于在算子 Kernel 执行前后插入 Dump 钩子。相关代码位于 src/dfx/adump/ 目录。
以 AdumpManager::DumpTensor() 为例:
// src/dfx/adump/adump_manager.cpp
Status AdumpManager::DumpTensor(const std::string& op_name,
const std::string& tensor_name,
const void* data, size_t size,
const TensorDesc& desc) {
if (!IsDumpEnabled(op_name)) return SUCCESS;
// 构造文件路径
std::string filepath = GetDumpPath() + "/" + op_name + "/" + tensor_name + ".npy";
// 将 data 转换为 NPY 格式并写入
NpyWriter writer(filepath);
RETURN_IF_ERROR(writer.Write(data, desc.shape, desc.data_type));
// 记录元信息到日志
LOG(INFO) << "Dumped tensor " << tensor_name << " of op " << op_name;
return SUCCESS;
}
该函数由 runtime 在 aclnnLaunchOp 等算子调度接口中调用,确保在 Kernel 启动前 Dump 输入,在回调完成后 Dump 输出。
最新提交(2026年1月)优化了 Dump 文件的 I/O 性能,避免大模型场景下磁盘写入成为瓶颈。
三、msprof:性能剖析的“雷达系统”
msprof 是 CANN runtime 提供的性能剖析工具,支持对 AI 任务进行全栈性能数据采集,涵盖 Host 侧(CPU)、Device 侧(NPU)以及通信链路。
3.1 三层性能数据模型
msprof 定义了清晰的性能事件层级:
| 层级 | 内容 | 采集方式 |
|---|---|---|
| Host Layer | Python/PyTorch 调用栈、API 耗时 | 插桩(Instrumentation) |
| Runtime Layer | 内存分配、流同步、任务提交延迟 | runtime 内部计时器 |
| Device Layer | AI Core 指令周期、L2 Cache 命中率、DDR 带宽 | 硬件性能计数器(PMU) |
3.2 动态剖析(Dynamic Profiling)流程
msprof 支持“运行时开启/关闭”的动态剖析模式,适用于长时间训练任务:
# 启动剖析服务
msprof --dynamic start
# 运行业务程序
python train.py
# 停止剖析并生成报告
msprof --dynamic stop --output ./profile_data
其内部通过 Unix Domain Socket 与 runtime 中的 Profiler Daemon 通信。
3.3 性能事件注册与采样
关键代码位于 src/dfx/msprof/。性能事件通过 MsprofRegisterEvent() 注册:
// src/dfx/msprof/profiler_api.cpp
void MsprofRegisterEvent(const char* event_name, MsprofEventType type) {
auto& profiler = MsprofCore::GetInstance();
profiler.RegisterEvent(event_name, type);
}
// 在算子执行前后插入事件
void LaunchOpWithProfiling(...) {
MsprofBeginEvent("MatMul_0");
aclrtLaunchKernel(...);
MsprofEndEvent("MatMul_0");
}
对于 Device 层事件,runtime 通过 ioctl 向驱动请求启动 PMU 采样,采样数据以环形缓冲区形式返回。
3.4 报告生成与可视化
采集结束后,msprof analyze 命令将原始数据转换为多种格式:
- JSON:供自动化分析脚本使用;
- HTML Trace Viewer:类似 Chrome DevTools 的时间线视图;
- Flame Graph:展示函数调用栈的 CPU/NPU 时间分布。
2025 年底的 PR #380 新增了对 多设备同步时间戳 的支持,确保多卡训练场景下的事件对齐。
四、log 与 msnpureport:设备状态的“黑匣子”
当系统发生严重故障(如设备挂死、驱动崩溃)时,常规日志可能无法获取。log 模块结合 msnpureport 工具,提供了从设备固件层提取关键状态的能力。
4.1 日志分级与输出控制
runtime 日志采用五级分类(DEBUG/INFO/WARNING/ERROR/FATAL),通过环境变量控制输出:
export ASCEND_GLOBAL_LOG_LEVEL=3 # 3=WARNING, 仅输出警告及以上
export ASCEND_SLOG_PRINT_TO_STDOUT=1 # 同时输出到 stdout
日志内容包含:
- API 调用参数与返回码;
- 内存分配/释放记录;
- 流(Stream)与事件(Event)状态变更;
- 驱动交互错误码。
4.2 msnpureport:设备侧状态导出
msnpureport 是一个独立命令行工具,位于 src/dfx/log/msnpureport/,可直接与设备固件通信:
# 导出设备0的全部日志
msnpureport -g -d 0 > device0.log
# 查询设备健康状态
msnpureport -q health -d 0
# 获取最后发生的错误码
msnpureport -q error_code -d 0
其底层通过 /dev/davinciX 的特殊 ioctl 命令(如 DRIVER_CMD_GET_FW_LOG)读取固件日志缓冲区。
4.3 错误码映射与根因分析
runtime 维护了一套完整的错误码映射表(src/include/acl/acl_base.h):
// 常见错误码示例
#define ACL_ERROR_RT_AICORE_OVERFLOW (-1073741823) // AI Core 浮点溢出
#define ACL_ERROR_RT_MEMORY_ALLOCATION (-1073741822) // 内存分配失败
#define ACL_ERROR_DRV_DEVICE_LOST (-1073741821) // 设备丢失(可能过热或掉电)
当应用捕获到 aclError 时,可结合 msnpureport 输出的设备日志,快速定位是软件配置错误还是硬件异常。
五、维测组件的协同工作流程
在实际故障排查中,三大组件往往协同使用。以下是一个典型场景:
问题:某 Transformer 模型在推理时偶发输出全零。
排查步骤:
- 启用 adump,Dump 异常样本对应的 Attention 算子输入/输出;
- 发现某次 MatMul 输出全为 Inf,怀疑数值溢出;
- 使用 msprof 采集该批次的性能数据,确认无硬件 stall;
- 检查 runtime 日志,发现
ACL_ERROR_RT_AICORE_OVERFLOW错误; - 运行
msnpureport -q error_code,确认设备侧记录相同错误码; - 结论:模型权重或输入数据存在极端值,需在预处理阶段增加裁剪。
此流程体现了 CANN 维测体系“数据驱动、层层下钻”的设计理念。
六、本地验证与 UT 测试机制
runtime 仓库提供了完整的单元测试(UT)框架,验证维测功能正确性。
例如,adump 的 UT 用例位于 tests/ut/dfx/adump/:
// tests/ut/dfx/adump/adump_test.cpp
TEST_F(AdumpTest, DumpTensorSuccess) {
SetEnv("DUMP_MODE", "specific");
SetEnv("DUMP_OP_NAME", "TestOp");
SetEnv("DUMP_PATH", "/tmp/test_dump");
// 模拟算子执行
void* data = malloc(1024);
AdumpManager::GetInstance().DumpTensor("TestOp", "input_0", data, 1024, desc);
// 验证文件是否存在
EXPECT_TRUE(FileExists("/tmp/test_dump/TestOp/input_0.npy"));
free(data);
}
msprof 的 UT 则通过 Mock Profiler Daemon 验证事件注册与时间戳精度。
2026 年初的提交优化了 UT 的覆盖率统计,确保维测路径被充分测试。
七、总结
CANN runtime 的维测功能组件(adump、msprof、log)构成了一个立体化、多层次的可观测性体系。它不仅支持传统的日志记录,更通过精准数据 Dump、硬件级性能采样、设备状态直连等手段,将“黑盒”AI加速过程变为“白盒”。这种设计极大降低了开发者在复杂异构环境下的调试成本,尤其在大模型、多卡训练等高价值场景中,其价值尤为凸显。
随着 CANN 生态的持续演进,维测组件将进一步融合 AI 编译器(GE)的图优化信息、支持更细粒度的 Tile 级性能剖析,并探索与云原生日志系统(如 Prometheus + Grafana)的集成,为 AI 应用的稳定高效运行保驾护航。
相关链接:
- CANN 组织主页:https://atomgit.com/cann
- runtime 仓库地址:https://atomgit.com/cann/runtime
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐


所有评论(0)