【大模型】对齐机制(下):M-RoPE 与动态分辨率,视觉 token 如何“知道“自己在哪?|多模态大模型专栏⑤

📅 2026/7/9 4:51:44
【大模型】对齐机制(下):M-RoPE 与动态分辨率,视觉 token 如何“知道“自己在哪?|多模态大模型专栏⑤
对齐机制下M-RoPE 与动态分辨率视觉 token 如何知道自己在哪多模态大模型专栏⑤一句话讲透本篇把图像拍平成一条序列喂给 LLM1D 位置编码会让上下相邻和左右相邻看起来差了 3 倍距离。M-RoPE 的解法极优雅把位置编码拆成 (时间, 行, 列) 三段文本退化、图像获益。写在前面第④篇上 我们搞定了 Projector视觉特征(N, d_v)被翻译成(N, d_h)塞进 LLM 文本流。但还差最后一块拼图——位置。文本 token 用 1D-RoPE 就够了因为文本天然是一维序列。但图像 patch 是二维网格第 0 号 patch 和第 1 号 patch 是左右相邻第 0 号和第 3 号下一行第一个是上下相邻——几何上它们等距但拍平后 1D 序号差分别是 1 和 3。这就是本篇要解决的两个问题M-RoPE怎么让位置编码感知 2D甚至 3D 视频结构Qwen2-VL 的核心创新动态分辨率固定 336×336 输入做不好文档怎么处理任意大小的高分辨率图阅读本篇后可获得✅ 讲清 M-RoPE 的 (t, h, w) 三段设计理解它为什么在文本上严格等于 1D-RoPE✅ 用真实数值证明1D-RoPE 拍平图像会破坏邻接知道 M-RoPE 怎么修复✅ 区分两种动态分辨率方案AnyRes TileLLaVA-NeXTvs Native Resolution BucketQwen2-VL✅ 跑通一份零依赖的 4 段 demo亲手验证上述每一条结论一、RoPE 30 秒回顾NLP 工程师可直接跳到第二节RoPE旋转位置编码对每一对相邻维度(q_{2k}, q_{2k1})做旋转角度由位置pos和频率θ_i决定angle i pos ⋅ θ i , θ i base − 2 i / d \text{angle}_i \text{pos} \cdot \theta_i, \qquad \theta_i \text{base}^{-2i/d}anglei​pos⋅θi​,θi​base−2i/dpos是 token 在序列里的位置0, 1, 2, …θ_i是第 i 个维度对的频率i 越大频率越高转得越快两个 token 在第 i 对上对齐的好坏取决于它们的(pos_a - pos_b)·θ_i关键直觉1D-RoPE 里pos是一个标量序列下标。M-RoPE 唯一的改动就是把这个标量换成三个标量分别驱动不同子空间。仅此而已。二、M-RoPE(t, h, w) 三段拆分Qwen2-VL 把d/2个维度对平均切成三段每段用一个独立的位置标量驱动head_dim d 的 d/2 个旋转对时段 T前 1/3 对由 temporal 驱动行段 H中 1/3 对由 height 驱动列段 W后 1/3 对由 width 驱动temporal_idx视频帧号height_idxpatch 行号width_idxpatch 列号文本 token设(t, h, w) (p, p, p)p 是序列下标三段用同一个数 → M-RoPE 退化为 1D-RoPE图像 token(t, h, w) (帧, 行, 列)h/w 按 2D 网格赋值视频 tokent 随帧变化这就是全部设计。下面用 4 段 demo 的真实数值验证它code/02_alignment/04_mrope_numpy.py零依赖可跑。三、Demo 验证四步看懂 M-RoPEDemo 11D-RoPE 的角度长什么样基线在d84 个旋转对的小配置上6 个 token 的 1D-RoPE 角度Tokens: [BOS] The cat sat on mat pos0 | 0.0000 0.0000 0.0000 0.0000 pos1 | 1.0000 0.1000 0.0100 0.0010 pos2 | 2.0000 0.2000 0.0200 0.0020 pos3 | 3.0000 0.3000 0.0300 0.0030读法pos0全零不旋转pos越大每对转得越快pair0最低频转最慢最后一个对转最快。这就是 RoPE 相对位置泛化的来源。记住这 4 个角度随 pos 线性增长的形态下一步对比要用。Demo 2M-RoPE 在 3×3 图像网格上的角度把图像排成 3×3 patch 网格单帧 t0每个 patch 拿(t0, h, w)patch | pair0 (T) pair1 (H) pair2 (W) (h0,w0) | 0.0000 0.0000 0.0000 (h0,w1) | 0.0000 0.0000 0.0100 (h0,w2) | 0.0000 0.0000 0.0200 (h1,w0) | 0.0000 0.1000 0.0000 (h1,w1) | 0.0000 0.1000 0.0100 (h2,w2) | 0.0000 0.2000 0.0200关键洞察同一行如(0,0)(0,1)(0,2)的 H 段角度全相同都是 0.0000只有 W 段在变。这意味着同一行的 patch 在 H 子空间里看起来一样互相 attend 时不受列差异干扰——这就是 2D 邻接被编码进去的方式。1D-RoPE 在拍平序列上做不到这点。Demo 3退化证明最关键的性质文本 token 设(t,h,w)(p,p,p)对比两种算法的 pair0 角度pos | 1D-RoPE pair0 M-RoPE pair0 | match 0 | 0.000000 0.000000 | OK 1 | 1.000000 1.000000 | OK 2 | 2.000000 2.000000 | OK 3 | 3.000000 3.000000 | OK 4 | 4.000000 4.000000 | OK All pairs match across all positions: True全部精确匹配。这就是 M-RoPE 最巧妙的地方它是 1D-RoPE 的严格推广strict generalization。文本 token 行为和之前一模一样零回归代价图像/视频 token 才获得额外的 2D/3D 结构。 这个性质为什么重要它意味着把一个纯文本 LLM 换成 M-RoPE不会损失任何语言能力。Qwen2-VL 敢直接复用 Qwen2 的预训练权重底气就在这里。Demo 41D-RoPE 拍平图像为什么是错的核心证据把 3×3 图像按 row-major 拍平flat index 0…8看四对邻居的位置差pair | 1D Δ | T Δ H Δ W Δ same row (horiz) | 1.0000 | 0.0000 0.0000 0.0100 same col (vert) | 3.0000 | 0.0000 0.1000 0.0000 diagonal | 2.0000 | 0.0000 0.1000 0.0100 far, diff row/col | 1.0000 | 0.0000 0.1000 0.0200这张表是本篇的灵魂逐行读邻居关系几何真相1D-RoPE 看到的距离问题同行左右相邻距离 1Δ 1.0✓ 正确同列上下相邻距离 1Δ 3.0❌几何等距却被看成 3 倍远对角线距离 √2Δ 2.0偏差1D-RoPE 把上下相邻误判成3 倍远——因为拍平后下一行的同列 patch 序号差是行宽 3。这就是为什么纯文本 LLM 直接看图像效果差位置先验是错的。M-RoPE 怎么修复看右边三列同行邻居H Δ 0行坐标相同W Δ 0.01列差 1→ 正确反映水平相邻同列邻居W Δ 0列坐标相同H Δ 0.1行差 1→ 正确反映垂直相邻不再用单一标量把 2D 压扁而是 per-axis 各自保留坐标M-RoPE 三段同行: HΔ0, WΔ≠0同列: WΔ0, HΔ≠02D 邻接 per-axis 保留✅ 文本零回归1D-RoPE 拍平图像同行 Δ1同列 Δ3几何等距 → 看成 3× 远❌ 位置先验错误四、动态分辨率高分辨率图怎么处理M-RoPE 解决了位置但还有个前置问题输入分辨率。固定 336×336 输入LLaVA-1.5会把所有图 resize 成同一个大小——文档里的小字 resize 后糊掉OCR 必然崩。于是演化出两种动态分辨率方案。方案 1AnyRes TileLLaVA-NeXT / OneVision思路把大图切成多个固定大小的 tile。原图任意 H×W → 选最近的长宽比6:1, 3:1, 4:3 … 共 9 档 → 切成 K 个 336×336 的 tile → 额外加 1 个缩略图 tile原图缩到 336×336提供全局上下文 → 每个 tile 过 ViT 得 576 token → 总共 (K1) × 576 个视觉 token一张 2:1 的长文档图 → K2 个 tile 1 缩略图 3 × 576 1728个视觉 token。优点细节每个 tile 全局缩略图都有OCR 大幅提升缺点高分辨率图能产生 2880 token显存压力大tile 间的空间关系靠缩略图隐式补方案 2Native Dynamic Resolution BucketQwen2-VL / InternVL2.5思路不切 tile直接让 patch 数随图像大小变化。输入(H, W)→ patch 数N_v (H/14) × (W/14)动态变化不再用固定 336小图几十个 token、大图几千个 token问题来了变长序列怎么组 batchQwen2-VL 用bucket 分桶Step 1: 按 patch 数划分 K 个 bucket bucket_0: [0, 256] ← 小图图标 bucket_1: [256, 576] ← 中图照片 bucket_2: [576, 1024] ← 大图文档 bucket_3: [1024, 2304] ← 高分图票据 bucket_4: [2304, ∞) ← 超高分 Step 2: 每 batch 只从一个 bucket 取样 → batch 内 patch 数接近 → padding 浪费 30% Step 3: 不同 bucket 按比例采样如 1:4:4:2:1防止只学小图为什么不直接 pad 到全局最大全局最大可能 2304 token小图 pad 到 2304 浪费 90% 算力且 pad token 干扰注意力。Bucket 把浪费控制在桶内。注意bucket 是训练专用优化推理单张图不需要。两种方案对比维度AnyRes TileLLaVA-NeXTNative ResolutionQwen2-VL处理方式切固定块 缩略图直接变 patch 数视觉 token(K1) × 576离散档位连续变化任意 N_v跨区域空间关系缩略图隐式补M-RoPE 显式编码batch 处理tile 数固定易组 batch需 bucket 分桶优雅度工程化、务实更统一、更彻底趋势Native Resolution M-RoPE 是更晚、更彻底的方案Qwen2-VL 之后逐渐成主流AnyRes 因实现简单仍是很多框架的默认选项。五、5 个关键1D-RoPE 拍平图像是错的上下相邻和左右相邻几何等距却被看成差 3 倍——这是纯文本 LLM 看图效果差的根因之一。M-RoPE 的改动极小只是把 1 个位置标量换成 (t, h, w) 三个分别驱动 head_dim 的三段子空间。M-RoPE 是 1D-RoPE 的严格推广文本设(p,p,p)就精确退化零回归代价——这是它能直接复用预训练 LLM 的底气。2D 邻接靠 per-axis 保留同行 H 坐标相同、同列 W 坐标相同而不是压成一个标量。动态分辨率两条路线Tile切块 缩略图工程务实vs Native变 patch 数 bucket更彻底。配合 M-RoPENative 方案更统一。 本篇涉及代码文件说明code/02_alignment/04_mrope_numpy.pyM-RoPE vs 1D-RoPE 对比4 段 demo含退化证明与邻接破坏分析动态分辨率AnyRes / Native Bucket目前以docs/02_alignment.md文档形式说明暂无独立 demo。小结概念一句话1D-RoPE 的问题拍平图像后上下相邻 3× 左右相邻的距离M-RoPE(t, h, w) 三段文本退化、图像获益退化性质文本 (p,p,p) → M-RoPE 严格等于 1D-RoPEAnyRes Tile切 K 个固定 tile 1 缩略图LLaVA-NeXTNative Resolution变 patch 数 bucket 分桶训练Qwen2-VL至此阶段 2 对齐机制全部讲完——已覆盖 Projector 设计、token layout、M-RoPE、动态分辨率足以拆解任意现代 VLM 的架构。下一篇进入阶段 3训练 Pipeline——多阶段训练配方、显存预算、文档 SFT 数据构造将真正动手训练一个文档领域的 VLM。专栏《从 NLP 到 VLM多模态大模型研发实战》上一篇④ 对齐机制上· Projector 本篇⑤ 对齐机制下· M-RoPE 与动态分辨率 下一篇⑥ 训练 Pipeline · LoRA SFT