ByteDance Seed and Tsinghua AIR Introduces CUDA Agent: A Large-Scale Agentic RL System for CUDA Kernel Generation
ByteDance Seed and Tsinghua AIR have launched CUDA Agent, an agentic reinforcement studying system that trains a big language mannequin to put in writing GPU kernels that beat a compiler. The hole it targets is slim however cussed: frontier fashions already produce appropriate CUDA, they simply produce sluggish CUDA. On KernelBench, the bottom mannequin Seed1.6 passes 74.0% of duties but outruns torch.compile on solely 27.2% of them, at a 0.69× geometric-mean speedup which implies its kernels are, on common, slower than what the compiler generates by itself. CUDA Agent closes that hole by placing the mannequin inside an actual CUDA growth atmosphere with profiling, correctness checks and a permission-locked sandbox, then coaching it with PPO for 150 steps at a 131,072-token context. The result’s a 98.8% move charge and a 96.8% faster-than-torch.compile charge throughout the 250-task benchmark, at 2.11× geomean over compile — roughly 40 factors forward of Claude Opus 4.5 and Gemini 3 Pro on the toughest Level-3 cut up.
Is it deployable?
Partly, however the skilled agent is just not launched. It is constructed on Seed1.6, a proprietary MoE mannequin with 23B energetic and 230B whole 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 corporations: The profiling sandbox alone used 128 NVIDIA H20 GPUs, which places full replication inside frontier labs, GPU clouds and massive infrastructure groups. Mid-size groups can nonetheless undertake the components — dataset, milestone reward, anti-reward-hacking constraints, ability spec — on prime of an open base mannequin.
Industries and functions: AI infrastructure and inference serving, GPU cloud, autonomous driving, quantitative buying and selling, medical imaging and suggestion methods — wherever fused kernels sit on a latency-critical path. Uses embody fusing operator sequences torch.compile handles poorly, reducing price per token, and re-tuning kernels throughout GPU generations.
Data synthesis
The analysis staff crawls reference operators from the torch and transformers libraries. An LLM then samples as much as 5 torch operator courses and stacks them into one fused layer. A filter retains solely operators that execute in each keen and compile modes, are deterministic, produce non-constant outputs, and run between 1 ms and 100 ms in keen mode. Samples with AST similarity above 0.9 to any KernelBench process are eliminated. The result’s 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, Pocket bookEdit, BashOutput, KillBash — underneath a ReAct sample. CUDA directions ship within the Agent Skills format. SKILL.md tells the mannequin to profile the PyTorch mannequin, rewrite model_new.py with customized kernels, compile in a GPU sandbox, and iterate till the kernel is at the least 5% quicker than torch.compile at atol=1e-2, rtol=1e-2.
Reward hacking will get 5 countermeasures: permission-locked verification and profiling scripts, context managers that forbid torch.nn.practical fallbacks, checks towards 5 random inputs, profiling with system synchronization and warm-up, and no internet search instrument.
The reward is discrete quite than a uncooked speedup ratio. r ∈ {−1, 1, 2, 3}: −1 on correctness failure, 3 if the kernel clears each keen and torch.compile by greater than 5%, 2 if it clears keen solely, 1 in any other case.

Results
Table 1, total: 98.8% move charge, 98.4% quicker than keen, 96.8% quicker than torch.compile, at 2.60× and 2.11× geomean respectively. Level 2 (operator sequences) is the strongest cut up: 100% move, 100% quicker charge, 2.80× over torch.compile. Level 3 lands at 94.0% move, 90.0% quicker charge and 1.52×, roughly 40 factors above Claude Opus 4.5 (50.0%) and Gemini 3 Pro (52.0%) on quicker charge versus compile.
One inconsistency: the summary and introduction state 100% / 100% / 92% quicker charges for Levels 1–3, whereas Table 1 studies 97.0% / 100.0% / 90.0%. Table 1 is the primary outcomes desk.
Ablations are blunt. Removing the agent loop drops quicker charge versus compile from 96.8% to 14.1%. A uncooked speedup reward offers 60.4%, no RFT offers 49.8% plus reward collapse, no worth pretraining offers 50.9% plus runaway trajectories.
Case research present what the coverage 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 –>
<part class=”mod” id=”m3″>
<h3>Why the reward is discrete, not a speedup ratio</h3>
<p class=”lede”>Raw speedup rewards bias the coverage towards straightforward kernels and blow up on outliers. CUDA Agent makes use of milestones as a substitute. Move the slider to set your kernel’s runtime and watch the reward flip.</p>
<div class=”ctrl”>
<label>Generated kernel runtime <span class=”mono” id=”rt-lab”>1.26 ms</span></label>
<enter sort=”vary” id=”rt” min=”20″ max=”320″ step=”1″ worth=”126″>
</div>
<div class=”row”><button class=”btn ghost” id=”ok-tog”>Correctness test: <b id=”ok-lab”>PASS</b></button></div>
<div class=”bars3″ id=”bars3″></div>
<div class=”verdict” id=”verdict”>
<div class=”r” id=”v-r”>3</div>
<div class=”why” id=”v-why”></div>
</div>
<div class=”ref”>Exact rule from Equation 1: r = −1 if correctness fails; 3 if quicker than each keen and <span class=”mono”>torch.compile</span>; 2 if quicker than keen solely; in any other case 1. “Faster” means b(t, t₀) = 𝟙[(t₀ − t)/t₀ > 5%]. Baselines fastened on the Figure 2 values.</div>
</part>
<!– 04 –>
<part class=”mod” id=”m4″>
<h3>KernelBench outcomes, Table 1</h3>
<p class=”lede”>250 duties throughout three ranges, weighted 100 / 100 / 50. Switch the cut up and the metric — the bars redraw with the paper’s reported numbers.</p>
<div class=”selrow”>
<div class=”seg” id=”lvl”>
<button data-k=”ov” class=”on”>Overall</button><button data-k=”l1″>Level 1</button><button data-k=”l2″>Level 2</button><button data-k=”l3″>Level 3</button>
</div>
<div class=”seg” id=”met”>
<button data-k=”move”>Pass charge</button><button data-k=”fe”>Faster vs keen</button><button data-k=”fc” class=”on”>Faster vs compile</button><button data-k=”se”>Speed-up vs keen</button><button data-k=”sc”>Speed-up vs compile</button>
</div>
</div>
<div id=”chart”></div>
<div class=”ref” id=”chart-note”></div>
<div class=”observe”>The summary and introduction state 100% / 100% / 92% quicker charges over <span class=”mono”>torch.compile</span> for Level 1 / 2 / 3, whereas Table 1 studies 97.0% / 100.0% / 90.0%. This widget makes use of Table 1, the paper’s important outcomes desk.</div>
</part>
<!– 05 –>
<part class=”mod” id=”m5″>
<h3>What breaks whenever you take away a bit</h3>
<p class=”lede”>Leave-one-out variants, total cut up, quicker charge versus <span class=”mono”>torch.compile</span>. The agent loop issues most; the 2 warm-up phases hold coaching from collapsing.</p>
<div id=”abl”></div>
<div class=”row” type=”margin-top:14px”><button class=”btn” id=”st-run”>
Replay coaching curve</button></div>
<svg class=”spark” id=”spark” viewBox=”0 0 600 150″ preserveAspectRatio=”none”></svg>
<div class=”legend”><span><i type=”background:#4D9BFF”></i>PPO with RFT + worth pretraining</span><span><i type=”background:#f5a623″></i>PPO with out warm-up</span></div>
<div class=”observe”>Schematic redraw of Figure 4a, illustrative. The paper’s acknowledged information: the primary RL trial stayed secure for 17 steps earlier than collapse; with actor RFT and critic worth pretraining, coaching ran 150 steps with constant reward progress.</div>
<div class=”ref”>Root trigger given within the paper: CUDA code is underneath 0.01% of pretraining information, so sampled low-probability tokens make the PPO significance ratio fluctuate or explode underneath prepare/inference precision mismatch.</div>
</part>
<div class=”foot”>
<span>Source: Dai, Wu, Yu et al., arXiv 2602.24286 · ByteDance Seed × Tsinghua AIR</span>
<span><b>Marktechpost</b> · interactive explainer</span>
</div>
</div>
<script>
(perform(){
var $=perform(s){return doc.querySelector(s)};
var $$=perform(s){return Array.prototype.slice.name(doc.querySelectorAll(s))};
/* —- resize —- */
var wrap=doc.getElementById(‘ca-wrap’);
var lastH=0;
perform ping(){
var h=wrap.offsetHeight+40;
if(h===lastH)return; lastH=h;
attempt{ dad or mum.postMessage({sort:’mtpEmbedHeight’,id:’cuda-agent-explainer’,peak:h},’*’); }catch(e){}
}
setInterval(ping,600); window.addEventListener(‘load’,ping); ping();
/* —- nav —- */
$$(‘nav.ca-nav button’).forEach(perform(b){
b.addEventListener(‘click on’,perform(){
$$(‘nav.ca-nav button’).forEach(perform(x){x.classList.take away(‘energetic’)});
$$(‘part.mod’).forEach(perform(x){x.classList.take away(‘present’)});
b.classList.add(‘energetic’);
var m=b.getAttribute(‘data-m’);
doc.getElementById(m).classList.add(‘present’);
if(m===’m5′){ setTimeout(drawSpark,30); }
ping();
});
});
/* —- 01 pipeline —- */
var comp=[[‘torch ops ×2’,83.77],[‘torch ops ×3’,7.62],[‘torch ops ×1’,3.40],
[‘torch ops ×4’,2.80],[‘torch ops ×5’,1.23],[‘transformers’,1.18]];
var compHTML=”;
comp.forEach(perform(c,i){
compHTML+='<div class=”cb”><div class=”lab”>’+c[0]+'</div><div class=”monitor”><div class=”fill” data-w=”‘+
(c[1]/83.77*100)+'”></div></div><div class=”val”>’+c[1].toFixed(2)+’%</div></div>’;
});
$(‘#comp’).innerHTML=compHTML;
perform tick(el,to,ms,suffix){
var t0=null;
perform step(ts)
requestAnimationFrame(step);
}
perform runPipe(){
resetPipe();
setTimeout(perform(){$(‘#s1’).classList.add(‘lit’); $(‘#c1′).textContent=’torch + transformers’;},80);
setTimeout(perform(){$(‘#s2’).classList.add(‘lit’); $(‘#c2′).textContent=’u2264 5 ops / process’;},1100);
setTimeout(perform(){$(‘#s3’).classList.add(‘lit’); tick($(‘#c3′),6000,1000,’ samples saved’);},2200);
setTimeout(perform(){$$(‘#comp .fill’).forEach(perform(f,i){
setTimeout(perform(){f.type.width=f.getAttribute(‘data-w’)+’%’},i*110)});},2900);
}
perform resetPipe(){
[‘s1′,’s2′,’s3’].forEach(perform(id){$(‘#’+id).classList.take away(‘lit’)});
[‘c1′,’c2′,’c3’].forEach(perform(id){$(‘#’+id).textContent=’—’});
$$(‘#comp .fill’).forEach(perform(f){f.type.width=’0%’});
}
$(‘#p-run’).addEventListener(‘click on’,runPipe);
$(‘#p-reset’).addEventListener(‘click on’,resetPipe);
/* —- 02 agent loop —- */
var lt=null, li=0, flip=0, gen=2.90;
perform loopStep(){
[‘n0′,’n1′,’n2′,’n3’].forEach(perform(id){$(‘#’+id).classList.take away(‘act’)});
$(‘#n’+(lipercent4)).classList.add(‘act’);
if(lipercent4===3){
flip++; gen=Math.max(1.26, gen-(gen-1.26)*0.42);
$(‘#g-turn’).textContent=flip;
$(‘#g-gen’).textContent=gen.toFixed(2)+’ ms’;
$(‘#g-gen’).className=’v ‘+(gen<1.71?’good’:’warn’);
}
li++;
}
perform loopStart(){ if(lt)return; loopStep(); lt=setInterval(loopStep,460); }
perform loopStop(){ clearInterval(lt); lt=null; }
$(‘#l-run’).addEventListener(‘click on’,perform(){ if(flip>=6){flip=0;gen=2.90;} loopStart(); });
$(‘#l-stop’).addEventListener(‘click on’,loopStop);
/* —- 03 reward —- */
var EAGER=2.30, COMP=1.80, okay=true;
perform b(t,t0){ return (t0-t)/t0 > 0.05; }
perform drawReward(){
var t=parseInt($(‘#rt’).worth,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(perform(r){
h+='<div class=”b3″><div class=”lab”>’+r[0]+'</div><div class=”monitor”><div class=”fill” type=”width:’+
(r[1]/max*100)+’%;background:linear-gradient(90deg,’+r[2]+’55,’+r[2]+’)”></div></div><div class=”val”>’+
r[1].toFixed(2)+’ ms</div></div>’;
});
$(‘#bars3′).innerHTML=h;
var be=b(t,EAGER), bc=b(t,COMP), r, why, col;
if(!okay){ r=-1; why=’Correctness test failed. Runtime is irrelevant — the trajectory is penalised.’; col=’#f5a623′; }
else if(be&&bc){ r=3; why=’More than 5% quicker than keen AND than torch.compile. Top milestone.’; col=’#3ddc97′; }
else if(be){ r=2; why=’More than 5% quicker than keen, however not than torch.compile.’; col=’#5BE1F5′; }
else { r=1; why=’Correct, however no important speed-up over both baseline.’; col=’#8fa3c0′; }
$(‘#v-r’).textContent=(r>0?’+’:”)+r; $(‘#v-r’).type.colour=col;
$(‘#v-why’).textContent=why;
$(‘#verdict’).type.borderColor=col;
}
$(‘#rt’).addEventListener(‘enter’,drawReward);
$(‘#ok-tog’).addEventListener(‘click on’,perform(){
okay=!okay; $(‘#ok-lab’).textContent=okay?’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:{move:[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:{move:[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:{move:[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:{move:[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 issues per stage (Level 1: 100, Level 2: 100, Level 3: 50).’,
l1:’Level 1 = single operations.’, l2:’Level 2 = operator sequences, the place fusion issues most.’,
l3:’Level 3 = life like neural-network blocks, the toughest cut up.’};
var lvl=’ov’, met=’fc’;
perform 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(perform(m,i){
var v=vals[i];
h+='<div class=”forehead’+(i===5?’ ours’:”)+'”><div class=”lab”>’+m+'</div><div class=”monitor”><div class=”fill” data-w=”‘+
(v/max*100)+'”></div></div><div class=”val”>’+(pct?v.toFixed(1)+’%’:v.toFixed(2)+’×’)+'</div></div>’;
});
$(‘#chart’).innerHTML=h;
$(‘#chart-note’).textContent=NOTES[lvl]+’ All figures from Table 1 of the paper.’;
setTimeout(perform(){$$(‘#chart .fill’).forEach(perform(f,i){
setTimeout(perform(){f.type.width=f.getAttribute(‘data-w’)+’%’},i*70)})},30);
}
$$(‘#lvl button’).forEach(perform(b2){b2.addEventListener(‘click on’,perform(){
$$(‘#lvl button’).forEach(perform(x){x.classList.take away(‘on’)});b2.classList.add(‘on’);
lvl=b2.getAttribute(‘data-k’);drawChart();})});
$$(‘#met button’).forEach(perform(b2){b2.addEventListener(‘click on’,perform(){
$$(‘#met button’).forEach(perform(x){x.classList.take away(‘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(perform(a,i){
ah+='<div class=”forehead’+(i===4?’ ours’:”)+'”><div class=”lab”>’+a[0]+
‘</div><div class=”monitor”><div class=”fill” data-w=”‘+a[1]+'”></div></div><div class=”val”>’+
a[1].toFixed(1)+’%</div></div>’;
});
$(‘#abl’).innerHTML=ah;
setTimeout(perform(){$$(‘#abl .fill’).forEach(perform(f,i){
setTimeout(perform(){f.type.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 dangerous =[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];
perform pts(a){ return a.map(perform(v,i){
return (30+i*(555/(a.length-1))).toFixed(1)+’,’+(130-v/2.1*112).toFixed(1); }).be part of(‘ ‘); }
perform drawSpark(){
var s=$(‘#spark’);
s.innerHTML='<line x1=”30″ y1=”130″ x2=”588″ y2=”130″ stroke=”#1c2942″ stroke-width=”1″/>’+
‘<line x1=”30″ y1=”18″ x2=”30″ y2=”130″ stroke=”#1c2942″ stroke-width=”1″/>’+
‘<line x1=”200″ y1=”18″ x2=”200″ y2=”130″ stroke=”#f5a62355″ stroke-width=”1″ stroke-dasharray=”4 4″/>’+
‘<textual content x=”205″ y=”30″ fill=”#8fa3c0″ font-size=”10″ font-family=”monospace”>step 17: collapse</textual content>’+
‘<textual content x=”4″ y=”24″ fill=”#8fa3c0″ font-size=”9″ font-family=”monospace”>reward</textual content>’+
‘<polyline id=”pl-bad” factors=”‘+pts(dangerous)+'” fill=”none” stroke=”#f5a623″ stroke-width=”2″/>’+
‘<polyline id=”pl-good” factors=”‘+pts(good)+'” fill=”none” stroke=”#4D9BFF” stroke-width=”2″/>’;
[‘pl-bad’,’pl-good’].forEach(perform(id){
var p=doc.getElementById(id), L=0;
attempt{ L=p.getTotalLength(); }catch(e){ return; }
if(!L) return;
p.type.strokeDasharray=L; p.type.strokeDashoffset=L;
p.type.transition=’stroke-dashoffset 1.8s ease’;
setTimeout(perform(){p.type.strokeDashoffset=0},60);
});
}
$(‘#st-run’).addEventListener(‘click on’,drawSpark);
drawSpark();
})();
</script>
</physique>
</html>
“>
Key Takeaways
- CUDA Agent hits 98.8% move charge and 96.8% faster-than-
torch.compilecharge on KernelBench, at 2.11× geomean. - Level 2 fusion is the standout: 100% quicker charge and 2.80× over
torch.compile. - The discrete milestone reward beats a uncooked speedup ratio by 36.4 factors on quicker charge.
- RFT plus worth pretraining is what turns a 17-step collapse into 150 secure steps.
- Weights are closed; the 6,000-sample dataset,
SKILL.mdand the recipe are public.
Check out the Paper, the Project Page and the Dataset. Also, be happy to comply with us on Twitter and don’t overlook to hitch our 150k+ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.
Need to companion with us for selling your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar and so forth.? Connect with us
The put up ByteDance Seed and Tsinghua AIR Introduces CUDA Agent: A Large-Scale Agentic RL System for CUDA Kernel Generation appeared first on MarkTechPost.
