已关闭
【26.2.0众测】GuardFilter无法消除GRAD_MODE/DETERMINISTIC_ALGORITHMS类重编译:运行时状态校验走C层GlobalStateGuard,不经过guard_filter_fn通道 #4833
GMOW创建于  9月15日关闭于  1 天前
GMOW
GMOW
9月15日 创建

标题:【26.2.0众测】Guard Filter无法消除GRAD_MODE/DETERMINISTIC_ALGORITHMS类重编译:运行时状态校验走C层GlobalStateGuard,不经过guard_filter_fn通道

建议标签:文档 / torch.compile / guard

环境信息

项 值
硬件 Atlas 800T A2(Ascend 910B3)
CANN 9.1.0
PyTorch 2.9.0(Guard Filter 文档要求 ≥ 2.9.0,已满足)
torch_npu 2.9.0.post6(TorchNPU 26.1.0 配套)
Python 3.11.15

问题描述

按官方文档《Guard Filter》示例2(过滤运行时状态 guard)的写法,编译模型后交替切换
torch.no_grad() / torch.enable_grad(),或翻转 torch.use_deterministic_algorithms(),
重编译仍然发生,guard_filter_fn 过滤集无效。而文档示例2的注释明确写着
"切换grad mode不会触发重编译",与实测不符。

复现步骤

import torch
import torch_npu
import torch._dynamo as dynamo

model = resnet18().npu().eval()          # TorchBench 清单模型
x = torch.randn(8, 3, 224, 224, device="npu")

_RUNTIME_STATE_GUARD_TYPES = frozenset({
    "GRAD_MODE", "TORCH_FUNCTION_STATE", "GLOBAL_STATE",
    "DEFAULT_DEVICE", "DETERMINISTIC_ALGORITHMS", "AUTOCAST_STATE",
    "FSDP_TRAINING_STATE",
})

def filter_runtime_state_guards(entries):
    return [e.guard_type not in _RUNTIME_STATE_GUARD_TYPES for e in entries]

compiled = torch.compile(model, options={"guard_filter_fn": filter_runtime_state_guards})
with torch.no_grad():
    compiled(x)
g1 = dynamo.utils.counters["stats"]["unique_graphs"]   # = 1

torch.use_deterministic_algorithms(True)   # 翻转运行时状态
with torch.no_grad():
    compiled(x)
g2 = dynamo.utils.counters["stats"]["unique_graphs"]   # = 2,仍然重编译!

TORCH_LOGS=recompiles 显示触发原因:

[__recompiles] triggered by the following guard failure(s):
[__recompiles]  - 0/0: GLOBAL_STATE changed: deterministic_algorithms

根因分析

PyTorch 2.9.0 源码中,运行时状态(grad_mode、deterministic_algorithms 等)的实际校验
在 C++ 层 GlobalStateGuard 完成,且 Python 层的 guard 条目生成被显式短路:

# torch/_dynamo/guards.py:2432
def GRAD_MODE(self, guard: Guard) -> None:
    pass  # we always guard on this via GlobalStateGuard()

即:guard_filter_fn 通道收到的 guard 条目列表中根本不包含运行时状态类条目
(filter 回调收到的 59 条 guard 中有 GRAD_MODE 类型,但其校验语义由 C 层独立执行),
丢弃 Python 层条目不影响 C 层 GlobalStateGuard 的检查,重编译无法通过
guard_filter_fn 消除。

对照组(Guard Filter 其他示例均有效,证明通道本身工作正常)

示例 触发器 过滤结果
示例1(dict guard) KV-cache 式 dict 内值 None↔tensor 切换 扩展过滤集后 PASS(图数 1→1)
示例3(组合过滤) 可选参数 None↔tensor 交替 扩展过滤集后 PASS
示例4(按名过滤) mask=None ↔ mask=tensor PASS
示例5(全局变量) 模块级全局变量修改 PASS
示例2(运行时状态) grad_mode / deterministic_algorithms 翻转 FAIL(本 issue)

另附发现:文档示例1的 DICT_* 过滤集在实际场景中也需要扩展——dict 读取被常量特化后,
实际失效的 guard 是 dict 内值的 None 检查(CONSTANT_MATCH,name=attn['mask']),
不在 DICT_VERSION/DICT_KEYS 集合内。按文档过滤集原样使用无法消除重编译,
需用 TORCH_LOGS=recompiles 定位真实失效类型后针对性构造 filter。

影响

  • 文档示例2宣称的效果("切换grad mode不会触发重编译")在 2.9.0 上无法实现
  • HuggingFace 等推理管线中 prefill/decode 交替(past_key_values=None ↔ tuple、
    attention_mask=None ↔ Tensor)正是文档描述的目标场景,此类重编译在真实业务中高频发生

期望

  1. 推动 Dynamo 将 GlobalStateGuard 的检查纳入 guard_filter_fn 通道
    (或提供显式开关允许用户在明确知情的前提下跳过 C 层全局状态校验)
  2. 文档先行:在《Guard Filter》示例2中注明当前版本的限制,避免用户按文档操作后
    得出"Guard Filter 无效"的错误结论

证明材料

运行结果截图(下图为 PR #38 配套材料中的运行终端输出,可直接点击查看):

本 issue 截图(重编译未消除的证据):

运行时状态guard:过滤后重编译仍发生

对照组截图(Guard Filter 通道本身有效,重编译可被消除——证明问题不在用法而在
C 层 GlobalStateGuard 机制):

对照组:dict类guard过滤后重编译消除PASS

提交 issue 时请将上述两张图作为附件上传(02 图含 [阶段A|未过滤] 图数 1→2 与
[阶段B|已过滤] 图数 1→2 的对比输出;01 图为过滤后 图数 1→1 的 PASS 对照)。

完整终端日志:补充-测试报告与原始日志/原始日志/02_过滤运行时状态guard.log(本 issue)、
补充-测试报告与原始日志/原始日志/01_过滤字典版本guard.log(对照组)

likedislike
TorchNPU-BotTorchNPU-Bot成员
9月15日 添加了label:triage-review
TorchNPU-Bot
TorchNPU-Bot成员
9月15日 评论:

issue待分派,添加triage-review标签

likedislike
GMOWGMOW
9月15日 修改标题为 “【26.1.0众测】GuardFilter无法消除GRAD_MODE/DETERMINISTIC_ALGORITHMS类重编译:运行时状态校验走C层GlobalStateGuard,不经过guard_filter_fn通道”,原标题为“【26.2.0众测】GuardFilter无法消除GRAD_MODE/DETERMINISTIC_ALGORITHMS类重编译:运行时状态校验走C层GlobalStateGuard,不经过guard_filter_fn通道”
GMOWGMOW
9月15日 修改了issue 的描述
TorchNPU-BotTorchNPU-Bot成员
9月15日 添加了label:bot-triaged;删除了label:triage-review
TorchNPU-Bot
TorchNPU-Bot成员
9月15日 评论:

检测到当前 issue 已关联 PR,自动添加标签:bot-triaged

likedislike
GMOWGMOW
25 天前 修改标题为 “【26.2.0众测】GuardFilter无法消除GRAD_MODE/DETERMINISTIC_ALGORITHMS类重编译:运行时状态校验走C层GlobalStateGuard,不经过guard_filter_fn通道”,原标题为“【26.1.0众测】GuardFilter无法消除GRAD_MODE/DETERMINISTIC_ALGORITHMS类重编译:运行时状态校验走C层GlobalStateGuard,不经过guard_filter_fn通道”
GMOWGMOW
25 天前 修改了issue 的描述
TorchNPU-BotTorchNPU-Bot成员
25 天前 添加了label:help-wanted
TorchNPU-Bot
TorchNPU-Bot成员
25 天前 评论:

检测到社区任务相关 issue,自动添加标签:help-wanted

likedislike
GMOWGMOW
25 天前 修改了issue 的描述
GMOW
GMOW
22 天前 评论:

查重补充说明(2026-09-25):

本 issue 与以下同主题 issue 相关:

  • #4767(guard_filter_fn 无法过滤 GLOBAL_STATE guard,更早报告)
  • #4853 / #4856 / #4895 / #4996 / #5043 / #5059(后续同类报告)

本 issue 的独特增量(如有重复敬请合并,以下供汇总参考):

  1. 源码级定位:运行时状态校验走 C 层 GlobalStateGuard
    (torch/_dynamo/guards.py:2432 的 GRAD_MODE 分支为空实现,注释
    "we always guard on this via GlobalStateGuard()"),不经过
    guard_filter_fn 通道——解释了为何文档示例 2 的过滤集无效
  2. 对照组验证:dict 类/按名/全局变量 guard 过滤均有效(证明 filter 通道
    本身工作正常,问题仅限运行时状态类)
  3. 附带发现:文档示例 1 的 DICT_* 过滤集与实际失效 guard 类型
    (CONSTANT_MATCH,dict 内值的 None 检查)不匹配,需用
    TORCH_LOGS=recompiles 定位真实失效类型后针对性构造
likedislike
GMOWGMOW
3 天前 修改了issue 的描述
GMOWGMOW
3 天前 修改了issue 的描述
ascend-robotascend-robot成员
1 天前 关闭了 issue
ascend-robotascend-robot成员
1 天前 issue状态由 TODO 改变为 DONE
ascend-robotascend-robot成员
1 天前 添加了label:resolved