朋友前两天问我一个问题给多模态大模型一张照片问它“这人是在跑步还是散步”它不仅能答对还能自言自语补一句“地面是湿的估计刚下过雨”。听上去确实玄乎但更值得琢磨的是背后的机制——文本和图像明明是两种完全不同的信号一个是离散字符一个是连续像素凭什么能被同一个模型“统一处理”还在同一个推理过程里互相配合这篇就想把这件事聊透多模态大模型如何把文本、图像统一成同一种内部表示再在高密度注意力网络里完成联合推理。内容适合两类读者一类是已经在用各类对话式AI工具、想弄明白“它凭什么能看图说话”的好奇用户另一类是准备开始做多模态训练或微调项目的开发者。我不会堆论文摘要而是按一条真实数据从输入到输出的路径把每个环节的“为什么”和“怎么做”讲清楚。1. 为什么要“统一”文本和图像原本生活在两套完全不同的坐标系里很多人第一次接触多模态时最容易产生的一个错觉是模型里肯定存在一个“翻译器”把图片翻译成文字然后再用语言模型处理。这个说法只对了一半。真正的主流做法并不是把图像转成自然语言而是把两种模态都转换成一种模型内部的、统一的离散序列。想理解这件事得先看清楚文本和图像各自的起点差异有多大。1.1 文本的天然优势本身就是离散符号序列在处理语言这件事上人类文明已经替模型做了最难的一步把连续含义切割成了符号。一段文字天然就能被拆成词或子词单元例如“多模态大模型”可以被切分成若干个子词每个子词在词汇表里都有一个唯一编号。模型要做的只是查表把编号映射成一个向量这个操作在算法上叫嵌入Embedding。也就是说文本从一开始就是一串长度可控、含义明确、可以直接扔进注意力网络做计算的离散 token。这一点非常重要因为注意力网络本质上操作的对象是序列序列越长计算量越大序列里的每个元素越有语义模型越容易学到结构。文本恰好两者都满足。反过来说图像就没有这个先天条件这是所有多模态问题绕不开的第一道坎。1.2 图像没有天然“单词”像素只是连续数值算不上语义单元一张彩色图像在计算机里就是一个三维数组高、宽、每个像素的 RGB 三个通道。拿一张 224×224 的普通照片来说总共 224×224×3约 15 万个数值。如果直接把每个像素当成一个 token会产生 15 万个 token序列长度直接爆炸而且单个像素的语义含量极其有限它只知道颜色不知道边缘、纹理、物体。模型很难从单像素里自己悟出“这是一只猫”。图像领域过去常靠卷积网络做特征提取通过一层层卷积和池化把局部模式组合成越来越抽象的特征图。但卷积特征图是二维的、连续分布的和文本 token 那种一维离散序列并不是同一种接口。早期多模态系统经常把视觉编码器和文本编码器分开训练、最后只做一个粗浅拼接效果总是不理想根因就是两边的“语言体系”不一样硬凑在一起很难产生真正的跨模态推理。1.3 统一的本质把图像也“翻译”成同一种 token 方言所谓多模态大模型实现统一处理核心思路其实非常朴素不要在接口层面搞特殊化而是把文本和图像都翻译成同一种“方言”——一个由向量组成的、长度可控的离散序列。文本本来就是这种序列图像则通过分块、编码、投影等手段也变成一个近似的 token 序列。之后它们一起被送进同一个注意力网络文本 token 可以与图像 token 互相参与计算共享同一套参数。这个设计背后有一个更底层的假设虽然文本和图像的表层形态差异巨大但高层次的语义可以被压缩成一组有限的表示在足够大的语义空间里“猫”这个文字符号和“一张猫的照片”对应的图像块是可以被映射到邻近区域的。统一处理要做的事就是找到并利用这种跨模态的邻近性。后面所有训练目标、投影层的设计本质上都是在把这种邻近性逼出来。2. 第一道转换关卡视觉编码器如何把一张图拆成可计算的序列既然要统一第一件事就是让图像变得像文本一样“可切分、可编号、可向量化”。这一步通常是整个系统里最容易被低估的环节。很多人只关注语言模型有多强却忘了如果图像入口做得稀烂后面再强的网络也白搭。2.1 图像分块Patch Embedding 的原理与计算量估算现在最常见的图像 token 化方式是分块嵌入。思路是把图片切成大小相同的小方块每个小方块叫一个 Patch。以 16×16 为例一张 224×224 的输入图高度方向有 224÷1614 个 Patch宽度方向也有 14 个 Patch一共 14×14196 个 Patch。每个 Patch 的原始数据量是 16×16×3768 个数值把它展开成 768 维向量再乘一个可学习的投影矩阵就得到嵌入维度为 d比如 768的向量。于是“图片”从二维网格变成了 196 个 token 组成的一维序列。196 对文本来说是个什么概念一段 200 字左右的说明文字拆成子词后也差不多是几百个 token。所以分块策略让图像第一次在规模上能够和文本放到同一个计算预算里。为什么选 16×16 而不是更小因为 Patch 越小 token 越多注意力的计算复杂度随序列长度平方增长token 数量翻倍显存压力不是线性上涨而是指数级上涨但 Patch 太大又会把细节抹掉。16×16 是多年实践试出来的平衡点很多项目会根据任务微调这个值。2.2 分辨率问题的两种解法固定窗口切割与动态切片现实中的图片没有统一的尺寸和宽高比直接把长图压成 224×224 会丢掉大量细节。常用的折中方案有两种。第一种是固定窗口切割把高分辨率图按固定大小的窗口切成若干块每块单独缩放到模型输入尺寸再把输出拼起来。实现简单但容易把同一个物体切断边界上的信息会被浪费。第二种是动态切片先让模型看一张完整的缩略图再根据图像的宽高比把原图切成若干个子图每个子图缩放成固定尺寸并记录它们各自的坐标信息。这样做高清细节保留得最好是很多多模态方案的主流选择。代价是可能产生很多子图token 量成倍增长显存压力剧增。于是项目里一般会加一个硬限制比如最多切 6 块或 9 块超过部分直接丢弃或做粗缩放。方案细节保留序列长度实现复杂度适用场景固定窗口切割中可控低物体分布比较均匀的文档、表格动态切片高高高自然照片、复杂版面、细粒度识别2.3 投影层连接视觉特征与语言模型空间的“翻译官”分块得到的 Patch token 还只是视觉空间中的向量它的坐标系由视觉编码器的预训练任务决定而语言模型的空间由语言建模任务决定。两个空间的坐标轴含义不同直接硬拼会导致模型无法理解图像向量。因此视觉编码器输出的向量要先过一个投影层一般是一个线性层或两层 MLP把维度统一到语言模型嵌入层的维度同时让视觉向量的分布向文本向量空间靠拢。很多人会忽略一个细节投影层不是随便初始化就能用的。早期有人用随机初始化的线性投影直接接语言模型训练极不稳定损失曲线像心电图一样跳。实践中更稳妥的做法是先用对比学习把视觉编码器和投影层粗对齐再接入语言模型做生成式微调。理解这一点就不容易在复现时乱调学习率——投影层的损失尺度跟语言模型头部的损失尺度可能差好几个数量级。3. 进入主网络之后文本 token 与图像 token 到底是怎么协作的图像变成 token 序列只是拿到了“入场券”。真正有意思的部分在后面的注意力网络里两类来自不同世界的 token被放在同一条序列中通过注意力机制反复“对话”。这一节我把协作机制拆开讲。3.1 自注意力机制所有 token 在一张“会议桌”上互相交换信息统一后的 token 序列会进入由几十层自注意力模块组成的网络。每个 token 向量会同时充当三种角色它先被线性变换成 Query、Key、Value。Query 问的不是别人而是序列里所有其他 token 的 Key“我跟你相关吗”两个向量点积相似度越高注意力权重越大之后按权重把 Value 加权求和得到更新后的向量。这个机制有两层意义。第一每个 token 都能根据全序列语义调整自己的表示第二文本 token 和图像 token 之间没有了硬边界图像里的“水面反光”可以影响文本里“下过雨”的预测。我用一个场景类比开会时每个 token 就是一个与会者没人事先规定谁必须跟谁交流每个人发言都听全场听到关键词相关的就重点记下来。这种“全员自由讨论”的机制才是多模态统一处理能在同一个网络里发生的根本原因。3.2 两种信息注入方式拼接输入与交叉注意力实际部署时图像 token 进入网络的姿势有两种。第一种是直接拼接把图像 token 放在文本 token 前面组成一条长序列然后做普通注意力运算。这也是目前多数自回归多模态模型采用的方式好处是代码路径单一图像和文本用的完全是同一套参数工程上最省事。第二种是交叉注意力文本侧保持独立的解码路径每一步生成文本时让当前 token 的 Query 去“查阅”图像编码器输出的 Key 和 Value。相比拼接交叉注意力能更显式地区分“哪些信息来自图像、哪些来自文本”早期很多生成式方法常用缺点是需要维护两套注意力逻辑工程实现更重。两种方法没有绝对的优劣近期趋势明显偏向拼接方案因为它更简单也更容易在大规模数据上扩展。3.3 二维位置编码图像是有空间的不能拿一维位置糊弄在自注意力机制里token 本身是“无序”的位置信息完全靠位置编码注入。文本用一维位置就够因为字就是一个接一个的。但图像 Patch 天然是二维网格第 1 行第 5 列的 Patch 和第 5 行第 1 列的 Patch空间关系完全不同。如果直接套一维位置模型很容易把“左上方”和“右下方”搞混。主流做法是用二维可学习位置编码分别给行坐标和列坐标各学一组向量相加后作为 Patch 的位置表示。对于动态切片产生的子图还要额外编码“子图序号原始坐标”否则模型只知道看单个切片搞不清切片之间的相对位置回答“窗帘左边是什么”这类空间问题时就会翻车。3.4 超长序列时的 token 压缩策略图像 token 数量是个变量一张普通图上采样后可能产生 576、1024、甚至 4096 个 token而文本问题往往只有几十个 token。长序列直接拖慢训练、吃光显存。实践中常用三种压缩策略一是池化对相邻 Patch 向量做均值或最大池化把 196 个 token 并成 49 个二是引入一组较少的可学习查询向量通过注意力机制把图像信息“蒸馏”到少量向量上三是 token 合并把语义相近的 token 合并成一个。压缩必然损失细节所以很多项目会用“底座低分辨率图若干高清切片”的组合压缩只作用于全局图重要细节保留在切片里。这个思路在落地时非常实用相当于让模型先看全局、再放大局部。4. 实现“统一”的临门一脚训练目标怎么设计结构搭好了下一步是让模型真的“学会”把文本和图像对应起来。这一步比想象中复杂因为不是把两种数据扔进去训一遍就行。训练目标的设计直接决定了模型是“真理解”还是“背答案”。4.1 对比学习把匹配的图文拉近把不匹配的推远要让文本和图像共享语义空间首先要让模型知道“哪张图和哪句话是匹配的”。对比学习就是干这个的典型范式。训练时从大规模图文对数据里取一个 batch对每张图它对应的文本描述是正样本batch 里其他文本都是负样本。模型要做的是让正样本图像特征和文本特征在向量空间里距离变近负样本距离变远。这里有个常被忽略的细节作用在特征上的损失通常需要先对特征做归一化否则模型会耍小聪明把向量模长变大来降低损失而不是真正学到语义对齐。此外负样本很容易“太简单”batch 不够大时区分度不够所以数据采样、batch 大小、温度系数都会显著影响对齐效果。这个阶段的目标不是让模型会说话而是把两个空间粗略焊在一起。4.2 生成式目标让模型学会“看着图把话说完”对比学习只解决“相似”不解决“会输出”。多模态大模型的最终形态是对话或描述所以必须引入生成目标把图像 token 和文本前缀一起输入让模型自回归地预测下一个文本 token损失只计算在文本 token 上。这个看似简单的目标梯度的回传路径是“语言模型输出头 → 文本 token → 自注意力 → 图像 token → 投影层 → 视觉编码器”相当于告诉视觉侧你提取的特征要服务于文本生成。很多人第一次跑通训练时会有疑问视觉编码器这边的损失曲线不太动是不是没在学其实是因为生成式损失的梯度主要被文本侧吸收了视觉侧梯度很小。这时需要给视觉部分单独设置合适的学习率或者干脆分阶段训练先冻结视觉编码器只训投影层等文本能顺着图像 token 说人话了再解冻视觉编码器做细调。4.3 多阶段训练对齐、指令微调、偏好优化各司其职把所有目标塞在一个 loss 里一锅端理论上可以实际上极易失控。大型项目普遍采用三阶段方案。第一阶段是对齐预训练用海量图文对跑对比学习和简单生成目标让视觉 token 落到语义空间里。第二阶段是指令微调用人类标注的问答数据教模型按照用户的问法组织回答这个阶段数据量不需要太大但质量要求极高。第三阶段是偏好优化用人类反馈或规则构造“好回答/差回答”数据让模型学会拒绝不相关请求、避免幻觉。三个阶段的损失形式、数据来源、学习率、是否冻结某些模块都不同。我见过不少复现失败案例都是把阶段一训练好的权重直接拿去做阶段三跳过了指令微调结果模型虽然知识很足但完全听不懂人话。多模态训练最忌讳“省步骤”对齐、微调、优化每一步都有不可替代的作用。5. 工程落地最容易踩的坑按真实翻车率排序原理聊完说点实际的。我在实践里见过、也踩过不少坑下面这些属于“不看必然吃亏、看了能省一个月时间”的级别。5.1 显存爆炸图像 token 数量比文本大两个数量级第一个坑就是显存。文本任务里一条样本几百 token 已经算长但一张高清图可以轻松切出几千个 token再叠加 batch 内 padding 和激活值一个 batch 直接让显卡尖啸。解决思路有三层第一限制单样本总 token 数超出部分裁剪或降采样第二用梯度检查点技术用时间换显存第三启用混合精度训练注意某些视觉算子在低的数值精度下容易出现数值溢出必要时对部分层单独保持更高的精度。问题现象根本原因有效应对训练中途 OOM图像 token 量激增注意力复杂度平方增长限制 token 数、开梯度检查点、混合精度损失曲线剧烈抖动视觉侧梯度太小学习率设置不当分阶段解冻、按模块调整学习率特征对齐效果差跳过对比预训练阶段先做对齐再接生成式目标5.2 分辨率不是越高越好需要分任务取舍直觉上分辨率高一定更好但实测经常打脸。对于“图片整体在说什么”这种全局任务过高的分辨率会产生大量 token反而稀释注意力模型容易漏掉重点对于“图片里的小字是什么”这类局部精细任务低分辨率则完全不行。所以合理做法是按任务给输入分辨率分级全局理解用低分辨率底图OCR 和细节阅读用高分辨率切片甚至同一个样本同时喂两种尺度让模型自己决定优先看哪部分。5.3 提示词会影响模型“看”图的侧重点多模态模型不是对着整张图“平均用力”的。同一个问题换一种措辞模型的注意力分布会有可感知的变化。比如“描述这张图片”得到的回答一般比较笼统“图片里有哪些不寻常的细节”会把注意力引向容易被忽略的区域。这个特性在工程上既是麻烦也是工具。一方面评测时提示词必须固定否则指标波动很大另一方面可以通过针对性提问把模型已经提取到但没有主动输出的信息引导出来。它不是模型真的去看了新地方更像让已有特征里的某部分在输出时占了主导权重。5.4 评估方法传统文本指标根本不顶用如果拿 BLEU、ROUGE 这类文本评测指标去衡量多模态回答分数几乎不能反映真实质量。原因是这类指标只看词汇重叠而图文回答经常存在“说法不同但语义一致”的合法答案。做落地评估至少需要三类信号任务级准确率比如视觉问答是否答对了选项人类偏好打分看回答是否自然、是否抓住了关键信息以及针对幻觉的专项测试故意问图片里不存在的东西看模型会不会胡编。我见过太多项目在跑分上好看、一上真实场景就露馅多半就是评估方案偷了懒。6. 一点个人体会“统一”别理解成“同一套权重”6.1 “统一”是多层次的不是所有模块共用一份参数很多人以为多模态大模型是输入任何模态都走同一套网络。实际工程里视觉编码器、投影层、语言模型、输出头通常分别是不同模块前两者负责把图像变成语言模型能读的表示后两者负责理解和生成。真正统一的是接口和语义空间不是所有参数。理解这一点能帮你少走弯路调视觉编码器时别动语言模型的学习率调语言模型时别指望视觉侧跟着变。每次训练前先明确当前阶段到底想动哪部分权重比盲目追新结构有用得多。6.2 给想上手做多模态实践的人几句大实话如果刚起步别一上来就想着从零预训练。更高效的路径是拿一个现成的冻结视觉编码器再加一个冻结的语言模型中间只训练一个投影层用几百条高质量图文对先跑通流程跑通后再逐步解冻、加指令微调。整个过程中数据质量比数据量重要得多一张标注错误的图文对造成的负面影响可能抵消几十张好数据带来的收益。另外时刻盯着梯度范数。图像侧梯度长期处于极小值往往是学习率设置不当的早期信号如果某一层梯度突然暴涨优先检查是不是输入里混进了异常尺寸的图片。这些经验都是常规文档里不会写的但遇到一次就知道有多值钱。最后说一句个人心得我觉得理解多模态统一最难的坎不是数学而是接受“文本和图像最终会在同一张序列里互相影响”这件事。一旦建立这个直觉再看各种投影层、对比损失、动态切片都是在为这个核心服务。希望这篇能帮你把这条链路的每一环都串起来。
阅读完成 · 觉得有帮助?