上个月我们把组里的多模态大模型系统从“能跑Demo”推进到了“能稳定对外提供服务”的状态半年折腾下来最深的体会是多模态大模型的系统架构设计难点从来不在某一个模态模型本身而在如何把图像、文本、音频、视频这些异构输入塞进同一条推理管线并且让上层应用真正用得住、用得起。这篇文章就围绕我实际搭建并迭代的一套通用AI系统架构展开讲清楚每一层做了什么、为什么这么拆、数据怎么对齐、推理怎么加速、评测怎么建最后把踩过的坑也一并列出来。这套架构定位很明确面向多模态输入的通用人工智能系统核心能力是“看得见、听得懂、能规划、会调用工具”。系统既要支持图文问答这种基础场景也要支持跨模态检索、视频内容理解、Agent式任务执行这类复杂场景。适合正在做多模态大模型落地的工程师、架构师以及想了解整个系统全貌而不是只盯着模型本身的技术负责人。我会尽量把每个设计决策背后的理由讲清楚而不是只丢结论。1. 为什么我把多模态系统拆成了五层而不是直接调API1.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走向生产的关键。