上个月我们把组里的多模态大模型系统从“能跑Demo”推进到了“能稳定对外提供服务”的状态,半年折腾下来,最深的体会是:多模态大模型的系统架构设计,难点从来不在某一个模态模型本身,而在如何把图像、文本、音频、视频这些异构输入塞进同一条推理管线,并且让上层应用真正用得住、用得起。这篇文章就围绕我实际搭建并迭代的一套通用AI系统架构展开,讲清楚每一层做了什么、为什么这么拆、数据怎么对齐、推理怎么加速、评测怎么建,最后把踩过的坑也一并列出来。
这套架构定位很明确:面向多模态输入的通用人工智能系统,核心能力是“看得见、听得懂、能规划、会调用工具”。系统既要支持图文问答这种基础场景,也要支持跨模态检索、视频内容理解、Agent式任务执行这类复杂场景。适合正在做多模态大模型落地的工程师、架构师,以及想了解整个系统全貌而不是只盯着模型本身的技术负责人。我会尽量把每个设计决策背后的理由讲清楚,而不是只丢结论。
1. 为什么我把多模态系统拆成了五层而不是直接调API
1.1 从“堆模型”到“层间解耦”的转变过程
项目刚开始时,团队的想法很简单:在某个开源大语言模型基础上,接入一个视觉编码器,再挂一个语音识别模型,跑通几个场景就算完事。头两周确实很快,图文问答能出结果,语音转写也能跑起来。但随着场景变多,问题接踵而至:不同模态的输入格式不一样,需要写一堆if-else判断;模型升级时接口参数对不上,调用方跟着遭殃;Agent需要把视觉结果反馈给语言模型,结果两条链路之间的数据结构根本不统一,每次只能靠硬编码拼字符串。更麻烦的是,当用户输入一张截图加一段语音,系统要先识别语音、再看图片、再综合推理,这种多模态交错输入让直接拼接的方案彻底失效。
后来我们做了一次大的架构调整,核心思路是“层间解耦”。整个系统被拆成五层:接入与预处理层、语义解析层、融合推理层、决策规划层、执行反馈层。每一层只做自己职责范围内的事,层与层之间通过统一的数据结构通信,不再允许跨层直接调用模型API。这个调整花了两周,但之后所有新增场景都变得很有秩序,新模型接入只改对应层,上层业务完全无感。
1.2 统一中间表示:整个系统的“通用语言”
层间通信最关键的是一套统一中间表示,我们内部叫它“多模态事件对象”。这个对象的核心字段包括:模态类型、时间戳、空间位置信息、语义向量、置信度、原始内容引用。无论输入是文本、图像、视频片段还是音频流,在经过接入层处理后,都会变成这样一个结构化的对象。比如一帧图像被检测到有“一个红色杯子在桌上”,语义解析层会输出包含“杯子”“桌”这两个实体的对象,带bounding box坐标和视觉向量,而不是一段非结构化的JSON嵌套。
这样设计的好处非常多。融合推理层不用关心上游是哪个品牌、哪个版本的视觉模型,拿到的永远是同一套结构。决策规划层做工具调用时,可以基于结构化对象直接生成参数,而不是从文本里解析。最明显的变化是排障效率:以前报错要顺着调用链查到底才知道是哪一步格式错了,现在只要打印中间表示对象,一眼就能看出是哪一层出了问题。
1.3 五层各自的职责边界
接入与预处理层负责多路输入的数据解析,包括图像压缩、音频重采样、视频抽帧、文本清洗,同时维护每条输入的时间轴和来源信息。语义解析层做模态识别与实体抽取,判断当前的输入是什么类型、包含哪些关键元素。融合推理层是多模态能力最集中的地方,负责跨模态匹配、推理问答和内容生成。决策规划层在Agent场景中发挥作用,做任务拆解、工具选择和规划生成。执行反馈层则负责调用外部工具(搜索、数据库、业务API等),并把执行结果反馈回融合推理层形成闭环。
直接拼接模型的方式就像是让几个互不认识的人临时组队干活,谁跟谁对接全靠现场喊话;五层架构则像把整个流程定义成一条流水线,每个工位只跟上下环节通过标准接口打交道。对比见下表:
| 维度 | 直接拼接模型 | 五层分层架构 |
|---|---|---|
| 新模型接入成本 | 所有调用方都要改 | 只改对应层 |
| 多模态交错输入支持 | 很差,靠硬编码拼接 | 天然支持 |
| 问题定位效率 | 链路长,定位慢 | 按层隔离,快速定位 |
| 输出结构化程度 | 低,依赖文本解析 | 高,层间全结构化 |
| Agent闭环支持 | 几乎不支持 | 原生支持 |
2. 输入侧的核心难题:多模态数据如何对齐到同一个语义空间
2.1 输入管线:图像patch、音频帧、视频shot的统一表示
多模态系统的第一个拦路虎是输入数据形态差异太大。文本是离散token序列,图像是二维像素矩阵,音频是一维波形,视频又是图像加时间轴。要让模型统一处理,第一步就是把它们全部映射到同一套表示空间。
我们的做法是:文本走常规tokenizer;图像切成固定大小的patch,每块patch经过视觉编码器变成向量;音频按帧滑窗切分,每帧提取频谱图再编码;视频则先做场景检测,把连续画面切成shot,再从每个shot里抽关键帧,保留shot级别的时间信息。这个阶段最容易犯的错误是“一刀切”——把所有图像都缩放到同一分辨率、所有音频都重采样到同一长度,结果信息损失严重。我们的处理策略是保留分辨率信息和原始时间戳,缩放只发生在编码器输入前的最后一步,中间对象始终携带原始尺寸和采样率元数据。
视频处理比图像复杂一个数量级。一套90分钟的视频内容,如果全部按帧编码,token数量能轻松超过百万,在融合推理层根本跑不动。我们的经验是:先通过场景切分把视频段拆开,对每个shot抽1到3个关键帧,关键帧的抽取策略也很讲究。一开始简单抽首帧,结果大量动态内容被漏掉;后来改为检测画面变化幅度,变化大的shot多抽帧,静态画面少抽帧,召回率提升非常明显。
2.2 模态对齐的两种思路:对比式与生成式
模态对齐是让模型真正具备“跨模态理解”能力的关键。主流的对齐方案可以分成两大类:对比式对齐和生成式对齐。
对比式对齐的核心思想是拉近同类样本在不同模态下的表示距离。具体实现上,我们把图像和文本分别编码,然后计算相似度矩阵,训练目标是让配对样本的相似度高于非配对样本。这套方法适合做图文检索、跨模态匹配,训练效率高。但它有个天生缺陷:只学习到“哪个跟哪个像”,没有学习到更深层的语义关系。比如它能知道“一只猫”和猫的图片相似,但问它“猫为什么喜欢抓沙发”,对比式对齐就完全答不上来。
生成式对齐则是直接让模型根据一个模态的内容生成另一个模态的内容。训练时给图像,让语言模型描述画面内容;给文本,让视觉模型生成对应画面。这种方式学到的语义更充分,因为生成过程强迫模型理解细节和关系。我们最终采用了以生成式对齐为主、对比式对齐为辅的混合方案:底层用对比学习做粗粒度对齐,上层用生成式目标做细粒度语义理解。具体参数上,两阶段损失的权重比设为1比4,这个比例是我们在验证集上反复调出来的,偏低会让检索能力退化,偏高则会拖慢推理收敛速度。
2.3 数据配比:总把多模态效果差归因于模型,其实瓶颈在数据配比
很多团队在训练多模态模型时,注意力全放在模型结构上,数据配比却比较随意。我们把训练数据分成四类:纯文本数据、图文对数据、视频文本对数据、音频文本对数据。一开始图省事,把四类数据按来源自然分布直接混在一起训练,结果模型严重偏向图文数据,视频理解能力很差,音频问答几乎失效。后来重新分析,发现纯文本、图文、视频、音频四类数据在语义复杂度和对齐难度上完全不一样,不能简单按数量配比。
我们最后采用的策略是按“语义信息量”做配比:图文对占比约50%,纯文本占20%,视频文本对占20%,音频文本对占10%。每类数据再按难度分三层:简单描述、细节关系推理、跨模态逻辑推理,按1比2比1的比例抽样。这个配比让模型在四类模态上的能力比较均衡。纯文本数据比重不高,但很重要——它承担了保留语言能力和常识推理的任务,如果纯文本被其他数据冲掉,模型会出现“视觉变好但常识变差”的退化现象。
3. 推理链路设计:从单问答到Agent任务闭环的细节
3.1 向量记忆与对话状态管理
系统早期只支持单轮问答,模型接收输入、给出回答,没有记忆。但在真实场景里,用户大概率会追加上下文,比如先问“这张图片里的产品是什么”,再问“它适合什么人群”,后一个问题依赖前文的信息。我们把推理链路改造成带记忆的对话系统:短期记忆用滑动窗口保存最近若干轮的多模态事件对象,长期记忆用向量数据库按语义相似度召回历史相关片段。
记忆模块的设计有几个容易忽视的细节。第一,短期记忆不只是文本,多模态事件对象也要按时间序列缓存,否则用户追问“刚才那个红色的按钮有多大”,系统找不到之前图像里的bounding box。第二,向量检索的召回数量要设置上限,我们默认取Top5,因为召回太多历史片段会让模型混淆当前用户意图。第三,记忆必须带时间衰减,三小时前的对话和多模态信息如果没有被主动引用,应该被降权,否则系统会“记住”太久远的内容回答当前问题,反而干扰判断。
3.2 工具调用的多模态反馈闭环
Agent闭环中最关键的一环是工具调用后的反馈理解。用户让系统“查一下这张发票的总金额并统计”,模型第一步需要调用OCR工具提取发票上的数字,然后调用计算工具做汇总。这个过程中,工具的返回结果可能是一张表格截图、一段文本、甚至一个结构化JSON。执行反馈层要把这些结果统一封装成中间表示对象,再送回融合推理层做下一轮推理。
这里有个非常实际的坑:OCR工具返回的识别结果往往带置信度,如果直接把低置信度的内容当事实,模型很容易基于错误数字做计算。我们在反馈封装时加入了“置信度标签”,低于阈值的字段标记为“待确认”,融合推理层看到这个标记后会自动生成澄清问题,而不是闷头往下算。这个设计看似简单,但把错误率从15%降到了3%左右。类似地,当工具返回的是一张新的截图时,系统会递归进入视觉理解流程,确保多模态信息在闭环中被充分利用,而不是被丢弃。
3.3 护栏机制:防止Agent在错误方向上反复尝试
Agent式推理最大的风险是“越错越自信”。模型一旦选错了工具或误解了任务,可能会在同一个错误方向上反复调用资源,不仅浪费计算,还会给用户错误结果。我们的护栏机制分三道:第一道是工具选择时的强制校验,规划层生成工具调用参数前,必须经过一个独立的校验模块,检查参数类型、取值范围、是否与当前上下文矛盾;第二道是执行次数上限,单个Agent任务最多允许执行8次工具调用,达到上限后强制进入总结模式;第三道是置信度评估,设定最终输出必须带着自信指数,低于阈值时生成“结果可能不准确”的提示,必要时追问用户确认。
这三道护栏实现起来并不复杂,但对系统的稳定感知提升很大。尤其是第二道,最开始没加次数限制时,某个Agent陷入死循环,连续调了27次搜索接口才被我们人工发现——那次的账单让人印象深刻。从那以后上限改成8次,再配合每轮调用的“暂停权”,也就是用户随时可以打断Agent继续执行的机制,体验才真正可控。
4. 训练与工程加速:小集群上跑千亿级模型的实际取舍
4.1 训练阶段拆解:先冻视觉塔,再全量微调
系统选定的基座模型参数规模大约700亿,放在八卡集群上训练,显存压力非常大。我们分了三个训练阶段,每个阶段策略不同。
第一阶段是视觉编码器与语言模型的桥接训练。这一步固定视觉塔和语言模型参数,只训练连接两者的投影层和位置编码。因为连接层参数量小,显存占用可控,训练数据用量也不大,主要目标是把视觉token映射到语言模型的语义空间。第二阶段是联合指令微调,放开语言模型的部分层和视觉塔的最后两层,用多模态指令数据集做全量微调。第三阶段是RLHF对齐,基于人类偏好数据优化模型的回答风格和安全性。
三个阶段拆分的目的,是尽量降低训练资源的峰值需求,同时避免“一步到位”带来的灾难性遗忘。我们试过一次直接全量微调所有参数,结果模型在纯文本任务上全面退化,多模态能力提升也很有限,典型的捡了芝麻丢西瓜。拆阶段之后可以精确控制每阶段的数据配比和损失权重,效果稳定很多。
4.2 推理优化:量化与投机采样的实际收益
模型训练完之后,上线推理的耗时和成本才是真正头疼的问题。700亿模型如果全精度推理,单次问答的显存需求超过200GB,根本没法在线部署。我们的做法是两步走。
第一步是量化。把权重量化到INT8,视觉塔和文本塔分开处理:视觉塔基本不吃量化敏感度,损失很小;语言模型部分用逐层校准的方式量化,选一小批校准数据来调整每个层的缩放系数,避免直接PTQ导致精度崩塌。量化后模型体积下降了约70%,单卡推理成为可能,精度损失控制在一个可接受的范围。
第二步是投机采样。我们训练了一个参数量约十亿的草稿模型,用它先快速生成候选token序列,再由大模型并行验证和修正。实际测试中,批量推理吞吐量提升了约2.8倍。投机采样虽然增加了一个模型,但它只跑在廉价的小模型上,整体算力成本反而降了。这个方案比较适合生成链路比较长的场景——如果回答只有一两个词,投机采样的收益很小,系统会自动降级到普通自回归生成。
4.3 显存调度:多模态任务负载的不确定性
多模态推理比纯文本推理的显存波动大得多。一张高分辨率图片进视觉塔时,中间的临时feature map会瞬间占用大量显存,但在推理完成后又全部释放。如果按照峰值显存给每个并发任务预留空间,整体资源利用率非常低。
我们的解决思路是引入显存池和按需调度。服务启动时预先分配一个统一的显存池,每个请求进来先估算它的模态复杂度:图片分辨率、视频帧数、文本长度这些指标共同决定需要申请的显存大小。推理框架按请求优先级动态分配显存块,而不是固定给每个worker分配独占显存。实现上借助了虚拟显存机制,把部分暂不访问的中间状态换出到CPU内存,让GPU显存专供计算密集部分使用。这套机制上线后,单机并发能力提升了接近一倍,而且没有出现因显存不足导致的请求失败。
5. 系统评测与线上迭代:不只看分数,还要看失败样本
5.1 评测维度:感知、理解、推理、执行的四层打分
多模态系统没法用一个指标衡量好坏,我们把评测拆成四个维度:感知层、理解层、推理层、执行层。感知层测的是模型能不能准确识别图像中的物体、音频中的关键字、视频中的场景变化;理解层测的是能不能理解这些元素之间的关系;推理层测的是多模态信息加上常识能不能完成推理;执行层测的是Agent能不能正确调用工具并完成任务闭环。
四个维度需要不同的评测方法和数据集。感知层可以用标准数据集做自动打分,执行层则必须结合真实工具环境做端到端测试。我们在执行层搭建了一个沙箱环境,内置模拟搜索、模拟数据库、模拟计算器等虚拟工具,系统在沙箱里执行任务后,自动化脚本核验结果正确性。这套测试框架让每次版本迭代都能快速发现问题,而不是等上线后被用户报告。
5.2 失败样本聚类:最常见的三类错误
跑通评测体系之后,我们对累积的失败样本做聚类分析,发现错误高度集中在三类问题上。
第一类是“目标幻觉”。模型描述了自己没有真正看到的物体,比如图像里根本没有电脑,但回答里硬说有。这多是因为训练数据里图文相关性不够强,模型学会了“看图说话”的模式但实际上没有把视觉特征和语言生成强绑定。我们通过提高图文数据中负样本比例来缓解,让模型知道“没看到就是没看到”。第二类是“时间轴混乱”,主要出现在视频理解中。模型能识别画面内容,却分不清事件先后顺序,把“门打开了”说成“门关上了”。处理方法是在视频数据中引入时间标注监督,强制模型学习帧与帧之间的时序关系。第三类是“工具滥用”,Agent在简单问题上过度调用工具,导致响应变慢、成本变高。我们增加了规划层的最小工具调用策略,当任务可以用已有上下文直接回答时,禁止执行额外调用。
5.3 线上回归与数据回流
评测体系搭好以后,最关键的是让它跑进版本迭代闭环。每次模型更新或架构变更,都必须跑一遍完整的四层评测,任何一层得分下降都视为回归,不能合入线上。我们用一套定时任务每晚拉取最新数据重新评测,第二天早上检查报告。
然后再把线上真实用户请求中模型表现不佳的数据人工标注后追加进训练集,形成数据飞轮。具体做法是:线上服务记录低置信度的回答和用户反馈,每周抽一批样本人工标注,标注后的样本进入训练流水线重新微调。这个飞轮转起来之后,系统的迭代速度明显加快。前三个月一共回流了约两万条高质量标注数据,很多边缘case就是靠这些数据才修复的。
6. 这套架构半年运行后的问题复盘
6.1 视频输入的“偶发掉帧”:运气式效果
视频理解是上线后问题最多的模块。最开始我们按固定间隔抽帧,每隔两秒取一帧,结果遇到内容变化快的场景,比如体育视频或教程操作画面,经常漏掉关键动作。用户反馈“系统完全没看到他在纸上写了什么”。后来改成动态抽帧,根据相邻帧的相似度决定抽帧密度,效果有改善,又发现新的问题:动态抽帧导致视频的播放速度感和真实时间轴对不上,模型在回答“第几分钟发生的事情”时经常出错。
最终方案是双轨道结构:一条轨道做稀疏固定抽帧,保证时间轴的完整性;另一条轨道做密集动态抽帧,捕捉关键变化。两条轨道的结果在语义解析层合并,时间属性统一以第一条轨道为基准。这个设计让时间相关问题的准确率提升了约四成,代价是视频理解的计算开销略有上升。
6.2 Agent死循环与预算控制
即使加了执行次数上限,Agent陷入低效循环的问题仍然偶有发生。有次系统规划者为了查一个产品的价格,先搜索产品名称、再搜索品牌背景、又搜索竞品信息,绕了一大圈才回到最初的问题,整整用了6次工具调用,而最终答案其实在第一次搜索结果里就有。这属于规划策略问题,不是死循环,但同样浪费资源。
我们的解决方法是给每个Agent任务配置预算条,它不是一个固定数字,而是根据任务复杂度的预估动态调整。任务开始时规划层会预估所需调用次数,实际执行过程中每调用一次工具,预算就减少一次。如果预算低于某个比例但任务还没完成,模型会被强制切换到“简化策略”——只做最必要的调用,或者在完成一半时先给用户阶段性结果,而不是一直憋大招。
6.3 上下文爆炸:多模态token管理
多模态输入的token消耗远比纯文本大。一张高分辨率图片可能产生上千个视觉token,一段十分钟的视频几百帧抽帧后,token数量轻松超过语言模型的上下文窗口。我们试过把上下文窗口从4K扩到8K,效果有限,因为模型在超长上下文上的注意力质量会下降,而且推理延迟明显爬升。
目前采用的分层摘要策略是:先对视频的每个shot做独立摘要,把几百帧压缩成几十条短文本摘要,再把摘要和关键帧的视觉token一起送到融合推理层。这样既能保留视频的主要信息,又不会让token数量失控。对图片也做了类似处理,高分辨率大图会先按语义区域切块,分别编码后合并结果,只在需要细节定位时才加载全图信息。
6.4 幻觉治理:引用来源与回答可信度
幻觉问题比预期顽固。纯粹提高数据质量能缓解一部分,但无法彻底消除。我们最后引入了一个“引用来源”机制:模型回答中凡是涉及特定实体、数字、时间的表述,都必须附带对应的中间表示对象引用——比如图像里的bounding box、视频片段的时间戳、文档中的段落编号。如果回答中出现了无法提供来源的内容,系统会在最终输出中降低该句的可信度标注,或直接标记为推测性内容。
这个机制上线后最大的变化是用户信任度明显提升。模型能明确说“根据视频片段00:32到00:45的画面,这个设备是黑色外壳”,也能坦然承认“关于这个产品的历史版本,我没有找到确切资料”。相比硬着头皮编造答案,这种带来源和置信度的回答方式让系统的可靠性上升了一个台阶。
半年下来,我最深的体会是:多模态大模型的系统架构,本质上是在“模型的强大能力”和“工程的可控性”之间搭一座桥。模型决定天花板,架构决定你能不能稳定够到那个天花板。如果让我重新做一遍,我会把数据配比和评测体系更早地搭起来,而不是等模型调完再回头补。这两件事看似不起眼,却是整个系统能否从Demo走向生产的关键。