@liao_lucas: https://x.com/liao_lucas/status/2097149853499588971
Summary
This article provides an introduction to GPU kernels in the context of AI inference and performance engineering, explaining their definition, how they are used, and the advantages of custom kernels for optimization.
View Cached Full Text
Cached at: 09/08/26, 05:12 AM
what is a kernel, anyway?
Everyone seems to be talking about inference and performance engineering right now.
I have seen the word “kernel” show up in every other post on my timeline, and inference companies are raising huge rounds left and right.
So here’s an intro to GPU kernels and why writing custom kernels is useful.
background: “kernel” is overloaded
In an operating system, a kernel is the core program that provides an API between software programs and physical hardware (CPU, memory etc).
In GPU programming, a kernel is a function that is run in parallel across thousands of GPU threads. NVIDIA GPUs are shipped with the cuBLAS library, which provides precompiled kernels for matrix multiply, matrix-vector multiply, dot product, and so on.
These two definitions of “kernel” are vastly different. You’ve probably heard more about the last one: when someone says they “wrote a kernel,” or that a model runs fast because of “custom kernels,” they are referring to writing a custom GPU kernel.
what a kernel is
A kernel is a function run on the GPU. The GPU runs that same function across thousands of threads at the same time, and each thread is assigned a thread ID, allowing it to identify itself and its scope.
This is an example of a kernel that adds two vectors:
Notice how there is no loop. a[], b[], out[] are in shared memory, and you can run this on thousands of threads split across GPU cores.
This is the main idea! Each thread figures out which piece of shared memory they’re responsible for, loads it from shared memory, does some math, then writes it back to shared memory.
how a kernel gets called
You do not call a kernel directly unless you write a custom one.
For example, torch.matmul(a, b) gets compiled like so:
-
PyTorch sees the two arrays are on the GPU and picks the C++ function for matmul on GPU
-
That function calls into a precompiled library that NVIDIA ships (e.g. cuBLAS for matrix multiply, cuDNN for other common neural net operations), or into a kernel PyTorch wrote itself.
-
The library tells the GPU driver to launch the kernel. Here’s the code and pointers to the data; now run it with this many threads.
-
The CPU puts the launch in a queue and moves on to the next line of Python. The GPU works through the queue in order.
So running a model once entails the CPU queuing a bunch of kernel launches and the GPU processing them. If you open a profiler that records what the GPU is doing over time, you will see exactly this: a timeline of hundreds of little boxes, each one a kernel.
many little boxes, each a kernel
many little boxes, each a kernel
Every kernel launch has a cost of a few microseconds, which adds up!
writing custom kernels
At first glance, GPU kernels seem to be a solved problem; surely we have written a near-perfect matmul kernel by now. However, a model isn’t one matmul; It’s hundreds of small operations in a row, and optimizations can be made in fusing them, specializing for various input shapes, optimizing fewer kernel launches, and using brand-new hardware features.
We’ll cover kernel fusion here:
A GPU is made of up of slow, large High Bandwidth Memory (HBM) and small, fast SRAM. HBM ↔ SRAM bandwidth is maybe a few terabytes / second, but the cores can do math much faster than that. So for most steps in inference, the cores sit idle waiting for data to arrive.
a claude-generated diagram of a GPU. numbers are from H100
a claude-generated diagram of a GPU. numbers are from H100
Now look at what a stock PyTorch model does. Say you have three operations in a row: multiply, add a constant, run every number through an activation function. This would mean three separate kernels, each reading its input from slow memory, doing a small amount of math, then writing it back to slow memory.
A custom kernel would do all three steps in one pass. Read once, do the multiply, the add, and the activation function while the numbers are still in SRAM, and write back once. This is what people mean by “fused” kernels.
FlashAttention is the famous example: Standard attention computes the full attention matrix, writes it to HBM, then reads it back to apply softmax and multiply by V.
FlashAttention instead computes attention scores, softmax, and multiplies by V in tiles while each tile is in SRAM, then accumulates the result before moving to the next block. (Note: doing this in tiles is actually quite hard and requires a clever algorithm)
writing custom kernels is sexy, but comes last
it is important to know that while writing custom kernels is the cool, sexy way to improve time to first token (TTFT), latency per token, and throughput, most gains are made in the unsexy layers above the kernel:
-
Batching: grouping many requests into one forward pass
-
Quantization: storing weights in 8 or 4 bits instead of 16, so there’s less to read per token
-
Speculative decoding: using a small model to guess several tokens, then verifying them with the big model in one pass
-
Compiler work: letting an ML compiler fuse easy ops before you write anything by hand
-
Other tricks like prefix caching, prefill/decode disaggregation, paged attention and more
A slow inference system is probably slow because it’s skipping the standard tricks above. Writing a custom kernel is a lot of work and it’s only worth it once everything above it is already fast.
where to start
For NVIDIA GPUs, Triton is a Python library where you write logic for one block of data and it generates GPU code for you. It gets you most of the way, but CUDA is the next level down and gives you full control.
There is a lot of work left in this space. Most of it is above the kernel: better batching, scheduling, and memory management across the whole inference stack. A lot of it is next to the kernel too..Triton is one of many kernel DSLs (languages built just for writing kernels) and the field is moving fast, with projects like ThunderKittens, TileLang, CuTe, and Mojo all trying different tradeoffs between control and ease of use.
“Making Deep Learning Go Brrrr From First Principles” by Horace He is a great introductory piece to performance engineering and inference, and I highly recommend a read even if you’re not particularly interested in writing kernels.
Similar Articles
@TheAhmadOsman: You wanna learn how do these AI kernels work? Start here
Tweet by @TheAhmadOsman pointing to a resource for learning how AI kernels work.
Introducing @huggingface/kernels: 200+ WebGPU Kernels for Local AI
Hugging Face releases 207 WebGPU kernels for local AI inference in browsers, along with a JavaScript loader library and a benchmarking tool called Fleet.
@levidiamode: 163/365 of GPU Programming Looking at a few different agentic GPU kernel optimization systems today. The two I'm most i…
A tweet discussing two agentic GPU kernel optimization systems: Auto GPU Kernel by @dogacel0 and Kernel Design Agents from @songhan_mit's lab, both winners at the MLSys Sparse Attention FlashInfer competition. The thread highlights different approaches using subagents and Claude skills for GPU programming.
A hackable compiler to generate efficient fused GPU kernels for AI models [P]
The author presents a custom, hackable ML compiler written in Python that lowers LLMs to optimized CUDA kernels through a multi-stage IR pipeline, achieving performance competitive with or superior to PyTorch on specific operations. The article details the compiler's optimization passes, lowering rules, and CLI usage for generating efficient fused GPU kernels.
@akshay_pachaar: GPU architecture, clearly explained. The usual assumption is that a faster GPU means more compute, so a chip rated for …
The article clarifies that GPU performance in AI inference is limited by memory bandwidth rather than compute power, using the NVIDIA H100 as an example to explain GPU architecture and its effect on token generation rates.