MLLM动态分辨率
MLLM中的动态分辨率发展历程
·未分类
为什么需要动态分辨率?
传统 ViT 使用固定分辨率(如 224×224 或 336×336),存在以下问题:
- 高分辨率图像被压缩,丢失细节
- 不同长宽比图像被强制 resize,造成形变
- 无法处理需要高清细节的任务(如 OCR、文档理解)
主流动态分辨率实现方案
1. LLaVA-NeXT (AnyRes)
思路:全局图 + 局部裁剪
实现:
- 原图 resize 到固定分辨率作为全局图
- 根据原图尺寸选择最佳切分策略(如 2×2、1×3 等)
- 将切分后的 patches 分别过 ViT
- 拼接所有 patch tokens + 全局 tokens
2. Qwen2-VL (NaViT-style)
思路:原生动态分辨率
实现:
- 移除 ViT 的固定位置编码,使用 2D RoPE
- 图像按 14×14 patch 切分,保持原始长宽比
- 不同图像的 tokens 打包成一个 batch(packing)
- 支持任意分辨率,无需预定义切分策略
3. InternVL / InternLM-XComposer2
思路:动态切分 + 缩略图
实现:
- 预定义多种分辨率模板
- 选择最匹配原图的模板
- 动态切分成多个 448×448 tiles
- 加入缩略图保留全局信息
4. MiniCPM-V / OmniLMM
思路:自适应切片
实现:
- 根据图像分辨率动态决定切片数量
- 使用滑动窗口或网格切分
- 重采样器压缩 visual tokens
Qwen-VL 动态分辨率演进
Qwen-VL (初代)
- 方案:固定分辨率 448×448
- 问题:高分辨率图像细节丢失,长宽比变形
Qwen2-VL 重大改进 ⭐
这是动态分辨率的里程碑式改进:
1. Naive Dynamic Resolution(原生动态分辨率)
传统方案:图像 → resize 到固定尺寸 → ViT
Qwen2-VL:图像 → 保持原始尺寸 → 动态切 patch → ViT
2. 移除绝对位置编码,使用 2D-RoPE
- 传统 ViT 使用固定的 1D 位置编码(只支持固定分辨率)
- Qwen2-VL 采用 Multimodal Rotary Position Embedding (M-RoPE)
- 将位置信息分解为:时间维度 + 高度维度 + 宽度维度
- 支持任意分辨率和长宽比
3. 动态 Token 数量
- 分辨率越高 → token 数量越多
- 设置最大/最小像素数限制,控制计算开销
- 例如:
min_pixels=256*28*28,max_pixels=1280*28*28
4. 视频原生支持
- 视频帧也使用动态分辨率
- 通过 M-RoPE 的时间维度处理帧间关系
Qwen2.5-VL 进一步优化
1. Window Attention + 全局 Attention
- 对高分辨率图像使用窗口注意力降低计算量
- 保留全局 attention 层维持全局理解
2. 动态 FPS 采样(视频)
- 根据视频内容动态调整采样帧率
- 快速运动场景 → 高 FPS
- 静态场景 → 低 FPS
3. 更精细的分辨率控制
# Qwen2.5-VL 配置示例
processor = AutoProcessor.from_pretrained(
"Qwen/Qwen2.5-VL-7B-Instruct",
min_pixels=256 * 28 * 28, # 最小 token 数
max_pixels=1280 * 28 * 28, # 最大 token 数
)
核心改进点总结
- 位置编码:从 1D 绝对位置编码 → 2D RoPE / 相对位置编码
- Token 压缩:Resampler / Perceiver / Q-Former 减少 visual tokens
- 分辨率选择:预定义模板 → 动态计算最优分辨率
- 全局信息保留:缩略图 / 全局 token / 多尺度特征
Qwen2-VL 动态分辨率的核心优势
- 真正的任意分辨率 - 不需要预定义切分策略
- 保持原始长宽比 - 无形变
- 计算量可控 - 通过 min/max pixels 限制
- 统一处理图像和视频 - M-RoPE 自然支持时序