ByteDance Seed and Tsinghua AIR have released CUDA Agent, an agentic reinforcement learning system that trains a large language model to write GPU kernels that beat a compiler. The gap it targets is narrow but stubborn: frontier models already produce correct CUDA, they just produce slow CUDA. On KernelBench, the base model Seed1.6 passes 74.0% of tasks yet outruns torch.compile on only 27.2% of them, at a 0.69× geometric-mean speedup which means its kernels are, on average, slower than what the compiler generates on its own. CUDA Agent closes that gap by putting the model inside a real CUDA development environment with profiling, correctness checks and a permission-locked sandbox, then training it with PPO for 150 steps at a 131,072-token context. The result is a 98.8% pass rate and a 96.8% faster-than-torch.compile rate across the 250-task benchmark, at 2.11× geomean over compile — roughly 40 points ahead of Claude Opus 4.5 and Gemini 3 Pro on the hardest Level-3 split.
Is it deployable?
Partly, but the trained agent is not released. It is built on Seed1.6, a proprietary MoE model with 23B active and 230B total parameters, and the paper ships no weights. Public: the CUDA-Agent-Ops-6K dataset, the SKILL.md spec and the reward and warm-up recipes.
Which companies: The profiling sandbox alone used 128 NVIDIA H20 GPUs, which puts full replication inside frontier labs, GPU clouds and large infrastructure teams. Mid-size teams can still adopt the parts — dataset, milestone reward, anti-reward-hacking constraints, skill spec — on top of an open base model.
Industries and applications: AI infrastructure and inference serving, GPU cloud, autonomous driving, quantitative trading, medical imaging and recommendation systems — anywhere fused kernels sit on a latency-critical path. Uses include fusing operator sequences torch.compile handles poorly, cutting cost per token, and re-tuning kernels across GPU generations.
Data synthesis
The research team crawls reference operators from the torch and transformers libraries. An LLM then samples up to five torch operator classes and stacks them into one fused layer. A filter keeps only operators that execute in both eager and compile modes, are deterministic, produce non-constant outputs, and run between 1 ms and 100 ms in eager mode. Samples with AST similarity above 0.9 to any KernelBench task are removed. The result is CUDA-Agent-Ops-6K: 6,000 samples, 83.77% of them two-operator compositions.
Environment and reward
The agent loop mirrors OpenHands tooling — Bash, Read/Write, Edit/MultiEdit, Glob, Grep, NotebookEdit, BashOutput, KillBash — under a ReAct pattern. CUDA instructions ship in the Agent Skills format. SKILL.md tells the model to profile the PyTorch model, rewrite model_new.py with custom kernels, compile in a GPU sandbox, and iterate until the kernel is at least 5% faster than torch.compile at atol=1e-2, rtol=1e-2.
Reward hacking gets five countermeasures: permission-locked verification and profiling scripts, context managers that forbid torch.nn.functional fallbacks, checks against five random inputs, profiling with device synchronization and warm-up, and no web search tool.
The reward is discrete rather than a raw speedup ratio. r ∈ {−1, 1, 2, 3}: −1 on correctness failure, 3 if the kernel clears both eager and torch.compile by more than 5%, 2 if it clears eager only, 1 otherwise.


Results
Table 1, overall: 98.8% pass rate, 98.4% faster than eager, 96.8% faster than torch.compile, at 2.60× and 2.11× geomean respectively. Level 2 (operator sequences) is the strongest split: 100% pass, 100% faster rate, 2.80× over torch.compile. Level 3 lands at 94.0% pass, 90.0% faster rate and 1.52×, roughly 40 points above Claude Opus 4.5 (50.0%) and Gemini 3 Pro (52.0%) on faster rate versus compile.
One inconsistency: the abstract and introduction state 100% / 100% / 92% faster rates for Levels 1–3, while Table 1 reports 97.0% / 100.0% / 90.0%. Table 1 is the main results table.
Ablations are blunt. Removing the agent loop drops faster rate versus compile from 96.8% to 14.1%. A raw speedup reward gives 60.4%, no RFT gives 49.8% plus reward collapse, no value pretraining gives 50.9% plus runaway trajectories.
Case studies show what the policy learns. A diagonal matmul rewritten as row-wise scaling: 73.31× over torch.compile. A matmul-divide-sum-scale chain reordered and fused: 24.04×. A ResNet BasicBlock with BatchNorm folded into convolution andcudnnConvolutionBiasActivationForward: 3.59×.
/* —- 03 reward —- */
var EAGER=2.30, COMP=1.80, ok=true;
function b(t,t0){ return (t0-t)/t0 > 0.05; }
function drawReward(){
var t=parseInt($(‘#rt’).value,10)/100;
$(‘#rt-lab’).textContent=t.toFixed(2)+’ ms’;
var max=3.4;
var rows=[[‘torch eager’,EAGER,’#f5a623′],[‘torch.compile’,COMP,’#4D9BFF’],[‘your kernel’,t,’#5BE1F5′]];
var h=””;
rows.forEach(function(r){
h+=’
‘+r[0]+’
‘+
r[1].toFixed(2)+’ ms
‘;
});
$(‘#bars3′).innerHTML=h;
var be=b(t,EAGER), bc=b(t,COMP), r, why, col;
if(!ok){ r=-1; why=’Correctness check failed. Runtime is irrelevant — the trajectory is penalised.’; col=”#f5a623″; }
else if(be&&bc){ r=3; why=’More than 5% faster than eager AND than torch.compile. Top milestone.’; col=”#3ddc97″; }
else if(be){ r=2; why=’More than 5% faster than eager, but not than torch.compile.’; col=”#5BE1F5″; }
else { r=1; why=’Correct, but no significant speed-up over either baseline.’; col=”#8fa3c0″; }
$(‘#v-r’).textContent=(r>0?’+’:”)+r; $(‘#v-r’).style.color=col;
$(‘#v-why’).textContent=why;
$(‘#verdict’).style.borderColor=col;
}
$(‘#rt’).addEventListener(‘input’,drawReward);
$(‘#ok-tog’).addEventListener(‘click’,function(){
ok=!ok; $(‘#ok-lab’).textContent=ok?’PASS’:’FAIL’; drawReward();
});
drawReward();
/* —- 04 chart (Table 1) —- */
var MODELS=[‘Seed1.6 (base)’,’GLM 4.6′,’Kimi K2′,’Gemini 3 Pro’,’Claude Opus 4.5′,’CUDA Agent’];
var D={
ov:{pass:[74.0,75.6,66.8,91.2,95.2,98.8],fe:[43.6,44.8,40.8,87.6,90.4,98.4],
fc:[27.2,19.2,22.8,69.6,66.4,96.8],se:[0.95,0.78,0.93,1.92,1.99,2.60],
sc:[0.69,0.57,0.66,1.42,1.46,2.11]},
l1:{pass:[90.0,86.0,85.0,95.0,96.0,100.0],fe:[63.0,57.0,56.0,90.0,88.0,99.0],
fc:[51.0,32.0,39.0,72.0,72.0,97.0],se:[1.65,0.99,1.43,1.99,2.03,2.48],
sc:[1.25,0.73,1.00,1.51,1.54,1.87]},
l2:{pass:[74.0,76.0,65.0,93.0,98.0,100.0],fe:[40.0,43.0,40.0,91.0,97.0,100.0],
fc:[16.0,11.0,15.0,76.0,69.0,100.0],se:[0.68,0.60,0.93,2.03,2.24,3.27],
sc:[0.50,0.42,0.65,1.46,1.60,2.80]},
l3:{pass:[42.0,54.0,34.0,80.0,88.0,94.0],fe:[12.0,24.0,12.0,76.0,82.0,94.0],
fc:[2.0,10.0,6.0,52.0,50.0,90.0],se:[0.60,0.83,0.40,1.58,1.52,1.80],
sc:[0.40,0.62,0.29,1.17,1.10,1.52]}
};
var NOTES={ov:’Overall = weighted by problems per level (Level 1: 100, Level 2: 100, Level 3: 50).’,
l1:’Level 1 = single operations.’, l2:’Level 2 = operator sequences, where fusion matters most.’,
l3:’Level 3 = realistic neural-network blocks, the hardest split.’};
var lvl=”ov”, met=”fc”;
function drawChart(){
var vals=D[lvl][met], pct=(met===’se’||met===’sc’)?false:true;
var max=Math.max.apply(null,vals)*1.06;
var h=””;
MODELS.forEach(function(m,i){
var v=vals[i];
h+=’
‘+m+’
‘+(pct?v.toFixed(1)+’%’:v.toFixed(2)+’×’)+’
‘;
});
$(‘#chart’).innerHTML=h;
$(‘#chart-note’).textContent=NOTES[lvl]+’ All figures from Table 1 of the paper.’;
setTimeout(function(){$$(‘#chart .fill’).forEach(function(f,i){
setTimeout(function(){f.style.width=f.getAttribute(‘data-w’)+’%’},i*70)})},30);
}
$$(‘#lvl button’).forEach(function(b2){b2.addEventListener(‘click’,function(){
$$(‘#lvl button’).forEach(function(x){x.classList.remove(‘on’)});b2.classList.add(‘on’);
lvl=b2.getAttribute(‘data-k’);drawChart();})});
$$(‘#met button’).forEach(function(b2){b2.addEventListener(‘click’,function(){
$$(‘#met button’).forEach(function(x){x.classList.remove(‘on’)});b2.classList.add(‘on’);
met=b2.getAttribute(‘data-k’);drawChart();})});
drawChart();
/* —- 05 ablation —- */
var ABL=[[‘w/o Agent Loop’,14.1],[‘w/o Robust Reward’,60.4],[‘w/o RFT’,49.8],
[‘w/o Value Pretraining’,50.9],[‘CUDA Agent (full)’,96.8]];
var ah=””;
ABL.forEach(function(a,i){
ah+=’
‘+a[0]+
‘
‘+
a[1].toFixed(1)+’%
‘;
});
$(‘#abl’).innerHTML=ah;
setTimeout(function(){$$(‘#abl .fill’).forEach(function(f,i){
setTimeout(function(){f.style.width=f.getAttribute(‘data-w’)+’%’},i*90)})},250);
/* —- 05 spark —- */
var good=[0.35,0.62,0.95,1.10,1.02,1.28,1.20,1.44,1.35,1.52,1.41,1.63,1.55,1.72,1.66,1.80,1.74,1.88,1.82,1.95];
var bad =[0.32,0.58,0.88,1.05,1.18,1.30,1.22,1.05,0.86,0.62,0.40,0.22,0.12,0.06,0.03,0.02,0.02,0.01,0.01,0.01];
function pts(a){ return a.map(function(v,i){
return (30+i*(555/(a.length-1))).toFixed(1)+’,’+(130-v/2.1*112).toFixed(1); }).join(‘ ‘); }
function drawSpark(){
var s=$(‘#spark’);
s.innerHTML=’
‘
‘
‘
‘
‘
‘
[‘pl-bad’,’pl-good’].forEach(function(id){
var p=document.getElementById(id), L=0;
try{ L=p.getTotalLength(); }catch(e){ return; }
if(!L) return;
p.style.strokeDasharray=L; p.style.strokeDashoffset=L;
p.style.transition=’stroke-dashoffset 1.8s ease’;
setTimeout(function(){p.style.strokeDashoffset=0},60);
});
}
$(‘#st-run’).addEventListener(‘click’,drawSpark);
drawSpark();
})();
