已开启
[Feature]: torch_npu 多版本兼容(COMPAT)贡献指南和检查工具 #4424
li_jing_hw创建于 21 天前
21 天前 添加了label:feature
21 天前 添加了label:triage-review
TorchNPU-Bot
21 天前 评论:
21 天前 评论:
issue待分派,添加triage-review标签


21 天前 关联了pull request:Add tools to check version compatibility
21 天前 添加了label:bot-triaged;删除了label:triage-review
TorchNPU-Bot
21 天前 评论:
21 天前 评论:
检测到当前 issue 已关联 PR,自动添加标签:bot-triaged


提交提案之前,请先检索仓库内是否已有相同的提案,如已有请在同一提案中进行讨论。
💻 需求背景、当前现状、期望实现的功能内容、具体的设计方案、以及测试方案
torch_npu 多版本兼容(COMPAT)贡献指南
本RFC涉及文档和工具。背景如下:
1. 背景与总体原则
torch_npu 用一个代码分支同时支持多个上游 PyTorch 版本(当前支持下限 2.13)。为了让业务代码不散落版本判断,所有版本差异都被隔离在统一的「兼容适配层」:
torch_npu/_compat/下的包装函数,运行时读取torch.__version__判断;torch_npu/csrc/_compat/下的头文件与编译期宏,构建时读取TORCH_VERSION_MAJOR / TORCH_VERSION_MINOR判断。核心原则:业务代码优先调用_compat层提供的统一接口/符号,不写版本判断。 版本差异只存在于
_compat层内。2. Python 侧方案
Python 兼容点都遵循「包装函数 + 运行时 if」模式:
_compat的某个模块里新增一个包装函数;if CURRENT_VERSION >= (X, Y)走新/旧 API;from torch_npu._compat.xxx import 包装函数并调用,不感知版本。示例(
utils.make_config_entry):flowchart TD ROOT["业务代码调用<br/>make_config_entry(config, name='npu_backend')"] V["version.py<br/>CURRENT_VERSION = _parse(torch.__version__)"] D{"CURRENT_VERSION >= (2,12)?"} D -- "是" --> B1["_ConfigEntry(config, name=name)<br/>新签名"] D -- "否" --> B2["_ConfigEntry(config)<br/>旧签名,不传 name"] B1 --> UPNEW["上游 PyTorch >= 2.12<br/>_ConfigEntry.__init__ 带 name 参数"] B2 --> UPOLD["上游 PyTorch 2.10 / 2.11<br/>_ConfigEntry.__init__ 无 name 参数"] ROOT --> D V -. 提供版本号 .-> DPython 侧标注规范(写在每个兼容块上方):
# COMPAT(>= 2.12): 上游 _ConfigEntry.__init__ 增加必填 name 参数 # CAN REMOVE when MIN_SUPPORTED >= (2, 12): 直接构造 _ConfigEntry(config, name=name) def make_config_entry(config, *, name: str): from torch.utils._config_module import _ConfigEntry if CURRENT_VERSION >= (2, 12): return _ConfigEntry(config, name=name) return _ConfigEntry(config) # 旧版本没有 name 参数4. C++ 侧方案
C++ 兼容点遵循「头文件 + 编译期宏」模式:
#include <torch_npu/csrc/_compat/version.h>;_compat头文件里用#if TORCH_NPU_VERSION_GE(X, Y)分出新旧实现示例(
autograd.h的GradFnPtr,省略号表示中间有make_grad_fn等 helper):flowchart TD ROOT["业务代码 include<br/>torch_npu/csrc/_compat/autograd.h"] V["version.h<br/>TORCH_NPU_VERSION_GE(MAJOR, MINOR)<br/>基于 <torch/version.h>"] D{"TORCH_NPU_VERSION_GE(2, 13)?"} D -- "1(是)" --> B1["GradFnPtr = c10::intrusive_ptr<T><br/>make_grad_fn = c10::make_intrusive<Op>(...)"] D -- "0(否)" --> B2["GradFnPtr = std::shared_ptr<T><br/>make_grad_fn = shared_ptr<Op>(new Op, deleteNode)"] B1 --> UPNEW["上游 PyTorch >= 2.13<br/>grad_fn 改 intrusive_ptr(上游 #181782)"] B2 --> UPOLD["上游 PyTorch <= 2.12<br/>grad_fn 用 shared_ptr + deleteNode"] ROOT --> D V -. 编译期提供宏 .-> DC++ 侧标注规范:
// COMPAT(>= 2.13): grad_fn 从 shared_ptr 迁移到 c10::intrusive_ptr(上游 #181782) // CAN REMOVE the version branches below when MIN_SUPPORTED >= (2, 13) #if TORCH_NPU_VERSION_GE(2, 13) template <typename T> using GradFnPtr = c10::intrusive_ptr<T>; #else template <typename T> using GradFnPtr = std::shared_ptr<T>; #endif5. 新增一个兼容点的流程
X.Y、影响哪些 API/符号;_compat对应模块加包装函数(或改现有函数),内部if CURRENT_VERSION >= (X, Y);_compat对应头文件加#if TORCH_NPU_VERSION_GE(X, Y)条件编译宏;tools/check_compat.py,确保没有引入过期块。(本提交涉及的工具)替代方案
补充说明
欢迎加入社区,感谢您对社区的贡献 🎉!