02 - 多模态大模型怎么工作
用户对着点单机器人说了句话,同时拍了张菜单照片,问「这个有什么推荐」。他期待听到语音回答。
这一个请求里,要处理的东西有三样:一段音频、一张图片、最后还要吐出一段音频。
问题来了:一个大模型本来只会读写文字。这三样东西是怎么进去、又怎么出来的?
这一篇按三个问题往下走:为什么非要这样做(第一节)、模型怎么学会的(第二节)、内部长什么样(第三节起)。
一、为什么非要多模态
先说个反问:这事不用多模态也能做。
语音转文字有现成的,大模型有现成的,文字转语音也有现成的。三个串起来就行 —— 这套叫拼接式,至今仍是绝大多数产品的实现方式,因为每一段都能单独换、单独调、单独买。
那为什么还要有多模态模型?两个理由。
理由一:每转换一次,管子就窄一次。
用户第三遍重复「少冰」,语气已经不耐烦了。语音转文字之后,输出是一行纯文字「我要少冰」—— 「不耐烦」这三个字不在里面。后面的大模型看到的只有那行字,它不知道用户在生气;再后面的语音合成拿到的也只有一行字,更没有依据挑语气。
丢掉的不只是情绪。口音、语速、背景里有没有别人在讲话 —— 只要过了「转成文字」这一步就全没了。文字是个很窄的管子。
图片那边同理:先让一个模型把图描述成一句话,再把这句话给大模型 —— 描述里没提到的细节,后面永远拿不回来。
理由二:串行的三段,延迟是加起来的。
拼接式必须等前一段完全结束才能开始下一段:听完 → 想完 → 才开始说。而多模态模型可以边想边说 —— 文字刚吐出几个字,语音合成就能开工。这个差别在语音对话里是决定性的。
如果你的场景只是「把用户说的话转成文字,然后走已有的文本流程」,拼接式更好 —— 便宜、灵活、每段都能单独优化,而且不会幻觉出用户没说过的话。
只有当「听出情绪并据此调整回答」这类能力成为核心体验时,多模态模型的代价才划算。
二、一个只会读文字的模型,怎么学会看图
这是最反直觉的一步,也是最该先想明白的。
你可能以为要把 LLM 重训一遍,让它「学会看图」。不是的 —— 训练时 LLM 基本是冻住不动的。
真正的做法是:在旁边训一个翻译层。
为什么这样行得通?关键在于 LLM 已经会的东西比你想的多。它读过海量文本,早就理解「一只猫趴在沙发上」这句话意味着什么 —— 它的内部空间里,这句话对应着一个位置。
所以要让它「看懂」一张猫的照片,不需要教它什么是猫。只需要一个翻译层,把这张照片算出来的向量,搬到跟那句话相近的位置上去。搬对了,LLM 就当它是那句话来处理。
训练分两步:
| 阶段 | 用什么数据 | 训哪部分 | 目的 |
|---|---|---|---|
| ① 对齐预训练 | 海量「图—文字描述」配对 | 只训翻译层 | 让图像向量落到正确的位置上 |
| ② 指令微调 | 「图 + 问题 → 答案」 | 翻译层,有时也轻调 LLM | 让它会按指令回答,而不只是描述 |
这就解释了一个常被问的问题:为什么接一个新模态那么快? 因为不用重训 LLM,也不用重训编码器 —— 图像编码器(比如 CLIP ViT)和 LLM 都是现成的、冻住的,你只训中间那个翻译层。这也是为什么开源社区能在一个基座上迅速衍生出几十个多模态变体。
三、内部拆成五个部件
有了上面的直觉,再看结构就清楚了。业界把这套东西拆成五个部件,几乎所有多模态模型都能往上套:
左边两个是进(理解侧),右边两个是出(生成侧),中间那个是原来就有的语言模型。LLM 还额外有一条出口:直接吐文字回答,不走 ④ ⑤。
| 部件 | 干什么 |
|---|---|
| ① 模态编码器 | 把原始信号(波形、像素)算成一串向量 |
| ② 输入投影器 | 把这串向量对齐到 LLM 认识的空间 |
| ③ LLM 骨干 | 真正做理解和推理,也是唯一「懂语义」的一层 |
| ④ 输出投影器 | 把 LLM 的输出翻译给生成器 |
| ⑤ 模态生成器 | 变回音频、图片、视频 |
把这五个格子填上真实模型名,就是下面这张业界 通用的示意图:

左半边叫多模态理解(进),右半边叫多模态生成(出)。很多模型只做左半边 —— 那类叫 VLM(能看图但不能画图)。
LLM 骨干还在正中间 —— 这是最该先记住的一点。多模态不是另起炉灶,是在语言模型外面接翻译官。所以你对文本推理的全部认知(01 篇那六个概念)都还成立,只是外面多了几层。
这一章后面几篇,就是把这五个部件逐个拆开:
| 部件 | 哪一篇 |
|---|---|
| 音频进来(① ②) | 03 听 |
| 语音出去(④ ⑤) | 04 说 |
| 图像视频进来(① ②) | 05 看 |
| 图像视频出去(④ ⑤) | 06 画 |
| 五个部件长在一个模型里 | 08 Omni |
四、进来这一侧:编码器和投影器
先说清楚 LLM 那一端要什么:一串长度相同的向量。
文字天然对得上 —— 「珍珠」在词表里是第 28374 号,去嵌入表取第 28374 行就完事,查表而已。
音频、图片、视频对不上,因为它们是连续的,没有天然的「一颗一颗」。
① 模态编码器干的就是「切开并算成向量」这件事。不同模态用不同的编码器:
| 模态 | 常用编码器 | 输出 |
|---|---|---|
| 图像 | ViT、CLIP ViT、SigLIP | 每个小方块一个向量 |
| 音频 | Whisper 编码器、CLAP | 每 20~40 毫秒一个向量 |
| 视频 | 图像编码器逐帧 + 时间维处理 | 每帧若干向量 |
② 输入投影器解决的是另一个问题:编码器吐出来的向量维度、分布,跟 LLM 嵌入表里那些向量对不上。投影器把它们「翻译」到同一个空间里,通常就是一个 MLP,有时是交叉注意力。
翻译完之后,这些向量被塞进 LLM 输入序列里 —— 塞在哪?塞在占位符的位置上。提示词里先留好 N 个坑(形如 image_pad 的特殊标记),forward 时把真实向量覆盖上去。
坑的数量必须和向量数量严格对上。留了 256 个坑、编码器给了 257 个向量,多的那个要么被丢、要么把后面顶掉 —— 而且不报错。
更麻烦的是:两张完全不同的图,占位符的编号是一模一样的。拿它当缓存键会让一个用户看到另一个用户的图。09 篇专门讲怎么堵。
五、出去这一侧:投影器和生成器
生成侧是反着走的。
LLM 只会吐文字 token。要让它「说话」或者「画图」,得在后面接一个⑤ 模态生成器 —— 语音这边是声码器,图像这边是扩散 模型。
中间的④ 输出投影器负责把 LLM 的输出翻成生成器认识的形式。
这里有个关键取舍:生成器要的到底是文字,还是 LLM 的中间状态?
| 接什么 | 好处 | 代价 |
|---|---|---|
| 接文字 | 简单,每段都能单独换 | 语气、情绪、口音全丢了 —— 文字是个很窄的管子 |
| 接中间状态(隐状态) | 副语言信息能传下去 | 两段绑死,而且要边生成边传 |
Omni 模型选后者,代价是整个服务架构都得跟着变。这条线索会贯穿 08 篇。
六、从服务的角度看,这五个部件各自要多少钱
上面是模型视角。换成服务视角,你真正要关心的是每个部件吃什么资源、会怎么坏:
| 部件 | 计算特点 | 显存 | 主要风险 |
|---|---|---|---|
| ① 模态编码器 | 一次算完,算力密集 | 尖峰后立刻释放 | 它一跑,正在解码的所有人都要停下等 |
| ② 输入投影器 | 一个小 MLP,可忽略 | 可忽略 | 坑位数和向量数对不上 |
| ③ LLM 骨干 | 一步一个字,步数不定 | 随生成不断增长 | 显存不够时要抢占 |
| ④ 输出投影器 | 同 ② | 可忽略 | —— |
| ⑤ 模态生成器 | 声码器一次算完;扩散要算几十轮 | 恒定 | 扩散那类不能抢占,踢出去等于白算 |
这张表里藏着整章后半段的全部动机:① ③ ⑤ 三类计算的脾气完全不同,而你只有一套调度器。07 篇专讲这个冲突。
七、一笔 token 账
最后给一个换算,后面估容量时反复要用。
三条经验:
- 理解侧看「向量/秒」,生成侧看「步/秒」。前者决定显存和预填充长度,后者决定用户等多久才听到第一个音。混用是最常见的估算错误。
- 一张普通清晰度的图,进序列就是几百到一千多个 token,跟一篇短文档同量级。视频再乘帧数。
- 多模态请求「看起来短,跑起来长」。一句「帮我看下这段视频」,序列长度可能相当于七篇 500 字短文。
八、新手最容易混的三件事
「多模态」不等于「什么都能出」。 很多模型只有左半边 —— 能看图听声,但只会吐文字,这类叫 VLM。要它画图或说话,得配上右边的输出投影器和生成器,那是另一套训练。看一个模型支持什么,要分开看进和出。
「能看图」不等于「看懂图」。 编码器把图变成了向量,不代表 LLM 真的理解了空间关系、文字细节、数量。这是模型能力问题,不是工程问题。
编码器不是免费的。 很多人把注意力全放在 LLM 上,但在多模态服务里,编码器经常是那个把所有人卡住的家伙 —— 它跑的时候,正在等字的用户全都得停。
下一篇:03 - 听,从音频这一路开始,看编码器具体怎么工作。