多模态:Qwen2-VL / InternVL / MiniCPM-V
ms-swift 多模态支持是它的招牌:覆盖 50+ VLM / 音频模型,且数据格式统一。本章把多模态训练流程过一遍。
8.1支持的多模态模型
| 类别 | 模型 |
|---|---|
| 视觉 LLM (VLM) | Qwen2-VL / Qwen2.5-VL, InternVL2 / InternVL3, MiniCPM-V-2.5/2.6, LLaVA-1.5/1.6/NeXT, Llama-3.2-Vision, Pixtral, Gemma3-vision, Idefics2/3, DeepSeek-VL2, GLM4V, Yi-VL, Phi-3-vision |
| 音频 LLM | Qwen2-Audio, Llama3.1-Whisper, MiniCPM-Audio |
| OCR / 文档 | Qwen2-VL OCR mode, GOT-OCR2 |
| 多模态 R1 | Qwen2.5-VL + GRPO(推理增强) |
8.2统一数据格式
所有 VLM 训练都用 messages + 引用图片/音频文件:
{"messages": [
{"role": "user", "content": "<image>描述这张图"},
{"role": "assistant", "content": "图中有一只猫..."}
],
"images": ["./imgs/cat.jpg"]
}
{"messages": [
{"role": "user", "content": "<audio>这段话说了什么?"},
{"role": "assistant", "content": "..."}
],
"audios": ["./audios/clip.wav"]
}
<image> 占位符的数量必须等于 images 列表长度。ms-swift 自动按模型 template 替换成正确的 image token。
8.3典型 SFT:Qwen2-VL-7B + LoRA
swift sft \
--model Qwen/Qwen2-VL-7B-Instruct \
--dataset AI-ModelScope/llava-instruct-mix-vsft \
--train_type lora \
--num_train_epochs 1 \
--per_device_train_batch_size 1 --gradient_accumulation_steps 16 \
--learning_rate 1e-4 \
--max_length 4096 \
--torch_dtype bfloat16 \
--target_modules all-linear \
--freeze_vit true \ # ★ 冻结 ViT 节省显存
--freeze_aligner true # ★ 冻结对齐 MLP(可选)
关键开关:
| 字段 | 作用 |
|---|---|
--freeze_vit | 冻结视觉 encoder(推荐 true,省 30% 显存) |
--freeze_llm | 冻结 LLM 部分(罕见) |
--freeze_aligner | 冻结 vision-LLM 对齐 MLP |
--vit_lr | 给 ViT 单独 lr(默认 = lr) |
--aligner_lr | 给 aligner 单独 lr |
8.4多图 / 视频
多图:
{"messages": [{"role":"user","content":"<image><image>这两张图区别?"}, ...],
"images": ["./a.jpg", "./b.jpg"]}
视频(自动抽帧):
{"messages": [{"role":"user","content":"<video>视频里发生了什么"}, ...],
"videos": ["./clip.mp4"]}
视频抽帧由模型 template 内部处理,通常 8-32 帧。可以传 --video_max_pixels 控制分辨率。
8.5多模态 GRPO(R1 风格视觉推理)
swift rlhf \
--rlhf_type grpo \
--model Qwen/Qwen2.5-VL-7B-Instruct \
--dataset AI-ModelScope/clevr_cogen_a_train \
--train_type lora \
--num_generations 8 \
--max_completion_length 1024 \
--reward_funcs accuracy format \
--use_vllm true \
--vllm_gpu_memory_utilization 0.3 \
--beta 0.04
这是 2025 年很火的"视觉 R1"配方:让 VLM 学会 <think>...</think><answer>...</answer> 推理。
8.6显存预算
Qwen2-VL-7B、LoRA、freeze_vit=True、单卡:
| 序列长度 | 显存 |
|---|---|
| 2K + 1 张图 | ~18 GB |
| 4K + 4 张图 | ~26 GB |
| 8K + 8 张图 | ~38 GB |
| 视频 16 帧 + 2K text | ~32 GB |
8.7常见踩坑
| 现象 | 处理 |
|---|---|
| 图片找不到 | jsonl 里写绝对路径;或设 --media_dir |
| OOM | 开 --freeze_vit true;降图片分辨率 --max_pixels 1024*1024 |
| 训完只会输出文字、不"看"图 | 检查 vision token 是否生效;用 swift infer --stream true 看注意力 |
| 视频抽帧慢 | 用 decord / pyav 后端;预处理时持久化抽帧结果 |
8.8VLM 60+ 族实际覆盖
v4 之后 ms-swift 支持的 VLM 族在 swift/model/constant.py 的 MLLMModelType 类下。按"图像 / 视频 / 音频 / 全模态"分类:
| 类别 | 代表模型 |
|---|---|
| 图像 VLM | Qwen2-VL / Qwen2.5-VL / Qwen3-VL / InternVL3 / InternVL3.5 / GLM4.5-V / MiniCPM-V-4 / Ovis2.5 / LLaVA-Next / LLaVA-OneVision / DeepSeek-VL2 / DeepSeek-OCR / Llama4-VL / Gemma3-VL / MiniMax-M2-VL / mPLUG-OWL3 / CogVLM2 |
| 视频 VLM | Qwen2.5-VL(原生视频)/ MiniCPM-V(多帧)/ InternVL3(视频) |
| 音频 LLM | Qwen-Audio / Qwen2-Audio / MiniCPM-o / Qwen3-Omni |
| 全模态(Omni) | Qwen2.5-Omni / Qwen3-Omni / MiniCPM-o |
| OCR 专用 | DeepSeek-OCR / KeyeOCR / HunyuanOCR |
| Reranker VLM | Qwen3-VL-Reranker |
8.9Template 多模态 token 占位
VLM 训练用的 template 跟纯 LLM 不同,会处理 <image> / <video> / <audio> 三种占位符。看 swift/template/templates/vl/ 目录组织:
| 文件 | 注册的 template | 关键能力 |
|---|---|---|
qwen_vl.py | qwen_vl / qwen2_vl / qwen3_vl | 视觉 token 嵌入;视频抽帧后多 <image> |
internvl.py | internvl3 / internvl3_5 | image patch 切分(动态分辨率) |
minicpm_v.py | minicpmv 系列 | 多 patch 视觉编码 |
llava.py | llava-next / llava-onevision | 多图 + 视频统一 |
deepseek_vl2.py | deepseek_vl2 / deepseek_ocr | OCR 专用 special token |
qwen_omni.py | qwen2_5_omni / qwen3_omni | image + audio + video 一体 |
cogvlm.py | cogvlm2 | 双向视觉 |
8.10视觉 token 数控制(--max_pixels 实际怎么算)
训练 VLM 时显存最敏感的字段是 --max_pixels。Qwen2-VL 系列规则(来自 template/vision_utils.py):
- 图像缩放到
max_pixels范围内,按 28×28 patch 切; - 视觉 token 数 ≈
image_w × image_h / (28×28); 768×768 → 729 token / 1024×1024 → 1296 / 1280×720 → 1080 token;- 视频按帧累加:16 帧 × 768×768 ≈ 11664 视觉 token;
- 所以
cutoff_len配 VLM 时要预留 1-2k 给视觉 token,文本 budget 反而少。
8.11多模态 packing(2025 新)
2025-06 之后 ms-swift 引入多模态 packing,README 声称训练吞吐 +100%。原理:
- 把多个短样本拼成长序列,省 padding;
- 视觉 token 不跨样本边界(attention mask 隔开);
- 需要 FlashAttention-2 +
packing_samples=True; - 多模态 packing 在
swift/dataset/packing.py(7.3 KB)实现。
启用:swift sft --packing true --use_flash_attn true。新人首次跑 VLM 强烈建议开。
8.12Grounding(bbox / 关键点)
VLM 训练除了"看图说话"还可以训"指物"。swift/template/grounding.py(3.1 KB)支持把 bounding box 归一到 [0, 1000] 或原始像素坐标。数据 schema 示例:
{
"messages": [
{"role": "user", "content": "<image>找到图中的红色汽车"},
{"role": "assistant", "content": "<ref>红色汽车</ref><box>(123,456),(789,012)</box>"}
],
"images": ["/path/img.jpg"]
}
训完模型能输出含 <box> 标签的位置;推理时 swift 自动解析回像素坐标。
8.13这章你需要带走的
- ms-swift 支持 50+ 多模态模型,覆盖最广;
- 数据格式统一:messages + images/audios/videos 字段;
- VLM 训练推荐
--freeze_vit true省显存; - 2025 视觉 R1 配方 = Qwen2.5-VL + GRPO + accuracy reward;
- 视频自动抽帧,可调 max_pixels / video_max_frames。