Qwen 3.5 SFT data: fill the special tokens that wrap an assistant turn.
The two special tokens are <|im_start|> and <|im_end|>. Qwen uses the ChatML grammar: open with <|im_start|>assistant, content, close with <|im_end|>.
Picture a stage play script. Every spoken line has a clear opening cue, the actor's name with a colon, and a clear ending cue, a blank line before the next speaker. Without those cues the actors would never know when to stop talking. A chat-tuned model has the same problem. Each assistant turn starts with a small marker that tells the model a reply is beginning, and ends with another marker that tells it to stop. Forget the ending marker in the training data and the model never learns where its turn ends, so at run time it just keeps going. The two markers Qwen uses are short tags that the tokenizer treats as single special words.
Detailed answer & concept explanation~7 min readEverything 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. 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.
3 min: name the two tokens, sketch the ChatML grammar, explain the train versus inference flag distinction, then walk through the common labels-slicing bug that breaks stop behavior.
Real products, models, and research that use this idea.
- Qwen 3.5 and the wider Qwen family use ChatML out of the box; the model card on Hugging Face documents the <|im_start|> and <|im_end|> markers as the canonical chat template.
- Hugging Face TRL SFTTrainer routes training data through tokenizer.apply_chat_template by default for Qwen models, which renders the special tokens as single ids correctly.
- Production serving stacks like vLLM and TGI configure stop tokens for Qwen as the ids of <|im_end|> rather than as string matches, so generation halts deterministically.
- Practitioners building custom multi-turn datasets often round-trip a sample through apply_chat_template plus decode with skip_special_tokens=False to confirm <|im_end|> appears in the right positions.
- Axolotl and Unsloth fine-tuning recipes for Qwen 3.5 expose chat_template='chatml' as a config flag and handle the apply_chat_template call so the user does not have to assemble the string manually.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhat changes if you set add_generation_prompt=True versus False, and which is right for training versus inference?
QHow would you verify your training data has the correct special-token placement before launching a fine-tune?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Treating <|im_start|> or <|im_end|> as plain ASCII strings the tokenizer would split. They are single registered vocabulary entries; getting them wrong breaks stop behavior at inference.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.