#10817·LlamaFactory

[BUG] KTO with mrope models (Qwen3.5 family) crashes at step 0: "Multimodal data was passed ... but mm_token_type_ids is missing"

Author: haqishenCreated Sep 5, 2026Updated Sep 5, 2026

Reminder

  • I have read the above rules and searched the existing issues.

System Info

  • llamafactory 版本:最新 maindata/collator.py / train/kto/trainer.py 相关代码与当前 main 完全一致,已核对)
  • 平台:Linux x86_64
  • Python:3.11
  • PyTorch:2.10 / 2.11 均复现
  • Transformers:5.5.0 与 5.10.1 均复现(引入 mm_token_type_ids 强校验的版本起)
  • GPU:单卡 / 多卡(torchrun)均复现

Reproduction

对任意 mrope 架构模型(例如 Qwen3.5 系列,纯文本 checkpoint 也一样)跑 KTO,第 0 步 forward 即崩溃。SFT 和 DPO 同配置正常。

最小配置:

model_name_or_path: Qwen/Qwen3.5-0.8B
stage: kto
finetuning_type: lora
template: qwen3_5
dataset: kto_en_demo
cutoff_len: 1024

报错堆栈:

File "llamafactory/train/kto/trainer.py", line 190, in forward
    logits = model(**model_inputs, return_dict=True, use_cache=False).logits.to(torch.float32)
File "transformers/models/qwen3_5/modeling_qwen3_5.py", line 1589, in forward
    position_ids = self.compute_3d_position_ids(
File "transformers/models/qwen3_5/modeling_qwen3_5.py", line 1502, in compute_3d_position_ids
    raise ValueError(
ValueError: Multimodal data was passed (via `image_grid_thw` or `video_grid_thw`) but `mm_token_type_ids` is missing. Please pass `mm_token_type_ids` to the model so that multimodal RoPE (M-RoPE) can be computed correctly. `mm_token_type_ids` is returned by the processor alongside `input_ids`.

根因分析

三个环节叠加:

  1. MultiModalDataCollatorForSeq2Seq.__call__纯文本 batch 注入 dummy image(zero3/FSDP 防挂死的 workaround),因此 image_grid_thw 在每个 batch 里都存在。collator 同时通过 get_rope_index 预计算了 position_ids / rope_deltas 并放进 features。
  2. CustomKTOTrainer.forward()显式白名单构造 model_inputs:转发了 image_grid_thw,但不转发 collator 已算好的 position_ids / rope_deltaskl_ 前缀侧更是从未从 kl batch 里带出这两个 key —— KTODataCollatorWithPadding 只拷贝 kl_input_ids/kl_attention_mask/kl_labels 等)。
  3. transformers 的 modeling_qwen3_5.forward 看到 position_ids=Noneimage_grid_thw 非 None,走 compute_3d_position_ids 自行重算——该路径要求 mm_token_type_ids,而没有任何一方提供 → raise。

SFT 不受影响(标准 Trainer 全量透传 collator 输出,position_ids 到达 forward);DPO 不受影响(concatenated_forwardmodel(**batch))。只有 KTO 的白名单丢 key。

修复建议

两处都需要(只补 trainer 一侧时 kl_ forward 仍崩,已实测):

  1. KTODataCollatorWithPadding.__call__:把 kl batch 的 position_ids / rope_deltaskl_position_ids / kl_rope_deltas 带出。
  2. KTO trainer forward():白名单增加 {prefix}position_ids / {prefix}rope_deltas 的透传。position_ids 一旦到达 forward,模型完全跳过 3D 位置重算路径,mm_token_type_ids 不再被需要。仅在 key 存在时转发,非 mrope 模型零影响。

已在 Qwen/Qwen3.5-0.8B LoRA KTO(单卡、真实偏好数据)上验证:修复前第 0 步崩溃,修复后完整训练收敛。PR 随后提交。