多模态Agent整体项目架构¶
多模态Agent系统设计为能够理解文本、图像等多模态输入,并调用多种工具完成复杂任务的智能助手。整体架构采用分层设计,主要包含以下模块:
-
感知层:以多模态大模型(如Qwen-VL系列)为核心,负责统一理解图文输入,生成自然语言推理结果和工具调用指令。视觉编码器(ViT)提取图像特征,通过跨模态连接器(Resampler/Linear Projection)将视觉token投影到语言模型的词嵌入空间,LLM进行多模态理解和生成。
-
记忆层:包含短期记忆(对话历史的KV Cache和token序列)和长期记忆(基于向量数据库的多模态RAG)。RAG支持图文混合检索,将文本和图像分别编码后存入统一或独立的向量空间,为Agent提供外部知识支撑。
-
执行层:采用ReAct范式,模型输出“思考-行动-观察”循环。定义了一套工具调用协议,模型生成JSON格式的function call,支持调用多种工具:OCR、目标检测、搜索引擎、计算器、数据库查询、图像编辑等。工具执行结果作为新的多模态上下文追加到对话中,形成闭环。
-
服务层:提供API网关、推理加速(vLLM/TGI)、多轮会话管理、自动标注评估等基础设施。模型通过LoRA微调适配特定领域,实现高效部署。
此架构将多模态感知、工具调用、知识检索和交互式推理融为一体,具有较强的通用性和可扩展性。
基于Qwen多模态模型做LoRA微调遇到的问题及数据泄露规避¶
遇到的问题:
-
梯度不平衡:视觉编码器和LLM的收敛速度差异大。视觉部分若完全解冻容易破坏预训练表征,完全冻结则下游对齐不足。需要分层设置学习率,对视觉部分设较小学习率或仅微调跨模态连接器和LoRA注入的LLM部分。
-
显存溢出:多模态输入中图像特征占用大量显存。通过限制图像分辨率(如448×448),利用视觉Resampler将变长图像token压缩到固定数量(如256),降低序列长度。
-
数据格式与对齐:训练数据需严格符合Qwen-VL的对话模板,包括
<img>...</img>标签和特定角色标识,构造数据时容易遗漏系统提示或图片路径导致训练失败。 -
灾难性遗忘:单一领域微调后通用能力下降,可混合部分通用指令数据,并使用较小LoRA秩(r=8或16)限制参数变化幅度。
会话滑动窗口切分与数据泄露规避:
长会话数据通过滑动窗口切分成多个训练样本。窗口大小设为2048 token,滑动步长为窗口一半,每次截取子对话。关键原则是按会话级别隔离:同一会话的所有片段必须全部分配到训练集或测试集,绝不允许跨集合。此外,验证集/测试集使用独立数据源或时间切分(如最新数据),避免模型在训练中看到未来用户意图,从而虚高评测分数。
多模态任务中文本和图片特征的模态对齐¶
模态对齐的目的是让视觉特征和文本特征处于相同的语义空间,以便LLM理解图像。主流方法:
-
基于可学习连接器(Qwen-VL、LLaVA风格):使用预训练ViT提取图像patch特征,通过轻量连接模块(如Resampler,由cross-attention构成)将这些视觉token压缩并投影到LLM的词嵌入维度。训练分两阶段:第一阶段冻结视觉编码器和LLM,只训练连接器进行对齐预训练;第二阶段解冻LLM(或使用LoRA)和连接器进行指令微调。
-
对比学习对齐(如CLIP):双塔结构分别编码图文到同一向量空间,通过对比损失拉近匹配对。在多模态LLM中常采用CLIP的视觉编码器作为初始化,因其特征已与文本粗略对齐。
-
交叉注意力对齐(如Flamingo):在LLM层间插入交叉注意力,视觉特征直接注入,对齐紧密但需修改LLM结构。
本项目采用Qwen-VL风格:ViT-G作为视觉编码器,通过Resampler压缩为256个视觉token,送入LLM。训练时先对齐预训练,再做LoRA微调。
多模态自动标注Agent如何保证识别精准度及工具调用逻辑¶
保证识别精准度:
-
强基座模型+专项微调:以Qwen-VL-Max为底座,针对标注任务进行LoRA微调,注入领域知识和输出规范(schema定义)。构造高质量、高覆盖的微调数据。
-
工具链与交叉验证:不单一依赖生成结果。对精确OCR调用PaddleOCR,对目标检测调用Grounding DINO。多工具结果相互校验,若模型声称某区域有文本但OCR未识别,则标记为低置信度,交由人工复核或重新推理。
-
自省与校准机制:Agent输出标注结果后自我反问:“是否符合类别体系?坐标是否在图像范围内?有无漏标?”生成自检报告,不确定case自动上报人工。
-
人在回路反馈闭环:人工修正结果作为新训练数据持续微调,并采用主动学习优先选择低置信度或工具分歧样本供人工标注。
工具调用逻辑设计:
Agent采用ReAct模式,核心循环:观察→思考→行动→观察。系统提示中定义所有可用工具的名称、功能、参数schema。模型在需要时输出标准function call JSON,调度器解析并调用对应API,结果以观察文本追加到对话历史。设置最大调用轮数为5,超过则强制基于当前信息输出。
项目中的多模态RAG实现及图文混合检索策略¶
多模态RAG采用双路召回+融合重排序架构。
-
向量化:文本使用BGE-M3编码器,图像使用CLIP-ViT-L视觉编码器,分别存入独立的向量索引(文本FAISS、图像Milvus)。
-
双路召回:查询时,文本query用文本编码器在文本库中召回Top-K1文本;图像或文本描述通过CLIP在图像库中召回Top-K2图像。
-
融合与重排序:对召回的两类结果,若query同时包含图文,用多模态重排序模型(基于BLIP-2的图文匹配打分)统一排序;纯文本query则按来源类型赋予先验权重并结合文本相似度排序,最终取Top-N送入生成模型。
-
为何不用统一向量空间?专业领域(如工业图纸、医学影像)通用对齐模型性能不佳。双路召回允许分别选用领域最优编码器,灵活性高,且便于独立扩展和增量更新。后期正在尝试引入多模态大模型进行重排序和答案生成,直接整合图文列表。
LoRA低秩适配的底层原理¶
LoRA(Low-Rank Adaptation)基于假设:模型适应下游任务时,权重更新量 ΔW 是低秩的,可用两个小矩阵的乘积近似。

为什么少量参数就能微调?
大模型预训练已学到通用知识,下游任务只需对知识进行重新组合或微小方向调整,这种任务特定调整集中在低维子流形上,低秩矩阵足以捕捉主要适应方向。经验表明全秩微调产生的变化矩阵有效秩远低于矩阵维度。
为什么能合并而不破坏原权重?

多模态模型训练中视觉编码器和文本编码器梯度不平衡及解决¶
问题理解:多模态模型通常包含视觉编码器(ViT)、跨模态连接器和LLM。三者参数量、预训练程度、学习动态差异巨大。LLM参数数十亿,梯度范数大;视觉编码器预训练任务与多模态指令差距大,直接联合训练易导致LLM主导梯度更新,视觉部分欠训练或梯度爆炸。同时连接器随机初始化,需要较大学习率快速对齐,而LLM只需微调,统一学习率会导致不协调。
解决方案:
-
分层学习率:视觉编码器设小学习率(如1e-6)或冻结;连接器设较大学习率(如5e-5);LLM设中等学习率(如1e-5)或通过LoRA间接调整。
-
两阶段训练:第一阶段只训练连接器,冻结视觉和LLM,用大量图文对进行对齐预训练;第二阶段再解冻LLM(或加LoRA)做指令微调。从根本上解决不同步问题。
-
梯度裁剪与归一化:全局梯度裁剪(max_norm=1.0),监控各模块梯度范数,及时调整学习率。
-
适当的冻结策略:高效微调场景下直接冻结视觉编码器,仅训练连接器和LLM的LoRA参数。
手撕:¶
移除最少区间使剩余区间无重叠¶
问题:给定多个区间 [start, end),求最少移除数量,使剩余区间互不重叠。
解法:贪心,等价于求最多不重叠区间数。按区间结束时间升序排序,依次选择最早结束且不与已选区间重叠的区间。最少移除数 = 总区间数 - 最多可选数。
算法步骤:
-
将所有区间按结束端点升序排列。
-
初始化
last_end = -inf,count = 0(最多可选区间数)。 -
遍历每个区间
[start, end):若start >= last_end,则选择该区间,更新last_end = end,count += 1。 -
返回
n - count。
代码:
def eraseOverlapIntervals(intervals):
if not intervals: return 0
intervals.sort(key=lambda x: x[1])
count = 1
last_end = intervals[0][1]
for i in range(1, len(intervals)):
start, end = intervals[i]
if start >= last_end:
count += 1
last_end = end
return len(intervals) - count
复杂度:O(n log n) 排序,O(n) 遍历。这是该问题的最优解。