已关闭
[RFC]: 支持非饱和模式场景溢出状态设置能力(FORCE_OVERFLOW_CHECK) #4374
wuyouqi1创建于 8月26日关闭于 8月27日
8月26日 添加了label:rfc
8月26日 关联了看板:FrameworkPTAdapter 版本issue看板
8月26日 添加了label:triage-review
TorchNPU-Bot
8月26日 评论:
8月26日 评论:
issue待分派,添加triage-review标签


8月26日 修改了issue 的描述
此处折叠了5条事件消息 查看更多
8月26日 添加了label:bot-triaged;删除了label:triage-review
TorchNPU-Bot
8月26日 评论:
8月26日 评论:
检测到当前 issue 已关联 PR,自动添加标签:bot-triaged


8月26日 关联了里程碑:v26.2.0
此处折叠了15条事件消息 查看更多
9月14日 关联了pull request:[sync] PR-46197: fix(test): skip float_status UTs on Ascend950
状态(Status): Reviewing
作者(Authors): @wuyouqi1
创建日期(Created): 2026-08-26
更新日期(Updated): 2026-08-26
相关 Issue/PR: MR !44962(Ascend/pytorch v2.7.1,分支
v2.7.1-force-overflow-check,单 commite805760bf);环境变量文档分支docs/force-overflow-check-master(commit33fbe097f)1. 概述
1.1 简介
当前 TorchNPU 仅在饱和模式下支持 stream 级溢出检测开关(
aclrtSetStreamOverflowSwitch),非饱和模式(INF_NAN 模式)设备(如 Atlas A2/A3、Ascend 950DT)上的溢出检测只能依赖将梯度同步搬运至 Host 侧做值检测,该过程插入同步点、改变执行时序,导致"时序敏感型"问题无法复现。本提案新增环境变量FORCE_OVERFLOW_CHECK:在 CANN >= 9.1.0 前提下,放开非饱和模式下溢出检测开关的限制,使溢出状态寄存器(float_status)检测路径在 INF_NAN 模式下同样可用,为大规模训练场景 Inf/NaN 问题的异步、不打断时序定位提供基础能力。1.2 动机
客户现场 512 卡多模型训练偶现 nan。现有定位手段均破坏执行时序,导致问题无法复现:
npu_check_overflow(grad)在 INF_NAN 模式下需将 grad 求和后.cpu()同步判断 inf/nan,同样改变时序;不做此提案的影响:INF_NAN 模式(社区主流设备形态)上始终缺少不影响时序的溢出定位手段,下游精度工具(旁路探测任务异步轮询 float_status)无法落地。
1.3 目标
目标:
FORCE_OVERFLOW_CHECK,配置为 1 且 CANN >= 9.1.0 时,非饱和模式下 stream 创建时同样开启溢出检测开关;npu_get_float_status/npu_check_overflow/npu_clear_float_status相关 Python 接口(get_npu_overflow_flag/npu_check_overflow/clear_npu_overflow_flag)在 force 开启时走寄存器异步路径;torch_npu.npu.utils.is_force_overflow_check(),供下游精度工具决定探测策略。非目标(边界):
IsSupportInfNan()返回值语义(其同时驱动内核 INF_NAN 编译模式选择,影响面不可控);npu_sys_ctrl.cpp的OverflowSwitchEnable()(_enable_overflow_npu已无 Python 调用方);_sync_dist_overflow_count的 INF_NAN 提前 return 行为保持不变)。2. 用例分析
用例 1:训练过程中 Inf/NaN 异步定位(核心用例)
FORCE_OVERFLOW_CHECK=1;旁路探测任务周期性调用get_npu_overflow_flag()读取溢出状态寄存器,定位 nan 产生的时间区间;aclrtSetStreamOverflowSwitch在非饱和模式下生效的版本前提)。用例 2:溢出检测接口的同步值检测路径替换
npu_check_overflow(grad)在 force 开启后不再将 grad 同步搬运至 Host,直接读寄存器并自动清除标志;用例 3:检测能力查询
is_force_overflow_check()区分"寄存器检测可用"与"值检测兜底",选择探测策略;使用限制与约束:
== "1"判断一致,无 0/1 值域校验);os.environ不会使 C++ 侧开关状态变化(C++ 侧 static 缓存首次建 stream 时的判断结果);3. 方案设计
3.1 总体方案
采用最小改动方案(方案 A):不修改
IsSupportInfNan()本身,在两处各内联一份相同的判断逻辑(环境变量 == "1" 且 CANN >= 9.1.0):torch_npu/csrc/core/npu/interface/AclInterface.cpp,AclrtCreateStreamWithConfig):原判断if (!IsSupportInfNan())扩展为if (!IsSupportInfNan() || forceOverflowCheck);forceOverflowCheck 由 static lambda 一次性求值(进程内仅判断/告警一次),覆盖 torch_npu 创建的所有 stream(默认 stream、secondary stream、stream pool 均经此入口);torch_npu/npu/utils.py):新增is_force_overflow_check();get_npu_overflow_flag/npu_check_overflow/clear_npu_overflow_flag三个接口的分支条件由is_support_inf_nan()改为is_support_inf_nan() and not is_force_overflow_check()。前置条件与约束:CANN >= 9.1.0(依赖
aclrtSetStreamOverflowSwitch在非饱和模式下使寄存器生效的新能力);用户自定义 stream 若绕过AclrtCreateStreamWithConfig创建则开关不生效(现状即如此,非本提案新增问题)。3.2 技术选型
npu_sys_ctrl.cppOverflowSwitchEnable()_enable_overflow_npu已无 Python 调用方,属无效改动关键选型说明——为什么新增
is_force_overflow_check()而不复用(修改)is_support_inf_nan():is_support_inf_nan()表达"硬件是否处于 INF_NAN 模式",force 开关不改变硬件模式,只改变检测手段;复用等于谎报硬件模式;is_support_inf_nan()是公开文档化 API,被grad_scaler.py两处及用户代码调用,修改其语义会让调用方在 force 下静默切换行为;3.3 功能与性能设计
功能流程:
FORCE_OVERFLOW_CHECK=1;IsGteCANNVersion("9.1.0");版本不满足时ASCEND_LOGW告警一次(受ASCEND_GLOBAL_LOG_LEVEL门控,默认级别下不打印)并回退原逻辑;AclrtCreateStreamWithConfig创建的 stream 均执行AclrtSetStreamOverflowSwitch(stream, 1),算子执行时溢出写入 float_status 寄存器;get_npu_overflow_flag()读标志;npu_check_overflow(grad)读标志并自动 clear(不再同步搬运 grad);clear_npu_overflow_flag()真正执行 clear(原仅告警);is_support_inf_nan()返回值不变,内核仍按 INF_NAN 模式编译执行。数据模型变更: 无。
性能影响: 开启溢出开关后算子执行存在额外开销(写入状态寄存器),为"不影响训练时序"定位能力的必要代价。已提供
--perf手工对比手段(4096x4096 fp16 mm 迭代耗时,开关开启/关闭各跑一次对比),量化数据待 ≥9.1.0 环境实测补充。注意:性能影响指算子执行开销,不改变算子下发时序(同步点数量不变)。影响范围: 仅 force 显式开启(env == "1" 且版本满足)时行为变化;默认行为(未配置/版本不满足/非法取值)与修改前完全一致。
3.4 安全隐私与DFX设计
is_force_overflow_check()登记test/torch_npu_schema.json受签名兼容性门禁监督;仅导出npu.utils命名空间,不做顶级导出(避免额外 schema 登记成本,2026-08-21 评审结论);3.5 编程与调用设计
3.5.1 编程模型基本设计
ASCEND_GLOBAL_LOG_LEVEL=2观察 WARNING);manual_verify_force_overflow.py全部断言通过(fp16 溢出经寄存器检出、正常运算不误报、npu_check_overflow检出后自动 clear)+ UT 全绿。3.5.2 接口定义与设计
变更点 1:新增环境变量
FORCE_OVERFLOW_CHECKdocs/zh/api/environment_variable/op_execution/FORCE_OVERFLOW_CHECK.md(分支docs/force-overflow-check-master,随资料侧 docs 流程合入)。变更点 2:新增 Python 查询接口
is_force_overflow_check()torch_npu.npu.utils.is_force_overflow_check() -> boolnpu.utils命名空间导出(torch_npu.npu.utils.is_force_overflow_check),不顶级导出。test/torch_npu_schema.json。import torch_npu.npu.utils as utils if utils.is_force_overflow_check(): flag = utils.get_npu_overflow_flag() # 寄存器异步路径变更点 3:既有接口行为变更(force 开启时)
get_npu_overflow_flag()npu_check_overflow(grad).cpu()同步值检测clear_npu_overflow_flag()npu_clear_float_statusis_support_inf_nan()→is_support_inf_nan() and not is_force_overflow_check();force 未开启时行为与现状完全一致。C++ 侧变更(内部接口,不对外暴露):
AclrtCreateStreamWithConfig(AclInterface.cpp)内联 forceOverflowCheck 判断,static lambda 单次求值 + 版本不足 LOGW 回退。3.5.3 编程手册设计
在已有《环境变量参考》中新增 FORCE_OVERFLOW_CHECK 词条(归入"算子执行"分类,紧邻 INF_NAN_MODE_ENABLE / INF_NAN_MODE_FORCE_DISABLE),内容含功能描述(0/1 语义、三接口行为变化、不改变计算模式的说明、NOTICE 性能提示)、配置示例、使用约束(CANN >= 9.1.0、仅 0/1、启动前配置)、支持型号。不新编手册,同步更新
env_variable_list.md与两级菜单。变更已备于docs/force-overflow-check-master分支。4. 测试设计
单元测试(并入既有
test/npu/test_check_over_flow.py,不新建文件):npu_check_overflow检出且自动 clearis_force_overflow_check()为 False;get_npu_overflow_flag仍 raise设备过滤:
NON_SATURATION_DEVICES = [Ascend910B, Ascend910C, Ascend910_93, Ascend950](门禁机器池含 A1 等仅饱和模式设备,避免误导性失败)。手工验证(e2e):
manual_verify_force_overflow.py——环境状态查询 → fp16 溢出(65504+65504)寄存器检出 →npu_check_overflow路径 + 自动 clear → 正常运算不误报;--perf提供开关前后 mm 耗时对比。回归:既有
test_check_over_flow.py、test_inf_nan_mode.py全量通过;test_compatibility.py门禁(新 API schema 登记)通过。限制:寄存器真实检出能力依赖 CANN >= 9.1.0 非饱和设备实测(配套环境满足,无版本 skip),UT 断言已按此设计。
5. 缺点和风险
--perf实测数据待补实现成本:4 文件 +149/-7(C++ 16 行 / Python 16 行 / UT 121 行 / schema 3 行),维护成本可控。
6. 现有技术
torch.cuda.amp.GradScaler检查 inf/nan 依赖torch.isinf/isnan值检测(需同步);本提案的寄存器异步检测是 NPU 硬件特性(float_status 寄存器)驱动的差异化能力,借鉴其GradScaler溢出检查接口形态(get_npu_overflow_flag命名与之对齐);aclrtSetStreamOverflowSwitch+npu_get_float_status的完整链路(FloatStatusKernelNpu.cppop 实现、OverflowUtils.cpp调用)即本提案复用的路径,差异仅在于放开 INF_NAN 模式的开关限制(依赖 CANN 9.1.0 新能力)。7. 未解决问题
--perf)待 CANN >= 9.1.0 环境实测后补充归档;is_force_overflow_check/get_npu_overflow_flag语义需与下游异步探测工具侧评审确认(探测轮询频率、多 rank 聚合策略不在本提案范围);附录
/home/wyq/q2/Q2/pta_force_overflow_check/需求分析与实现方案.mdv2.7.1-force-overflow-check,commite805760bf)docs/force-overflow-check-master(commit33fbe097f)/home/wyq/q2/Q2/pta_force_overflow_check/manual_verify_force_overflow.pydocs/zh/api/environment_variable/op_execution/INF_NAN_MODE_ENABLE.mdIsSupportInfNan() == true欢迎加入社区,感谢您对社区的贡献 🎉!