A primer on GPUs and kernel optimization
nabo.dev
nabo.dev
IMO at this time when all performant GPU kernels are generated/hill-climbed, its the largest source of error we see.
Should be kernel run with a hot or cold cache in practice? Should your kernel be bitwise equivalent to a ref? What error margins should your kernel have to ref? How many times are you running the kernel to avoid thermal noise? Are you running on separate GPUs to avoid overfitting the current hardware? Can you cudagraph-compiling your kernel to remove launch overhead? Are you A/B B/A interleaving your kernel/reference runs to avoid running thermal bias?
Do I want to set a particular threshold on any individual op (or a layer for a given transformer)? e.g "for this test set, 99% of l2norms being within 1e-4 error of the golden reference kernel"
Or do I want to just shortcut all that and go with task based evals? eg "word error no worse than 1% greater than the reference speech-to-text model"?
I'm assuming the latter is the way to go in the first instance?
For your task with the 3090, and I assume inference, I would like you suggest do end-to-end on target task.
Sometimes for example, a normalization layer can cancel out/fix an error from a previous layer, then it makes no sense to spend flops to save the numerics.
This is kind of a wild west in inference serving, you sometimes change exp to tanh, sometimes go full 4bit, sometimes remove full layers because you still perform fine on the end-task.
Numerics and correctness are more important for training kernels and backwards passes
I'll update the post in the coming week with a section on benchmarking. The current post does have some details on measurement, but I agree that maybe it's not covered in the required depth.
Primer: https://ornith.ai/defense_kernel_hack.html
In-depth(follow links etc): https://x.com/myainotez/article/2037258418843771349
Parts relevant: https://www.coreauto.com/blog/when-ai-starts-writing-systems...
----
When you do this with benchmarking, the same thing happens but on a much deeper, shittier, harder to understand level. It will set up the caches to benefit your kernels, it will set up the timing to benefit your kernels, it will set up the evaluation order to benefit your kernels. I've seen half-cache flushes, which only benefit large shapes.
I wouldn't be surprised if you pointed a language model on your benchmarking with the comment above, and it found something that is reward-hacking your task.
Same thing applies to benchmarking, a few guardrails goes a long way. As long as you aren't completely vague ("set up benchmarks", vs. "write tests over a variety of common shapes, be careful to control for environmental variables") the models do quite well. I've checked over the code it's written and it's all fairly reasonable. I do mention cache eviction in the article, this generally wasn't an issue and the model did this automatically on the first pass (back in Opus 4.6 days). I think you might not be giving them enough credit here.
I'm not completely familiar with the writers of this article, but I've never had an LLM try to hack this, even sometimes telling me a target was impossible without quantization or approximation:
"Code based analysis already tells a detailed story, but there is an overlooked parameter: "boundaries of the hardware". " - the myainotez post
This project has spanned several models since Opus 4.5. I think even then such details were trivially known by them, thought they required much more handholding than they do now. I'm honestly not sure how the article writers ran into the hacks they did.
edit: I should mention this article is based on my experience developing an RL and inference framework dealing with trainer-inference mismatch. I don't know if hill-climbing a kernel in an isolated set of benchmarks would perform differently. At the end of the article, I mention what my hill-climber looks like: https://www.nabo.dev/blogs/kernel-primer#section-in-the-age-... It has to go through numerics and correctness checks, then isolated tests for common shapes (where launch parameters are determined by an autotuner, not the agent), followed by end-to-end throughput tests.
Look at this challenge:
https://openkernelchallenge.dev/#leaderboard
If you have the tokens, let your harness go at let's say the first bf16 problem, I am curious how far you will get with it (1.73x is the leader and 2.04x is roofline). I think if you manage to get above 1.63x, I would be really interested in learning how you did that.
The top of the article shows the e2e times on some math RL tasks, with fp8 weights/activations/KV, comparing against SGLang on two models. They use the same concurrent batch size, quantization scheme, and the final lengths were about the same. I think Qwen3 models are probably very mature compared to Muse by now.
30B-A3B MoE
Jam - 67,241
SGLang - 44,696
+50.4%
8B Dense
Jam - 58,821
SGLang - 41,759
+40.9%
Math RL is pure decode, so kernels are the most major factor here.
Also-- I feel as if this has gone a bit off-track. The point of my reply was to comment on agents being actually decent at benchmark development and usage if you tell them to be, not as a comment on how great the harness is (I even state in the article: "it's a fairly simple and minimal setup that seems to work well.").
I don't think it's a footgun at all, and generally feel like (at least OpenAI's models) tend to do well in stating when there is some caveat to watch out for (they'll probably say when they're about to hack for the user to catch). The benchmarking suite they've made is actually very similar to what's in the open kernel challenge. Given that this was initially made many months ago, I'd think Opus and GPT did a pretty good job if someone is betting $100k+ (in prize money) on a similar suite being decent.
Thanks for bringing up these points, it's definitely good food for thought to add to the blog!
Nit: HBM is off chip, unlike shared memory and registers