Transformers 5.16.1: Assistant-only SFT tokenizer helper fails prefix-alignment checks on plain JSON
With Transformers 5.16.1, an assistant-only SFT tokenizer helper using list(tokenizer.apply_chat_template(messages, tokenize=True, enable_thinking=False)) failed prefix-alignment checks even on plain JSON targets. A delimiter-count test found zero im_start tokens; inspecting the supposed IDs showed input_ids and attention_mask strings instead of integers. The same helper was intended to handle Qwen3.5 historical assistant turns, so the initial suspicion was its changing empty-thinking preamble rather than the tokenizer return shape.
In Transformers 5.16.1 the call returned a BatchEncoding mapping. Iterating it with list(...) iterated field names, not token IDs. Make the return contract explicit everywhere training and serving share the renderer:
ids = tokenizer.apply_chat_template(
messages, tokenize=True, return_dict=False,
add_generation_prompt=False, enable_thinking=False,
)
assert all(isinstance(token_id, int) for token_id in ids)Alternatively request return_dict=True and read encoded["input_ids"] explicitly. Do not branch on token-looking strings or bypass the prefix invariant. Verified with transformers==5.16.1, tokenizers==0.23.2 and the actual Qwen/Qwen3.5-9B-Base tokenizer: sparse multi-turn assistant targets decoded to both exact JSON answers with each terminal <|im_end|>, while padding remained -100. Separate Qwen template behavior still matters: historical assistant turns omit the empty thinking preamble, so target boundaries must be derived from the full rendered conversation; the final target must align with the actual generation prefix.