:MLP vs Q-Former,视觉特征到底怎么塞进 LLM?|多模态大模型专栏④)
对齐机制上MLP vs Q-Former视觉特征到底怎么塞进 LLM多模态大模型专栏④一句话讲透本篇视觉编码器输出(N, d_v)的特征LLM 需要d_h维的 token——中间这个翻译官即 Projector。其设计取向直接决定一个 VLM 属于主流范式还是早期方案。写在前面前三篇 已依次讲完架构全景 → CLIP 如何训练视觉编码器 → 张量如何一路流动。由此可知视觉特征最终都要塞进 LLM 的文本流。但有个关键问题一直被我们悬置了视觉编码器输出是(N, d_v)比如 SigLIP 的729 × 1152而 LLM 的每个 token 必须是d_h维比如 Qwen2.5 的3584。这个维度差的桥到底怎么搭这就是对齐机制alignment——VLM 区别于纯 LLM 的灵魂。这部分内容很厚Projector 设计、M-RoPE、动态分辨率塞进一篇会又长又散所以我拆成上下两篇本篇上Projector 的设计选择MLP vs Q-Former 训练侧 token layout 与 loss mask下篇M-RoPE 与动态分辨率视觉 token 如何知道自己在图里的位置阅读本篇后可获得✅ 讲清 MLP Projector 和 Q-Former 的本质区别知道为什么前者一统江湖✅ 理解为什么文档/OCR 任务绝不能用 Q-Former呼应本专栏的文档领域定位✅ 动手构建 VLM 训练的三个并行数组input_ids / attention_mask / labels✅ 跑通一份零依赖的 token layout demo避开手写训练 loop 的头号 silent bug一、核心命题维度对齐问题给定两个东西视觉编码器输出V ∈ R^{N_v × d_v}如 SigLIP-SO400M729 × 1152LLM 期望输入每个 token 都是d_h维如 Qwen2.5-7B3584问题怎么把V变成 LLM 能消化的东西约束有三条维度必须对齐d_v → d_h数量可保留可压缩直接喂N_v个或压成更少选哪种取决于训练目标、数据、任务这三条约束历史上演化出了三种方案。二、三种 Projector 方案演进方案 AMLP ProjectorLLaVA 范式—— 当今主流V (N_v, d_v) → Linear(d_v → d_h) → GELU → Linear(d_h → d_h) → 输出 (N_v, d_h)核心特征只改维度不改数量。729个视觉 token 一个不丢地映射成d_h维全送进 LLM。用 2 层 MLP 是 LLaVA-1.5 起的标准做法。方案 BQ-FormerBLIP-2 范式—— 早期方案learnable queries Q ∈ R^{32 × d_h} → CrossAttention(Q, V) → 32 个 token用一组可学习的 query通过 cross-attention 从729个视觉特征里提取出固定32个 token。强行压缩729 → 32。方案 CPerceiver ResamplerFlamingo 范式和 Q-Former 类似也是 cross-attention 压缩结构略有不同。PaliGemma-2 等仍在用变体。一张图看懂核心区别Q-Former · BLIP-2强压缩MLP Projector · LLaVA不压缩2 层 MLPCrossAttn32 个 query视觉特征(729, 1152)(729, 3584)token 数不变视觉特征(729, 1152)(32, 3584)压缩 23×进 LLM729 文本 ≈ 1000 tokenOCR/细节 ✓ 强进 LLM32 文本 ≈ 100 tokenOCR/细节 ✗ 差完整对比维度MLP ProjectorLLaVAQ-FormerBLIP-2视觉 token 进 LLM 数729不压缩32压缩 23×LLM 序列总长729 文本 ≈ 100032 文本 ≈ 100attention 显存O(729²)高O(32²)低信息保真度无损有损瓶颈严重OCR / 文档 / 细粒度✅ 强❌ 致命差通用对话✅✅32 token 够用训练复杂度1 阶段只训 projector多阶段先 Q-Former 再 LLM一句话总结MLP 不压缩729→729Q-Former 强压缩729→32。历史趋势2022Q-Former 当道BLIP-2、MiniGPT-4 2023 起MLP Projector 一统江湖LLaVA-1.5、Qwen-VL、InternVL结论先吃透 MLP ProjectorQ-Former 当作历史了解。现代主流 VLM 清一色 MLP 路线。三、为什么文档 VLM 绝不能用 Q-Former这点对本专栏的文档领域定位尤其关键值得单独说。32个 token 想表达729个 patch 的信息相当于每个 token 要代表 23 个 patch。在文档/票据任务里一个数字往往就占好几个 patch——32个 token 根本装不下一张发票的所有数字。一张发票日期、金额、税号、商品明细……每个数字都是独立 patch MLP729 token每个数字有专属载体 → 能准确读出 12,345.67 Q-Former32 token23 个 patch 挤一个 → 数字必然被丢、串行错乱正因如此LLaVA-1.5 之后的文档向 VLMQwen-VL、InternVL、Donut 类全面抛弃 Q-Former、转向 MLP。面向文档理解任务时有一条铁律Projector 不得压缩信息无损是底线。 Q-Former 的价值场景少样本对话、视觉问答这种不需要精确细节的任务32 个 token 够概括图像大意。但一旦要精确 OCR它就力不从心。四、LLaVA现代范式的奠基LLaVAVisual Instruction Tuning, NeurIPS 2023是当今所有主流 VLM 的参考实现。它的架构极简Image → CLIP-ViT-L/14 (frozen) → (576, 1024) features → MLP Projector (2-layer, trainable) → (576, 4096) → concat with text embeddings → Vicuna-7B/13BLLaVA-1.5-7B 的三组件参数来自实际模型组件参数量训练状态Vision TowerCLIP-ViT-L~304M frozenProjector2 层 MLP~8MtrainableStage 1 唯一LLMVicuna-7B~6738M frozen → ⚡ LoRA注意Projector 只有 8M 参数相比 LLM 的 6.7B 微不足道——这正是它能用大学习率1e-3、在几小时内训完的原因。它的 Projector 实现简单到令人发指code/02_alignment/02_projector_train.pyclassProjector(nn.Module):2-layer MLP projector, exactly LLaVA-1.5s design.def__init__(self,d_v:int,d_h:int):super().__init__()self.mlpnn.Sequential(nn.Linear(d_v,d_h),# 1024 - 4096nn.GELU(),nn.Linear(d_h,d_h),# 4096 - 4096)defforward(self,x):returnself.mlp(x)没错LLaVA-1.5 区别于纯 LLM 的灵魂组件就是这么一个两层 MLP。换到 SigLIP-SO400M1152→ Qwen2.5-7B3584的场景Projector 参数约1152·3584 3584·3584 ≈ 17M依然很小。两阶段训练关键阶段训什么数据目的1. Pretrain Projector只训 MLP558K 图文对学把视觉特征翻译到 LLM 维度2. Instruction Tuningprojector LLM (LoRA)150K GPT-4V 指令数据学指令对齐、视觉问答这就是 LLM 训练里没有的第一阶段详见第①篇的三阶段矩阵。Stage 1 的目标极其纯粹让随机初始化的 Projector在冻结的视觉编码器和冻结的 LLM 之间学会翻译。五、训练侧的 token layout最容易踩坑的地方到这里架构清楚了。但真要自己写 VLM 训练 loop绝大多数人死在 token 序列的构建上。这是 NLP 工程师转 VLM 的头号坑。核心认知图像不是 1 个特殊 token而是 N 个 token 组成的子序列。训练时要构建三个并行数组。我们跑 demo 看真实过程code/02_alignment/03_token_layout_demo.py零依赖可跑。Step 1-2image占位符如何展开用户的 prompt 是What is in this image?chat template 会插入一个image占位符prompt_ids | len 8 | 1 IMG 10 11 12 13 14 15 ↑ image 占位符1 个 token然后这个IMG占位符展开成 N 个 slot这里用 N9 演示真实 SigLIP384 是 729Qwen2-VL672 是 2304expanded | len 16 | 1 IMG IMG IMG IMG IMG IMG IMG IMG IMG 10 11 12 13 14 15 └──────────── 9 个视觉 slot ────────────┘注意展开后是9 个相同 id 的 slot不是 9 个不同 id。因为 LLM 不会真的用nn.Embedding去查这些 id框架会拦截它们、替换成 Projector 输出的真实视觉 embedding。id 只是位置标记。Step 3三个并行数组训练的灵魂把 assistant 的回答拼接上构建训练三元组。真实输出input_ids | len 24 | 1 IMG IMG IMG IMG IMG IMG IMG IMG IMG 10 11 12 13 14 15 20 21 22 23 24 25 26 2 attention_mask | len 24 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 labels (X-100) | len 24 | X X X X X X X X X X X X X X X X 20 21 22 23 24 25 26 2读这三行就懂了 VLM 训练的全部 label 策略位置label含义视觉 token9 个 IMG-100不算 loss——它们是输入不是目标prompt 文本10..15-100不算 loss——只学怎么回答不学怎么提问answer token20..26, 2真实 id只在这里算 next-token losspad-100同时 mask 掉 loss 和 attentionlabel-100label-100label真实 idlabel-100, attn0视觉 token×9❌ 不算 lossprompt 文本What is in this image?answer 文本A cat sitting on a table.✅ 算 losspad token❌ 不算 loss 不参与 attnStep 4每个训练者都该做的断言demo 末尾自动做了 sanity checktotal sequence length : 24 visual tokens : 9 (expected N_VISUAL9) prompt text tokens : 7 answer tokens : 8 (these compute loss) tokens with loss : 8 (must equal answer length) All assertions passed.tokens with loss必须严格等于 answer 长度——这一条断言能挡住一大半手写训练 loop 的 bug。三个最容易写错的坑亲历血泪slot 找错找image位置必须定位第一个多图场景要循环找出所有位置依次替换。visual_emb 行顺序错乱visual_emb[i]必须严格对应图像 row-major 第 i 个 patch。如果 dataloader 做了transpose/flippatch 顺序就乱了——模型直接学不动loss 不收敛但不报错头号 silent bug。attention_mask 没扩展拼接后序列变长attention_mask 也要 pad 出对应长度的 1否则 LLM 把视觉 token 当 pad 忽略掉。配图说明上面的三数组对齐输出和 mermaid label 策略图是本篇最该收藏的两张图。终端输出截图在 CSDN 很吃香建议把 demo 跑一遍截真实图。六、4 个关键点Projector 只做一件事d_v → d_h的维度翻译MLP 不压缩、Q-Former 强压缩这是两派分水岭。MLP 一统江湖的原因是信息无损——尤其文档/OCR 任务压缩就是丢数字。Projector 参数极小几 M ~ 二十 M能用大学习率快速训完是 Stage 1 的唯一主角。训练 label 的核心规则只在 answer token 上算 loss视觉和 prompt 全-100。visual_emb行顺序必须匹配 patch row-major 顺序否则静默失败。 本篇涉及代码文件说明code/02_alignment/02_projector_train.pyLLaVA Projector 实现 Stage 1 训练仅训 Projectorcode/02_alignment/01_minimal_llava.pyLLaVA 架构检视三组件 参数量code/02_alignment/03_token_layout_demo.pytoken layout 与 label mask 构建演示小结概念一句话对齐问题把视觉特征(N, d_v)翻译成 LLM 要的d_hMLP Projector2 层 MLP不压缩729→729主流Q-Formercross-attn 压缩729→32文档任务致命LLaVA Stage 1只训 8M 的 Projector学翻译label 策略只在 answer 算 loss视觉/prompt 全-100下一篇是对齐机制下视觉 token 怎么知道自己在图里的位置我们会从 1D-RoPE 推到M-RoPEQwen2-VL 的核心创新并讲清动态分辨率AnyRes Tile vs Native Resolution Bucket。配套一个零依赖的 4 段 demo能亲眼验证M-RoPE 在文本上严格等于 1D-RoPE。关注专栏更新第一时间通知。专栏《从 NLP 到 VLM多模态大模型研发实战》上一篇③ 张量级 walkthrough 本篇④ 对齐机制上 下一篇⑤ 对齐机制下· M-RoPE 与动态分辨率