ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CUDA Kernel Agent技术路线与评测实践综述

CUDA Kernel Agent技术路线与评测实践综述 1. 从手写Kernel到Agent自动调优这个方向为什么突然火了如果你在过去两年里持续关注GPU高性能计算这个圈子应该能明显感觉到一个变化以前大家聊CUDA Kernel优化聊的都是怎么手动调shared memory大小、怎么用__ldg做只读缓存、怎么把warp divergence压到最低。但从2025年下半年开始越来越多的讨论开始转向另一个话题——能不能让一个智能体Agent自己去写Kernel、自己去测性能、自己迭代优化这个转变不是凭空出现的。我自己的观察是三个因素叠加到了一起。第一大模型在代码生成上的能力已经跨过了一个临界点尤其是对CUDA这种有明确编译反馈和性能反馈的语言模型可以通过生成-编译-测速-修正的闭环不断逼近更优解。第二Kernel优化的搜索空间实在太大一个矩阵乘法的tiling策略组合轻松上百万种人工调优的经验再丰富也覆盖不全而Agent恰好擅长在这种大空间里做有方向的搜索。第三GPU算力本身越来越便宜但会写高性能Kernel的人越来越贵这个供需缺口逼着大家去找自动化方案。所谓CUDA Kernel Agent说白了就是一个能自主完成Kernel编写、性能评测、迭代改进的智能系统。它通常由几个部分组成一个负责生成代码的模型、一个负责编译和跑benchmark的执行环境、一个负责分析性能瓶颈的反馈模块以及一个决定下一步怎么改的决策策略。这四块拼在一起形成一个闭环让Kernel优化从人的手艺活变成系统的搜索过程。这篇文章适合谁看如果你是做GPU算子优化的工程师想了解自动化工具会怎么改变你的工作方式如果你是做AI Infra的在考虑要不要把Kernel调优纳入自动化流水线或者你是刚入门CUDA、想知道这个领域未来几年往哪走——那这篇综述性的梳理应该能给你一个相对完整的图景。我不会只罗列论文而是把每个技术路线的核心逻辑、实际效果、以及我踩过或见过的坑都摊开讲。2. Kernel Agent的四种技术路线各自解决什么问题2.1 基于编译反馈的迭代式生成最直接的一条路线是把编译器当成裁判。Agent生成一段CUDA代码交给nvcc编译如果编译失败就把错误信息喂回给模型让它修编译通过就跑benchmark拿到耗时再根据耗时决定要不要继续改。这个循环听起来简单但实际做起来有几个关键设计点。第一个点是错误信息的处理。nvcc的报错有时候非常冗长直接塞给模型会浪费大量context。我见过比较有效的做法是做一层错误摘要把哪个文件哪一行、什么类型的错误、最可能的修复方向提取出来再喂给模型。第二个点是性能反馈的粒度。只告诉Agent这次跑了2.3毫秒信息量太少更好的做法是同时给出occupancy、寄存器使用量、shared memory bank conflict次数这些底层指标让Agent知道瓶颈在哪。这条路线的好处是通用性强不依赖特定算子理论上任何能编译的Kernel都能优化。缺点是迭代次数多每次编译加跑benchmark都要时间一个复杂Kernel优化几十轮很常见算力成本不低。2.2 基于搜索的策略空间探索第二条路线不依赖模型想出好代码而是预先定义一个参数化的Kernel模板然后让Agent在参数空间里搜索。比如一个矩阵乘法模板可以参数化tile大小、线程块维度、是否用向量化加载、是否用double bufferingAgent的任务是找到最优参数组合。这条路线本质上和传统的auto-tuning比如TVM的Ansor、Triton的autotuner是一脉相承的但Agent的介入让搜索更有方向感。传统auto-tuning基本是网格搜索或随机搜索而Agent可以根据前几轮的结果推断哪些参数区间更有希望从而把搜索预算集中在高价值区域。我实测下来的感受是这条路线在成熟算子上非常稳因为它不会生成语法错误的代码搜索空间也是可控的。但它的天花板受限于模板本身的设计——如果模板里没有某个关键优化Agent再怎么搜也搜不出来。2.3 基于检索增强的经验复用第三条路线引入了外部知识库。Agent在优化一个新Kernel时会先去检索历史上类似算子的优化案例把相关的代码片段、优化技巧、性能数据作为参考再生成新的方案。这解决了一个很现实的问题模型本身的知识是静态的但Kernel优化的经验是不断积累的。检索的粒度可以很粗也可以很细。粗粒度是检索类似算子的完整优化方案细粒度是检索某个具体瓶颈的解决手法比如shared memory bank conflict怎么消除。我倾向于细粒度检索更有效因为粗粒度的方案往往和当前场景不完全匹配直接套用反而会误导模型。这条路线的一个隐藏难点是知识库的构建和维护。你得把每次优化的过程、结果、失败原因都结构化地存下来还要设计好的检索策略否则检索出来的东西要么不相关要么过时。2.4 多Agent协作的分工模式第四条路线是把优化任务拆给多个Agent各司其职。比如一个Agent专门负责分析性能瓶颈一个专门负责生成优化方案一个专门负责验证正确性还有一个负责做最终的性能回归测试。这种分工的好处是每个Agent的prompt可以更聚焦不用在一个prompt里塞进所有要求。但多Agent协作的代价是通信开销和协调复杂度。Agent之间怎么传递信息、怎么避免互相矛盾的建议、怎么在有限轮次内收敛这些都是工程上的硬骨头。我见过一些实现Agent之间来回讨论十几轮还没定下方案效率反而不如单Agent。下面这张表是我对这四条路线的横向对比方便你快速判断哪种更适合自己的场景路线核心机制优势主要局限适合场景编译反馈迭代生成-编译-测速-修正闭环通用性强不依赖模板迭代轮次多算力成本高新算子、无现成模板策略空间搜索参数化模板智能搜索稳定不会出语法错受限于模板设计成熟算子、有明确参数检索增强复用外部知识库生成能复用历史经验知识库构建成本高有积累的团队多Agent协作分工协调每个环节更专注通信开销大难收敛复杂优化任务3. 评测一个Kernel Agent到底该看什么指标3.1 正确性验证不能只看跑通了很多人在评测Kernel Agent时第一关就是看生成的Kernel能不能编译、能不能跑出结果。但跑出结果和结果正确是两回事。我见过Agent生成的Kernel在小规模输入上结果正确一到大矩阵就出现数值偏差原因是累加顺序变了导致浮点误差累积。所以正确性验证必须包含几个层次首先是和参考实现比如cuBLAS或PyTorch的对应算子做逐元素对比设定合理的误差容忍度其次是在多个规模上测试从小规模到大规模都要覆盖最后是边界情况比如非对齐的矩阵维度、极小的输入、包含特殊值的输入。只有这几层都过了才能说这个Kernel是正确的。3.2 性能指标要区分峰值和稳定值性能评测里最容易踩的坑是只看最好成绩。Agent可能在某次运行中碰巧拿到了一个很高的性能数字但重复跑几次就掉下来了。这背后的原因可能是GPU频率波动、缓存状态不同、或者Kernel本身对输入数据分布敏感。我的做法是每个Kernel至少跑20次取中位数和95分位数同时记录标准差。如果一个Kernel的中位数很好但标准差很大说明它的性能不稳定在实际生产环境里可能是个隐患。另外性能对比一定要在同一个GPU、同一个驱动版本、同一个功耗设置下做否则数字没有可比性。3.3 优化过程的性价比同样重要除了最终性能Agent优化过程的效率也值得关注。具体来说优化一个Kernel花了多少轮迭代、消耗了多少token、用了多少GPU小时这些都应该纳入评测。一个Agent可能最终能把Kernel优化到cuBLAS的95%但如果它花了200轮迭代和几十个GPU小时那这个方案的实用性就要打问号。我一般会算一个优化效率指标就是最终性能提升除以消耗的资源。这个指标能帮你判断一个Agent是真的聪明还是靠蛮力堆出来的。在实际落地时蛮力方案往往因为成本太高而不可行。3.4 泛化能力换个算子还灵不灵最后一个但可能最重要的指标是泛化能力。一个Agent在矩阵乘法上表现很好换个卷积、换个attention、换个reduce操作还行不行如果只在特定算子上有效那它的价值就大打折扣。测试泛化能力的做法是准备一组不同类型的算子涵盖计算密集型如矩阵乘、访存密集型如element-wise、规约型如softmax、以及混合型如attention。看Agent在这些算子上的平均表现和方差。方差小说明泛化好方差大说明它可能过拟合到了某类算子的特定模式上。4. 实际落地时绕不开的几个工程难题4.1 编译环境的隔离与复现Kernel Agent要跑起来必须有一个能编译CUDA代码的环境。这个环境听起来简单实际做起来坑很多。首先是CUDA版本和GPU架构的匹配问题不同架构比如不同代的GPU支持的指令集不一样Agent生成的代码可能用了某个架构特有的指令换到另一个架构就编译不过。其次是环境的隔离。如果多个Agent共享一个编译环境一个Agent的编译产物可能污染另一个Agent的测试。我建议每个Agent的每次迭代都在独立的容器或沙箱里跑虽然这样资源开销大一些但能保证结果的可复现性。另外编译缓存也要小心处理有时候缓存会导致你以为代码改了但实际跑的还是旧版本。4.2 性能测量的噪声控制GPU性能测量的噪声比CPU大得多这是很多人一开始没意识到的。同一个Kernel连续跑两次耗时可能差5%甚至更多原因是GPU的boost clock会根据温度和功耗动态调整。如果不控制这个噪声Agent可能会把噪声当成真实的性能提升从而做出错误的优化决策。控制噪声的常见做法有几个一是跑之前先做warm-up让GPU进入稳定状态二是固定GPU频率如果硬件支持三是多次测量取统计量而不是单次值四是在测量时关闭其他占用GPU的进程。我自己的经验是warm-up至少跑10次正式测量至少20次这样得到的数字才比较可靠。4.3 反馈信号的设计Agent能不能有效优化很大程度上取决于你给它的反馈信号设计得好不好。如果只给一个耗时数字Agent就像在黑暗中摸索。如果给太多底层指标又可能让Agent抓不住重点。我比较推荐的反馈结构是分层的第一层给最终性能数字和相对基线比如cuBLAS的百分比第二层给关键瓶颈指标比如occupancy、内存带宽利用率、计算单元利用率第三层给具体的优化建议线索比如检测到shared memory bank conflict较多或寄存器溢出导致spill。这样Agent既能知道好不好也能知道哪里不好还能知道往哪个方向改。4.4 安全与合规的边界Agent自动生成和执行的代码必须在一个受控的环境里运行。一方面是要防止生成的代码里有恶意逻辑虽然概率低但不能不防另一方面是要防止Agent在优化过程中把GPU资源占满影响其他任务。我建议给Agent的执行环境设置明确的资源配额包括GPU显存上限、运行时间上限、以及并发任务数上限。另外Agent生成的代码在正式使用前一定要经过人工review。自动化优化可以帮你找到候选方案但最终上生产的代码还是得有人把关。这不是对Agent不信任而是工程上必要的安全冗余。5. 我看到的几个有代表性的实现思路5.1 以性能模型为核心的方案有一类实现思路是先训练一个性能预测模型输入是Kernel的配置参数输出是预测的耗时。Agent在搜索时先用这个模型快速筛选出有希望的候选再实际编译测试。这样能大幅减少实际编译和benchmark的次数。这个思路的关键在于性能模型的准确度。如果模型预测不准Agent就会被误导到错误的方向。我见过的做法是用历史数据训练一个轻量级的模型比如梯度提升树或小神经网络然后在实际使用中不断用新数据更新它。这个方案的优点是效率高缺点是模型需要足够的训练数据才能准冷启动阶段效果一般。5.2 以代码变换为核心的方案另一类思路是不做参数搜索而是让Agent直接对代码做变换。比如识别出代码里的某个循环可以展开、某个访存可以向量化、某个计算可以提前然后应用相应的变换。这种方案更接近人类专家的优化方式因为它是在理解代码的基础上做改进。代码变换的难点在于变换的正确性保证。一个变换可能在某些情况下正确在另一些情况下引入bug。所以每次变换后都要做正确性验证这就增加了迭代成本。另外变换的粒度也不好把握太粗可能改不动太细可能改了半天没效果。5.3 以课程学习为核心的方案还有一种思路是让Agent从简单的Kernel开始优化逐步过渡到复杂的。比如先优化element-wise加法再优化reduce再优化矩阵乘最后优化attention。这样Agent能积累经验后面的任务能受益于前面的积累。课程学习的核心是课程的设计也就是任务难度的排序。排得太简单Agent学不到东西排得太难Agent一开始就受挫。我见过的做法是按照Kernel的算术强度、访存模式、并行度等维度来排序从算术强度低、访存规则、并行度高的开始逐步增加难度。6. 当前方案的共同短板与可能的突破方向6.1 对非标准算子的适应能力弱目前大多数Kernel Agent在标准算子上表现不错但遇到非标准算子就明显吃力。所谓非标准算子是指那些没有现成参考实现、访存模式不规则、或者计算逻辑比较特殊的算子。比如某些稀疏操作、某些自定义的融合算子、某些带有复杂边界条件的算子。这个短板的原因是Agent的优化能力很大程度上依赖于它见过的模式。标准算子的优化模式在训练数据里很常见Agent能学到。非标准算子的模式少见Agent就不知道怎么下手。可能的突破方向是增强Agent的推理能力让它能从不相关的经验中迁移出解决方案而不是只靠模式匹配。6.2 长尾性能的优化不够另一个共同短板是Agent往往能把Kernel优化到还不错的水平但很难推到极致。比如把矩阵乘优化到cuBLAS的90%相对容易但要从90%推到98%就非常难。这最后几个百分点的优化往往需要对硬件微架构有极深的理解而这是当前Agent比较欠缺的。突破这个短板可能需要把硬件层面的知识更显式地注入到Agent里比如把GPU的微架构手册、指令延迟表、缓存层次结构等信息结构化地提供给Agent。另外也可以考虑让Agent和人类专家协作Agent负责搜索和尝试人类专家负责在关键节点给出方向性指导。6.3 跨代GPU的迁移能力GPU架构迭代很快每一代都有新的指令、新的缓存结构、新的并行模型。一个在上一代GPU上优化得很好的Kernel换到新一代GPU上可能就不是最优了。当前Agent的跨代迁移能力还比较弱往往需要在新架构上重新优化一遍。这个问题的本质是Agent学到的优化策略和特定硬件绑定了。要解决它可能需要让Agent学习更抽象的优化原则而不是具体的参数配置。比如学到当访存成为瓶颈时应该增加数据复用而不是shared memory设成48KB。抽象原则更容易跨代迁移。7. 如果你现在想上手我的几点实操建议7.1 从半自动开始别一上来就全自动我见过不少人一上来就想搭一个全自动的Kernel优化流水线结果卡在工程细节上几个月出不来东西。我的建议是从半自动开始Agent负责生成候选方案你负责筛选和验证。这样你能快速看到Agent的能力边界也能积累对Agent输出的判断经验。半自动阶段的目标不是追求全自动而是搞清楚Agent在哪些环节靠谱、在哪些环节不靠谱。等你对Agent的行为模式有了直觉再逐步把靠谱的环节自动化把不靠谱的环节保留人工介入。7.2 先建评测基线再谈优化在让Agent优化任何Kernel之前先把评测基线建好。基线包括参考实现的性能比如cuBLAS、cuDNN、或者手写的最优版本、正确性验证的方法、性能测量的流程。没有基线你根本不知道Agent的优化是真好还是假好。基线建设本身也是个技术活。参考实现要选对有些算子的cuBLAS版本未必是最优的可能需要自己手写一个强基线。性能测量要控制噪声前面讲过的warm-up、多次测量、固定频率这些都要做到位。7.3 把失败案例当成资产Agent优化过程中会产生大量失败案例编译不过的、结果不对的、性能反而变差的。这些失败案例很多人直接扔了但我觉得它们是最有价值的资产。把失败案例结构化地存下来分析失败的原因能帮你改进Agent的prompt、改进反馈信号、改进搜索策略。我自己的做法是给每个失败案例打标签比如语法错误数值精度问题性能回退资源超限然后定期分析这些标签的分布。如果某一类失败特别多就说明Agent在这个环节有系统性问题需要针对性改进。7.4 关注可解释性别只看结果Agent给出的优化方案最好能附带一个解释为什么这么改、预期能带来什么收益、有什么风险。这个解释不一定完全准确但它能帮你判断Agent的决策是否合理。如果Agent只是给了一个方案但说不出理由那这个方案的可信度就要打折扣。可解释性对调试也很有帮助。当Agent的优化效果不好时看它的解释能帮你快速定位是方向错了还是执行错了。方向错了要改prompt或改搜索策略执行错了要改代码生成或改验证流程。7.5 保持对人工优化的敬畏最后一点也是我觉得最重要的一点不要因为有了Agent就放弃人工优化能力的培养。Agent能帮你省很多力但它不能替代你对硬件的理解、对算法的理解、对性能瓶颈的直觉。这些能力在你判断Agent方案好坏、在Agent卡住时给它指方向、在处理Agent搞不定的非标准问题时都是不可替代的。我自己的做法是即使有Agent帮忙我也会定期手写一些Kernel保持手感。手写的过程能让我更清楚地感受到硬件的特性也能让我在Agent给出方案时更快地判断它靠不靠谱。Agent是工具不是替代品这个定位要摆正。8. 这个方向接下来可能怎么走从2026年这个时间点往前看我觉得Kernel Agent这个方向会往几个方向分化。一个是专用化针对特定类型的算子比如attention、卷积、稀疏操作做深度优化的Agent这类Agent在特定场景下能做到极致性能。另一个是通用化追求一个Agent能处理各种算子性能不一定最优但覆盖面广。还有一个方向是协同化就是Agent和人类专家、Agent和Agent之间的协作。人类专家负责定义问题和判断方向Agent负责搜索和尝试多个Agent之间分工合作处理复杂任务。这个方向的技术挑战主要在协调机制和通信效率上。最后我觉得评测标准化会成为一个重要议题。现在各个方案各测各的数字之间没法直接比较。如果社区能形成一套标准的评测基准和评测流程那这个领域的进展会更快大家也能更清楚地知道什么方案是真的好。我在实际做Kernel优化的这些年里最大的体会是性能优化没有银弹Agent也好、auto-tuning也好都是帮你扩大搜索范围的工具但最终能不能找到好方案还是取决于你对问题的理解深度。Agent能帮你跑得更快但方向对不对还是得你自己判断。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进