InternVL3-1B-Pretrained 架构剖析:ViT-MLP-LLM 范式如何串联视觉与语言
InternVL3-1B-Pretrained 架构剖析:ViT-MLP-LLM 范式如何串联视觉与语言
InternVL3-1B-Pretrained 是 OpenGVLab 开源多模态大模型(MLLM)InternVL3 系列的预训练版本,采用经典的 ViT-MLP-LLM 三段式架构:InternViT 视觉编码器负责"看图",MLP 投影层做特征压缩与维度对齐,Qwen2.5-0.5B 语言模型负责"表达"。本文帮你零基础看懂这套架构的设计思路、关键参数与完整的数据流动过程。
InternVL3-1B-Pretrained 是什么?🧐
- 预训练版 ≠ 对话版:它只完成了原生多模态预训练(Native Multimodal Pre-Training),没有经过 SFT 指令微调与 MPO 偏好优化。想直接对话看图,请用正式版 InternVL3-1B;想做二次开发或微调,这个 Pretrained 底座是更好的起点。
- 原生多模态预训练:不同于"先训纯语言模型、再适配视觉"的传统路线,InternVL3 将图文、视频文本、交错序列与大规模文本语料混合,在同一个预训练阶段同时学习语言与视觉表征,无需独立的对齐模块。
- 小巧但能打:InternViT-300M 视觉部分 + Qwen2.5-0.5B 语言部分,总体约 1B 参数,单卡即可轻松推理。
ViT-MLP-LLM:三段式架构全景 🏗️
InternVL3 延续了 InternVL 1.5 / 2.0 / 2.5 的"ViT-MLP-LLM"范式,三大组件职责清晰、可插拔:
| 组件 | 选型 | 职责 | 核心参数 |
|---|---|---|---|
| ViT(视觉编码器) | InternViT-300M-448px | 图像切块并编码为视觉 token | tile 448×448,patch 14×14,24 层 |
| MLP(投影层) | 两层全连接 + 归一化 | 像素重排降采样 + 维度对齐 | 4096 → 896 维 |
| LLM(语言模型) | Qwen2.5-0.5B | 融合视觉与文本 token 生成回答 | 隐藏维 896,24 层,32K 上下文 |
ViT 视觉编码器:InternViT 如何"看"图?
视觉编码器 InternVisionModel 是标准 ViT 结构,但有两个亮点:
- 动态分辨率:图像先切成若干 448×448 的 tile(最多 12 个、最少 1 个,见 config.json 中
max_dynamic_patch: 12),并追加一张整图缩略图(use_thumbnail: true)——宽幅图不糊,小图不浪费算力,这也让它天然支持多图与视频输入。 - Patch Embedding + 位置编码:每个 tile 按 14×14 切 patch,448÷14=32,得到 32×32=1024 个 patch token,再叠加可双三次插值的二维位置编码,实现在 modeling_intern_vit.py。
MLP 投影层:像素重排实现"4 倍压缩"
ViT 输出的 token 太多会挤占 LLM 上下文窗口,InternVL 用两步压缩:
- Pixel Shuffle 像素重排(pixel_shuffle):以
downsample_ratio=0.5把相邻 2×2 的视觉特征合并为 1 个 token,token 数直接变为原来的 1/4 —— 1024 个变 256 个。 - MLP 投影(mlp1):结构为
LayerNorm → Linear(4096→896) → GELU → Linear(896→896),把重排后的 4096 维视觉特征投影到 LLM 的 896 维空间,完成"视觉—语言对齐"。
每个 tile 最终贡献 256 个视觉 token(代码中的 num_image_token,modeling_internvl_chat.py#L52),整个特征提取由 extract_feature 统一完成。
LLM 语言模型:Qwen2.5-0.5B 负责"表达"
语言部分采用 Qwen2.5-0.5B(config.json 的 llm_config 段):隐藏维度 896、24 层 Transformer、14 个注意力头(GQA 仅 2 个 KV 头)、32K 最大上下文、动态 RoPE。得益于原生多模态预训练,其纯文本表现甚至优于同期的 Qwen2.5 Chat 系列。
一次完整推理中,数据如何流动?🔁
以"描述这张小熊猫照片"为例,链路如下:
- 图像预处理:
examples/image1.jpg按动态分辨率切成若干 448×448 tile + 缩略图; - ViT 编码:每个 tile 独立过 InternViT,输出 1024 个视觉特征;
- 压缩投影:Pixel Shuffle + MLP,压缩为 256 个 896 维 token;
- Token 替换:对话模板(conversation.py)把
<image>展开为<img>+ 256 个<IMG_CONTEXT>+</img>,前向时这些位置的文本嵌入被视觉特征直接替换(forward); - LLM 生成:语言模型在同一条序列中"看到"视觉与文本,自回归输出回答。
💡 "占位符 + 嵌入替换"让视觉信息无缝混入文本流,无需额外的跨模态注意力模块,这就是 ViT-MLP-LLM 范式简单高效的原因。
config.json 关键参数速查表 ⚙️
| 参数 | 值 | 含义 |
|---|---|---|
force_image_size |
448 | 每个视觉 tile 的边长 |
downsample_ratio |
0.5 | Pixel Shuffle 比例,token 压缩为 1/4 |
max_dynamic_patch |
12 | 单图最多切 12 个 tile |
use_thumbnail |
true | 额外加入整图缩略图 |
select_layer |
-1 | 取 ViT 最后一层特征 |
ps_version |
v2 | 修复 v1 宽高转置问题的像素重排版本 |
template |
internvl2_5 | 对话模板名称 |
顶层配置类见 InternVLChatConfig,视觉子配置见 InternVisionConfig。
InternVL3 的两项架构升级 ✨
- V2PE 可变视觉位置编码:为视觉 token 使用更小、更灵活的位置增量,显著提升多图、视频等长上下文场景的理解能力。
- 原生多模态预训练:语言与视觉同阶段学习,文本能力不降反升。训练策略细节见 README.md。
源码导读:架构关键文件清单 📂
| 文件 | 作用 |
|---|---|
| modeling_internvl_chat.py | 主模型 InternVLChatModel:前向推理、chat 接口、Pixel Shuffle 与 MLP 投影 |
| modeling_intern_vit.py | 视觉编码器 InternVisionModel:patch 嵌入、位置编码、注意力 |
| configuration_internvl_chat.py | 顶层配置:组合 vision_config 与 llm_config |
| configuration_intern_vit.py | ViT 子配置(patch_size、层数等) |
| conversation.py | 对话模板(internvl2_5) |
| config.json | 模型超参数总表 |
| examples/ | 示例图片(image1.jpg、image2.jpg)与视频(red-panda.mp4) |
常见问题 FAQ ❓
Q1:Pretrained 版和正式版 InternVL3-1B 怎么选? 想直接问答、看图描述,用正式版(经 SFT + MPO,对话表现更好);想做领域微调或架构研究,Pretrained 底座更合适。
Q2:一张图会变成多少视觉 token? 每个 448×448 tile 固定 256 个 token,加上缩略图;整图 token 数 = tile 数 × 256(动态范围 1~12 个 tile)。
Q3:为什么叫"ViT-MLP-LLM"范式? 因为架构就是三个模块线性串联:ViT 编码图像 → MLP 投影对齐 → LLM 生成语言,结构直观,还能自由替换不同规模的 ViT 与 LLM 组合。
总结 🎯
InternVL3-1B-Pretrained 用一条极简主线——ViT 看图、MLP 压缩对齐、LLM 说话——把视觉与语言串成同一条序列,再配合动态分辨率、Pixel Shuffle 与 V2PE,在约 1B 参数下实现高效的多模态理解。读懂 modeling_internvl_chat.py 中的 extract_feature 与 forward 两个方法,你就掌握了主流 MLLM 架构设计的核心范式。
