Batching Text for Language Model Training
Comparing the decoded text against the original is the sanity check.
Testing a Tokenizer With a Round Trip
A tokenizer is only as trustworthy as the checks we run on it. One of the simplest checks is a round trip. You take some text, convert it into token IDs, convert those IDs back into text, and compare the result with what you started with. If the two match, the tokenizer handled that text faithfully. If they do not match, the difference tells you something about the vocabulary the tokenizer was built from.
What do you think happens?
Before running any tokenizer, what do you expect to happen to a word that the vocabulary never saw during training?
Reveal answer
A tokenizer that uses an unknown-word token replaces that word with the placeholder, so the original word cannot be recovered after decoding.
The vocabulary is built earlier from a single training text. Words that were present in that training text receive their own IDs. Words that were not present are not dropped; they are mapped to an unknown-word token, and decoding that token cannot bring back the original word.
The check used in this article is deliberately awkward. The sample joins two sentences that have nothing to do with each other: a question about tea and a line about a sunlit terrace. The two sentences are joined with the <|endoftext|> token placed between them. Because the sample is unrelated text pasted together, it puts pressure on the vocabulary in two places at once: at the words themselves and at the boundary where one text ends and the next begins.
Tracing the Round Trip Step by Step
Follow the sample through the round trip in order. The first step is the joining step, which decides what the tokenizer sees at the boundary between the two texts. The <|endoftext|> separator must be present in the joined text for the tokenizer to treat it as a boundary marker. Keep track of that separator as you move forward, because it is the one piece of the sample that is meant to be special.
Encoding walks through the text and assigns each piece a numeric ID from the vocabulary. Ordinary words the vocabulary knows receive their own IDs. The separator is handled as one special token rather than being broken into pieces, so it appears in the ID sequence as a single entry. Words the vocabulary does not contain are not dropped. They are mapped to an unknown-word token instead, so the ID sequence still has an entry at that position.
Decoding converts the IDs back into text. In this sample, the decoded text keeps the separator, the punctuation, and the ordinary words. Only the words the vocabulary lacked come back as unknown-word placeholders. Comparing the decoded text against the original is the sanity check. Any position where the two disagree tells you about the vocabulary, not about the decoding code, because decoding faithfully reproduces whatever the IDs say.
Reading the Output for the First Mismatch
When you read the decoded output, do not scan for a general sense of whether it looks right. Read it position by position and ask one question: at which point does the recovered text stop matching the original? The first position of disagreement is the most useful one, because everything before it was handled correctly and the cause of the change lies at or just before that point.
How Special Tokens Mark Boundaries
Special tokens are markers that do not come from ordinary language. Their job is to tell the model something about structure: where a text begins, where it ends, or how to fill space so that texts of different lengths can be processed together. Some LLM pipelines define several such markers. The markers named in this course are [BOS], which marks a beginning, [EOS], which marks an ending, and [PAD], which fills unused space. The separator <|endoftext|> plays a similar structural role in the GPT family.
The GPT tokenizer does not need [BOS], [EOS], or [PAD]. For simplicity, it uses only the <|endoftext|> token. That single token plays the role of [EOS], and it is also reused for padding. This reuse is acceptable because of how training is set up. When training on batched inputs, a mask is applied so that the model does not attend to padded positions. Because of that mask, the specific token chosen for padding has no real effect on the result.
Worked Example: Padding an Uneven Batch
Aligning two sequences with the padding marker
A batch holds one sequence of four tokens and one sequence of two tokens. Both must have the same length before they can be processed together. Show how the shorter sequence is handled, and say which marker fills the gap.
- 1Measure each sequence
The first sequence has four token positions and the second has two. The batch must be padded to the longest length, which is four.
- 2Find the gap
The second sequence is missing two positions at the end. Those positions are unused space, not part of the text.
- 3Choose the marker
In the GPT setup, the separator <|endoftext|> is reused for padding. It fills the two empty positions at the end of the shorter sequence.
- 4Apply the mask
During training, a mask is applied so the model does not attend to those padded positions. The marker occupies a slot, but the mask keeps it from influencing the result.
Both sequences now have four positions. The shorter one ends with two <|endoftext|> entries that serve as padding, and the mask ensures those entries are ignored during training.
Unknown-Word Tokens Versus Byte Pair Encoding
The sample above used an unknown-word token, and it produced placeholders for words the vocabulary lacked. GPT models take a different route. They do not use an unknown-word token at all. Instead, they rely on byte pair encoding, a tokenizer that breaks words down into smaller subword units. The detailed mechanism of byte pair encoding is taught in a later discussion, so for now the important point is the contrast between the two approaches.
| Question | Unknown-word token | GPT byte pair encoding |
|---|---|---|
| What happens to an out-of-vocabulary word? | It is replaced by one unknown-word placeholder | It is broken into smaller subword units |
| Can the original word be recovered after decoding? | No, the placeholder cannot recover it | Its pieces are still represented, so the identity is kept in pieces |
| Is an unknown-word token used? | Yes | No |
Two ways a tokenizer can handle a word missing from its vocabulary
Mistakes Beginners Make With Round Trips
Common mistake Assuming a successful round trip proves the tokenizer knows every word
Why it failsA round trip only shows what the vocabulary can represent. A mismatch reveals gaps, and a match for the sample says nothing about words outside it.
Do this insteadUse a round trip on text that contains the words you care about, and read the output position by position.
Common mistake Blaming the decoding code for a changed word
Why it failsDecoding reproduces whatever the token IDs describe. A changed word means the encoding step mapped it to a placeholder or to pieces.
Do this insteadTrace the word back through encoding to see whether it received its own ID, was split, or was replaced.
Common mistake Treating <|endoftext|> as an ordinary word
Why it failsIt is handled as one special token, so it appears as a single entry in the ID sequence rather than being broken into pieces.
Do this insteadExpect the separator to come back intact in the decoded text and use it to mark the boundary between texts.
Common mistake Thinking the padding token must be a special, distinct marker in GPT
Why it failsGPT reuses <|endoftext|> for padding. The mask applied during batched training is what keeps padded positions from affecting the result.
Do this insteadRemember that the padding choice matters less than the mask that excludes padded positions.
Practice: Find the Divergence Point
A sample is encoded and decoded. The decoded output keeps the separator and most of the ordinary words, but one word has come back as an unknown-word placeholder. Explain what this tells you about the vocabulary, and state where you would look first to find the cause of the divergence.
Hints
- Ask whether the word was present in the training text the vocabulary was built from.
- Locate the position in the decoded output where the first disagreement appears, then trace that position back to the encoding step.
- Remember that decoding does not invent changes; it reproduces the IDs.
Key Takeaways
- A round trip of encode followed by decode reveals which words the vocabulary can represent, and any mismatch points to the vocabulary rather than the decoder.
- Known words receive their own token IDs, the separator <|endoftext|> is kept as one special token, and unfamiliar words are mapped to an unknown-word placeholder in tokenizers that use one.
- Special tokens mark where a text begins, where it ends, and how to pad sequences so they can be batched; GPT uses <|endoftext|> for both the end marker and padding.
- GPT models avoid an unknown-word token and use byte pair encoding, which breaks unfamiliar words into subword pieces that keep part of the word's identity.
- A padding mask keeps padded positions from affecting training, which is why reusing <|endoftext|> for padding is acceptable.