☰
InternVL3_5-2B-Flash双路压缩管线详解:pixel_shuffle实现1024→256→64 Token极致压缩
2026/10/20 4:40:45 网站建设 项目流程

【免费下载链接】InternVL3_5-2B-Flash

项目地址:https://ai.gitcode.com/OpenGVLab/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×3210241024—
标准路(256)0.516×162561024×4 = 4096mlp1 → 2048
极速路(64)0.25(0.5²)8×8641024×16 = 16384mlp2 → 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 → mlp1
  • vit_embeds_64:pixel_shuffle(0.25) → 64 个 Token → mlp2

这一步的计算量相比 LLM 预填充 256 个 Token 的开销几乎可以忽略,属于"提前备好货"。

第三步:ViR 路由器给每个 tile 打分

路由器由两个组件构成:

  1. CrossAttentionPooling:用一个可学习的 query token,通过 4 轮交叉注意力把每个 tile 的 1024 个特征"投票"成 1 个汇总向量——相当于先看整块内容再决策。
  2. 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_modetrue开启 Flash 模式,generate()走双路管线config.json
downsample_ratio0.5256 路缩放因子;64 路为其平方 0.25config.json
flash_relative_threshold0.1相对分位数阈值(10% 分位)config.json
flash_absolute_threshold0.5绝对概率下限config.json
ps_version"v2"pixel_shuffle 版本;v2 修正了 v1 宽高未换回导致的图像转置问题configuration_internvl_chat.py
max_dynamic_patch12单图最大 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

项目地址:https://ai.gitcode.com/OpenGVLab/InternVL3_5-2B-Flash
点击查看免费下载
上一篇:如何追踪被重命名的文件?Markdown Preview的FileWatcher原子保存检测技巧详解
下一篇:Modern Web Guidance CSS布局实战:容器查询、:has()与滚动驱动动画的Agent友好写法

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询