GPU 内核,第二部分:用监督微调和 GPU 训练场教会 27B 模型写 Triton 内核
在第一部分里,我们剖析了 GPU 内核的底层原理——为什么算子融合和内存分块如此重要,以及 KernelBench 这类基准测试如何评估大语言模型(LLM)写出的内核是否真能跑赢 PyTorch。本文是动手实践的续篇。我们拿开源模型 Qwen3.8-27B 开刀,分两个阶段训练它写 Triton 内核:先是在 2,034 个高质量内核上做监督微调(SFT),这些内核全部在 NVIDIA H100 上重新验证过;然后把它放进一个自动化的 GPU 训练场做强化学习(RL),每个候选内核都会经过编译、正确性验证和性能跑分。
在标准的 200 道 KernelBench 题目上评估(每题只做一次贪婪解码),所有主要指标都在往好的方向走。整体正确率从 21.5% 提升到 29.5%。既数学正确又比原生 PyTorch 跑得快的内核,占比从 7.0% 涨到 9.5%。在 Level 1(单个独立算子)上,模型现在能解出 47 道题,此前是 31 道;能跑赢 PyTorch 的有 15 道,此前是 8 道。
但与此同时,前沿商业模型仍然保持明显领先。下面我们会拆解数据集和验证训练场是怎么搭的,每个训练阶段各自取得了什么成果,奖励设计里那些微妙坑——训练场一度教会了模型错误的策略——以及要抹平剩下的性能差距还需要做些什么。
开源权重与数据:发布的检查点已上传至 Hugging Face,名为 Qwen3.8-27B-GFT-Triton-Kernels-LoRA,附带可直接用于 vLLM 的配置和我们完整的评估工具链。SFT 训练集也已开放,名为 GFT-Triton-Kernels-SFT-H100-Verified:包含 2,034 对 PyTorch 到 Triton 的转换样本,每一对都在 H100 上编译并验证过。本文提到的所有指标都收录在 JSON 下载包里。
KernelBench Triton,Level 1–2(共 200 题),每题一次贪婪回答,H100,FP32。对比对象:基座模型、SFT 之后、以及 SFT + RL 之后(即发布的检查点)。
| 指标 | 基础模型 | SFT 后 | SFT + RL 后 | 变化 |
|---|---|---|---|---|
| 编译并成功运行的答案 | 79.5% | 86.5% | 88.5% | +9.0 个百分点 |
| 正确(fast₀) | 21.5% | 26.0% | 29.5% | +8.0 个百分点 |
| 正确且快于 eager PyTorch(fast₁) | 7.0% | 8.0% | 9.5% | +2.5 个百分点 |
| … 快于 1.5 倍以上(fast₁.₅) | 5.0% | 5.0% | 6.0% | +1.0 个百分点 |
| … 快于 2 倍以上(fast₂) | 3.5% | 4.5% | 5.0% | +1.5 个百分点 |
| 正确且快于 torch.compile | 12.5% | 15.0% | 16.0% | +3.5 个百分点 |
| Level 1 正确 | 31.0% | 43.0% | 47.0% | +16.0 个百分点 |
| Level 1 快于 eager | 8.0% | 13.0% | 15.0% | +7.0 个百分点 |
| Level 2 正确 | 12.0% | 9.0% | 12.0% | ±0.0 个百分点 |
| Level 2 快于 eager | 6.0% | 3.0% | 4.0% | −2.0 个百分点 |
从这里开始
我们如何构建一套在目标 GPU 上验证过的 SFT kernel 数据集;kernel gym 如何给答案打分并转化为奖励;七个 gym 版本以及各自失败的原因;SFT 和 RL 在 KernelBench 上分别改变了什么;Level 2 为何没有提升;前沿模型在同样 200 道题上的表现对比。
-
SFT:有监督微调(Supervised Fine-Tuning),用带有已验证目标答案的示例提示进行训练。
-
RL / GRPO:强化学习(Reinforcement Learning),模型对每个任务生成 8 个答案,得分高于组内平均的候选会获得正向策略梯度。
-
Gym:执行环境,负责分发任务并给答案打分,包含一个参考 PyTorch 模块和一个隔离的 H100 工作节点来对结果做基准测试。
-
Verifier gate:验证门,一个二元通过/失败检查。未通过硬性门槛的答案,无论其他方面多好,该回合奖励直接归零。
-
Hybrid answer:混合答案,把计算密集的底层操作留在 PyTorch 里(cuDNN 卷积或 cuBLAS GEMM),只对融合激活的尾部用 Triton 编写。
-
fast₁:在所有题目中,答案数学上正确且严格快于基线的比例。fast₀ 则是正确率。
-
LoRA:低秩适配(Low-Rank Adaptation),只更新小型低秩分解矩阵,而不是全部 27B 权重。我们的适配器使用秩 8。
1. 评分标准
为了保证比较的严谨和公平,本文中每个模型都使用完全相同的测试框架:KernelBench(第 1、2 级,Triton 后端),提示词逐字节相同,并在同一块 NVIDIA H100 SXM 上运行同一套验证程序。第 1 级覆盖 100 个独立算子(矩阵乘法、卷积、归一化、激活函数和损失函数)。第 2 级测试 100 个复合模块——通常是一个大型 GEMM 或卷积,后面接一段逐元素运算,这种结构下算子融合有明显优化空间。(第 1 部分详细介绍了 KernelBench 如何评估提交结果,以及对比基准时需要注意的关键点)。
本文中每个 Qwen 检查点的评估协议。
| 基准 | KernelBench 修订版 423217d,Triton 后端,第 1–2 级,共 200 道题 |
| 提示 | KernelBench 针对 FP32 的一次性 Triton 提示,系统提示为“You are a helpful assistant” |
| 解码 | vLLM,贪心解码(temperature 0),关闭思考模式,最多生成 8,192 个新 token,每题一个答案 |
| 正确性 | 5 组随机输入,FP32,atol = rtol = 1e-4 |
| 计时 | 100 次 CUDA event 运行取均值,对照同一 GPU 上的 eager PyTorch 和 torch.compile(mode="max-autotune") |
| 硬件 | NVIDIA H100 80GB HBM3;PyTorch 2.9.1,Triton 3.5.1,CUDA 13.0 |

2. SFT 和 RL 带来了什么变化
未经训练时,基础版 Qwen3.8-27B 已经能理解基本的 Triton 语法——大约五分之四的生成答案能编译并运行,没有语法错误。它欠缺的是数值精度(正确处理边界条件和索引计算)以及击败 PyTorch 所需的架构直觉。我们的两阶段训练同时解决了这两个问题:

-
编译可靠性更高:能干净地编译并执行的方案从 79.5% 升到 88.5%。Level 2 上提升更明显(76 → 94),因为模型学会了避开无效的张量形状,以及会触发驱动崩溃的非法内存访问。
-
正确率提升超过三分之一:通过全部验证检查的任务从 200 个里的 43 个增加到 59 个。Level 1 上的跃升尤其明显(31 → 47),相当于通过验证的独立算子增加了 50%。
-
加速比随准确率一起提高:既在数学上正确、又比 eager PyTorch 更快的 kernel,从 14 个任务增加到 19 个。跟 torch.compile 相比,快速方案从 25 个增加到 32 个,2 倍以上加速的从 7 个增加到 10 个。Level 1 上,快速 kernel 的数量几乎翻倍(8 → 15)。
监督微调为正确率打下了基础(Level 1:31 → 43),RL 则进一步打磨了边缘情况的处理。由于每个检查点都在完全相同的问题集上评估,我们可以做配对 bootstrap 分析。与 SFT 基线相比,最终的 RL 检查点成功解决了之前失败的 8 个问题,只有 1 个出现回退:
在同一组 200 个问题上相对 SFT 适配器的变化,单位为百分点,附 95% 配对 bootstrap 区间(对问题重采样 100,000 次)。一次 300 步 RL 训练中的四个检查点。
| RL 检查点 | 正确率 | 比 eager 快 | 比 torch.compile 快 |
|---|---|---|---|
| Step 100(已发布) | +3.5 [+1.0; +6.5] | +1.5 [−0.5; +4.0] | +1.0 [±0.0; +2.5] |
| Step 150 | +3.0 [±0.0; +6.0] | +1.5 [±0.0; +3.5] | ±0.0 [−2.0; +2.0] |
| Step 200 | +1.0 [−1.5; +3.5] | +0.5 [−1.0; +2.5] | +0.5 [−1.0; +2.5] |
| Step 300 | +1.5 [−2.0; +5.0] | ±0.0 [−2.0; +2.0] | −1.0 [−3.0; +1.0] |
引导重采样得到的置信区间说明,第 100 步的正确率提升在统计上是有意义的:提升了 3.5 个百分点,95% 置信区间为 [+1.0, +6.5]。相比 SFT,速度提升更有限,置信区间下界几乎贴到零。第 100 步之后性能进入平台期;由于我们是在能看到后续 checkpoint 的情况下挑选了第 100 步,因此它的数字反映的是整轮运行中的最优选择。Level 2 仍是明显的例外:整体正确率保持在 12 道题,但快速 kernel 从 6 个略微降到 4 个。第 6 节会拆解这一平台期背后的机制。
3. 第一阶段:在目标 GPU 上验证过的 SFT 数据集
公开网页抓取的 kernel 数据集纸面上看很可观,但有一个严重的资质问题:大多数样本只用极小的玩具输入验证过,或者在消费级 GPU 上用宽松容差跑过,甚至从未真正执行。为了让 SFT 教会模型真实的 GPU 行为,我们构建了一个过滤后的数据集,其中每一个样本都必须在 NVIDIA H100 上以生产规模通过严格的执行检查:

-
精选开源数据:我们从 siro1 合集中 KernelBook 模块的 Kimi K2 解法开始。每个问题都重构为 KernelBench 的标准接口(Model→ModelNew,位置参数 get_init_inputs),每个模块最多纳入两个解法。
-
真实的张量规模:KernelBook 的参考形状经常默认使用 4 × 4 × 4 × 4 这样的玩具维度,此时执行时间主要由驱动开销而非内存带宽决定。我们把张量维度扩大到约 1,000,000 个元素,并在这些生产负载下重新验证所有 kernel。
-
严格的去污染:任何问题只要与 270 个 KernelBench 问题中的任意一个 token 集合 Jaccard 相似度超过 0.6,就会被清除。
-
强制纯 Triton 实现:静态 AST 检查会剔除那些在
forward()里偷偷回退到 PyTorch 算子的“作弊”解法。本意是设定质量门槛,但第 6 节会讲到,这个过滤器后来在复合模块上适得其反。 -
Gym 回放数据:我们加入了 682 个来自早期 gym 探索运行的已验证成功解法(每个算子族最多 40 个,防止简单的逐元素任务淹没数据分布)。
最终数据集包含 2,034 个已验证配对——其中 1,624 个在目标规模下优于 torch.compile——全部控制在 4,096 token 的上下文窗口内。我们在单张 H100 上训练了一个 rank-8 的 LoRA 适配器,2 个 epoch(3,674 步,学习率 2e-4),耗时约五小时。
4. 第二阶段:内核健身房
SFT 展示了结构良好的内核长什么样,而强化学习则赋予模型自主权:去实验、去调试编译器报错、去接收即时奖励信号。我们的内核健身房采用 OpenEnv 风格的架构:每个回合中,一个 worker 提供参考 PyTorch 模块,模型起草一份实现,然后一个隔离的 GPU 子进程在 H100 上对候选方案进行基准测试。

任务
这个训练环境会生成十四类不同的任务,覆盖 KernelBench 第 1 级和第 2 级涉及的操作范围。每个任务都由程序化种子动态实例化,种子中规定了数学算子、张量形状(规模从 100 万到 3200 万个元素,确保执行时间主要反映内存带宽,而非内核启动的抖动)以及测试数据的分布。对于那些模型一开始几乎无法完成的困难操作,我们引入了分阶段的课程变体:smallshape(小形状)、scaffold(脚手架,提供主机端设置和 tile 偏移,内部数学运算留空),以及 epilogue(尾声任务,核心库 GEMM 保持不变,只要求用 Triton 实现融合的激活尾部)。
最终训练环境中的任务家族如下:
| 家族 | 示例 | 分阶段变体 |
|---|---|---|
| 逐元素 | ReLU、GELU、LeakyReLU、sigmoid | — |
| 归约 | 行求和、均值和最大值;列求和 | — |
| 扫描 | 行和列的累积求和 | — |
| 归一化 | RMSNorm、LayerNorm | — |
| softmax | softmax、log-softmax | — |
| 融合 | SiLU 和 GELU 门控、add + ReLU | — |
| 矩阵乘法 | matmul、转置 matmul | small、scaffold |
| GEMM 尾声 | linear + ReLU 或 GELU,带残差和缩放 | small、epilogue |
| conv1d | 深度可分离 conv1d,带偏置、ReLU 或残差 | small、scaffold |
| conv2d | 3×3、步进和逐点卷积 | small、scaffold |
| pool2d | 最大池化和平均池化 | — |
| 模块 | linear 和 conv2d 模块、分组卷积 | small、scaffold |
| 融合混合 | conv + ReLU + 偏置、linear + GroupNorm + ReLU、linear + max + GELU;允许调用一次 cuBLAS/cuDNN | small、epilogue |
| KernelBook | 1,201 个经过验证的真实模块,输入规模扩大到约 100 万个元素 | — |
两种作答方式
训练片段以两种互补的交互格式运行:
-
单轮模式(占 25% 的片段):模拟 KernelBench 的标准提示格式,要求一次性给出完整解决方案,以便与基准评测对齐。
-
多轮修复模式(占 75% 的训练回合):模型可以反复调用
submit_kernel,通过inspect_evaluation查看编译器报错或运行时差异,在最多四次迭代中改进实现,最后再调用finalize。
最终训练中,模型解决了 63.8% 的修复回合,而单轮模式下只有 50.5%。这说明编译器反馈能把那些差一点就成功的实现救回来。
五道关卡
-
静态策略沙箱:只允许白名单内的导入;私有 PyTorch 内部接口和任意子进程调用在执行前就会被拦下。
-
编译与启动验证:代码必须干净编译,执行时必须确实在 GPU 上启动 Triton 核,这一点通过 CUDA 运行时事件来验证。
-
计算隔离:
forward()执行期间禁用 PyTorch 原生计算(混合任务中允许一次 cuBLAS/cuDNN 调用),确保实际算术由 Triton 核完成。 -
五个隐藏测试用例:覆盖正常规模、3 倍规模、0.01 倍规模、符号取反和绝对值,FP32 容差为
1e-4(按数值量级缩放)。这样能防止硬编码查表的作弊手法,也能验证非线性激活的两个分支。 -
低方差计时:候选核、eager PyTorch 和
torch.compile(mode="max-autotune")在同一块 GPU 上基准测试。只有运行间方差低于 10%(微型核上为 30 微秒)时,计时结果才会被接受。
奖励
奖励函数在正确性和性能之间取平衡。第 1 到第 3 关是硬性要求:如果代码编译失败、在计算上作弊或违反沙箱规则,奖励立刻归零。
其中,c 表示通过隐藏测试用例的比例,v 是相对基线的实测加速比,ρ 用来检查计时稳定性,e 则惩罚不必要的工具调用折腾。速度奖励有严格门槛:只有五个隐藏测试用例全部稳定通过,内核才能拿到速度分。对于复杂任务族,如果一组八个回答全部失败,那么在 1e-2 的宽松容差内答对部分也算部分进展分——这能提供梯度信号,把「差一点就对」和「语法完全崩掉」区分开。
RL 训练配方
下面是发布检查点所用的 RL 训练设置。
| 起点 | SFT 适配器(LoRA r = 8,alpha = 16,覆盖 q、k、v、o、gate、up 和 down 投影) |
| 算法 | GRPO 式分组,每个任务 8 个回答,每步一个任务,CISPO 损失,REPO-R 熵控制,KL β = 0.08 |
| 优化器 | 学习率 1e-5,线性调度,300 步;每 10 步存一次检查点 |
| 采样 | 温度 1.0,最多 6,144 个补全 token,关闭思考;八个回答得分全相同的组会重新采样 |
| 模型 | Qwen3.8-27B,4-bit NF4 加 BF16 LoRA(QLoRA),单张 H100 负责训练、生成和评分 |
| 实际耗时 | 300 步约 28 小时;300 步中有 294 步拿到了非零梯度 |
这套训练配置建立在我们之前的多奖励 RL 研究之上:CISPO 约束策略权重更新,同时不丢弃有信息量的 token;REPO-R 则维持探索熵。
5. 七个 gym 版本,以及各自被什么搞坏
前面说的验证环境是第 9 版。走到这一步,中间踩过七种不同的失败模式。正如我们在验证器手册里记录的那样,RL 智能体会毫不留情地利用环境里的每一个漏洞。要抓住奖励泄漏,唯一可靠的办法是在整个训练过程中直接检查生成的代码:
每个 gym 版本、我们在前一版中发现的问题,以及做了哪些改动。
| 版本 | 上一版发现的问题 | 改动 |
|---|---|---|
| v3 | 复制参考输入辅助函数的答案被当作不安全的代码提交而拒绝。 | 复制的辅助函数会被干净地剥离,而不是被惩罚。 |
| v4 | FP32 容差过于宽松,导致一些内核通过了测试,但后来被 KernelBench 拒绝。 | FP32 输出必须在 KernelBench 严格的 1e-4 容差内与参考张量匹配。 |
| v5 | 在困难的算子族上,一组中全部 8 个样本经常得零分(例如使用 TF32 的矩阵乘法未达到 1e-4),导致梯度为零。 | 在放宽的 1e-2 范围内匹配的内核可获得部分进度分,但严格低于已验证解。 |
| v6 | 速度奖励 clip(speedup − 1) 在 2 倍处饱和;在约 30 万元素的张量上,编译开销让几乎任何内核看起来都比 torch.compile 快 6–9 倍。已解出的内核无论质量如何都得分约 1.0,速度优化停滞。 | 将张量规模调整到 1–32M 元素;引入对数速度奖励,范围从 0.75 倍到 4 倍;内存使用量决定奖励资格。 |
| v7 | 没有任何机制验证 Triton 内核确实在 GPU 上运行,允许答案通过,而 PyTorch 在回退路径中静默处理计算。 | 引入原生执行门控:GPU 内核启动必须通过 CUDA 事件确认。移除仅宽松匹配的得分和对慢速内核的奖励。 |
| v8 | 训练环境与 KernelBench 出现偏差:提示不同,且缺少 2D 卷积/模块。审计发现内部 PyTorch 导入可能绕过计算保护,且一个种子 bug 只采样了 966 行 KernelBook 中的 69 行。 | 新增 14 个算子族,包括 conv2d、pool2d、scan、模块、混合类型和 KernelBook;新增单轮模式,提示与 KernelBench 逐字节一致;新增第五个隐藏用例(|x|);在混合类型中实现计算保护,仅允许恰好一次库调用;强制执行严格的导入白名单;修复行哈希。 |
| v9 | 复杂算子族(conv2d、模块、混合类型)的解决率仍接近零;不稳定或部分正确的内核偶尔能排在组内第一。 |
| 引入分阶段的课程练习;速度奖励只发给稳定且完全验证通过的 kernel;新增按完整执行图构建的分布外(OOD)留出集。
有两种失败模式,可以说明奖励机制里的 bug 有多隐蔽:
-
指标饱和(v5):我们最初把速度奖励的上限卡在 2 倍加速。对于约 30 万元素的小张量,几乎任何编译后的 Triton kernel 都能轻松比
torch.compile快 6 到 9 倍,原因只是编译开销。由于每个跑通的 kernel 都拿到满分 1.0,梯度就无法给模型施加任何继续优化的压力。我们的修复办法是:把测试张量扩大到 100 万到 3200 万元素,并把评分改成 0.75 倍到 4 倍的对数刻度。 -
沙箱绕过(v8):一次代码审计发现,只要导入某个冷门的 PyTorch 内部调度函数,就能悄悄关掉我们的计算守卫。虽然模型当时还没发现这个漏洞,但 RL 环境里留着一个可被利用的口子,迟早会出事。我们用严格的 AST 导入白名单把环境锁死了。
在训练场(gym)里,v9 的分阶段练习成功解决了冷启动问题。此前产出零个有效样本的算子族,开始稳定地提供梯度反馈:

6. 训练场与 KernelBench 的分歧
我们大部分的基准提升出现得很早:集中在监督微调阶段和 RL 的前 100 步。此后,训练场的指标还在继续爬升,但 KernelBench 上的表现却停滞了。在 v9 训练的四个季度里,训练场的解决率依次为 73.4% → 59.0% → 54.9% → 61.7%,而对应的 KernelBench 检查点 fast₁ 得分只有 9.5%、9.5%、8.5%、8.0%。
为什么在训练场里多做 RL 训练,却没能迁移到基准上?复盘之后,我们发现训练环境和 KernelBench 之间存在三处结构性错配:
6.1 另一种速度对照目标
这个 gym 衡量加速比时,对照的是 torch.compile(mode="max-autotune");而 KernelBench 对照的是普通(非编译)PyTorch。在 gym 所用的大尺寸 FP32 张量下,编译后的 PyTorch 反而常常是更慢的基线:

86.8% 的正确训练 kernel 打败了 torch.compile,但只有 61.4% 打败了 eager PyTorch。事实上,通过测试的 kernel 里有 26.2% 拿到了正的加速奖励,实际却比 eager 模式跑得慢。编译后运行时间的中位数比 eager 慢 2.1 倍。也就是说,奖励函数教模型跨过的门槛,比实际测试的门槛更容易。
6.2 Level 2 上的不同策略
KernelBench Level 2 包含 63 个卷积任务和 36 个矩阵乘法任务,每个任务都带一段逐元素的后处理尾部。要在原始卷积或大矩阵乘法上超过 NVIDIA 手工调优的 cuDNN 和 cuBLAS,难度极高。最有效的架构选择是混合实现:核心的矩阵乘法或卷积交给 cuBLAS/cuDNN,只把融合后的激活尾部写成自定义 Triton kernel。

早期,基础版 Qwen 自然就采用了这个策略,在 Level 2 上有 55% 的提交是混合实现。事实上,早期的一个检查点(gym v5)产出了 11 个快速的混合解——是所有 Qwen 模型里 Level 2 的最好成绩。
遗憾的是,我们后来的数据过滤和训练环境规则恰恰惩罚了这种行为。在整理 SFT 数据时,我们把混合代码过滤掉了;在训练环境里,也严格禁止调用 PyTorch 做计算。结果,SFT 模型只有 8% 的时候会提交混合方案,其余时候都在尝试用 Triton 从零重写完整的二维卷积——这种代码既容易出数值 bug,又明显比 cuDNN 慢。相比之下,Claude Opus 和 GPT-6 这类前沿模型在 Level 2 的回答里有 61% 到 93% 采用了混合方案,它们的高分几乎全靠这个策略。
6.3 练习题不等于考试
分阶段的课程练习(脚手架和尾声部分)确实为复杂算子打开了训练信号,但收益主要集中在那几个有辅助的变体上。到了基准评测里面对完整的、无辅助的 Level 2 模块时,模型就很难独立写出端到端的完整 kernel。一套有效的课程,最后一个阶段必须尽量贴近真实目标分布——全尺寸、无辅助。

7. 前沿模型在同样 200 道题上的表现
为了给这些结果一个参照,我们用同一个 H100 执行评分器,把四款前沿商业模型放到完全相同的 200 道 KernelBench 题上跑了一遍。这些模型通过各自的 CLI 接口调用,使用标准推理模式,所以这并非与贪心解码、非推理模式的 Qwen 做严格逐参数对齐的对比。尽管如此,这个比较仍能提供有价值的架构层面洞察:

Level 1–2,共 200 道题。fast₁ 按评分器的口径,把被标记的加速(超过 10 倍)计入;「未标记」一列则把这些结果剔除。
| 模型 | 正确率 | fast₁ 相对 eager | fast₁(未标记) | fast₂ | fast₁ 相对 torch.compile | 平均答案 token 数 |
|---|---|---|---|---|---|---|
| Qwen3.8-27B base | 21.5% | 7.0% | 7.0% | 3.5% | 12.5% | 未记录 |
| Qwen3.8-27B SFT + RL | 29.5% | 9.5% | 9.5% | 5.0% | 16.0% | 1,109 |
| Fable 5.1 | 70.0% | 46.5% | 43.0% | 17.5% | 43.5% | 2,906 |
| Opus 5.5 | 68.5% | 51.5% | 47.5% | 22.5% | 41.0% | 2,535 |
| GPT-6 Astra | 84.0% | 66.5% | 63.5% | 19.5% | 50.0% | 1,871 |
| GPT-6.1 Sol | 85.0% | 66.5% | 62.5% | 20.0% | 51.0% | 1,747 |
-
Level 1 与 Level 2 的差距:在独立的 Level 1 算子上,我们微调过的 27B 模型已经接近前沿水平:最强的商用模型在未标记 fast₁ 上只领先约 3 倍(47 对 15)。但在复合型的 Level 2 模块上,前沿模型领先 20 倍(81 对 4),原因几乎只有一个:它们能生成 cuDNN + Triton 的混合方案。
-
速度反常的标记:商用模型有 6 到 8 个方案报告的加速超过 10 倍。其中一部分确实是算子融合带来的真实收益,但极端离群值往往源于计时误差或基准测试的漏洞;把这些标记过滤掉后,fast₁ 分数会下降 3 到 4 个百分点。
-
生成预算差距:前沿模型消耗了大量推理预算,每题平均输出 1,747 到 2,906 个 token;而我们的直接贪心输出大约只有 1,109 个 token。
8. 下一步我们会改什么
-
让训练环境和基准的基线对齐:改为以 eager PyTorch 为基准(或采用 eager + 编译的联合目标),这样奖励就不会再鼓励那些被 KernelBench 判定为慢的 kernel。训练环境现在已经支持这个开关,后续训练可以直接使用。
-
拥抱混合模式:在 Level 2 类任务中,允许调用 cuBLAS/cuDNN 等库函数来处理大型 GEMM 和卷积,对融合的 elementwise 尾部给予奖励,并把这些混合实现保留在 SFT 语料里,而不是把它们过滤掉。
-
让课程锚定目标规模:早期探索阶段可以保留分阶段的脚手架,但要确保最终训练阶段在目标生产尺寸上给无辅助的完整任务足够权重。
-
多采样评估:每个问题只评估一个贪婪样本会引入噪声,1–3 个问题的差异很难解读。对每个任务用三个随机种子各跑一遍再取平均,虽然更费算力,但能更清楚地区分不同 checkpoint。
9. 局限
-
单一训练种子与贪婪采样:文中 Qwen 的数字来自单次训练运行,并在 temperature-0 的贪婪解码下评估。
-
选取运行中最优 checkpoint:Step 100 是在观察了所有 checkpoint 的评估结果之后才选出的,因此引入了轻微的选优偏差。
-
前沿模型条件不对等:商业前沿模型使用了厂商提供的 CLI 封装、多轮推理轨迹和随机采样;Qwen 则是在单轮贪婪执行、没有推理的条件下运行。
-
精度与架构范围:所有评估都在 NVIDIA H100 SXM 上以 FP32 进行,覆盖 KernelBench 的 Level 1 和 Level 2;Level 3 架构和其他代际 GPU 没有评估。
-
静态模式启发式判定:混合实现的分类(“保留了 PyTorch 算子”)是通过静态 AST 检查判定的,而不是动态运行时剖析。
本研究每张图表背后的遥测与配置数据都在 JSON 下载 中提供。模型权重和经过验证的训练数据集已在 Hugging Face 上开源:LoRA adapter 和 verified SFT dataset。
原文发表于 g-ftech.com。