【免费下载链接】InternVL3_5-2B-Flash
InternVL3_5-2B-Flash 是开源多模态大模型 InternVL3.5 家族的轻量高效版本,其核心创新是双路视觉 Token 压缩管线:通过 pixel_shuffle 将每个图像分块(tile)的 1024 个视觉 Token 压缩到 256 或 64 个,配合内置的 Visual Resolution Router(ViR)逐块路由,在视觉输入减少约 50% 的情况下保持接近 100% 的原版性能。本文带你完整看懂这条"1024→256→64"压缩管线的每一环实现。
🎯 一句话认识 InternVL3_5-2B-Flash
| 项目 | 说明 |
|---|---|
| 模型构成 | InternViT-300M(视觉编码器)+ MLP 投影 + Qwen3-1.7B(语言模型),总计约 2.3B 参数 |
| 核心创新 | 双路压缩管线 + 逐 tile 路由(ViR),对应官方训练中的 Visual Consistency Learning(ViCO)阶段 |
| 解决的问题 | 视觉 Token 数量大导致 LLM 预填充(prefill)开销高、推理慢 |
| 推理入口 | 开启flash_mode后,generate()自动路由到generate_flash |
模型的关键配置都在 config.json 末尾几行:flash_mode: true、downsample_ratio: 0.5、flash_relative_threshold: 0.1、flash_absolute_threshold: 0.5。
📉 为什么必须压缩?视觉 Token 的"膨胀"问题
InternVL 系列采用动态高分辨率策略:任意图像会被切成若干 448×448 的 tile(最多 12 个,外加一张缩略图,见 config.json 中max_dynamic_patch: 12)。而 ViT 的 patch 尺寸为 14,因此:
每个 tile 产生 (448 ÷ 14)² = 32 × 32 =1024 个视觉 Token
一张图用满 12 个 tile + 缩略图时,仅图像输入就有13000+ 个 Token,文本还没开始呢。LLM 自回归推理的成本几乎与输入 Token 数成正比,这正是"Flash"版本要动刀的地方——在送进语言模型之前,把视觉 Token 数量砍下去。
📐 三档 Token 规模:1024 → 256 → 64
整个压缩体系基于同一个基础操作:pixel_shuffle。它本质是一次无损的张量重排——把空间上相邻的若干特征格子的通道"合并"到一个 Token 上,空间分辨率下降、单 Token 通道维上升,总信息量不变,只是表达更"浓缩"了。
| 档位 | pixel_shuffle 缩放因子 | 输出网格 | 每 tile Token 数 | 单 Token 通道维 | 后续投影 |
|---|---|---|---|---|---|
| ViT 原始输出 | — | 32×32 | 1024 | 1024 | — |
| 标准路(256) | 0.5 | 16×16 | 256 | 1024×4 = 4096 | mlp1 → 2048 |
| 极速路(64) | 0.25(0.5²) | 8×8 | 64 | 1024×16 = 16384 | mlp2 → 2048 |
- 1024:InternViT(24 层,hidden 1024,见 modeling_intern_vit.py)对单个 tile 的原始输出,去掉 CLS 位后就是 32×32 网格。
- 256:InternVL3.5 标准版的做法,缩放因子取
downsample_ratio = 0.5,4 个相邻格子的通道合并,Token 数降为 1/4。 - 64:Flash 新增的更狠一档,缩放因子直接取 0.5² = 0.25,相当于两次 pixel_shuffle,Token 数降为 1/16。
由于 64 路每个 Token 要"背"16384 维通道(256 路是 4096 维),所以配套的投影 MLP 也不同:256 路用两层的 mlp1,64 路用更深的三层 mlp2(中间维度 4096),把浓缩后的宽通道压回 LLM 的 2048 维输入空间。
🔀 双路压缩管线全流程拆解
双路管线的核心是extract_feature_flash,整个流程分三步:
第一步:ViT 统一抽取 1024 特征
所有 tile 先过一遍视觉编码器,拿到每 tile 1024 个 1024 维特征。注意 ViT 只跑一次——后面无论路由结果如何,都不需要重跑视觉编码器。
第二步:双路 pixel_shuffle 并行预备
在同一份 1024 特征上,代码同时预备出两种压缩表示(均在torch.no_grad()下完成,不产生额外梯度开销):
vit_embeds_256:pixel_shuffle(0.5) → 256 个 Token → mlp1vit_embeds_64:pixel_shuffle(0.25) → 64 个 Token → mlp2
这一步的计算量相比 LLM 预填充 256 个 Token 的开销几乎可以忽略,属于"提前备好货"。
第三步:ViR 路由器给每个 tile 打分
路由器由两个组件构成:
- CrossAttentionPooling:用一个可学习的 query token,通过 4 轮交叉注意力把每个 tile 的 1024 个特征"投票"成 1 个汇总向量——相当于先看整块内容再决策。
- Gating:4 个残差 MLP block 做特征细化,最后接一个 2 分类的 gate 层,输出 softmax 概率
probs[:, 0]/probs[:, 1]。
概率probs[:, 0]越高,说明该 tile 语义越"稀疏简单"(如纯色背景、大面积留白),可以放心压到 64;反之信息密集的 tile(文字、细节)应保留 256。
⚖️ 路由决策:相对 + 绝对"双阈值"判定
打分之后,真正的取舍发生在generate_flash中,判定条件有两条,必须同时满足才压缩到 64:
相对阈值:gate > quantile(gate 全集, 0.1) 绝对阈值:gate >= 0.5- 相对阈值(
flash_relative_threshold: 0.1):取整批 tile 打分分布的 10% 分位数,落在最低 10% 的 tile 一律不压——相当于给最没把握的一批"留后路"。 - 绝对阈值(
flash_absolute_threshold: 0.5):两分类 softmax 概率和为 1,>= 0.5意味着路由器必须"占多数票"才动手。
判定通过后,compress_visual_tokens_in_sentence会做最后一件关键事:把该 tile 在句子里占位的 256 个<IMG_CONTEXT>Token(token id 见 added_tokens.json)物理删除其中的 192 个,只保留 64 个位置再填入 64 路特征。注意这不是"算了但不省"——序列长度真正缩短了,attention 计算量随之下降。
⚙️ 核心配置参数速查
| 参数 | 取值 | 作用 | 定义位置 |
|---|---|---|---|
flash_mode | true | 开启 Flash 模式,generate()走双路管线 | config.json |
downsample_ratio | 0.5 | 256 路缩放因子;64 路为其平方 0.25 | config.json |
flash_relative_threshold | 0.1 | 相对分位数阈值(10% 分位) | config.json |
flash_absolute_threshold | 0.5 | 绝对概率下限 | config.json |
ps_version | "v2" | pixel_shuffle 版本;v2 修正了 v1 宽高未换回导致的图像转置问题 | configuration_internvl_chat.py |
max_dynamic_patch | 12 | 单图最大 tile 数,决定压缩收益上限 | config.json |
🚀 快速上手:加载即用
Flash 逻辑已内置在模型里,加载方式与普通 InternVL3.5 一致,无需额外开关(trust_remote_code=True会加载本仓库的自定义代码):
from transformers import AutoModel, AutoTokenizer model = AutoModel.from_pretrained( "OpenGVLab/InternVL3_5-2B-Flash", torch_dtype=torch.bfloat16, trust_remote_code=True, use_flash_attn=True, ).eval().cuda() tokenizer = AutoTokenizer.from_pretrained("OpenGVLab/InternVL3_5-2B-Flash", trust_remote_code=True, use_fast=False)之后正常调用model.chat(...)即可,双路压缩与逐 tile 路由全程自动完成,用户无感知。
✅ 小结
- 双路并行、按需取用:256 路与 64 路特征在同一次前向中并行算好,路由器(ViR)按 tile 的语义丰富度决定走哪一路,简单区域用 64、复杂区域保 256。
- 压缩是"真省":被选中压缩的 tile 会实际删除 192 个占位 Token,序列变短,LLM 预填充成本真实下降。
- 双阈值保险:相对分位数 + 绝对概率的双重判定,避免路由器"误伤"信息密集的图像块。
- 收益明确:官方数据显示该机制使视觉 Token 减少约 50%,同时保持接近 100% 的 InternVL3.5 原版性能,是端侧与低算力部署的利器。
如果你想继续深挖,推荐按 README.md 中的 Model Architecture 与 Visual Consistency Learning 两节,对照 modeling_internvl_chat.py 的extract_feature_flash、Gating、generate_flash三个函数逐行阅读,即可完整还原"1024→256→64"的每一步。
【免费下载链接】InternVL3_5-2B-Flash
相关推荐
InternVL3_5-30B-A3B-Flash视觉Token压缩:pixel_shuffle到ViR路由的源码逐行走读
InternVL3_5 30B A3B Flash视觉Token压缩:pixel_shuffle到ViR路由的源码逐行走读 想弄清楚 InternVL3_5 3
InternVL3_5-1B-Flash 核心源码逐行解读:pixel_shuffle 双路压缩与 Token 裁剪如何砍掉 50% 视觉 Token
InternVL3_5 1B Flash 核心源码逐行解读:pixel_shuffle 双路压缩与 Token 裁剪如何砍掉 50% 视觉 Token Inte
ViCO视觉一致性学习揭秘:InternVL3_5-14B-Flash从256到64 Token的压缩训练原理
ViCO视觉一致性学习揭秘:InternVL3_5 14B Flash从256到64 Token的压缩训练原理 InternVL3_5 14B Flash 是
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考