用 𝔽₂ 线性代数学习精确的 NVIDIA SASS 编码器
作者:Jiading Gai(独立研究者,通信邮箱:jiading.gai@gmail.com)
代码:https://github.com/JiadingGai/f2asm
原文:Learning Exact NVIDIA SASS Encoders with 𝔽₂ Linear Algebra,arXiv:2608.20532v3 cs.LG,2026 年 9 月 28 日
摘要
NVIDIA 为近期的数据中心 GPU 提供了 SASS 反汇编器,却没有公开的 SASS 汇编器,这限制了受控的机器码改写。我们提出 F2Asm:它从"反汇编文本---原始 CUBIN 指令字"配对数据中学习精确的 128 位 SASS 编码器。据我们所知,F2Asm 是第一个将 SASS 指令编码器学习为 𝔽₂ 上向量值仿射映射的系统,也是第一个支持 Rubin SM107 的开源 NVIDIA SASS 汇编器。F2Asm 使用 𝔽₂ 上的高斯消元增量式地构建紧凑的基、检测不一致性,并拒绝超出所学张成空间的输入。F2Asm 将特定目标的控制位、重定位规则和 CUBIN 元数据与其学习算法相分离。我们使用来自固定版本的 NVIDIA 与第三方生产库、CUDA 13.3 软件包以及 CUDA 13.4 开发者预览存档的 3,225 个 CUBIN,为 Hopper SM90/SM90a、Blackwell SM100 和 Rubin SM107 训练了编码器。在往返(round-trip)测试中,F2Asm 重新汇编了每个 CUBIN 的反汇编 SASS,所有参与比较的可执行代码节(text section)均与原始字节完全一致。用 F2Asm 进行联合训练,得到了一个由五个 Blackwell SM 目标共享的编码器,以及另一个由三个 Rubin SM 目标共享的编码器,这为"每个家族内部共享的指令具有共同的 SASS 编码方案"提供了强有力的证据。持续训练(continual training)将 Rubin 编码器扩展到全部 17,159 条此前不受支持的 cuTile 与 GROMACS 查询,仅新增 1,504 行基向量,与推导出的下界完全吻合。

图 1. F2Asm 的一个应用场景。诸如 KernelPro 之类的 CUDA 编程智能体利用性能分析器反馈执行源码级优化(Gai 等,2026)。优化后的 CUDA 源码被编译为 CUBIN 并反汇编为 SASS。随后,下游的 SASS 智能体搜索 SASS 级优化方案,使用 F2Asm 对优化后的指令进行编码并重建候选 CUBIN。
1 引言
性能关键的 GPU 内核最终以 NVIDIA SASS 机器码的形式执行。源码级 CUDA 优化决定算法、数据搬运、分块(tiling)与同步,而编译器降级(lowering)决定寄存器分配、指令调度以及机器级控制字段。这一边界对大语言模型(LLM)训练与推理等工作负载至关重要,因为它们的核心算子依赖专门的 CUDA 内核。FlashAttention 通过更好的工作划分、异步性和低精度支持,展示了源码级改进的影响力(Dao 等,2022;Dao,2023;Shah 等,2024)。
已有工作表明,在 PTX 之下还存在第二次优化机会。TuringAs 实现了原生 SASS 调优,并揭示了在更高层级无法获得的优化(Yan 等,2020)。CuAsmRL 从一个已优化的 Triton 内核出发,在依赖约束下重排其 SASS 指令、重建 CUBIN,并以实测吞吐量作为奖励。在其 Ampere 架构 LLM 内核测试集上,它报告了 9% 的平均提升,最高提升达 26%(He & Yoneki,2025)。这些收益表明,即使是已优化的 CUDA 内核,在编译之后仍能从额外的 SASS 级优化中获益。
要系统化地应用这类 SASS 级优化,需要一种可信的方式把选定的 SASS 候选重新汇编成可执行的 CUBIN。CUBIN 将 GPU 机器码存储在 ELF 节中。NVIDIA 的 nvdisasm 可以恢复出可读的 SASS,但 NVIDIA 没有提供公开工具,能在近期数据中心 GPU 上把这些 SASS 重新汇编回机器码(NVIDIA Corporation,2026a)。手工维护的指令编码规则扩展成本高,并且可能对新遇到的指令形式产生静默的错误编码(Gray,2015;Yan 等,2020)。
我们提出 F2Asm,它从"解析后的反汇编文本 + 原始 CUBIN 指令字"的配对中学习精确的 128 位 SASS 编码器。F2Asm 将指令编码表示为 𝔽₂ 上的向量值仿射映射。它使用位集(bitset)高斯消元构建紧凑的基,并且仅当该基唯一确定结果时才输出指令字。F2Asm 将其学习算法与特定目标的控制位、重定位规则和 CUBIN 元数据相分离。
图 1 展示了 F2Asm 的一个应用。诸如 KernelPro 的 CUDA 编程智能体首先利用性能分析器反馈修改 CUDA 或 CuTe 源码(Gai 等,2026)。随后,下游 SASS 智能体可以在 PTX 之下搜索进一步改进,并以 F2Asm 作为确定性的汇编后端。F2Asm 对选定的 SASS 候选进行支持性检查,输出其机器字,并在外部语义测试和硬件测量之前重建 CUBIN。
本文有五项贡献:
- 据我们所知,首次将"学习型 SASS 指令编码"形式化为 𝔽₂ 上的向量值仿射映射,并带有精确的支持性检查。
- 一种增量式位集高斯消元算法,可检测不一致的训练数据,并保留紧凑、可合并的基,而不是保存每一个"指令---指令字"配对。
- 一套将共享学习与特定目标机器码规则分离的训练流水线,使其可以扩展到 Hopper、Blackwell、Rubin 以及未来的 GPU 目标。
- 一种持续训练过程,可利用额外的 CUBIN 观测扩展已冻结的编码器,并给出支持给定未支持查询集所需独立观测数量的紧下界。
- 大规模实证验证:F2Asm 在 Hopper、Blackwell 和 Rubin 上精确重建了 34.1 亿字节的可执行代码;同时,Blackwell 联合训练提供了语料库规模的证据,表明 5 个 SM 目标对公共指令共享同一套 SASS 编码方案。
2 精确的位线性编码
2.1 构建训练系统
我们在二元域 𝔽₂ = {0, 1} 上表示指令编码,其中加法为 XOR(异或),乘法为 AND(与)(Mullen & Panario,2013)。形式(form) f 将助记符与有序的操作数类型组合在一起,例如 Tensor Core 指令的 HMMA R R R R。令 m 为有序元组,包含助记符以及所有解析出的指令级与操作数级修饰符。令 v 为解析值向量,F2Asm 将其位向量化,构成下文定义的特征向量 ϕ(x)。解析器把指令守卫(guard)放在最前,随后按文本顺序放入各操作数值。在本例中,隐式的 PT 守卫映射为 7,而 R4、R68.reuse、R72、R4 分别贡献 4、68、72、4,得到 v = (7, 4, 68, 72, 4);reuse 修饰符保留在 m 中。令 s 为操作数签名(operand signature) :解析值的符号、与操作数类型相关的哨兵(sentinel)类别,以及取值相等的位置对。F2Asm 用 s 区分可能需要不同仿射映射的情形,然后检验这些情形能否共享同一个映射。本例中所有值均为非负,只有 v₀ = 7 是 PT 哨兵(其余均为普通值),且 v₁ = v₄ = 4,给出相等对 (1, 4)。实现中将 p = (m, s) 表示为 InstructionContext 类的实例。精确上下文(exact context) c = (f, p) 将具有相同 f、m、s 的训练观测归为一组。图 2 展示了一条 HMMA 指令对应的 f、m、v、s、p、c;特别地,R68.reuse 向 v 贡献 68,并向 m 贡献"第一源操作数复用"(first-source reuse)(另见附录 C)。对每个精确上下文组,F2Asm 对训练系统 ΦW = Y(式 (3) 与第 2.2 节)应用高斯消元,并保留线性无关行构成的基。这保持了方程组的解集不变。
每条训练观测 i 是一个配对 (xᵢ, yᵢ),其中 xᵢ 是 nvdisasm 生成的文本 SASS 指令,被解析为 fᵢ、mᵢ、vᵢ;yᵢ ∈ 𝔽₂¹²⁸ 是其原始指令字,其中调度器控制位已被清零。F2Asm 使用特定目标的位布局单独处理调度器控制(附录 C)。对于 nvdisasm 省略第 122 位和第 124 位的那个 DEPBAR.LE 上下文,F2Asm 在训练时也将这些位清零,并单独保存其原始值,以实现字节级精确重建(附录 D)。
由 vᵢ 导出的符号、哨兵类别和相等关系构成操作数签名 sᵢ,因此 pᵢ = (mᵢ, sᵢ),cᵢ = (fᵢ, pᵢ)。F2Asm 构造特征向量
ϕ(xi)= 1 ∥ bits64(vi,0) ∥ ⋯ ∥ bits64(vi,k−1) ∈F21+64k.(1)\phi(x_i) = \\,1 \\;\\\|\\; \\mathrm{bits}_{64}(v_{i,0}) \\;\\\|\\; \\cdots \\;\\\|\\; \\mathrm{bits}_{64}(v_{i,k-1})\\, \in \mathbb{F}_2^{1+64k}. \tag{1}ϕ(xi)=1∥bits64(vi,0)∥⋯∥bits64(vi,k−1)∈F21+64k.(1)
特征向量 ϕ(xᵢ) 为仿射映射提供数值输入。F2Asm 首先对每个精确的 (f, m, s) 组单独训练,然后检验具有相同 (f, m) 的组能否共享一个映射。它对每个 (f, m) 独立训练仿射映射,因为 ϕ(x) 只包含 v。由于 s 由 v 导出,观测到不同 s 的组仍可能遵循同一个仿射映射。F2Asm 合并它们的基并应用高斯消元:如果方程一致且输出掩码匹配,就存储一个共享映射;否则保留按 s 选择的独立映射。下面的 SM107 案例说明了修饰符如何在不改变特征向量的情况下改变所学映射的归属:即使原始指令字第 18 位被置位,nvdisasm 在输出 WARPSYNC.COLLECTIVE R88, 0x9fa0 时也省略了 .PHASE1。F2Asm 在解析前恢复该修饰符。这使 fᵢ、vᵢ、ϕ(xᵢ) 保持不变,但改变了 pᵢ 中的修饰符元组,从而选择为 .PHASE1 观测训练的映射,该映射将第 18 位输出为 1。
训练共享编码器时,F2Asm 把分配给同一所学映射的所有 SM 目标的观测汇集在一起。SM 目标既不是特征,也不是映射选择器。下面的推导针对单个所学映射,因此我们将 Φ、Y、W 写成不带映射下标的形式。
对观测 i,编码方程为
yi⏟1×128=ϕ(xi)⏟1×d W⏟d×128=⨁j: ϕj(xi)=1wj⏟1×128.(2)\underbrace{y_i}{1\times 128} = \underbrace{\phi(x_i)}{1\times d}\;\underbrace{W}{d\times 128} = \bigoplus{j:\,\phi_j(x_i)=1} \underbrace{w_j}_{1\times 128}. \tag{2}1×128 yi=1×d ϕ(xi)d×128 W=j:ϕj(xi)=1⨁1×128 wj.(2)
这里 wⱼ 是 W 的第 j 行。符号 ⨁ 表示 XOR 归约:选取特征位为 1 的那些行并做异或。这就是 𝔽₂ 上普通的"行向量---矩阵"乘法,其中标量乘法是 AND,加法是 XOR。
分配到同一所学映射的观测被堆叠成一个训练系统:
Φ⏟n×d W⏟d×128=Y⏟n×128在 F2 上.(3)\underbrace{\Phi}{n\times d}\;\underbrace{W}{d\times 128} = \underbrace{Y}_{n\times 128} \quad \text{在 } \mathbb{F}_2 \text{ 上}. \tag{3}n×d Φd×128 W=n×128 Y在 F2 上.(3)
Φ 的第 i 行是 ϕ(xᵢ),Y 的第 i 行是 yᵢ。稠密矩阵 W 只是这些约束的便利记号;实现并不需要在观测到的特征张成空间之外具体构造任意一个解。
对于上面的 HMMA 示例,共享映射的键包含形式 f = HMMA R R R R 以及修饰符元组 m,而 c = (f, p) 是其精确编码上下文。前导值 7 编码 PT------NVIDIA 的"恒真"谓词:3 位谓词字段将 0--6 分配给可编程寄存器 P0--P6,将 7 = 111₂ 分配给 PT。令 ∥ 表示向量拼接,bits₆₄(a) 将 a 的 64 个位按从最低有效位到最高有效位列出。由此得到的 SM100 HMMA 特征向量为
ϕ(x)= 1 ∥ bits64(7) ∥ bits64(4) ∥ bits64(68) ∥ bits64(72) ∥ bits64(4) ∈F2321.(4)\phi(x) = \\,1 \\;\\\|\\; \\mathrm{bits}_{64}(7) \\;\\\|\\; \\mathrm{bits}_{64}(4) \\;\\\|\\; \\mathrm{bits}_{64}(68) \\;\\\|\\; \\mathrm{bits}_{64}(72) \\;\\\|\\; \\mathrm{bits}_{64}(4)\\, \in \mathbb{F}_2^{321}. \tag{4}ϕ(x)=1∥bits64(7)∥bits64(4)∥bits64(68)∥bits64(72)∥bits64(4)∈F2321.(4)
前导的 1 提供仿射偏置(常数项),五个 64 位子向量分别是 PT、目的操作数 D、源操作数 A、源操作数 B 和累加器 C 的小端二进制编码,如图 2 所标注。附录 C 将沿着这条指令完整地走过训练与汇编过程。

图 2. HMMA 示例的指令上下文解剖。解析器产生 f、m、v 和 s。操作数签名 s 由符号(sign)、哨兵(sentinel)和相等性(equality)三行组成。随后 p = (m, s) 与 c = (f, p) 定义初始的精确上下文训练组。(图中:j 是 v 中从零开始的索引,始于守卫;助记符与修饰符不参与索引。† 表示解析器插入的隐式守卫;+ 表示非负,− 表示负;哨兵类别因操作数类型而异。)
2.2 基于流式高斯消元的训练
F2Asm 增量式地执行高斯消元,每次处理一条训练观测。它立即将每条增广行对已保留的主元基做归约,只有当该行能提升秩时才存储它。因此内存占用随保留的基(而非观测数量)增长。这在不具体构造稠密 W 的情况下,在观测张成空间上求解式 (3)。每条流入的行为
r ∣ z ⏟1×(d+128)= ϕ(xi)⏟1×d ∣ yi⏟1×128 在 F2 上(5)\underbrace{\\; r \\;\|\\; z \\;}_{1\times(d+128)} = \\; \\underbrace{\\phi(x_i)}_{1\\times d} \\;\|\\; \\underbrace{y_i}_{1\\times 128} \\; \quad \text{在 } \mathbb{F}_2 \text{ 上} \tag{5}1×(d+128) r∣z=1×d ϕ(xi)∣1×128 yi在 F2 上(5)
并维护一个归约基 B = {(rₖ, zₖ)}。每个 rₖ 是一条保留的特征方程,zₖ 是对 Y 施加相同行操作后得到的 128 位输出。秩即消元后保留的线性无关行数。
对每一行 (r, z),训练过程:(1) 对已存主元做 XOR 归约;(2) 若输入与输出残差均为零则丢弃;(3) 若输入残差为零而输出残差非零,则报告矛盾;否则 (4) 选取最高置位输入位作为主元,(5) 从已存行中清除该主元位,并插入 (r, z)。特征行和输出字被压缩为整数,因此 XOR 直接实现行加法。训练处理每一条观测,但只存储线性无关的基行。固定的观测顺序产生确定性的基。由不同语料分片分别计算出的基,可以通过对保留行再做消元来合并,从而实现并行采集而无需存储完整语料。
编码器将解析后的 SASS 映射为 128 位指令字;其映射、基与选择元数据共同构成模型仓库(model repository)。
2.3 用训练好的模型进行 SASS 编码
训练好的模型在观测到的特征子空间上获得支持:
S=rowspan(Φ)⊆F2d.(6)\mathcal{S} = \mathrm{rowspan}(\Phi) \subseteq \mathbb{F}_2^{d}. \tag{6}S=rowspan(Φ)⊆F2d.(6)
这里 Φ ∈ 𝔽₂ⁿˣᵈ 是训练特征矩阵,其第 i 行是观测 i 的特征向量 ϕ(xᵢ)。其行张成空间为
rowspan(Φ)={ a⊤Φ:a∈F2n }.(7)\mathrm{rowspan}(\Phi) = \{\, a^{\top}\Phi : a \in \mathbb{F}_2^{n} \,\}. \tag{7}rowspan(Φ)={a⊤Φ:a∈F2n}.(7)
由于算术在 𝔽₂ 上进行,这就是观测特征行的所有 XOR 组合构成的集合。因此,查询指令 x 受支持当且仅当 ϕ(x) ∈ 𝒮,即 ϕ(x) 能表示为观测特征行的 XOR。观测是一致的,当且仅当
rank( Φ ∣ Y )=rank(Φ).(8)\mathrm{rank}(\\,\\Phi \\;\|\\; Y\\,) = \mathrm{rank}(\Phi). \tag{8}rank(Φ∣Y)=rank(Φ).(8)
当该条件成立时,消元定义了唯一的线性映射
T:S→F2128,T(ϕ(xi))=yi.(9)T : \mathcal{S} \to \mathbb{F}_2^{128}, \qquad T(\phi(x_i)) = y_i. \tag{9}T:S→F2128,T(ϕ(xi))=yi.(9)
存储的基对就是该映射的紧凑表示:T(rₖ) = zₖ。式 (3) 中的稠密 W 是 T 到全空间 𝔽₂ᵈ 的任意线性扩张;这种扩张在 𝒮 之外不必唯一。因此,精确训练要求的是一致性,而非 rank(Φ) = d。附录 B 通过一个完整算例演示了训练与编码。
为编码查询指令 x,F2Asm 构造 q = ϕ(x),并用已存的 rₖ 行对 q 做归约。每当从查询中异或掉 rₖ 时,同时把 zₖ 异或进一个初始为零的 128 位累加器。零残差证明 q ∈ 𝒮,此时累加器即为唯一受支持的值 T(q);非零残差证明 q ∉ 𝒮。只有当查询被保留的基支持时,F2Asm 才输出指令字;否则报告"不支持的指令"且不产生任何输出。尽管 F2Asm 会拒绝不支持的输入,第 4 节表明这一保护措施并未限制覆盖率:在 3,225 个生产 CUBIN 中遇到的每一条指令都成功编码。
2.4 已训练编码器的持续训练
持续训练对 Rubin 这类新引入的 GPU 架构尤其有用:起初可用的 CUBIN 训练语料有限,但会随后续库与软件发布而增长。
令 g 标识一个映射组:共享映射时 g = (f, m),签名专属映射时 g = (f, m, s)。当新的 CUBIN 暴露出不受支持的查询时,其训练行构成集合 E,并按映射组划分为 E_g。
算法 1 冻结编码器的持续更新
输入:模型仓库 R;训练行批次 E
1: 校验 E;由 R 初始化 R′,不修改 R
2: for 每个受影响的映射组 g do
3: 将 B′_g 设为其保留基,新映射组则为 ∅
4: for 每个 (r, z) ∈ E_g do
5: 用 B′_g 将 (r, z) 归约为 (r̄, z̄)
6: if r̄ ≠ 0 then 插入该主元
7: else if z̄ ≠ 0 then 中止
8: else 记录一次冗余的一致性检查
9: return 更新后的模型仓库 R′
若新观测与共享的 (f, m) 映射矛盾,算法 1 在第 7 行中止更新。自动重新划分会把该映射拆分为签名专属的 (f, m, s) 组并重建受影响的映射。第 4.4 节的实验无需重新划分,故留待未来工作。
对每个映射组 g,令 B_g 为保留的特征基,Q_g = {ϕ(x) : x 在 g 中不受支持} 为不受支持查询的特征行。设 S_g = span(B_g),S⁺_g = span(B_g ∪ Q_g)。则
δg=rank(Bg∪Qg)−rank(Bg)=dim(Sg+/Sg).(10)\delta_g = \mathrm{rank}(B_g \cup Q_g) - \mathrm{rank}(B_g) = \dim(S^{+}_g / S_g). \tag{10}δg=rank(Bg∪Qg)−rank(Bg)=dim(Sg+/Sg).(10)
由商维数恒等式(Hungerford,1980),每条提升秩的观测增加一个维数。因此,任何足以支持组 g 的观测集至少要包含 δ_g 条观测,而贪心插入恰好保留 δ_g 条(Oxley,2011);故全仓库范围的最小值为 δ = Σ_g δ_g。当某条指令查询不受支持时,自主 SASS 智能体可以调用算法 1,用新的 CUBIN 观测更新受影响的映射组。
3 训练数据与流水线
训练数据是 SHA-256 去重后提取的"指令---编码"配对。SM90/90a 语料来自固定版本的 NVIDIA 与第三方生产库;SM100 来自 NVIDIA CUDA 13.3 软件包;SM107 来自 NVIDIA CUDA 13.4 开发者预览存档(NVIDIA Corporation,2026b)。表 1 汇总了这些语料及其向训练基的归约。我们称一个 CUBIN 为经认证的(authenticated):当其来源被记录、其 SHA-256 摘要与目标元数据被核验、且其导出的观测可追溯到源工件。本文所有 CUBIN 均经认证。
训练数据流水线(我们称之为采集器,collector)有三个带检查点的阶段。第 1 阶段核验每个已索引的 CUBIN,并将压缩后的 nvdisasm -hex -c 输出存入按内容寻址的分片。第 2 阶段把每个已核验分片解析为可追溯的指令观测记录。第 3 阶段按语料顺序经流式高斯消元重放这些记录,并原子性地写出保留行、逐 CUBIN 台账与证据清单。
该流水线面向自动化的目标接入(onboarding)而设计,可由自主编程智能体驱动。其各阶段是确定性的、非交互的、带检查点的,并输出机器可读的通过/失败清单。一份架构配置(architecture profile)规定一组兼容 SM 目标的指令布局、控制字段、重定位与元数据规则、解析器修复方式以及模型仓库。兼容目标可共享一份配置和一个编码器。要接入新的 sm_* 目标,智能体定义或扩展架构配置、构建经核验的语料索引、固定反汇编器版本、运行模型训练与往返测试,并利用清单中的失败项指导下一轮迭代。
nvdisasm 有时会隐藏机器码中存在的差别:不同的 128 位指令字可能反汇编为相同的 SASS 文本。F2Asm 检查原始指令位以恢复这些差别;若无法安全恢复,则拒绝该观测。例如,在一个 Rubin SM107 的 cuSPARSE CUBIN 中,nvdisasm 从 WARPSYNC.COLLECTIVE R88, 0x9fa0 中省略了 .PHASE1 修饰符,尽管原始指令字的第 18 位编码了它。采集器在训练前恢复 .PHASE1。
在表 1 的各语料上,采集器将 212,937,948 条被接受的指令观测,通过在每个精确 (f, p) 上下文内分别施加流式高斯消元,归约为 1,063,639 行基,行数压缩约 200 倍。随后 F2Asm 按第 2.1 节的过程训练编码模型。汇集后模型仓库的最终映射与基数量见表 2。
表 1. 训练语料与精确上下文证据压缩。
| 目标 | GPU 架构 | 语料来源(CUBIN 数) | 总计 | 原始行数 | 精确上下文基行数 | 精确上下文数 | 跳过数 ᵃ |
|---|---|---|---|---|---|---|---|
| SM90/90a | Hopper | NVIDIA TensorRT-LLM (1,108);NVIDIA Transformer Engine (60);vLLM (239);FlashAttention (72);SGLang (60);xFormers (8);bitsandbytes (3);rVLLM (1) | 1,551 | 169.87M | 440,308 | 60,412 | 200 |
| SM100 | Blackwell | NVIDIA cuBLAS (378);cuDNN (283);cuSOLVER (194);NPP (182);cuSPARSE (100);nvJPEG (10);cuRAND (7);cuSPARSELt (3) | 1,157 | 25.09M | 385,141 | 59,894 | 0 |
| SM107 | Rubin | NVIDIA cuSOLVER (203);NPP (197);cuSPARSE (100);nvJPEG (10);cuRAND (7) | 517 | 17.98M | 238,190 | 37,277 | 13,524 |
| 总计 | 3,225 | 212,937,948 | 1,063,639 | 157,583 | 13,724 |
ᵃ "跳过"指符号地址行:其 nvdisasm 操作数无法无歧义地匹配到对应的 ELF 重定位项,从而无法安全地将指令位与链接器控制的位分离。这些行被排除在训练之外;其余行与重定位规则仍保留了操作码覆盖。意外跳过数为零,且所有 CUBIN 均通过字节级精确往返。SM90/90a:9 个 CUBIN 中的 172 条 MOV 符号加
@srel表达式和 28 条 UMOV 符号不匹配。SM107:13,506 条跨节 CALL 与 18 条 UMOV 重定位表达式。
表 2. 最终编码仓库结构。每个 (f, m) 组存储一个共享仿射映射;共享失败时则按操作数签名各存一个映射。基行数为各映射求和。
| 目标 | (f, m) 组数 | 仿射映射数 | 最终基行数 |
|---|---|---|---|
| SM90/90a | 2,865 | 2,936 | 50,099 |
| SM100 | 3,669 | 3,673 | 60,159 |
| SM107 | 2,896 | 2,896 | 44,882 |
| 总计 | 9,430 | 9,505 | 155,140 |
4 实验
实验评估 F2Asm 的四个性质。第一,字节级精确往返测试在 Hopper、Blackwell 与 Rubin 语料上验证所学编码。第二,联合训练在 5 个 Blackwell SM 目标上测试单一编码器。第三,受控的留出(held-out)与未见库评估刻画由 3 个 Rubin SM 目标共享的一个编码器。第四,持续训练利用新获得的 CUBIN 扩展冻结的 Rubin 编码器。
4.1 往返评估
往返测试是 F2Asm 的端到端验收测试,因为汇编器必须精确复现机器码。早期的 CUDA 汇编器也使用精确重建做验证:MaxAs 报告了对 cublas device.lib 的零错误"反汇编---重汇编"(Gray,2015);Decoding CUDA Binary 将生成的基准代码与原始代码比较(Hayes 等,2019);CuAssembler 将重编码的指令字与其原始编码比较(cloudcores,2019)。F2Asm 把这一准则扩展到带完整可执行节核算的去重生产 CUBIN 上。往返测试通过在 ELF 节头顺序中按名称与出现次序匹配节,保留重名节,然后逐字节检查每个匹配节。对每个去重后含代码的 CUBIN,F2Asm 反汇编可执行代码、解析 SASS、重编码每条指令、重建 CUBIN,并将每个 .text.* 节与原始节逐字节比较。只有当所有可执行节都存在且完全一致时,该 CUBIN 才算通过。
表 3 报告了往返结果。全部 3,225 个含代码 CUBIN 均通过:F2Asm 逐字节重建了 150,308 个可执行节(3,407,226,752 字节),0 失败、0 错误。在 F2Asm 支持的最新 GPU 架构 Rubin SM107 上,全部 517 个 CUDA 13.4 开发者预览 CUBIN 均通过,覆盖 32,676 个可执行节和 279 种指令形式。这包括第 3 节所述的 WARPSYNC.COLLECTIVE.PHASE1 案例------nvdisasm 省略了一个对编码有影响的修饰符,而 F2Asm 从原始指令字中恢复了它。
表 3. 3,225 个 CUBIN 发布语料的往返结果。所有可执行代码节均与原始字节完全一致。P/F/E 表示通过/失败/错误。
| 目标 | 形式数 | CUBIN 数 | 节数 | 代码 MiB | P/F/E |
|---|---|---|---|---|---|
| SM90/90a | 389 | 1,551 | 87,141 | 2,592.0 | 1,551/0/0 |
| SM100 | 326 | 1,157 | 30,491 | 382.8 | 1,157/0/0 |
| SM107 | 279 | 517 | 32,676 | 274.5 | 517/0/0 |
SM100 评估识别出三项必需的反汇编规范化和一项 CUBIN 格式要求。三项规范化------精确恢复 QNaN 有效载荷、符号化 RZ/URZ 与字面量 R255/UR63 的区分、PC 相对的 WARPSYNC 目标------使相同 25,089,192 条观测上的 𝔽₂ 冲突从 5,830 降为零。SM100 语料包含一个并行的逐内核 ELF 命名空间:全部 30,491 个 .text.* 节都有对应的 .nv.capmerc.text.* 节,并伴有 .nv.merc.* 元数据、重定位、符号与调试数据。该结构与 Blackwell 的"最终化封装"(finalization capsule)一致。¹ F2Asm 保留该结构,但不依赖其未文档化的语义。
¹ 独立的逆向工程分析将该格式描述为 Capsule Mercury:https://gh.evko.io/nvopen-tools/ptxas/codegen/capmerc.html。
SM107 的精确上下文证据系统呈显著低秩:17,977,652 条被接纳的观测归约为 238,190 行精确上下文基;精确上下文秩的中位数为 3,95% 不超过 21。仓库级汇集进一步将其压缩为分布在 2,896 个 (f, m) 组中的 44,882 行存储基,且全部由共享映射表示。SM107 仓库含有 23 个 SM100 中没有的形式签名。IADD、IMNMX 与 VISET 在 SM90 和 SM100 仓库中都不出现,却占 SM107 指令观测的 1,437,961 条(8.00%)。
4.2 一个编码器覆盖 5 个 Blackwell SM 目标
F2Asm 揭示:SM100、SM100f、SM100a、SM103 与 SM103a 对其公共指令形式与上下文使用相同的指令编码方案。为检验这些目标是否需要各自不同的所学编码规则,我们将 18,015 个 CUBIN 汇入一个训练语料。每条观测仅出于语料核验、特定目标指令合法性检查和 CUBIN 重建的目的保留其 SM 目标;它不影响所学编码器。flashinfer-cubin==0.6.13 软件包(FlashInfer Team,2026)提供了 14,036 个 SM100f CUBIN 中的 13,646 个,以及全部 1,952 个 SM103a CUBIN。
训练处理了 388 种形式、77,926 个编码上下文上的 127,926,344 条指令观测。其中 49,566 个上下文同时出现在 SM100 系与 SM103 系语料中,其余 28,360 个只出现在其中一系,但同样被纳入共享编码器。五次按目标分别采集的运行在其精确上下文系统上共保留 1,036,618 行基。联合训练把这些行在兼容上下文间汇合并重新消元,最终共享编码器的 (f, m) 组上保留 75,692 行基。共享编码器包含 4,397 个 (f, m) 组,其中 4,396 个在所有操作数签名 s 上共用一个映射;只有一个 DEPBAR (f, m) 组需要精确签名回退,使用五个映射,总计 4,401 个映射。所有训练观测都与单一共享编码器一致,没有任何观测需要特定目标的所学映射或输出规则。
表 4 报告了共享编码器工件的字节级精确往返结果。我们测试了完整的 SM100、SM100a 与 SM103 语料;对 SM100f 与 SM103a,则在覆盖每个已观测编码上下文的前提下对测试集做确定性下采样。全部 5,335 个 CUBIN 通过,覆盖 72,101 个可执行节和 1,254,796,416 字节。
表 4. 5 个 Blackwell SM 目标的共享编码器往返结果。覆盖率:完整语料或下采样测试比例。P/F/E 表示通过/失败/错误。
| SM | 训练 | 测试 | 覆盖率 | 节数 | MiB | P/F/E |
|---|---|---|---|---|---|---|
| SM100 ᵃ | 1,217 | 1,217 | 全部 | 30,611 | 384.7 | 1,217/0/0 |
| SM100f | 14,036 | 2,808 | 20.0% | 19,840 | 505.7 | 2,808/0/0 |
| SM100a | 314 | 314 | 全部 | 636 | 20.2 | 314/0/0 |
| SM103 | 496 | 496 | 全部 | 20,014 | 256.5 | 496/0/0 |
| SM103a | 1,952 | 500 | 25.6% | 1,000 | 29.6 | 500/0/0 |
| 总计 | 18,015 | 5,335 | 混合 | 72,101 | 1,196.7 | 5,335/0/0 |
ᵃ 包含表 1 中的 1,157 个 SM100 CUBIN,另有 60 个来自
flashinfer-cubin==0.6.13。
综上,这些结果实证确立了 SM100、SM100f、SM100a、SM103 与 SM103a 共享同一套 SASS 指令编码方案。据我们所知,F2Asm 首次在语料库规模上演示了这种跨 5 个 Blackwell SM 目标的共享编码。
4.3 一个编码器覆盖 3 个 Rubin SM 目标
我们为 sm_107、sm_107a 与 sm_107f 联合训练了一个编码器。我们汇集了 18,578 个 CUBIN 的 Rubin 开发语料:517 个来自 CUDA 13.4 库,17,999 个来自 FlashInfer,52 个编译自 CUTLASS,另有 10 个定向探针。我们将语料划分为 14,970 个训练 CUBIN 与 3,608 个留出 CUBIN。共享源或构建组、可执行载荷或目标姊妹关系的 CUBIN 被保留在同一分区中。训练集包含 510 个 sm_107、14,431 个 sm_107a 与全部 29 个 sm_107f CUBIN;留出集包含 10 个 sm_107 与 3,598 个 sm_107a CUBIN。留出 CUBIN 被排除在训练之外,同时确保其中每条规范化指令查询都被训练集覆盖。没有独立的 sm_107f 划分满足查询覆盖要求。
训练处理了 71,927,724 条指令观测,保留 296,403 行精确上下文基。仓库训练把这些行汇入 3,428 个 (f, m) 组,每组由一个共享仿射映射表示,最终在 368 种指令形式上保留 54,957 行基。
如表 5 所示,使用冻结的编码器与工具链,所有训练与留出 CUBIN 均通过严格往返,每个可执行节都精确匹配。
表 5. Rubin 开发语料划分及已训练编码器的往返结果。P/F/E 表示通过/失败/错误 CUBIN 数。
| 分区 | CUBIN 数 | 指令数 | 唯一查询数 | 代码节数 | P/F/E |
|---|---|---|---|---|---|
| 训练 | 14,970 | 71,927,724 | 4,412,203 | 59,921 | 14,970/0/0 |
| 留出 | 3,608 | 12,788,800 | 740,247 | 9,017 | 3,608/0/0 |
为在该开发语料之外评估冻结编码器,我们使用来自 NVIDIA cuTile Python(NVIDIA Corporation,2026c)与 GROMACS(Páll 等,2015)的 CUBIN 作为未见库测试集。表 6 报告冻结编码器在这些 CUBIN 上的覆盖率。不受支持的查询会被拒绝而不编码;完全受支持的 CUBIN 则要求通过严格往返。第 4.4 节利用本次评估中的不受支持查询来测试持续适配。
表 6. 已训练 Rubin 编码器在适配前对未见库 CUBIN(NVIDIA cuTile Python 与 GROMACS)的覆盖情况。"受支持"统计被编码器接受的指令出现次数;覆盖率 = 受支持出现次数 ÷ 指令数。
| 来源 | 目标 | 含代码 CUBIN 数 | 指令数 | 受支持 | 覆盖率 | 完全受支持 | 往返 |
|---|---|---|---|---|---|---|---|
| cuTile | sm_107a | 5 | 20,040 | 16,338 | 81.5% | 0 | N/A |
| GROMACS | sm_107 | 23 | 364,800 | 311,666 | 85.4% | 4 | 4/4 |
来源在检查载荷之前固定:NVIDIA cuTile Python 提交 068039e,GROMACS v2026.3。
4.4 Rubin 编码器的持续适配
对 Rubin 这类新引入的架构,起初可用的 CUBIN 语料可能很大,但对指令域的采样仍不均衡。持续训练使 F2Asm 能随新 CUBIN 的出现扩展现有编码器。我们用算法 1,根据 cuTile 与 GROMACS 评估中发现的不受支持查询更新 Rubin 编码器。含不受支持查询的 24 个 CUBIN 成为适配数据;4 个完全受支持的 GROMACS CUBIN 无需用于更新。
在受影响的映射组上,算法 1 处理了 5,431 条证据行。其中 1,504 条线性无关并扩展了编码器,与表 7 的下界吻合;其余 3,927 条确认了与所学映射的一致性。全部 206 个受影响映射组均一致,更新使全部 17,159 条此前不受支持的查询变为可支持。更新新增了 1 种指令形式、100 个仿射映射和 1,504 行基,使仓库达到 369 种形式、3,528 个映射、56,461 行基。
表 7. 适配前不受支持的 Rubin 查询,以及支持它们所需的最少新增独立指令观测数。Obs. 表示不受支持的指令观测数。
| 来源 | Obs. | 查询数 | 形式数 | 映射数 | Σ_g δ_g |
|---|---|---|---|---|---|
| cuTile | 3,702 | 3,421 | 21 | 33 | 104 |
| GROMACS | 53,134 | 13,738 | 63 | 173 | 1,400 |
| 合计 | 56,836 | 17,159 | 75 | 206 | 1,504 |
以三种不同顺序处理这 24 个 CUBIN 产生了相同的仓库,重放它们也不再引起任何变化。序列化并重新加载后,更新后的编码器在用于更新的全部 24 个 CUBIN 上通过严格往返。这些结果实证表明:持续训练过程在所测批次顺序下与顺序无关,且在重放下幂等。
5 相关工作
早期 CUDA 汇编器在更窄的范围内恢复编码。MaxAs 与 TuringAs 实现手工恢复的编码规则(Gray,2015;Yan 等,2020)。Decoding CUDA Binary 自动化指令格式恢复(Hayes 等,2019),而 CuAssembler 从"反汇编---二进制"配对中学习算术编码关系(cloudcores,2019)。CuAsmRL 在 SASS 调度循环内部使用这样一个汇编器(He & Yoneki,2025)。F2Asm 的不同之处在于:将编码学习为 𝔽₂ 上的向量值仿射映射;用精确高斯消元压缩观测并检验行张成支持性;并使用一套共享流水线与特定目标配置覆盖 Hopper SM90/SM90a、Blackwell SM100 与 Rubin SM107。
F2Asm 实证确立了 5 个 Blackwell SM 目标共享同一套 SASS 指令编码方案。Jia 等人发现了从 Volta 到 Turing 的类似延续性:Turing 对公共指令保留了 Volta 的编码(Jia 等,2019)。这些相互独立的发现共同表明,NVIDIA 在相关目标与世代之间反复保持了指令编码的延续。
F2Asm 对显式提供的调度器控制字段进行编码,但尚不能合成或优化它们。自动调度是一个序列级问题,与其指令局部的 𝔽₂ 编码器相分离。它需要特定目标的延迟模型、依赖分析、记分板屏障分配与硬件验证。MaxAs 为 Maxwell 提供基于规则的调度,而 CuAssembler 将控制字段留给程序员(Gray,2015;cloudcores,2019)。CuAsmRL 在保留原始控制字段的前提下搜索局部重排的调度,并拒绝违反所建模的寄存器、屏障、延迟或同步约束的交换(He & Yoneki,2025)。为 F2Asm 扩展目标感知的调度器仍是未来工作。
6 结论
F2Asm 将精确的 128 位 NVIDIA SASS 编码器学习为 𝔽₂ 上的仿射映射。流式高斯消元构建紧凑的基、检测不一致的证据,并拒绝不受支持的输入。据我们所知,F2Asm 是第一个支持 Rubin SM107 指令编码与 CUBIN 重建的开源 SASS 汇编器。一个联合训练的 Rubin 编码器同时支持 SM107、SM107a 与 SM107f。跨 5 个 Blackwell SM 目标的联合训练提供了强有力的实证:NVIDIA 对这些目标间共享的指令使用共同的 SASS 编码方案。对 Rubin,持续训练使全部 17,159 条此前不受支持的 cuTile 与 GROMACS 查询变得可编码,仅新增 1,504 行线性无关基------恰好是受影响映射组所需的最小数量。F2Asm 为 SASS 编程智能体、手工调优内核以及面向近期 NVIDIA GPU 架构的微基准测试提供了一个开源汇编后端。
参考文献
参考文献保留原文著录格式。
- cloudcores. CuAssembler: An unofficial CUDA assembler. https://github.com/cloudcores/CuAssembler, 2019. 软件仓库,2026 年 8 月访问。
- Dao, T. Flashattention-2: Faster attention with better parallelism and work partitioning. CoRR, abs/2307.08691, 2023. doi: 10.48550/ARXIV.2307.08691.
- Dao, T., Fu, D. Y., Ermon, S., Rudra, A., and Ré, C. Flashattention: Fast and memory-efficient exact attention with io-awareness. CoRR, abs/2205.14135, 2022. doi: 10.48550/ARXIV.2205.14135.
- FlashInfer Team. flashinfer-cubin 0.6.13. Python package, 2026. https://pypi.org/project/flashinfer-cubin/0.6.13/. 预编译 CUDA 内核 CUBIN;2026-08-27 访问。
- Gai, J., Zhang, S., Bostrom, K., Huang, J., Patil, V., Fang, H., Wang, Y., Rangwala, H., and Karypis, G. Optimizing CUDA like a human: Micro-profiling tools as expert surrogates for LLM-based GPU kernel optimization. CoRR, abs/2606.26453, 2026. doi: 10.48550/ARXIV.2606.26453.
- Gray, S. MaxAs: Assembler for NVIDIA Maxwell architecture. GitHub repository, 2015. https://github.com/NervanaSystems/maxas. 2026-08-17 访问。
- Gray, S. SGEMM. MaxAs wiki, 2017. https://github.com/NervanaSystems/maxas/wiki/SGEMM#calculating-c-register-banks-and-reuse. 小节"Calculating C: Register Banks and Reuse";2017-04-18 更新;2026-09-05 访问。
- Hayes, A. B., Hua, F., Huang, J., Chen, Y., and Zhang, E. Z. Decoding CUDA binary. In IEEE/ACM International Symposium on Code Generation and Optimization, CGO 2019, pp. 229--241. IEEE, 2019. doi: 10.1109/CGO.2019.8661186.
- He, G. and Yoneki, E. Cuasmrl: Optimizing GPU SASS schedules via deep reinforcement learning. In Proceedings of the 23rd ACM/IEEE International Symposium on Code Generation and Optimization, CGO 2025, pp. 493--506. ACM, 2025. doi: 10.1145/3696443.3708943.
- Hungerford, T. W. Algebra, volume 73 of Graduate Texts in Mathematics. Springer-Verlag, New York, 1980. ISBN 978-0-387-90518-1. doi: 10.1007/978-1-4612-6101-8.
- Jia, Z., Maggioni, M., Smith, J., and Scarpazza, D. P. Dissecting the NVIDIA Turing T4 GPU via microbenchmarking. CoRR, abs/1903.07486, 2019. doi: 10.48550/ARXIV.1903.07486.
- Mullen, G. L. and Panario, D. (eds.). Handbook of Finite Fields. Discrete mathematics and its applications. CRC Press, 2013. ISBN 978-1-439-87378-6.
- NVIDIA Corporation. CUDA Binary Utilities: Instruction Set Reference. NVIDIA Corporation, 2026a. https://docs.nvidia.com/cuda/archive/13.1.1/cuda-binary-utilities/index.html. CUDA Toolkit Documentation, Release 13.1.1,2026 年 5 月 26 日访问。
- NVIDIA Corporation. CUDA 13.4 Developer Preview: Linux x86_64 Binary Archives. NVIDIA Corporation, 2026b. https://packages.nvidia.com/bin-archive/linux-x86_64/preview/. 2026 年 8 月 20 日访问。
- NVIDIA Corporation. cuTile Python. NVIDIA Corporation, 2026c. https://docs.nvidia.com/cuda/cutile-python/. CUDA 文档,2026 年 9 月 13 日访问。
- Oxley, J. Matroid Theory, volume 21 of Oxford Graduate Texts in Mathematics. Oxford University Press, Oxford, second edition, 2011. ISBN 978-0-19-856694-6. doi: 10.1093/acprof:oso/9780198566946.001.0001.
- Páll, S., Abraham, M. J., Kutzner, C., Hess, B., and Lindahl, E. Tackling exascale software challenges in molecular dynamics simulations with GROMACS. In Solving Software Challenges for Exascale --- EASC 2014, volume 8759 of LNCS, pp. 3--27. Springer, 2015. doi: 10.1007/978-3-319-15976-8_1.
- Shah, J., Bikshandi, G., Zhang, Y., Thakkar, V., Ramani, P., and Dao, T. Flashattention-3: Fast and accurate attention with asynchrony and low-precision. CoRR, abs/2407.08608, 2024. doi: 10.48550/ARXIV.2407.08608.
- Yan, D., Wang, W., and Chu, X. Optimizing batched Winograd convolution on GPUs. In PPoPP '20: 25th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming, pp. 32--44. ACM, 2020. doi: 10.1145/3332466.3374520.
附录 A 支持的目标
表 8 列出了已评估的目标。"支持"的目标拥有训练好的编码器,并已在第 4 节报告的覆盖率下完成字节级精确往返评估。操作码(Opcodes)统计不同的受支持助记符,形式(Forms)统计不同的"助记符 + 有序操作数类型"结构。SM90/SM90a 共享一个编码器;SM100、SM100f、SM100a、SM103 与 SM103a 共享一个 Blackwell 编码器;SM107、SM107f 与 SM107a 共享一个 Rubin 编码器。
表 8. 已评估实现中的精确目标支持。
| 目标 | 架构 | 状态 | 操作码数 | 形式数 |
|---|---|---|---|---|
| sm_90/90a | Hopper | 支持 | 140 | 389 |
| sm_100/100f/100a、sm_103/103a | Blackwell | 支持 | 153 | 388 |
| sm_107/107f/107a | Rubin | 支持 | 153 | 369 |
将 F2Asm 扩展到更多 SM 架构仍是未来工作。其学习与训练流水线是跨目标共享的。计划中的未来目标包括 SM110*、SM120* 与 SM121*。
附录 B 流式高斯消元算例
本简化示例使用 4 位特征向量与 8 位编码字来展示每个消元步骤。F2Asm 对更大的特征向量与 128 位指令字应用相同算法。令 q = q₃, q₂, q₁, q₀ 为输入特征向量,q_res 为其当前残差(初始等于 q)。对非零残差,主元 k = msb(q_res) 是其最高置位索引,0 ≤ k ≤ 3。基表按主元位置 k 索引。每个存储项 Bk = (rₖ, zₖ) 包含主元为 k 的基向量 rₖ 及其对应的归约输出字 zₖ。
四条观测按如下顺序到达:
| 观测 | q | y |
|---|---|---|
| 1 | 1100 | 10011111 |
| 2 | 1000 | 10100101 |
| 3 | 1010 | 01100110 |
| 4 | 0110 | 11111001 |
观测 1 的最高置位为 q₃ = 1,故其主元 k = 3。由于基中尚无该主元的行,训练存储
B3=(1100, 10011111).(11)B3 = (1100,\ 10011111). \tag{11}B3=(1100, 10011111).(11)
观测 2 起初同样有 k = 3。与已存配对做 XOR 会同时更新两个残差并暴露新主元:
(1000, 10100101)⊕B3=(0100, 00111010),k:3→2.(12)(1000,\ 10100101) \oplus B3 = (0100,\ 00111010), \qquad k: 3 \to 2. \tag{12}(1000, 10100101)⊕B3=(0100, 00111010),k:3→2.(12)
在把新配对存到主元 2 之前,训练先将其异或进 B3,以从该已有行中清除第 2 位:
B3←(1100, 10011111)⊕(0100, 00111010)=(1000, 10100101).(13)B3 \leftarrow (1100,\ 10011111) \oplus (0100,\ 00111010) = (1000,\ 10100101). \tag{13}B3←(1100, 10011111)⊕(0100, 00111010)=(1000, 10100101).(13)
随后训练将新配对存为 B2 = (0100, 00111010)。此时基的秩为 2,包含 B3 与 B2。
观测 3 先经主元 3,随后暴露主元 1:
(1010, 01100110)⊕B3=(0010, 11000011),k:3→1.(14)(1010,\ 01100110) \oplus B3 = (0010,\ 11000011), \qquad k: 3 \to 1. \tag{14}(1010, 01100110)⊕B3=(0010, 11000011),k:3→1.(14)
训练将该配对存为 B1。所得的秩-3 基为
B3=(1000, 10100101),B2=(0100, 00111010),B1=(0010, 11000011).(15)B3 = (1000,\ 10100101), \quad B2 = (0100,\ 00111010), \quad B1 = (0010,\ 11000011). \tag{15}B3=(1000, 10100101),B2=(0100, 00111010),B1=(0010, 11000011).(15)
观测 4 依次访问主元 2 → 1:
(0110, 11111001)⊕B2=(0010, 11000011),⊕ B1=(0000, 00000000).(16)(0110,\ 11111001) \oplus B2 = (0010,\ 11000011), \quad \oplus\, B1 = (0000,\ 00000000). \tag{16}(0110, 11111001)⊕B2=(0010, 11000011),⊕B1=(0000, 00000000).(16)
两个残差均为零,故该观测是冗余的,被丢弃。若其输出改为 11111000,则最终残差将是 (0000, 00000001):相同特征却对应两种不同编码,训练将报告矛盾。
因此训练保留三对基 B3、B2、B1,构成秩-3 模型。第四条观测没有增加新信息。现在我们用这个固定的基来编码未见过的输入。
编码时,F2Asm 只接收查询特征向量,并将输出累加器初始化为零。未见查询 1110 不在四条训练观测之中。它依次访问主元 3 → 2 → 1:
| 操作 | q_res | y_acc |
|---|---|---|
| 初始 | 1110 | 00000000 |
| ⊕ B3 | 0110 | 10100101 |
| ⊕ B2 | 0010 | 10011111 |
| ⊕ B1 | 0000 | 01011100 |
零特征残差证明该未见查询受支持;最终累加器值 y_acc = 01011100 即该查询的 8 位编码。
对未见查询 q = 1001,用 r₃ = 1000 归约后留下
qres=1001⊕1000=0001.(18)q_{res} = 1001 \oplus 1000 = 0001. \tag{18}qres=1001⊕1000=0001.(18)
残差的主元为 0,但式 (15) 中训练好的基只含主元 3、2、1 的行。因此残差无法消除。F2Asm 拒绝该查询,丢弃部分累加器,不输出任何编码。
附录 C 端到端指令生命周期
本附录展示 F2Asm 如何学习并应用一个精确的指令编码器。它将编码方程的离线求解与运行时汇编分离,然后追踪一条 SM100 Tensor Core 指令从 SASS 文本到最终 16 字节指令字的全过程。该示例通过展示解析特征、存储的 𝔽₂ 系数、所学输出重建、调度器控制合并与 CUBIN 验证,使第 2 节的模型具体化。图 3 总结了这两个阶段。观测来自 NVIDIA cuDNN 9.25.0.15,CUBIN SHA-256 前缀 02618e0d,程序计数器 0x54d0。运行时输入为:
[B--23--:R-:W-:-:S01]
HMMA.16816.F32.BF16 R4, R68.reuse, R72, R4;
HMMA 按目的操作数 D、源操作数 A、源操作数 B、累加器 C 的顺序有四个寄存器操作数,并计算 D ← AB + C。本例中它们分别是 R4、R68、R72、R4。R68 上的 .reuse 后缀将第一源操作数 A 标记为操作数复用,使其值可被后续指令保留使用(Gray,2017)。复用标志按源操作数位置编码,而非按寄存器编号。
方括号前缀提供调度器控制 sc = 0x067f1。F2Asm 的 SASS 解析器产生形式 f = HMMA R R R R,修饰符元组 m = (HMMA, 16816, F32, BF16, 第一源操作数复用),以及值 v = (7, 4, 68, 72, 4)。它们的操作数角色为
(v0,v1,v2,v3,v4)=(PT,D,A,B,C)=(7,4,68,72,4).(19)(v_0, v_1, v_2, v_3, v_4) = (\mathrm{PT}, D, A, B, C) = (7, 4, 68, 72, 4). \tag{19}(v0,v1,v2,v3,v4)=(PT,D,A,B,C)=(7,4,68,72,4).(19)
式 (4) 给出所得的 ϕ(x) ∈ 𝔽₂³²¹。
式 (4) 提供每条训练方程的输入侧,而观测到的指令字提供式 (2) 中的 y。高斯消元对两侧施加相同的 XOR 行操作,产生存储对 (rₖ, zₖ)。这里 rₖ ∈ 𝔽₂ᵈ 是归约特征向量,其最高活跃特征 k 即其主元;zₖ ∈ 𝔽₂¹²⁸ 是相应归约后的指令字。因此每对满足
rk⏟1×d W⏟d×128=zk⏟1×128.(20)\underbrace{r_k}{1\times d}\;\underbrace{W}{d\times 128} = \underbrace{z_k}_{1\times 128}. \tag{20}1×d rkd×128 W=1×128 zk.(20)
要编码输入 SASS 指令 x,F2Asm 用已存的 rₖ 行归约 ϕ(x),并把对应的 zₖ 字异或进输出。

图 3. 指令生命周期的两个阶段。训练构建可复用的精确基;运行时汇编对其进行查询,若特征向量不受支持则失败。(图中上:离线训练------CUBIN → 提取 (x, y_learned);解析并向量化 → (f, p, ϕ(x));高斯消元 → 归约基 {(rₖ, zₖ)}。下:运行时汇编------输入 SASS 与控制 sc → (f, p, ϕ(x));用已存 rₖ 归约 ϕ(x),异或匹配的 zₖ;要求零残差,将 y_learned 与 sc ≪ 105 合并;写出 16 字节 → 重建 CUBIN → 比较 .text.*。)
对该 HMMA 示例所用的所学编码映射,16 条观测产生秩-16 基。F2Asm 把该所学映射存储为归约基对 (rₖ, zₖ),而非稠密的 321 × 128 系数矩阵。表 9 展示了在归约此 HMMA 查询时选出的、共享映射 16 个存储基对中的 5 个,其余 11 对对本查询的归约系数为零。
表 9. 该 HMMA 示例所用编码映射的 16 个存储基对中的 5 个。这里 vᵢb 表示解析值 vᵢ 的第 b 位;每个 zₖ 以 128 位十六进制字显示。
| k | rₖ 中的活跃特征 | zₖ(128 位十六进制) |
|---|---|---|
| 259 | v₁2 ⊕ v₂2 ⊕ v₄2 | 00000000000000040000000004040000 |
| 199 | v₃6 | 00000000000000000000004000000000 |
| 196 | v₃3 | 00000000000000000000000800000000 |
| 135 | v₂6 | 00000000000000000000000040000000 |
| 3 | 1 ⊕ v₀0 ⊕ v₀1 ⊕ v₀2 | 0400000000041800000000000000723c |
对该输入,活跃特征向量分解为
ϕ(x)=r259⊕r199⊕r196⊕r135⊕r3.(21)\phi(x) = r_{259} \oplus r_{199} \oplus r_{196} \oplus r_{135} \oplus r_{3}. \tag{21}ϕ(x)=r259⊕r199⊕r196⊕r135⊕r3.(21)
残差特征向量变为零,证明该查询受支持。异或五个系数得到所学的非调度器指令位:
ylearned=z259⊕z199⊕z196⊕z135⊕z3=0x0400000000041804000000484404723c.(22)y_{\mathrm{learned}} = z_{259} \oplus z_{199} \oplus z_{196} \oplus z_{135} \oplus z_{3} = \texttt{0x0400000000041804000000484404723c}. \tag{22}ylearned=z259⊕z199⊕z196⊕z135⊕z3=0x0400000000041804000000484404723c.(22)
调度器控制与所学指令位分开表示。SM100 配置将其 17 个位放在第 105--121 位:
sc≪105=0x00cfe200000000000000000000000000,sc \ll 105 = \texttt{0x00cfe200000000000000000000000000},sc≪105=0x00cfe200000000000000000000000000,
yfull=ylearned⊕(sc≪105)=0x04cfe20000041804000000484404723c.(23)y_{\mathrm{full}} = y_{\mathrm{learned}} \oplus (sc \ll 105) = \texttt{0x04cfe20000041804000000484404723c}. \tag{23}yfull=ylearned⊕(sc≪105)=0x04cfe20000041804000000484404723c.(23)
F2Asm 将 y_full 输出为以下 16 个小端字节并写入可执行节:
3c 72 04 44 48 00 00 00
04 18 04 00 00 e2 cf 04
随后,重建的 CUBIN 通过与全语料往返评估相同的字节级精确 .text.* 比较。
同样的 (f, p, v, ϕ) 表示也适用于 Blackwell 的带描述符与张量内存操作数的 UTCOMMA 指令(NVIDIA Corporation,2026a)。下面的 SM100f 示例来自 flashinfer-cubin==0.6.13(CUBIN SHA-256 前缀 04b33a6d):
UTCOMMA.2CTA.4X gdesc[UR42],
gdesc[UR52], tmem[UR73],
tmem[UR22], idesc[UR23],
tmem[UR26], UPT;
F2Asm 解析出包括隐式守卫在内的八个值
v=(7,42,52,73,22,23,26,7),v = (7, 42, 52, 73, 22, 23, 26, 7),v=(7,42,52,73,22,23,26,7),
得到特征向量 ϕ(x) ∈ 𝔽₂⁵¹³。第 4 节报告了在 Blackwell 与 Rubin 指令语料上的字节级精确验证。
附录 D 被 NVDISASM 省略的 DEPBAR 位
DEPBAR 是 SASS 的依赖屏障指令(NVIDIA Corporation,2026a)。示例反汇编为 DEPBAR.LE SB5, 0x2。对于 DEPBAR SB II 上下文中的这条指令,nvdisasm 在其文本输出中省略了第 122 位和第 124 位。这些位位于复用/控制区(第 122--125 位),紧邻调度器控制位(第 105--121 位)。
一个 SM100 示例把这种歧义具体化。清除调度器控制位后,两条观测给出
word A = 0x00000000000000000000d0800000791a
word B = 0x14000000000000000000d0800000791a
nvdisasm(A) = DEPBAR.LE SB5, 0x2;
nvdisasm(B) = DEPBAR.LE SB5, 0x2;
A XOR B = 0x14000000000000000000000000000000
XOR 结果仅在第 122 位和第 124 位为 1。因此 nvdisasm 的文本输出无法确定这两个位的取值。这是 nvdisasm 输出的局限,而非 F2Asm 编码模型的局限。我们在 SM100 上发现 6 处歧义位置,在 SM103 上发现 187 处,而在所收集的 SM100a、SM100f 或 SM103a 语料中均未发现。
F2Asm 显式处理 nvdisasm 的这一局限。它对该上下文应用一个与目标无关的不透明掩码(opaque mask),把第 122 位和第 124 位排除在所学指令位之外。在 CUBIN 到汇编的导出过程中,F2Asm 在增强的 :H... 状态中记录原始高半部分状态。汇编在所学编码之后恢复掩码选定的位。这在不把 SM 目标用作特征或所学映射选择器的前提下,保持了字节级精确重建。
未来工作将确定这些位是否具有架构含义。若有,F2Asm 可以把它们暴露为解析修饰符或特征,并像其他指令字段一样编码;否则,为保持字节级精确重建,显式的不透明状态保存仍然必要。