排查与调试 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、异常、崩溃、输出不对),请务必优先检查以下几点:
- 编译设备 == 加载设备:模型加载时使用的设备类型,必须与编译时完全一致
- 输入设备一致:运行时传入的 input 必须与编译模型所在设备一致
- 输入 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 |






