Learning vLLM via Hands-On Iteration | Generated by AI

Home 2026.07

Question: Why learning vLLM / inference requires the same iterative loop as nanoGPT training?

Answer:

Yes, exactly. The same experimental loop that made nanoGPT click is the right way to understand vLLM, nano-vLLM, and inference systems.

The difference is:

But the methodology is identical:

hypothesis
   ↓
change one thing
   ↓
run experiment
   ↓
print logs / inspect tensors / measure
   ↓
build mental model
   ↓
repeat

That is basically how Karpathy learns systems too.


For nanoGPT, your loop was:

model.py
   |
   | print(loss)
   | print(tokens)
   | print(attention)
   | modify architecture
   |
train
   |
observe behavior

After running 13 small models, your brain accumulated:

You didn’t “read transformer theory”; you built an internal simulator.


For vLLM the same thing happens, but the variables change.

A transformer forward pass:

tokens
  |
embedding
  |
attention
  |
MLP
  |
logits
  |
sampling
  |
next token

vLLM adds the serving layer:

HTTP request
      |
 tokenizer
      |
 scheduler
      |
 KV cache manager
      |
 GPU execution
      |
 sampling
      |
 streaming tokens

You need to observe:

1. Different input lengths

Example:

Prompt A:
"hello"

Prompt B:
10000 tokens document

Observe:

You start understanding:

“Ah, long prompt cost is not the same as generation cost.”


2. Different generation lengths

Example:

input:
Explain transformer

max_tokens=20

vs

max_tokens=2000

Observe:

You discover:

prefill = compute heavy

decode = memory bandwidth heavy

3. Different models

Run:

Qwen3-8B
Llama-8B
Mistral-7B

Same server.

Observe:

model size
      |
      v
VRAM
      |
      v
KV cache capacity
      |
      v
batch size
      |
      v
throughput

Then vLLM architecture becomes intuitive.


4. Change scheduler parameters

For example:

max_num_seqs
max_model_len
gpu_memory_utilization

Run:

10 users
50 users
100 users

Watch:

latency
throughput
OOM

You learn why vLLM invented PagedAttention.


The key experiment:

Run a tiny nano-vLLM.

Something like:

nano-vllm/
 ├── engine.py
 ├── scheduler.py
 ├── attention.py
 ├── kv_cache.py
 └── sampler.py

Add logs:

print(
    "request",
    request_id,
    "prompt_len",
    len(tokens),
)

print(
    "kv blocks",
    len(kv_cache.blocks)
)

print(
    "batch size",
    len(active_requests)
)

Then send:

request 1:
short prompt

request 2:
long prompt

request 3:
code generation

Watch the scheduler.

The moment you see:

Request A:
tokens 0-4096

KV blocks:
[1][2][3][4]

Request B:
tokens 0-512

KV blocks:
[5]

PagedAttention stops being a paper concept.

It becomes a thing you have watched happen.


Your previous nanoGPT learning pattern is actually closer to how research engineers work:

Not:

read paper
memorize formula
implement

but:

implement
break it
measure it
make wrong assumptions
fix mental model

For vLLM, I would do the same progression:

Step 1:
llama.cpp inference

Step 2:
naive PyTorch generate()

Step 3:
batch multiple requests

Step 4:
add KV cache

Step 5:
continuous batching

Step 6:
PagedAttention

Step 7:
CUDA kernel optimization

Each step should be a “small model experiment”.

The biggest jump is usually when you implement continuous batching + KV cache management. That is where inference systems become different from normal ML code. You stop thinking “one input → one output” and start thinking “GPU time scheduler managing many token streams.”


Generated by AI. Curating and sharing still takes effort. If you find it useful, feel free to donate. WeChat: @lzwjavaWeChat QR · X: @lzwjava · Say hi 👋

Back Donate