⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

扩展:多模态应用进阶

在线 Notebook

对应的交互式版本可在 Google Colab 打开,统一使用方式见 第0章说明

所属章节: 第7章:多模态LLM前置阅读: 7.4 多模态应用7.5 实战案例


概览

7.4 和 7.5 介绍了图像描述、VQA、图像搜索和三个实战案例的基本原理。本节补充:多模态 RAG 的架构设计、文档理解的完整技术栈(OCR+LLM 混合方案)、视觉 Agent 的工具调用模式,以及选择模型的决策框架。


多模态 RAG

为什么需要多模态 RAG

纯文本 RAG 的限制:

用户问:这份合同第5页的表格中,金额是多少?
纯文本 RAG:
  1. 用文本 embedding 检索 → 找到第5页的文字提取结果
  2. 问题:PDF 文字提取常常丢失表格结构
  3. 结果:答案不准确或找不到

多模态 RAG:
  1. 将 PDF 页面截图存入图像向量库
  2. 用 CLIP 编码查询文本,检索相关页面图像
  3. 将检索到的图像 + 问题送入多模态 LLM
  4. 结果:LLM 直接"看"表格,准确提取

架构

离线索引阶段:
  文档页面 → 截图 → CLIP 编码 → 图像向量库(Faiss/Weaviate)
                  → OCR 提取文字 → 文本向量库(可选双路检索)

在线查询阶段:
  用户问题 → CLIP 文本编码 → 向量检索 → Top-K 图像

  用户问题 + Top-K 图像 → 多模态 LLM → 最终答案

双路检索策略

检索路径优势劣势适合场景
图像向量(CLIP)捕获视觉布局对纯文字内容不如文本检索表格、图表、图文混排
文本向量(文字提取后)精确文字匹配依赖 OCR 质量纯文字段落
双路融合(RRF 重排序)互补优势实现复杂生产系统常见选择

RRF(Reciprocal Rank Fusion): 将两路检索的排名倒数相加重排序,公式:

score(d)=rrankers1k+r(d)

k=60 是经验值,防止 top-1 结果权重过大。


文档理解:OCR+LLM 混合方案

何时用纯多模态 LLM,何时需要 OCR

纯多模态 LLM 足够的场景:
  ✅ 清晰扫描件(300dpi+)
  ✅ 标准印刷字体
  ✅ 简单表格(行列对齐)
  ✅ 字段数量少(< 20 个)

需要 OCR 预处理的场景:
  ⚠️ 手写体或特殊字体
  ⚠️ 低分辨率扫描(<150dpi)
  ⚠️ 复杂嵌套表格
  ⚠️ 需要精确到字符的提取(合同条款)
  ⚠️ 大批量处理(OCR 比 LLM 便宜 10-100×)

混合方案架构

文档图像

预处理(倾斜校正、增强对比度)

OCR 引擎(PaddleOCR / Tesseract / Azure OCR)

结构化文字 + 边界框坐标

提示构造:
  "以下是文档中识别到的文字及其位置:
   [坐标(10,20)]: '发票号码'
   [坐标(150,20)]: 'INV-2024-001'
   ...
   请提取:发票号码、日期、总金额"

LLM 理解结构关系(不需要识别文字,只需推理)

结构化 JSON 输出

优势: LLM 只需做空间关系推理,文字识别由专用 OCR 完成;处理速度快 5-10×;成本低。

工具选型

工具优势适用场景
PaddleOCR开源,中英文强中文文档,本地部署
Azure Document Intelligence表格结构识别强生产级文档处理
Tesseract完全开源简单场景,无预算
Surya现代架构,多语言复杂版式文档

视觉 Agent

多模态 LLM 作为 Agent 的感知模块

第6章介绍了文本 Agent(ReAct 模式)。多模态 LLM 可以扩展 Agent 的感知能力:

传统文本 Agent:
  工具调用 → 文字结果 → LLM 推理 → 下一步

视觉 Agent:
  工具调用 → 截图/图像结果 → 多模态 LLM 感知 → LLM 推理 → 下一步

实际应用:网页操作 Agent

任务:"在电商网站上找到最便宜的红色耳机"

Step 1:
  Action: screenshot()
  Observe: [网页截图]
  Reason: "看到搜索框在右上角,输入关键词"

Step 2:
  Action: click(x=850, y=45)  # 搜索框坐标
  Action: type("红色耳机")

Step 3:
  Action: screenshot()
  Observe: [搜索结果页截图]
  Reason: "看到4个结果,需要按价格排序"

Step 4:
  Action: click_button("价格从低到高")
  Observe: [排序后截图]
  Reason: "第一个结果 ¥89,点击查看详情"

关键挑战

坐标幻觉: 模型看到截图后给出的点击坐标可能不准确,因为分辨率缩放后像素位置改变。

解决方案:

python
# 传入缩放比例让模型做坐标换算
prompt = f"""
截图分辨率已从 {original_w}×{original_h} 缩放到 {scaled_w}×{scaled_h}
如需点击,请给出原始分辨率下的坐标
"""

多步累积误差: 每一步的视觉理解误差会在多步中累积。缓解方法:在每步操作后截图确认,而不是一次性规划所有步骤。


模型选型决策框架

下面是选型维度示例,不是长期固定推荐。多模态模型迭代很快,生产选型需要重新确认当前模型能力、价格、许可证和部署约束。

按任务选择

任务需求

    ├─ 主要是文字提取(发票/合同)?
    │       → 高分辨率多模态模型 + OCR 混合方案

    ├─ 需要中文理解?
    │       → 优先评估中文多模态模型

    ├─ 图文检索/相似度搜索?
    │       → CLIP / OpenCLIP(轻量,不需要 LLM)

    ├─ 开源本地部署,通用场景?
    │       → LLaVA-NeXT / InternVL2

    ├─ 需要高能力 API 调用?
    │       → 评估当前主流闭源多模态 API

    └─ 端侧设备,内存 < 8GB?
            → MiniCPM-o / MobileVLM

按资源选择

显存示例候选分辨率上限推理速度
4GBMiniCPM-o-3B448×448
8GBLLaVA-1.5-7B336×336
12GBQwen2.5-VL-7B1024×1024
24GBQwen2.5-VL-32B / InternVL2-26B动态
API主流闭源多模态 API取决于服务商限制取决于网络

返回: 第7章:多模态LLM


推荐论文

基础论文

论文作者贡献
"Learning Transferable Visual Models From Natural Language Supervision"Radford et al. (2021)CLIP:对比学习实现零样本图文对齐
"An Image is Worth 16x16 Words"Dosovitskiy et al. (2020)ViT:用 Transformer 处理图像
"Visual Instruction Tuning"Liu et al. (2023)LLaVA:多模态指令微调的开创性工作
"Blip-2: Bootstrapping Language-Image Pre-training"Li et al. (2023)Q-Former:参数高效的多模态预训练
"Flamingo: a Visual Language Model for Few-Shot Learning"Alayrac et al. (2022)Gated cross-attention,few-shot 多模态

进阶论文

论文贡献
InstructBLIP (2023)指令感知的视觉特征提取
LLaVA-1.5 (2023)MLP 投影层替代线性层,显著提升性能
Qwen-VL (2023)中文多模态,位置感知输入

常见坑

坑1:CLIP 文本模板影响零样本分类准确率

模板准确率原因
"{class}"~60%单词无上下文,编码器特征弱
"a photo of a {class}"~85%描述性上下文,特征更强
多模板投票~92%多角度描述,降低单一模板的偏差
python
# 最佳实践:多模板投票
templates = [
    "a photo of a {}",
    "a picture of a {}",
    "an image of a {}",
]
text_features = [encode(t.format(class_name)) for t in templates]
final_feature = torch.stack(text_features).mean(0)
final_feature /= final_feature.norm()

坑2:Qwen2.5-VL 需要特定 transformers 版本

bash
# 需要 4.40.0+
pip install "transformers>=4.40.0"
python -c "import transformers; print(transformers.__version__)"

坑3:高分辨率导致显存溢出

场景推荐方案
显存 < 16GB,一般任务动态分辨率(自动限制上限)
显存 < 16GB,文档任务图像分块 + 量化(int8)
显存充足图像分块,保留最多细节

坑4:多图像处理时图像顺序混淆

python
# ❌ 容易混淆
prompt = "比较这两张图片的区别"

# ✅ 明确指代
prompt = "[图1] 是原始状态,[图2] 是处理后状态。请比较 [图1] 和 [图2] 的变化。"

本教程采用 CC BY-NC-SA 4.0 许可协议