day33-多模态RAG拓展(PDF图片多模态模型语义理解)
多模态RAG系统进阶:olmOCR工具使用
olmOCR部署与调用流程
olmOCR本质上其实是一个经过特定功能微调的多模态大模型,能够实现明显好于其他普通OCR模型的光学字符识别效果。
项目地址: https://github.com/allenai/olmocr
目前官方已发布 7B 等级模型 权重,微调自 Qwen2.5-VL-7B-Instruct。
项目模型:https://huggingface.co/allenai/olmOCR-7B-0825-FP8
实测效果:
1.硬件与系统说明
目前olmOCR只支持本地部署,硬件条件如下:
- NVIDIA GPU,建议显存 ≥ 15 GB(官方测试过 RTX 4090、L40S、A100、H100;磁盘需约 30 GB)。
- 操作系统:Linux。
因此,我们下面在autodl云服务器 ( 西北B区 / 963机 ) 进行实操和应用!
autodl云服务器使用流程
-
注册后进行登录
-
登录后进入到【控制台】
-
在个人主页中进行充值:5元
-
在【容器实例】中租用一个新实例(云服务器)
-
进行基础镜像配置
2.系统依赖(用于 PDF 渲染/字体)
需要安装相关依赖:下面的两个指令需要在cmd中逐一执行
sudo apt-get update
sudo apt-get install -y poppler-utils ttf-mscorefonts-installer msttcorefonts \
fonts-crosextra-caladea fonts-crosextra-carlito gsfonts lcdf-typetools
以上为olmOCR官方项目中 README 推荐依赖,用于将 PDF 页渲染为图像、补齐字体
3.创建虚拟环境
接下来继续创建虚拟环境:
conda create -n olmocr python=3.11 -y
#重启cmd切换虚拟环境
conda activate olmocr
4. 安装olmOCR
# GPU 推理(推荐)在olmocr虚拟环境中进行
pip install "olmocr[gpu]" --extra-index-url https://download.pytorch.org/whl/cu128
需要注意的是,真正的 OCR/VLM 推理必须用 GPU。这条安装命令的核心是安装带 GPU 支持的 olmOCR 依赖 和 包含自动安装推理工具vLLM。
安装完成后即可查看实际安装结果:
pip show olmocr
查看vllm作为推理引擎:
pip show vllm
5.下载olmOCR模型权重
需要先安装魔搭社区:在olmocr虚拟环境中执行
pip install modelscope
然后尝试下载olmOCR模型:https://www.modelscope.cn/models/allenai/olmOCR-7B-0825-FP8/
使用如下命令即可开始下载:
#在当前目录下创建一个olmOCR-7B-0825-FP8的文件夹(文件夹名字随便)
modelscope download --model allenai/olmOCR-7B-0825-FP8 --local_dir ./olmOCR-7B-0825-FP8
6.olmOCR模型调用流程
因为,后续我们也需要据此对模型进行提问。这里首先我们需要开启vLLM模型服务:
执行下面指令,autodl不可使用无卡模式开机,一定要有显卡的前提下启动模型服务!该服务一旦关闭,则本地无法进行模型调用!
vllm serve ./olmOCR-7B-0825-FP8 \
--served-model-name olmocr \
--max-model-len 16384 --port 8001
顺利启动后如下所示:
然后在命令行中将当前虚拟环境添加到Jupyter kernel中:
conda install ipykernel
python -m ipykernel install --user --name olmocr --display-name "Python (olmocr)"
借助olmOCR实现元素感知OCR
在进行pdf转换md后,olmocr可以实现将md图片进行元素感知和语义解析,即提取图片内容作为md的文字内容和图片语义解析,从而实现更高精度的视觉检索。
实现效果对比:


#传入output.md作为被增强文件
# 需要安装:pip install pdf2image pillow requests tqdm
'''自动分析 Markdown 文档中引用的图片(如图表、公式、流程图等),利用多模态大模型(如 olmOCR)理解图片内容,并将结构化信息以 Markdown 形式插入原文档中,从而提升文档的信息密度和可检索性。'''
import os, re, io, base64, requests, json
from PIL import Image
#指导多模态模型如何解析图片
'''你是OCR与文档理解助手。
分析此图像区域并生成:
1) ALT:非常简短的替代文本(<=12个词)。
2) CAPTION:1-2句简洁的说明。
3) CONTENT_MD:若图像包含表格,输出干净的Markdown表格;若包含公式,输出LaTeX($...$或$$...$$);否则提供3-6个要点总结内容,使用Markdown格式。
严格按以下格式返回:
ALT: <简短替代文本>
CAPTION: <一两句说明>
CONTENT_MD:
<此处为Markdown内容>'''
DEFAULT_PROMPT = (
"You are an OCR & document understanding assistant.\n"
"Analyze this image region and produce:\n"
"1) ALT: a very short alt text (<=12 words).\n"
"2) CAPTION: a 1-2 sentence concise caption.\n"
"3) CONTENT_MD: if the image contains a table, output a clean Markdown table;"
" if it contains a formula, output LaTeX ($...$ or $$...$$);"
" otherwise provide 3-6 bullet points summarizing key content, in Markdown.\n"
"Return strictly in the following format:\n"
"ALT: <short alt>\n"
"CAPTION: <one or two sentences>\n"
"CONTENT_MD:\n"
"<markdown content here>\n"
)
#正则匹配 Markdown文件内容中 图片链接的语法
IMG_PATTERN = re.compile(r'!\[[^\]]*\]\(([^)]+)\)')
#调用多模态模型解析单张图片
def call_olmocr_image(vllm_url, model, img_path,
temperature=0.2, max_tokens=2048,
prompt=DEFAULT_PROMPT):
#读取并编码图片为 Base64,目的是为了在vllm请求参数中使用
with Image.open(img_path) as im:
bio = io.BytesIO()
im.save(bio, format="PNG")
img_bytes = bio.getvalue()
#构造 vLLM API 请求(兼容 OpenAI 多模态格式)
payload = {
"model": model,
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{base64.b64encode(img_bytes).decode()}", "detail": "auto"}} #detail: "auto" 让模型自动选择分辨率。
]
}],
"temperature": temperature,
"max_tokens": max_tokens,
}
#发送 HTTP POST 请求
r = requests.post(vllm_url, json=payload, timeout=180)
r.raise_for_status()
text = r.json()["choices"][0]["message"]["content"].strip()
#解析模型返回的结构化文本,对其按行扫描,识别 ALT:、CAPTION:、CONTENT_MD: 标记,提取对应内容,组装为字典
alt, caption, content_md_lines = "", "", []
mode = None
for line in text.splitlines():
l = line.strip()
if l.upper().startswith("ALT:"):
alt = l.split(":", 1)[1].strip()
mode = None
elif l.upper().startswith("CAPTION:"):
caption = l.split(":", 1)[1].strip()
mode = None
elif l.upper().startswith("CONTENT_MD:"):
mode = "content"
else:
if mode == "content":
content_md_lines.append(line.rstrip())
#提取对应内容,组装为字典
return {
"alt": alt or "Figure",
"caption": caption or alt or "",
"content_md": "\n".join(content_md_lines).strip()
}
#主流程——增强整个 Markdown 文档
def augment_markdown(md_path, out_path,
vllm_url="http://localhost:8001/v1/chat/completions",
model="olmocr",
temperature=0.2, max_tokens=2048,
image_root=".",
cache_json=None):
#读取原始 Markdown 行数据
with open(md_path, "r", encoding="utf-8") as f:
md_lines = f.read().splitlines()
#加载缓存(避免重复解析同一张图)
cache = {}
if cache_json and os.path.exists(cache_json):
try:
cache = json.load(open(cache_json, "r", encoding="utf-8"))
except Exception:
cache = {}
#逐行处理,识别并增强图片
out_lines = []
for line in md_lines:
out_lines.append(line)
m = IMG_PATTERN.search(line)
if not m:
continue
img_rel = m.group(1).strip().split("?")[0]
img_path = img_rel if os.path.isabs(img_rel) else os.path.join(image_root, img_rel)
if not os.path.exists(img_path):
out_lines.append(f"<!-- WARN: image not found: {img_rel} -->")
continue
if cache_json and img_path in cache:
result = cache[img_path]
else:
result = call_olmocr_image(vllm_url, model, img_path,
temperature, max_tokens)
if cache_json:
cache[img_path] = result
alt, cap, body = result["alt"], result["caption"], result["content_md"]
if cap:
out_lines.append(f"*{cap}*")
if body:
out_lines.append("<details><summary>解析</summary>\n")
out_lines.append(body)
out_lines.append("\n</details>")
with open(out_path, "w", encoding="utf-8") as f:
f.write("\n".join(out_lines))
if cache_json:
with open(cache_json, "w", encoding="utf-8") as f:
json.dump(cache, f, ensure_ascii=False, indent=2)
print(f"✅ 已写入增强后的 Markdown:{out_path}")
augment_markdown(
md_path="output.md", # 第一步生成的 md
out_path="output_augmented.md", # 增强后的 md
vllm_url="http://localhost:8001/v1/chat/completions", # 你的 vLLM 服务
model="olmocr",
image_root=".", # 图片路径相对根目录
cache_json="image_cache.json" # 可选,缓存文件
)
agent(steamlit)
RAG(chat ui )
deepseek-ocr
工具调用
代码开发

浙公网安备 33010602011771号