【Bug已解决】Attention: onnx conformance skip-list follow-ups for mode-3 (CUDA NOT_IMPLEMENTED) + latent…

📅 2026/8/13 23:43:45
【Bug已解决】Attention: onnx conformance skip-list follow-ups for mode-3 (CUDA NOT_IMPLEMENTED) + latent…
【Bug已解决】Attention: onnx conformance skip-list follow-ups for mode-3 (CUDA NOT_IMPLEMENTED) latent fully-masked gaps 解决方案一、现象长什么样ONNX 有个一致性测试conformance test把 ORT 各 EP 的Attention算子输出和一个独立的参考实现对比确保数值一致。测试用一份skip-list跳过清单记录“某些配置当前暂不测”。问题是mode-3 的Attention在 CUDA 上被标NOT_IMPLEMENTED并跳过—— 意味着 CUDA 上这种配置通常是带attention_mask 某种 past/无 past 组合的模式根本没实现被 skip-list 掩盖没人发现它其实能用/该用。潜伏的“全 mask”缺口latent fully-masked gaps当某些位置被完全 mask 掉整行都是 -inf即该 query 看不到任何 keyORT 的输出在这些位置是错的或产生 nan/未定义但因为 skip-list 跳过了对应用例这个 bug 一直没暴露。conformance 报告mode-3 CUDA - SKIPPED (NOT_IMPLEMENTED) fully-masked 用例 - SKIPPED掩盖了输出错误 实际mode-3 该实现、fully-masked 该处理skip 只是把问题藏起来注意这不是用户直接踩的崩溃而是测试治理问题——skip-list 把未实现/有 bug 的路径“假装通过”导致回归无人察觉。二、背景Attention算子opset-23支持多种运行模式mode-0/1/2/3由输入组合决定mode-0/1基础 QKV 注意力mode-2带 past 的 decoder 自回归KV cachemode-3带attention_mask 无 past或特定组合的注意力常用于 encoder / cross-attention 场景。一致性测试会根据mode生成大量用例不同 q/k/v 形状、mask 布局、是否 past逐一和参考比。当某个 mode 在某个 EP 上没实现测试框架把它加进 skip-list 标NOT_IMPLEMENTED于是该 mode 不计入“通过/失败”。问题是 skip-list 容易被滥用用 skip 掩盖未实现mode-3 在 CUDA 上没实现本该“实现它”却长期 skip仿佛“不是问题”。用 skip 掩盖 bugfully-masked 位置整行 -inf在某些实现下输出 nan/0本该修却因为对应用例被 skipbug 潜伏。而一旦有人去掉 skip-list 想“补测”就会发现这些被藏起来的失败 —— 这就是 “follow-ups”后续要跟进的的含义。三、根因根因是conformance 的 skip-list 把 mode-3CUDA 未实现和 fully-masked输出错误两类本应修复的问题标记成 SKIPPED使它们脱离“必须通过”的约束长期潜伏mode-3 CUDA 未实现却只 skipCUDA 的Attention内核没实现 mode-3 路径正确做法是补齐实现却只是加进 skip-list导致该配置在 CUDA 上始终不可用且无人跟进。fully-masked 输出错误却 skip某些位置整行 -infquery 看不到任何 key时softmax 在exp(-inf - max)上产生 nan/0ORT 没做“全 mask 位置给 0 或安全值”的处理输出错对应用例被 skip 掩盖。skip 变成“永久豁免”skip-list 没有到期/跟进机制条目只增不减未实现和真 bug 都被当作“已知跳过”回归保护失效。不是推理错对普通用户只要用户不走 mode-3 / 不出现 fully-masked不受影响但测试治理上这些路径的正确性没人保证。所以这不是单点数值错而是测试 skip-list 治理缺失让未实现与真 bug 长期潜伏。四、最小可运行复现下面用 Python 模拟“skip-list 把失败用例藏起来导致 bug 不被发现”def reference_attention(mask): 参考实现fully-masked 位置整行 -inf输出安全值 0。 import math # 简化一行若全 -infsoftmax 归一化后给 0避免 nan if all(m float(-inf) for m in mask): return 0.0 # 正常 softmax ... return 1.0 def ort_attention(mask): ORT 当前实现fully-masked 没处理 - 产生 nan。 if all(m float(-inf) for m in mask): return float(nan) # bug应输出 0 return 1.0 def conformance_run(mask, skip_list): ref reference_attention(mask) got ort_attention(mask) case fully_masked if case in skip_list: return SKIPPED # 掩盖 bug return PASS if got ref else FAIL if __name__ __main__: skip {fully_masked, mode3_cuda} # 长期 skip result conformance_run([float(-inf)] * 4, skip) print(conformance 结果:, result) # SKIPPEDbug 被藏 # 去掉 skip 才会 FAIL暴露 bug跑出来因为有fully_masked在 skip-listconformance 报SKIPPEDbug 被藏一旦从 skip 移除就会FAIL暴露 nan。这复现了“skip 掩盖未实现/bug”的机制。五、解决方案第一层最小直接修复最小修复补齐 mode-3 的 CUDA 实现并修复 fully-masked 位置的安全处理然后把对应用例从 skip-list 移除或改为“预期失败”跟踪。对测试治理# 1) CUDA Attention 内核补齐 mode-3 路径带 attention_mask、无 past # —— 实现 mode-3 的 mask 应用 score 计算 # 2) fully-masked 安全处理 # softmax 前检测某行是否全 -inf若是输出置 0或对应安全值不进 exp # 伪代码row_all_masked (mask_row -inf).all() # out[row] 0.0 if row_all_masked else softmax(scores[row]) # 3) skip-list 治理被 skip 的条目必须带 issue 链接 到期跟进 # 不能“只 skip 不修”这一层让 mode-3 在 CUDA 可用、fully-masked 输出正确skip-list 不再藏 bug。六、解决方案第二层结构性改进把“conformance skip-list 的治理规则 Attention 必须支持的模式”收口成唯一的配置对象OrtAttentionConformanceSkipPolicy测试与内核读它from dataclasses import dataclass, field from typing import Tuple, Dict dataclass(frozenTrue) class OrtAttentionConformanceSkipPolicy: Attention conformance skip-list 治理的单一事实来源。 # Attention 必须支持的模式CUDA 也要实现不能长期 skip required_modes: Tuple[int, ...] (0, 1, 2, 3) # fully-masked 位置必须安全处理输出 0 而非 nan fully_masked_safe: bool True # skip-list 治理每条 skip 必须带 issue 跟进期限 skip_requires_issue: bool True skip_requires_due_date: bool True # 当前已知 skip应逐步清零 known_skips: Tuple[str, ...] (mode3_cuda, fully_masked) def is_mode_supported(self, mode: int) - bool: return mode in self.required_modes def describe(self) - str: return Attention 全模式 CUDA 实现 fully-masked 安全处理skip 必须带 issue 跟进 POLICY OrtAttentionConformanceSkipPolicy() def audit_skip(skip_entries: Dict[str, str], policy: OrtAttentionConformanceSkipPolicy POLICY) - list: problems [] for name, meta in skip_entries.items(): if policy.skip_requires_issue and issue not in meta: problems.append(f{name}: skip 无 issue 链接) if policy.skip_requires_due_date and due not in meta: problems.append(f{name}: skip 无跟进期限) return problems所有 conformance 配置与内核实现读同一份POLICYskip-list 不再是“永久豁免”。七、解决方案第三层断言 / CI 守护把“Attention 全模式可用 fully-masked 安全 skip 有跟进”做成断言。下面用 pytest 风格守护复用第四节逻辑import pytest def test_all_modes_required(policy): for m in (0, 1, 2, 3): assert policy.is_mode_supported(m) is True def test_fully_masked_safe(policy): assert policy.fully_masked_safe is True def test_skip_must_have_issue(policy): assert policy.skip_requires_issue is True def test_audit_catches_bad_skip(policy): bad {mode3_cuda: 临时跳过} # 无 issue / 无 due probs audit_skip(bad, policy) assert len(probs) 1这四组断言锁住(1) 全模式含 mode-3必须支持(2) fully-masked 安全处理(3) skip 必须带 issue(4) 审计能抓出无跟进的 skip。CI 跑通即代表 skip-list 治理被守护。八、排查清单遇到 conformance skip-list 藏了 Attention 问题看 skip-list 条目mode-3 CUDA / fully-masked 是不是在里面藏了未实现/bug。确认 mode-3 是否真未实现CUDA Attention 内核有没有对应路径。查 fully-masked 输出全 -inf 行是不是产生 nan应改安全值 0。补实现 修安全处理补齐 mode-3fully-masked 给 0。治理 skip-list每条 skip 带 issue 期限逐步清零。统一策略对象用OrtAttentionConformanceSkipPolicy固化。CI 守护断言全模式支持、fully-masked 安全、skip 有跟进。九、小结Attention: onnx conformance skip-list follow-ups for mode-3 (CUDA NOT_IMPLEMENTED) latent fully-masked gaps的根因是ONNX 一致性测试的 skip-list 把 mode-3CUDA 上Attention未实现和 fully-masked整行 -inf 位置输出 nan/错两类本应修复的问题标记成 SKIPPED使它们脱离“必须通过”的约束长期潜伏回归保护失效。最小修复是补齐 CUDA 的 mode-3 实现、给 fully-masked 位置安全输出 0并把对应用例从 skip 移除或加 issue 跟进结构性改进是用唯一的OrtAttentionConformanceSkipPolicy固化“全模式必须支持、fully-masked 安全、skip 带 issue期限”CI 用四组断言守护“全模式支持、fully-masked 安全、skip 有跟进、审计抓坏 skip”。记住skip-list 是临时豁免不是永久豁免未实现和真 bug 都必须跟进否则一致性测试形同虚设。