Oct 20, 20267 min read/2026/10/20/putting-it-together-how-a-model-picks-the-next-token/

Putting It Together: Watch a Model Pick Its Next Word, Through Its Weights

This series has been taking a model apart: tensors (the boxes of numbers), tokenizers (text into pieces), alphabets and bytes, where weights come from, and open weights (the file you download). This one puts it all back together and shows it working.

In the open-weights article, I ran this script on my Mac:

from mlx_lm import load, generate

model, tokenizer = load("mlx-community/Qwen3.5-2B-4bit")   # downloads once, then runs offline
messages = [{"role": "user", "content": "In one sentence: what are open model weights?"}]
prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True, enable_thinking=False)
print(generate(model, tokenizer, prompt=prompt, max_tokens=80, verbose=True))

and the model answered, confidently and wrongly, that open weights are "the publicly available source code and parameters" of a model. So I ran it again, one token at a time, and recorded everything that happens inside. Press Play:

Everything in the animation is real: recorded from that exact model and prompt, and the text it builds matches what generate() printed, word for word.

What you're watching

The strip at the top is the whole journey of one token:

  1. Text → tokens. The chat template wraps my question in special tokens, so the model knows who's speaking: 22 tokens in all, shown in the grey box.
  2. Tokens → embedding rows. Each token id picks one row of the embedding table: 248,320 rows of 2,048 numbers each. The bottom-right corner shows the first 12 numbers of one real row.
  3. Through 24 layers. Those vectors flow up the tower. Each layer is a big multiplication by its own weights. This model mixes two kinds of layers: three "linear attention" layers, then one "full attention" layer that can look back at every earlier token, repeated six times. Why 24? It's a design choice for a model this size: each layer is one more pass of "read the text so far, refine the understanding", and each one costs time on every token. Bigger models go deeper: Meta's Llama 3 uses 32 layers at 8B, 80 at 70B and 126 at 405B (Llama 3 paper).
  4. 248,320 scores. After the last layer, the model scores every token in its vocabulary, because it doesn't know in advance which words are possible. That sounds expensive, but it's one matrix multiplication: the 2,048 numbers for the current position times the 248,320 × 2,048 table, about 500 million multiply-adds, which a GPU does in a fraction of a millisecond.
  5. Probabilities. The scores become probabilities that add up to 100%. The bars show the top 8; the other 248,312 tokens share what's left. Sometimes the race is close: after "…and retrain" the top choices were "the" 23%, "models" 16% and "them" 14%, all of which would make a sensible sentence.
  6. Pick one, append, repeat. This run is greedy: it always takes the most likely token. Then the whole journey starts again, with one more token of text. 37 times.

The tower is the unusual part. For each layer I asked the model, "if you had to answer right now, what would you say?" (researchers call this the logit lens). The green bar is how likely the final choice already is at that layer.

Where do the candidates come from?

The model never invents a word. Every candidate comes from its vocabulary: a fixed list of text pieces decided before training, by the byte-pair-encoding process from the tokenizer article. For Qwen3.5 that process made 247,587 merges and ended with 248,044 pieces, plus 33 special markers like <|im_start|>. The list ships with the model as tokenizer.json, and every piece has a number:

Piece id
" the" 279
" code" 1970
" source" 2450
"Open" 4841
" parameters" 4868
源代码 ("source code") 120869

At the last step, the model compares its current 2,048 numbers with one row per id (in this model, the same table it used for the embeddings at the start), and how well they match is that token's score. The table has 248,320 rows: the 248,077 real entries, plus a few unused ones that round the size up for the GPU.

And they're pieces, not words. Frequent words get a piece of their own; everything else is built from fragments. Five entries picked from the list: " se", " transform", " forc", the Thai letter "ฏ", and " contemporaine". By my rough count, about 105,000 pieces are English letters, 55,000 Chinese, 18,600 Cyrillic, 22,000 digits, punctuation and code, and 46,000 other scripts and byte fragments. That's why 源代码 could compete with " source": both are on the same list, and the model scores the whole list every time. Training didn't teach it words; it taught it which entry to score highest.

Three things I didn't expect

1. The decision happens late. Watch the tower on almost any token: the lower layers' "answers" are noise (word fragments, punctuation, random scripts), or just an echo of the previous word. Across all 37 tokens, the final choice takes the top spot for good at layer 22 (the median), never earlier than layer 14, and for 12 of the 37 only at the very last layer. Most of the depth is spent building understanding; the word itself is chosen near the end.

2. Where it went wrong. The animation opens on that step. After "…the publicly available", the model's top 3 were:

Next token Probability
source 64.5%
code 20.9%
parameters 2.2%

The correct idea, "parameters", was a 2% long shot. Greedy decoding takes the top one, and after "source" the next step was almost forced: "code" at 99.4%. One probable-but-wrong word, and the rest of the sentence followed it.

3. It thought in Chinese first. On that same step, layers 19 and 20 would have said 源代码, which is Chinese for "source code". Only at layer 21 does it switch to the English " source". The same happens on the very first word: in the middle layers it leans toward 所谓 ("so-called"), and "Open" only appears at layer 20. Qwen is trained on a lot of Chinese, and its vocabulary has whole Chinese words as single tokens; on the way to an English answer, it passed through Chinese.

Putting it together

  • The tokenizer turned my question into 22 numbers.
  • Each number picked a row from a tensor of 248,320 × 2,048.
  • 24 layers of weights (learned from random noise, as in my toy experiment, only at enormous scale) transformed those rows.
  • The last layer produced probabilities for every possible next token.
  • A simple rule picked one, and the loop ran again.

That's all a language model does when it "writes": one probability distribution per token, 37 times for this answer. It's also why it can be confidently wrong. The model doesn't know facts the way a database does; it knows which token is likely next, and "source code" is a very likely phrase after "publicly available".

How much to trust this

  • One prompt, one small model (2B, 4-bit), greedy decoding. A bigger model, or sampling with temperature, would choose differently. The 4B model in the last article got the answer right.
  • The logit lens is an approximation. The intermediate layers weren't trained to produce words, so their "answers" are a window into the model, not its literal thoughts. That's why the early layers look like noise.
  • The code is short: a manual generation loop that records the top 8 tokens at each step, plus one extra forward pass per token that reads out every layer. The recorded data is exactly what the animation plays.

The one-line mental model

A language model is a loop: tokens in, through every layer of weights, one probability for every possible next token, pick one, repeat. Everything else in this series was a close-up of one piece of that loop.