跳转至

多模态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 是低秩的,可用两个小矩阵的乘积近似。

image.png

为什么少量参数就能微调?

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

为什么能合并而不破坏原权重?

image.png

多模态模型训练中视觉编码器和文本编码器梯度不平衡及解决

问题理解:多模态模型通常包含视觉编码器(ViT)、跨模态连接器和LLM。三者参数量、预训练程度、学习动态差异巨大。LLM参数数十亿,梯度范数大;视觉编码器预训练任务与多模态指令差距大,直接联合训练易导致LLM主导梯度更新,视觉部分欠训练或梯度爆炸。同时连接器随机初始化,需要较大学习率快速对齐,而LLM只需微调,统一学习率会导致不协调。

解决方案:

  • 分层学习率:视觉编码器设小学习率(如1e-6)或冻结;连接器设较大学习率(如5e-5);LLM设中等学习率(如1e-5)或通过LoRA间接调整。

  • 两阶段训练:第一阶段只训练连接器,冻结视觉和LLM,用大量图文对进行对齐预训练;第二阶段再解冻LLM(或加LoRA)做指令微调。从根本上解决不同步问题。

  • 梯度裁剪与归一化:全局梯度裁剪(max_norm=1.0),监控各模块梯度范数,及时调整学习率。

  • 适当的冻结策略:高效微调场景下直接冻结视觉编码器,仅训练连接器和LLM的LoRA参数。

手撕:

移除最少区间使剩余区间无重叠

问题:给定多个区间 [start, end),求最少移除数量,使剩余区间互不重叠。

解法:贪心,等价于求最多不重叠区间数。按区间结束时间升序排序,依次选择最早结束且不与已选区间重叠的区间。最少移除数 = 总区间数 - 最多可选数。

算法步骤:

  1. 将所有区间按结束端点升序排列。

  2. 初始化 last_end = -infcount = 0(最多可选区间数)。

  3. 遍历每个区间 [start, end):若 start >= last_end,则选择该区间,更新 last_end = endcount += 1

  4. 返回 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) 遍历。这是该问题的最优解。