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.
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 coreauto 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.
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.
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.
Thanks for bringing up these points, it's definitely good food for thought to add to the blog!
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?