aoti-debug

aoti-debug

热门

排查与调试 AOTInductor (AOTI) 的错误与崩溃问题。当遇到 AOTI 段错误(segfault)、设备不匹配错误、常量加载失败,或者调用 aot_compile、aot_load、aoti_compile_and_package、aoti_load_package 触发运行时错误时使用。

10万Star
2.9万Fork
更新于 2026/8/5
SKILL.md
只读
名称
aoti-debug
描述

排查与调试 AOTInductor (AOTI) 的错误与崩溃问题。当遇到 AOTI 段错误(segfault)、设备不匹配错误、常量加载失败,或者调用 aot_compile、aot_load、aoti_compile_and_package、aoti_load_package 触发运行时错误时使用。

AOTI 调试指南

本 Skill 旨在帮助诊断和修复常见的 AOTInductor 问题。

错误类型路由

请检查报错信息,并跳转到对应的排查子指南:

Triton 索引越界 (Index Out of Bounds)

如果报错匹配以下模式:

Assertion `index out of bounds: 0 <= tmpN < ksM` failed

→ 请参考 triton-index-out-of-bounds.md 中的指南进行排查

所有其他错误

请继续阅读下方章节。


第一步:务必检查设备(Device)与 Shape 是否匹配

对于任何 AOTI 报错(段错误 segfault、异常、崩溃、输出不对),请务必优先检查以下几点:

  1. 编译设备 == 加载设备:模型加载时使用的设备类型,必须与编译时完全一致
  2. 输入设备一致:运行时传入的 input 必须与编译模型所在设备一致
  3. 输入 Shape 一致:运行时输入的 shape 必须与编译阶段一致(或者满足动态 shape 的约束条件)
# 编译阶段 - 注意观察设备与 shape
model = MyModel().eval()           # 使用什么设备?CPU 还是 .cuda()?
inp = torch.randn(2, 10)           # 设备是什么?shape 是什么?
compiled_so = torch._inductor.aot_compile(model, (inp,))

# 加载阶段 - 设备类型必须与编译时保持一致
loaded = torch._export.aot_load(compiled_so, "???")  # 必须与上面的模型/输入设备一致

# 推理阶段 - 设备与 shape 必须匹配
out = loaded(inp.to("???"))  # 必须与编译设备一致,shape 也必须匹配

只要上述任何一项不匹配,就可能引发从 segfault、各种异常崩溃,到输出结果不正确等一系列报错。

核心约束:设备类型匹配

AOTI 要求编译和加载必须使用相同的设备类型。

  • 如果在 CUDA 上编译,就必须在 CUDA 上加载(设备索引/序号可以不同,例如 cuda:0 和 cuda:1)
  • 如果在 CPU 上编译,就必须在 CPU 上加载
  • 暂不支持跨设备加载(例如在 GPU 上编译,然后尝试在 CPU 上加载)

常见错误模式

1. 设备不匹配导致的段错误 (Segfault)

症状:在调用 aot_load() 或执行模型推理时出现 segfault、抛出异常或直接崩溃。

典型报错示例

  • The specified pointer resides on host memory and is not registered with any CUDA device
  • AOTInductorModelBase 加载常量阶段直接崩溃
  • Expected out tensor to have device cuda:0, but got cpu instead

原因:编译阶段与加载阶段的设备类型不一致(请参考上方“第一步”)。

解决办法:确保编译和加载使用同一种设备类型。如果是 CPU 编译,就在 CPU 加载;如果是 CUDA 编译,就在 CUDA 加载。

2. 运行时输入设备不匹配

症状:模型执行期间抛出 RuntimeError

原因:运行时输入的设备类型与编译时的设备不一致(请参考上方“第一步”)。

更高效的调试方式:运行脚本时加上 AOTI_RUNTIME_CHECK_INPUTS=1 环境变量,获取更清晰的报错提示。该 Flag 会对包括设备类型、数据类型(dtype)、Size 和 Strides 在内的所有输入属性进行校验:

AOTI_RUNTIME_CHECK_INPUTS=1 python your_script.py

这样可以输出具有明确排查方向的报错:

Error: input_handles[0]: unmatched device type, expected: 0(cpu), but got: 1(cuda)

调试 CUDA 非法内存访问 (IMA) 错误

如果遇到 CUDA illegal memory access (IMA) 错误,请按以下步骤系统排查:

第 1 步:基础诊断排查

在深入分析前,先尝试开启以下调试环境变量:

AOTI_RUNTIME_CHECK_INPUTS=1
TORCHINDUCTOR_NAN_ASSERTS=1

这些 Flag 在编译期(代码生成 codegen 阶段)生效:

  • AOTI_RUNTIME_CHECK_INPUTS=1 会检查输入是否满足编译阶段设置的 Guard 约束
  • TORCHINDUCTOR_NAN_ASSERTS=1 会在每个 Kernel 执行前后插入检查 NaN 的 Codegen 代码

第 2 步:复现并定位 CUDA IMA 错误

CUDA IMA 错误往往具有偶发性/非确定性。开启以下变量可以确定性地复现报错:

PYTORCH_NO_CUDA_MEMORY_CACHING=1
CUDA_LAUNCH_BLOCKING=1

这些 Flag 在运行期生效:

  • PYTORCH_NO_CUDA_MEMORY_CACHING=1 会禁用 PyTorch 的内存缓存分配器(Caching Allocator)。该分配器默认会立刻申请比实际需求更大的 Buffer,也是造成 IMA 错误呈现非确定性的主要原因。
  • CUDA_LAUNCH_BLOCKING=1 会强行让 Kernel 单步同步发射。如果不加这个,因为 Kernel 是异步发射的,报错时往往只能拿到 "CUDA kernel errors might be asynchronously reported" 这类模糊警告。

第 3 步:使用中间值调试器定位出问题的 Kernel

通过开启 AOTI 中间值调试器(Intermediate Value Debugger)找出具体引发问题的 Kernel:

AOT_INDUCTOR_DEBUG_INTERMEDIATE_VALUE_PRINTER=3

这会在运行时逐个打印正在执行的 Kernel。结合前文设置的变量,即可看出在报错发生前刚好发射的是哪一个 Kernel。

如果想要进一步检查某个特定 Kernel 的输入参数:

AOT_INDUCTOR_FILTERED_KERNELS_TO_PRINT="triton_poi_fused_add_ge_logical_and_logical_or_lt_231,_add_position_embeddings_kernel_5" AOT_INDUCTOR_DEBUG_INTERMEDIATE_VALUE_PRINTER=2

若发现该 Kernel 的输入符合预期异常,请倒推排查生成该异常输入的上游 Kernel。

更多调试工具

日志与 Trace

  • tlparse / TORCH_TRACE:提供完整的输出代码,并记录运行时使用的 Guard
  • TORCH_LOGS:设置 TORCH_LOGS="+inductor,output_code" 可查看更多 PT2 内部日志
  • TORCH_SHOW_CPP_STACKTRACES:设为 1 可以输出更详细的 C++ 调用栈跟踪信息(Stack Traces)

常见踩坑点

  • 动态 Shape (Dynamic shapes):历史上是引发很多 IMA 错误的主要诱因。在调试动态 shape 场景时需要重点关注。
  • 自定义算子 (Custom ops):尤其是用 C++ 实现且支持动态 shape 的自定义算子。其 meta 函数可能需要进行 SymInt 化改写。

API 注意事项

已废弃的 API (Deprecated)

torch._export.aot_compile()  # 已废弃
torch._export.aot_load()     # 已废弃

当前推荐 API

torch._inductor.aoti_compile_and_package()
torch._inductor.aoti_load_package()

新版 API 会把设备元数据直接打进 Package 中,因此 aoti_load_package() 会自动加载到正确的设备类型上。你只能变更设备的索引序号(比如从 cuda:0 改为 cuda:1),但无法更改设备类型

环境变量汇总清单

环境变量 生效时机 作用/用途
AOTI_RUNTIME_CHECK_INPUTS=1 编译期 校验运行时输入是否符合编译阶段的 Guard 约束
TORCHINDUCTOR_NAN_ASSERTS=1 编译期 在 Kernel 执行前后添加 NaN 断言检查
PYTORCH_NO_CUDA_MEMORY_CACHING=1 运行期 禁用内存缓存分配器,使 IMA 报错可稳定复现
CUDA_LAUNCH_BLOCKING=1 运行期 强制同步发射 Kernel,精准定位报错位置
AOT_INDUCTOR_DEBUG_INTERMEDIATE_VALUE_PRINTER=3 编译期 运行时逐个打印 Kernel 执行序列
TORCH_LOGS="+inductor,output_code" 运行期 输出 PT2 内部日志及生成的 Output Code
TORCH_SHOW_CPP_STACKTRACES=1 运行期 显示详细的 C++ Stack Traces