AI Engineer Track · Working With Llms
Autoregressive Generation: Training vs Inference
Autoregressive Generation: Training vs Inference
A language model generates text one token at a time: it looks at everything written so far, predicts the single most likely next token, appends it, and repeats. This autoregressive loop is why responses arrive as a stream rather than all at once, why longer answers take longer to produce, and why the same prompt can produce a different answer each time you run it.
Why this matters
Nearly every cost, latency, and nondeterminism property you will run into in production traces back to this one loop. Once you see generation as think, sample, append, repeat, behavior that otherwise looks mysterious becomes predictable.
The autoregressive loop
Given a sequence of tokens, the model computes a probability distribution over every possible next token, conditioned on everything that came before it. Generation samples one token from that distribution, appends it to the sequence, and runs the whole forward pass again on the new, longer sequence. Because each step depends on the result of the previous one, generation is inherently sequential: you cannot parallelize across output tokens the way you can parallelize across a batch of separate requests.
That single structural fact is why latency scales with the number of output tokens rather than the length of the prompt, and why the model is effectively re-reading the entire conversation on every single call rather than just the newest message.
One API call is not one token. It is a whole sequence of sequential forward passes, and every cost and latency property you will observe flows directly from that loop.
Training vs inference
Training and inference are the same forward pass used for opposite purposes. During training, the model sees real text, predicts the next token, and the error against what the text actually says updates the model's weights; this is the only phase where anything is learned. During inference, the trained distribution is sampled to produce new text, the weights are frozen, and nothing is learned from the interaction no matter how many times you run it.
Two consequences follow in practice. The first is the KV-cache: at inference time the model caches the key and value activations for every previous token, so each new token only has to attend to itself against that cache rather than recomputing attention over the whole sequence from scratch, which is the main reason inference is fast enough to ship at all. The second is that identical prompts can produce different outputs, because sampling is stochastic by design; getting the same output twice generally requires temperature zero and a fixed seed, and even then is not guaranteed across different providers or model versions.
Training is learning; inference is sampling from what was already learned. The loop producing the text is identical either way.
Why generation is sequential
Token n+1 is conditioned on token n, so the two cannot be computed independently of each other, and that one fact explains most of what surprises engineers the first time they build on top of an LLM API. Latency is dominated by output length rather than prompt length, because the prompt is processed once up front and then one additional forward pass runs per output token. Streaming exists specifically because each token becomes available the moment it is produced rather than only once the entire completion is finished. And the context window is shared between the prompt and the completion, so every output token the model generates also gets added back into context and consumes budget that could otherwise go toward a longer prompt or a longer conversation history.
Sequential generation is not an implementation detail that might get optimized away. It is the defining constraint of the architecture, and cost, latency, and nondeterminism all follow from it.
Worked example
Picture asking a model for a 200-word answer versus a 20-word answer to the same question, with an identical prompt in both cases. The prompt is processed once, so that part of the cost and latency is fixed. The 200-word answer requires roughly ten times as many sequential forward passes as the 20-word answer, which is why trimming the requested output length is one of the most direct latency levers available, and why a 'just summarize in one sentence' instruction measurably speeds up a response in a way that has nothing to do with the model 'trying harder.'
Practice
Clone nanoGPT and train on a small corpus on a laptop CPU for a few minutes. Instrument the forward pass to print the top five next-token probabilities at a chosen position in the generated text. The goal is to be able to explain, from your own run, where the logits come from, why generation has to be a loop, and why a repeated identical prefix still costs tokens on every single call.
Interview checks
- Why does the same prompt sometimes produce a different answer?
- Why is a long response slower than a short one, even with the same prompt?
- What does the KV-cache actually cache, and why does it matter for latency?
Common failure modes
- Treating the model as a black-box question-answering API rather than a sampler, which leads to confusion when outputs are nondeterministic.
- Expecting parallel or batched generation to speed up a single long response; the loop inside one response is sequential no matter how much compute you throw at it.
- Not realizing the full prompt is reprocessed on every turn of a multi-turn conversation, not just the newest message.
Resources
- Attention Is All You Need — The Transformer paper. Its architecture and self-attention definition are the substrate every modern LLM is built on.
- Scaling Laws for Neural Language Models — Shows loss scales predictably with parameters, data, and compute, which is why inference cost is a real design axis and not an afterthought.
- nanoGPT — The cleanest full GPT training and generation implementation in a few hundred lines; reading model.py and the generate loop demystifies the whole thing.
Expert signals
Being able to trace logits through softmax into sampling, explain why the KV-cache makes the first token slower to produce than every subsequent one, and reason separately about the prefill and decode phases is the difference between describing generation and actually being able to debug its latency. It is also worth internalizing that temperature zero is still a sampler running over the same autoregressive loop, not a different generation mode.
Confidence
high
Pathweys