Skip to content

About

Multimodal document understanding agent for Chinese documents, with Qwen-VL LoRA training, evaluation, and demo deployment.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

MM-Doc-Agent

MM-Doc-Agent 是一个面向中文文档图像的多模态文档理解项目,基于 Qwen2.5-VL-3B-Instruct 构建,目标是完成文档图像问答、结构化证据抽取和证据区域定位。

项目覆盖数据转换、多模态 SFT 数据导出、LoRA/projector 训练、结构化输出解析、grounding 指标评估、OCR-assisted grounding、错误分析和本地 Docker/GPU 复现实验。

方法概述

系统将文档理解拆分为两个可独立评估的子任务:答案抽取和证据定位。

文档图像 + 问题
  -> Qwen2.5-VL 生成 answer / evidence
  -> 结构化 JSON 解析
  -> Answer EM/F1 与 evidence 指标评估
预测 evidence.text + OCR 文本框
  -> 文本归一化与匹配
  -> OCR bbox 选择
  -> 替换生成式 bbox
  -> 重新评估证据定位指标

该设计避免只用答案准确率评价文档 VQA,并能够明确区分“模型答对了”和“模型是否定位到正确证据区域”。

主要工作

  • 基于 Qwen2.5-VL-3B-Instruct 构建中文文档 VQA 流水线,输出 answer、evidence.text 和 evidence.bbox。
  • 实现 XFUND-ZH 数据转换、固定基准集构造、LLaMA-Factory 多模态 SFT 数据导出、批量推理和评估脚本。
  • 扩展 grounding-aware 评估指标,包括 Answer EM/F1、BBox Coverage、Evidence IoU All 和 Evidence IoU at Answer EM。
  • 在本地 RTX 3060 12GB + Docker 环境下完成 base、language-side LoRA、strict-bbox LoRA 和 projector-adaptation 对比实验。
  • 诊断出 language-side LoRA 可提升答案抽取,但直接生成 bbox 仍难以稳定完成证据定位。
  • 实现 OCR-assisted grounding,将模型生成的 evidence.text 与 OCR 文本框匹配,用检索式定位修正生成式 bbox。
  • 提供错误样本分析和 bbox overlay 可视化,用于检查证据定位失败模式。

实验结果

评估集:data/processed/xfund_zh_val_50.jsonl

方法 Answer EM Answer F1 BBox Coverage Evidence IoU All
Qwen2.5-VL-3B base 0.3600 0.5434 0.7200 0.0183
500-sample LoRA 0.5000 0.6585 1.0000 0.0048
1000-sample strict-bbox LoRA 0.4600 0.6220 1.0000 0.0041
500-sample projector + LoRA 0.4600 0.6377 0.9800 0.0266
500-sample LoRA + OCR grounding 0.5000 0.6585 1.0000 0.4207
500-sample projector + OCR grounding 0.4600 0.6377 0.9800 0.3696

实验结论:

  • 500-sample LoRA 将 Answer F1 从 0.5434 提升到 0.6585,Answer EM 从 0.3600 提升到 0.5000。
  • LoRA 训练后 BBox Coverage 达到 1.0000,说明模型可以稳定输出 bbox 字段,但坐标本身仍不可靠。
  • visual.merger projector adaptation 将 Evidence IoU All 从 0.0048 提升到 0.0266,说明 projector 训练对定位有正向作用,但幅度有限。
  • OCR-assisted grounding 将最佳答案模型的 Evidence IoU All 提升到 0.4207,说明在当前任务中,基于证据文本检索 OCR 框比直接生成 bbox 更稳定。

可视化结果

Grounding Case Study

下图展示同一样本在 direct VLM bbox 与 OCR-assisted grounding 下的证据定位差异。绿色为 gold bbox,红色为预测 bbox。该样本中 direct bbox 的 Evidence IoU 为 0.00,OCR-assisted grounding 后 Evidence IoU 为 1.00。

Grounding case comparison

Metric Comparison

下图汇总了两个核心指标:Answer F1 体现答案抽取能力,Evidence IoU All 体现证据定位能力。

Metric comparison

目录结构

mm-doc-agent/
  app.py                         # Gradio / application 入口
  configs/                       # 模型与 LoRA 训练配置
  data/samples/                  # 轻量示例数据
  scripts/
    convert_xfund.py             # XFUND -> 项目 JSONL
    export_llamafactory.py       # 多模态 SFT 数据导出
    train_lora.py                # LLaMA-Factory 训练命令生成
    infer_jsonl.py               # 批量推理
    evaluate_jsonl.py            # 单模型评估
    compare_experiments.py       # 多实验对比
    export_xfund_ocr_index.py    # OCR 文本框索引导出
    apply_ocr_grounding.py       # OCR-assisted grounding
    render_error_overlays.py     # bbox 可视化
  src/mmdoc_agent/
    data/                        # 数据结构与 JSONL IO
    models/                      # Qwen-VL 加载、adapter 加载与输出解析
    eval/                        # 指标与报告
    alignment/                   # 偏好样本与规则校验
    serve/                       # Gradio UI 与 bbox 绘制
  tests/                         # 单元测试

数据格式

每条 JSONL 样本表示一个文档问答样本:

{
  "id": "zh_val_10_qa_214_199",
  "image": "data/external/xfund/zh.val/zh_val_10.jpg",
  "question": "表单中“固定电话”对应的值是什么?",
  "answer": "021-51981368",
  "evidence": {
    "text": "021-51981368",
    "page": 1,
    "bbox": [1916.0, 1570.0, 2205.0, 1617.0]
  },
  "task_type": "field_extraction"
}

转换 XFUND-ZH 标注:

python scripts/convert_xfund.py \
  --annotation data/external/xfund/zh.train.json \
  --image-dir data/external/xfund/zh.train \
  --output data/processed/xfund_zh_train.jsonl

构造固定基准集:

python scripts/make_fixed_benchmark.py \
  --input data/processed/xfund_zh_val.jsonl \
  --output-dir data/benchmarks/xfund_zh \
  --seed 20260809 \
  --val-count 200 \
  --test-count 200

训练

导出 LLaMA-Factory 多模态 SFT 数据:

python scripts/export_llamafactory.py \
  --input data/processed/xfund_zh_train_500.jsonl \
  --output-dir outputs/llamafactory_data_xfund_zh_500_strictbbox

生成 LoRA 训练命令:

python scripts/train_lora.py \
  --dataset-dir outputs/llamafactory_data_xfund_zh_500_strictbbox \
  --dataset-name mm_doc_agent \
  --quantization-bit 0

生成 projector-adaptation 训练命令:

python scripts/train_lora.py \
  --dataset-dir outputs/llamafactory_data_xfund_zh_500_strictbbox \
  --dataset-name mm_doc_agent \
  --quantization-bit 0 \
  --unfreeze-projector \
  --additional-target visual.merger

已验证训练环境:

GPU: NVIDIA RTX 3060 12GB
Base model: Qwen2.5-VL-3B-Instruct
Training backend: LLaMA-Factory
Container image: mm-doc-agent-lf:local

推理与评估

批量推理:

python scripts/infer_jsonl.py \
  --input data/processed/xfund_zh_val_50.jsonl \
  --output outputs/pred_xfund_zh_val_50_lora500.jsonl

单模型评估:

python scripts/evaluate_jsonl.py \
  --gold data/processed/xfund_zh_val_50.jsonl \
  --pred outputs/pred_xfund_zh_val_50_lora500.jsonl

多模型对比:

python scripts/compare_experiments.py \
  --gold data/processed/xfund_zh_val_50.jsonl \
  --run base=outputs/pred_xfund_zh_val_50_base.jsonl \
  --run lora500=outputs/pred_xfund_zh_val_50_lora500.jsonl \
  --run projector500=outputs/pred_xfund_zh_val_50_projector_additional.jsonl

OCR-Assisted Grounding

导出 OCR 文本框索引:

python scripts/export_xfund_ocr_index.py \
  --annotation data/external/xfund/zh.val.json \
  --image-dir data/external/xfund/zh.val \
  --output data/processed/xfund_zh_val_ocr.jsonl

使用 OCR 文本框修正生成式 bbox:

python scripts/apply_ocr_grounding.py \
  --pred outputs/pred_xfund_zh_val_50_lora500.jsonl \
  --ocr data/processed/xfund_zh_val_ocr.jsonl \
  --gold data/processed/xfund_zh_val_50.jsonl \
  --output outputs/pred_xfund_zh_val_50_lora500_ocr_grounded.jsonl

错误可视化

渲染 gold/pred evidence bbox:

python scripts/render_error_overlays.py \
  --gold data/processed/xfund_zh_val_50.jsonl \
  --pred outputs/pred_xfund_zh_val_50_lora500_ocr_grounded.jsonl \
  --image-root . \
  --output-dir outputs/error_overlays/xfund_zh_val50_lora500_ocr_grounded

可视化颜色约定:

green = gold bbox
red   = predicted bbox

测试

项目包含针对数据转换、输出解析、指标计算、训练命令生成、OCR grounding 和 bbox 可视化的单元测试。

PYTHONPATH=src python -m pytest -q

最近一次本地验证:

23 tests passed

About

Multimodal document understanding agent for Chinese documents, with Qwen-VL LoRA training, evaluation, and demo deployment.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages