- 模型原生支持:
- 文本 + 图像 + 语音 + 视频
- 技术架构:
- encoder → connector → LLM → generator
能力变化:
- 看图写代码
- 听语音做总结
- 视频理解 + QA
👉 本质变化:
LLM 从"文本智能" → "通用感知智能"
connector 本质是一个"对齐层(alignment layer)",负责把非文本模态(图像/音频/视频)的表示,转换成LLM可以理解的表示空间(通常是embedding/token序列)。
- encoder:把图像/语音 → 向量表示(feature)
- connector:把"向量表示" → "LLM能吃的输入格式"
- LLM:统一推理
- generator:输出文本/图像/语音
更直白一点:
encoder 负责"看懂",connector 负责"翻译给LLM听懂"。
connector 干了什么事?(本质)
它做了三件关键事情:
1️⃣ 模态对齐(Modality Alignment)
不同模态本质不一样:
- 图像:2D patch feature
- 音频:时间序列
- 文本:token序列
👉 connector 要做的是:
把这些统一到 LLM 的"token语义空间"
2️⃣ 维度映射(Projection)
例如:
- ViT输出:1024维向量
- LLM embedding:4096维
connector需要:
1024-d → 4096-d
3️⃣ 结构转换(Structure Transformation)
比如:
- 图像是 grid(patch)
- LLM是 sequence(token)
👉 connector要把:
image patches → token-like sequence
是的,connector 的输入是图像特征,输出是一个与LLM embedding空间对齐的向量序列(embedding sequence)
❗ 但这些向量并不对应任何离散token id,它们只是"处在同一个向量空间中的连续表示",可以被LLM当作token embedding来处理。
"不是token id对应的embedding" ✅(很关键)
完全正确 👍
这些向量:
- ❌ 不是从 embedding table lookup 得来的
- ❌ 不对应某个词(比如"cat"、"dog")
- ✔ 是 encoder + connector 生成的连续向量
👉 可以称为:
soft tokens / continuous tokens / pseudo tokens
Q:那模型怎么知道这些是图像?
你可以答:
- special tokens(如
<image>) - positional encoding
- 模态标识 embedding
Q:那为什么LLM能理解这些向量?
你可以答:
因为在训练过程中,这些视觉embedding与文本语义是联合对齐训练的,模型学会了在同一语义空间中建立跨模态映射。
✔ 一张图像经过 encoder + connector 后,确实会变成一个 embedding 序列(sequence of embeddings)
✔ 序列中的每个元素就是一个向量(维度 = LLM embedding维度)
❗ 序列长度是否固定,取决于具体架构:
- 有的固定长度(主流)
- 有的与输入分辨率相关(次主流)
问题:序列长度和"图像复杂度"有关吗?
答案分两种:
✔ 在主流模型里(固定长度方案):
❌ 和"图像复杂度"基本无关
原因:
- connector(如 Perceiver / Q-Former)会:
- 压缩信息到固定token数
- 类似"摘要"
👉 就像:
- 一张简单图 vs 一张复杂图
→ 都压成 64 个 token
✔ 在高分辨率/patch方案里:
✔ 和分辨率有关
❌ 和"语义复杂度"无直接关系
✔ 在前沿方法里:
✔ 有可能和"内容重要性"相关
但目前还不是工业主流
connector相当于对图像做"语义压缩",把一张高维信息的图像总结成固定数量的"视觉token",类似于把一篇长文章总结成几个关键句子。
一张图像经过encoder和connector后,会被转换成一个embedding序列,每个元素是与LLM embedding空间对齐的向量。这个序列的长度取决于具体架构,在当前主流模型中通常是固定长度,通过Q-Former或Perceiver等机制对图像信息进行压缩,从而控制计算成本;而在一些ViT-style方案中,序列长度与图像分辨率相关,但这种方式在大模型中较少直接使用,因为token数量增长过快。
音频:
✔ 原始情况下(不压缩),音频encoder输出的序列长度通常与时间长度(帧数)成正比
❗ 但在多模态LLM中,经过connector之后,往往会被压缩为固定长度或受控长度的embedding序列(主流做法)
👉 所以最终输入LLM的序列长度,不一定直接等于帧数
二、先看"原始音频表示"(关键基础)
音频通常这样处理:
audio waveform
→ 分帧(frame)
→ spectrogram / mel-spectrogram
→ encoder(CNN / Transformer)
→ 时间序列 embedding
例如:
- 10秒音频
- 每10ms一帧
→ 1000帧
👉 encoder输出:
[v1, v2, v3, ..., v1000]
✔ 这里是严格和时间成正比的
三、connector之后会发生什么?
这一步是关键区别。
三种主流处理方式👇
① 保留时间序列(ASR类任务常见)
audio embeddings(T个)
→ 直接输入LLM
特点:
- ✔ 长度 ∝ 时间
- ✔ 保留时序信息
- ❌ token数很大(成本高)
👉 常见于:
- 语音识别(ASR)
- 语音转文本
② 下采样 / 压缩(主流 ⭐⭐⭐)
类似图像的处理:
T个frame embeddings
→ connector压缩
→ K个embedding(K << T)
例如:
- 1000帧 → 压成 64 或 128 tokens
👉 方法:
- pooling(时间池化)
- attention压缩(Perceiver-like)
- learned queries(Q-Former-like)
③ 固定长度表示(语义级任务)
例如:
-
speaker recognition
-
音频分类
-
语义理解
audio → encoder → global embedding(1个或少量token)
👉 类似:
"整段音频的语义摘要"
总结一下:
✔ 训练/encoder阶段:
audio → 时间序列 embedding(变长)
✔ connector阶段:
变长序列 → 压缩 → 固定/受控长度
✔ 输入LLM:
[Audio tokens] + [Text tokens]
对于音频输入,encoder通常会输出一个与时间长度成正比的embedding序列,因为音频本质是时间序列数据。但在多模态LLM中,这个序列通常会经过connector进行压缩,例如通过attention或query-based方法,将长序列映射为固定或受控长度的embedding序列,以控制计算成本。因此最终输入LLM的token数量不一定与帧数成正比,而更多取决于connector的设计。