Spot the bug: a Llama-3 fine-tune that skips the end-of-turn token
Same topic, related formats. Practice these next.
Same topic, related formats. Practice these next.
Click any words you think contain an error. Click again to unmark.
The template drops the `<|eot_id|>` end-of-turn token, so the model never learns to stop and drifts into invented turns at inference.
Imagine teaching someone to write letters, but every example you give them runs all the letters together with no full stops or sign-offs. They learn the words fine, yet they never learn where one letter ends. So when they write their own, they just keep going, signing your name then starting a fresh letter from a stranger. The fix is to put the sign-off back in every example so they learn that a turn has an ending. Here the sign-off is a special end-of-turn marker the model is supposed to emit. Skip it during training and the model has no idea it should stop talking, so at answer time it rambles past its own reply into a fake follow-up.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
5 min: locate the dropped end-of-turn token, explain the train-time and inference-time consequences, cover the loss-masking boundary, then give the apply_chat_template fix plus a round-trip verification.
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
msgs = [
{"role": "user", "content": user_msg},
{"role": "assistant", "content": assistant_msg},
]
# Builds the exact Llama-3 string, inserting <|eot_id|> after every turn.
text = tok.apply_chat_template(msgs, tokenize=False)
assert "<|eot_id|>" in text # sanity-check the terminator is present| Aspect | Buggy hand-built template | apply_chat_template() |
|---|---|---|
| End-of-turn token | Dropped between turns and after assistant | Inserted after every turn automatically |
| Stop behaviour learned | No, the model never sees the terminator | Yes, the terminator is in every example |
| Cross-model portability | Breaks when the base model changes | Adapts to each model's own template |
| Failure visibility | Silent, training loss looks fine | Round-trip decode confirms correctness |
Real products, models, and research that use this idea.
What an interviewer would ask next. Try answering before peeking at the approach.
Red flags and common mistakes that signal junior thinking. Click to expand.
Building the prompt string by hand instead of calling the tokenizer's chat template. A single dropped end of turn token silently teaches the model never to stop.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.