已合并
refactor: remove LSTM.forward monkey-patch #43893
refactor: remove LSTM.forward monkey-patch #43893
已合并
ymdsall创建于 8月6日
ymdsall
ymdsall成员
8月6日

【合入来源】

如有社区issue,请关联issue链接
请勿携带内部流程信息(需求链接、问题单、内部issue等)

RFC:https://gitcode.com/Ascend/pytorch/issues/3810

前置依赖:https://gitcode.com/Ascend/op-plugin/merge_requests/5761

op-plugin 修改进入 PTA 官方基线后,本 PR 才能合入。

【修改方案】

  1. 删除 torch_npu/utils/_module.py 中复制自 PyTorch 官方实现的 _lstm_forward。
  2. 删除 _apply_module_patch() 中对 torch.nn.modules.rnn.LSTM.forward 的 monkey patch 注册。
  3. torch.nn.LSTM.forward 恢复使用 PyTorch 官方 torch.nn.modules.rnn.LSTM.forward。
  4. PackedSequence LSTM 的后端适配由前置 op-plugin PR 负责:
    • ACLop fallback 保持 CPU batch_sizes,由 ACLop 内部完成 packed 输出二维 reshape;
    • ACLNN 主路径将 batch_sizes 迁移至 packed data 所在设备,并在返回时完成 packed 输出二维 reshape。
  5. 不修改 PyTorch 官方代码、dense LSTM 计算逻辑或 third_party/op-plugin 子模块指针。

调用路径:

torch.nn.LSTM
    ↓
PyTorch torch.nn.modules.rnn.LSTM.forward
    ↓
torch._VF.lstm / aten::lstm
    ↓
op-plugin packed LSTM adapter

【资料变更】

不涉及。

【接口变更】

不涉及。

【功能验证】

官方实现来源

导入 torch_npu 后确认:

torch.nn.LSTM.forward.__module__:torch.nn.modules.rnn
源码文件:torch/nn/modules/rnn.py
torch_npu.utils._module._lstm_forward:不存在

迁移行为 A/B

使用相同脚本、随机种子、模型参数和输入数据,对保留 Python patch 与删除 patch 后的环境进行比较。

覆盖 16 个 packed 场景、4 个 dense 场景和 4 个 packed 3/4 层既有能力边界:

总场景数:24
支持场景:20,两个环境均成功且逐元素完全一致
既有能力边界:4,两个环境均失败
支持场景 output/h_n/c_n 最大绝对差:0
NPU 与 CPU 最大绝对误差:1.1920929e-7

packed 3/4 层场景的失败范围保持不变;异常类型和错误信息不作为等价性结论。

确定性与 Profiling

固定随机种子 20260813,启用确定性算法,使用 eval() 和 dropout=0。16 个 packed 场景和 4 个 dense 场景分别重复 5 次。

保留 patch 环境进程内一致:20/20
删除 patch 环境进程内一致:20/20
两个环境逐元素一致:20/20
output/h_n/c_n 最大绝对差:0
三类输出 SHA-256 一致:20/20

FP32 单层 packed LSTM 主路径在两个环境中的关键 Profiler 事件一致,均调用 aclnnLSTM 和 aclnnStack。删除 Python patch 后不再出现 patch 引入的 aten::item、aten::_local_scalar_dense,没有新增计算事件。

前置 op-plugin 路径验证

使用包含前置 PR 的构建库验证:

  • jit_compile=True 的 ACLop 直调通过,CPU batch_sizes 保持 CPU,输出 [15, 6],可执行 pad_packed_sequence;
  • ACLNN 主路径调用 aclnnLSTM;
  • 参数数量、BF16、混合 dtype fallback 均调用 npu_lstm_data;
  • 隐藏 aclnnLSTM 符号后,兼容 fallback 调用 npu_lstm_data;
  • 上述路径输出均为 [15, 6]。

LSTM 定向回归:

Ran 9 tests in 7.629s
OK

本 PR 只删除 monkey patch,不新增或修改测试文件;专项验证代码和日志不随 PR 提交。

【CheckList】

PR提交人对以下CheckList自检项进行全量自检,自检通过或不涉及,均修改 [ ] 为 [x]

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 ymdsall 的贡献)
ymdsallymdsall成员
8月6日 创建了 pull request,commit 64608b86
atomgit-bot
atomgit-bot
8月6日 评论:

变更摘要

此 PR 是一次重构优化,旨在移除 torch_npu 中对 torch.nn.modules.rnn.LSTM.forward 的 monkey-patch,让 NPU 设备上的 LSTM 恢复使用 PyTorch 官方的 LSTM.forward 实现。删除了 torch_npu/utils/_module.py 中复制自 PyTorch 官方的 _lstm_forward 函数(约 140 行),以及 _apply_module_patch() 中对应的 patch 注册语句。PackedSequence LSTM 所需的 NPU 适配(如 batch_sizes 设备迁移和 packed 输出形状恢复)已由前置 op-plugin PR 在算子接入层完成,因此本 PR 不再需要在模块层做 monkey-patch。

主要改动

  • 删除 _lstm_forward 函数:从 torch_npu/utils/_module.py 中移除了整个 _lstm_forward 函数定义(原第 184–328 行),该函数是对 PyTorch 官方 LSTM.forward 的副本,包含对 PackedSequence 输入的特殊处理逻辑(如 batch_sizes 设备迁移、输出形状恢复等)。
  • 移除 monkey-patch 注册:在 _apply_module_patch() 函数中删除了 torch.nn.modules.rnn.LSTM.forward = _lstm_forward 这一行,使 LSTM.forward 不再被替换为自定义实现。
  • 调用路径简化:删除 patch 后,torch.nn.LSTM 的调用路径恢复为标准链路——经 PyTorch 官方 LSTM.forward → torch._VF.lstm / aten::lstm → op-plugin 算子接入层,NPU 适配完全由 op-plugin 在底层处理。
likedislike
不准确?
atomgit-bot
atomgit-bot
8月6日 评论:

代码审查

✅ 未发现问题

likedislike
不准确?
ascend-robotascend-robot成员
8月6日 添加了label:ascend-cla/yes
此处折叠了87条消息 查看更多
ascend-robotascend-robot成员
8月28日 合入了pull request
ascend-robot
ascend-robot成员
8月28日 评论:

In response to this:

/sync v2.12.0 v2.11.0 v2.10.0 v2.9.0 v2.7.1 v2.7.1-26.1.0 v2.11.0-26.1.0 v2.12.0-26.1.0 v2.10.0-26.1.0 v2.9.0-26.1.0 ci-test

@qq_53278473

同步操作执行结果:

Branch Status Pull Request
v2.12.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.11.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.10.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.9.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.7.1 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.7.1-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.11.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.12.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.10.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.9.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
ci-test 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
likedislike
ymdsall
ymdsall成员
8月28日 评论:

/sync v2.12.0 v2.11.0 v2.10.0 v2.9.0 v2.7.1 v2.7.1-26.1.0 v2.11.0-26.1.0 v2.12.0-26.1.0 v2.10.0-26.1.0 v2.9.0-26.1.0 ci-test

likedislike
AtlasAccount
AtlasAccount成员
8月28日 评论:
流水线 pytorch_gitcode_PR_multiVersion#14639 [ commitID:863887e6 ] 已完成
likedislike
ascend-robot
ascend-robot成员
8月28日 评论:

In response to this:

/sync v2.12.0 v2.11.0 v2.10.0 v2.9.0 v2.7.1 v2.7.1-26.1.0 v2.11.0-26.1.0 v2.12.0-26.1.0 v2.10.0-26.1.0 v2.9.0-26.1.0 ci-test

@qq_53278473

同步操作执行结果:

Branch Status Pull Request
v2.12.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.11.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.10.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.9.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.7.1 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.7.1-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.11.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.12.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.10.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
v2.9.0-26.1.0 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
ci-test 同步失败:请手动创建 PR 进行同步,我们会继续完善分支之间同步操作,尽量避免同步失败的情况
likedislike