
这次我们来看一个很具体的需求把那些复制不了文字的文件变成大语言模型能直接读的文本。PDF 扫描件、图片型 PDF、加密文档、网页截图、带水印的合同……这些内容在屏幕上能看鼠标一拖却选不中文字。大语言模型本身只认文本 token多模态模型除外你没法直接把一个扫描 PDF 丢给 RAG 流程去切分也没法让纯文本 LLM 去总结一张截图。于是就有了 OCR It 这类工具的价值把不可复制的文档先做 OCR 提取得到干净文本再交给 LLM 做摘要、结构化、问答或者知识库入库。OCR It 解决的就是这条链路的前半段。它的核心目标不是从零训练一套 OCR 算法而是把成熟的 OCR 能力组织成一条面向 LLM 场景的文本提取管线支持常见文档输入、支持批量处理、可作为 API 服务接入最终产出适合喂给大模型的纯文本或 Markdown。下面我会围绕这条思路给出完整的能力速览、部署步骤、功能验证方法、API 与批量任务组织方式、性能观察手段和问题排查清单。如果你正在做 RAG 知识库、本地大模型应用、文档自动化处理或者经常需要把历史 PDF/截图喂给 LLM 做分析这篇文章可以直接收藏。本文不绑定单一硬件的实测数字因为不同 OCR 引擎、不同文档清晰度下的资源占用差异很大但部署流程和验证思路是通用的。1. OCR It 核心能力速览先把最关键的信息整理成一张表方便判断“这个工具/路线适不适合我”。能力项说明项目定位面向 LLM 数据管线的文档 OCR 文本提取工具输入类型扫描 PDF、图片型 PDF、PNG/JPG 截图、加密 PDF解密后、带水印文档输出类型纯文本、Markdown、JSON按实现方式不同而不同对接 LLM输出文本可作为 RAG、摘要、问答、知识库入库的前置数据部署方式命令行、Python 脚本、HTTP API 服务、批量任务目录API 支持常见实现会提供 HTTP 接口便于并入 LangChain、LlamaIndex 等框架批量任务按目录批量处理建议配合日志和失败重试硬件门槛CPU 可跑基础识别GPU 可加速大文档和批量场景显存占用与所选 OCR 引擎、文档分辨率、并发数有关需以本机实测为准适合读者RAG 开发者、本地 LLM 使用者、文档自动化工程师、知识库维护者这里特别说明一点如果你看到的 OCR It 是某个具体的开源仓库或一键包端口、启动脚本和模型文件位置请以项目 README 为准。下面所有命令都按通用模板给出实际使用时需要替换成你自己的目录和模型名。2. 为什么 LLM 需要 OCR 预处理2.1 LLM 的输入限制大多数开源大模型接受的是文本输入即使支持多模态也要先把图像转成视觉 token。对于纯文本模型来说一张图片、一个扫描 PDF 无法直接被读取。即便你强行把 PDF 文件塞进提示词模型看到的是二进制内容而不是文档里的文字。所以 OCR 在 LLM 应用里不是可选项而是前置环节。尤其在做 RAG 知识库时文档切分的前提是“文本已经被提取出来”。没有 OCR 这一步后续的 embedding、检索、增强生成都无从谈起。2.2 不可复制文档的常见类型“不可复制”分几种情况扫描件纸面文档扫描成 PDF 后本质是一张张图片没有文本层。图片型 PDF用截图工具或打印机“另存为 PDF”生成页面内容全是图。加密/受限文档PDF 设置了编辑或复制权限需要先解密再提取。网页截图、聊天记录截图、监控屏截图文字在像素里。带水印、盖章、压线的合同背景干扰严重普通复制功能无效低质量 OCR 也容易出错。OCR It 这类工具的定位就是把上述内容统一转成“可被 LLM 消费的文本”。2.3 OCR 到 LLM 的完整工作流一条典型的处理链路是原始文档扫描件/截图/图片 PDF ↓ OCR 文本提取 ↓ 清洗与结构化去水印噪点、按标题分层、转 Markdown ↓ LLM 摘要 / 问答 / 信息抽取 ↓ RAG 向量化入库 或 本地知识库如 LLM Wiki 范式这两年热词里的“LLM Wiki”“Karpathy 的 LLM Wiki 范式”本质上也是先把散落文档整理成结构化文本再交给模型参考。OCR It 要做的就是“整理成结构化文本”这一步的自动化。3. 适用场景与使用边界3.1 适合的场景合同、发票、报销单扫描件归档把历史纸质单据转成可检索文本。论文 PDF 解析很多知网、期刊 PDF 是扫描版直接复制乱码OCR 后可做论文问答。截图批量处理聊天记录、数据看板、报错界面统一提取文字。RAG 知识库构建把不可复制的文档转成文本后送去 embedding 和检索。迁移旧系统数据老系统导出的图片档案需要批量进入新数据库。本地 LLM 测试不想把文档发给在线 OCR 服务时本地部署更可控。3.2 不适合的场景实时视频 OCR 流处理比如监控画面每帧识别OCR It 这类文档工具不是为此设计的。复杂手写体识别如果文档是大量手写笔记通用 OCR 引擎准确率很低需要专门训练手写识别模型。需要精确还原复杂表格结构跨行跨列多、合并单元格极多的表格纯 OCR 输出经常乱需要额外的版面分析模块。高安全要求业务对保密等级高的文档要先确认本地 OCR 方案是否允许使用开源模型、是否需要断网运行。3.3 版权、隐私与合规边界使用 OCR 工具时务必注意只处理你拥有合法处理权限的文档。涉及他人隐私、个人信息、未公开商业文件时要遵守相关法律法规。尤其是把 OCR 结果喂给云上大模型 API 之前先确认数据是否会离开本地。涉及人脸照片、身份证件、含签名的文档时更要严格控制访问范围处理完及时删除临时文件。这些不是套话。OCR 提取出来的文本可能包含敏感信息一旦进入日志或 API 请求记录风险会被放大。建议在架构上把 OCR 服务和 LLM 调用都收敛到受控环境里。4. 环境准备与前置条件4.1 硬件与系统操作系统Windows、Linux、macOS 都可以。如果用到 GPU优先 Linux。CPU普通 x86 主机即可运行基础 OCR处理速度和文档页数相关。GPU可选NVIDIA 显卡配合 CUDA 可以显著加快批量识别没有 GPU 也能跑。内存建议 8GB 以上。处理高分辨率 PDF 时内存占用会明显上升。磁盘OCR 模型文件可能占用几百 MB 到几个 GB再加上输入输出文档目录建议预留至少 5GB。4.2 软件与依赖常见开源 OCR 方案有 Tesseract、PaddleOCR、Surya、OCRmyPDF、MinerU 等。OCR It 这类项目通常会封装其中一种或多种引擎。环境准备重点检查Python 版本多数工具要求 Python 3.8 以上。包管理器pip 或 conda。OCR 引擎二进制Tesseract 需要单独安装系统级程序PaddleOCR 通过 pip 安装但可能需要 GCC 编译环境。模型文件Tesseract 需要对应语言包比如中文简体 chi_simPaddleOCR 首次运行会自动下载模型。CUDA 与 PyTorch如果用 GPU 版 PaddleOCR 或深度学习类 OCR需要装匹配的 CUDA 工具包和 GPU 版 PyTorch。4.3 端口与目录规划如果 OCR It 作为 API 服务启动建议服务端口固定比如 8000 或 7860启动前检查是否被占用。输入目录、输出目录、日志目录分开。输出文本文件的命名规则保持一致方便批量任务对接。# 检查端口占用 netstat -ano | grep 80005. 安装部署与启动方式5.1 命令行 OCR 引擎最简单的方式是走命令行工具。以 Tesseract 类的流程为例先安装引擎再调用命令# Ubuntu/Debian 安装 Tesseract按系统包管理器调整 sudo apt update sudo apt install tesseract-ocr tesseract-ocr-chi-sim # 单张图片识别 tesseract input.png output -l chi_simeng执行后会在当前目录生成output.txt里面就是识别出的文本。这个流程适合快速验证 OCR 效果不适合大规模批量处理。5.2 用 Python 脚本批量处理 PDF如果输入是扫描 PDF建议用 Python 把“PDF 转图片 → OCR → 输出文本”串起来。下面是一个通用模板import os from pdf2image import convert_from_path import pytesseract input_pdf scan.pdf output_txt scan.txt # 把 PDF 每页转成图片dpi 越高识别越准但耗时更长 pages convert_from_path(input_pdf, dpi200) results [] for i, page in enumerate(pages): text pytesseract.image_to_string(page, langchi_simeng) results.append(f--- Page {i 1} ---\n{text}) with open(output_txt, w, encodingutf-8) as f: f.write(\n.join(results))这段代码不是某个项目的固定命令而是通用思路pdf2image负责把 PDF 拆成图片pytesseract负责识别。换成 PaddleOCR 时只需把image_to_string换成 PaddleOCR 的 Python API。5.3 启动本地 HTTP API 服务当 OCR It 要以服务形式供其他系统调用时可以包一层 FastAPI 或 Flask。启动命令类似# 示例实际启动脚本以项目 README 为准 python app.py --host 127.0.0.1 --port 8000启动后先在自己的机器上访问http://127.0.0.1:8000/docsSwagger 文档或简单 GET 探活接口确认服务在线。随后再通过下面第 7 章的接口示例调用。5.4 一键包或 WebUI按项目实现有些封装版本会提供start.bat或start.sh双击/运行后自动拉起 WebUI 和 API。这种方式的优点是把依赖隔离好模型文件和脚本都放在固定目录用户不用手动配置 CUDA。缺点是如果需要定制参数或改端口得先看它的启动脚本。一般会通过环境变量或配置文件控制端口例如host127.0.0.1 port7860 model_dir./models output_dir./output6. 功能测试与效果验证部署完成后不要直接上生产先用小样本做一轮功能验证。6.1 测试一单张截图文字识别输入素材一张清晰的中文网页截图包含标题、正文、数字。操作调用命令行或 API 识别。预期文字顺序和原图基本一致中英文混排不串行。判断成功标题、正文关键句都提取出来没有整行丢失。失败排查是否缺少中文语言包图片分辨率是否过低6.2 测试二扫描 PDF 解析输入素材一份 5 页以内的扫描 PDF清晰度 200 DPI 左右。操作按 5.2 的 Python 脚本处理。预期每页文本都有一个“--- Page N ---”分段页内段落相对完整。判断成功能定位到每一页的标题和正文关键句。失败排查PDF 是加密的还是纯图片pdftoppm是否安装6.3 测试三中英文混排与 Markdown 导出输入素材包含标题、正文、简单列表的中英文混排文档。操作识别后转成 Markdown 格式。预期能保留标题层级、列表结构中英文和数字不混成乱码。判断成功Markdown 渲染后基本能看没有大量无效换行。失败排查版面分析能力不足时需要开启 OCR 引擎的表格/布局模式。6.4 测试四批量目录处理输入素材一个目录下放 10 张不同格式的文档图片。操作脚本遍历目录输出同名.txt文件。预期每个输入文件都有对应输出失败文件被单独记录。判断成功10 个文件全部处理完日志里能看到失败原因而不是直接崩溃。失败排查程序是否忽略了非图片文件是否有异常捕获机制6.5 测试五API 接口调用输入素材用 curl 或 Python 请求 OCR It 的接口。操作POST 一个图片或文档。预期返回 JSON包含识别文本和耗时段。判断成功接口返回 200文本内容与预期一致。失败排查请求参数格式对不对文件大小是否超过服务端限制6.6 判断成功与常见失败点一次完整的验证要看四个方面召回率文字有没有被漏掉。正确率识别出的字是不是原字。顺序段落顺序有没有打乱。格式输出是不是 LLM 能直接用。常见失败点集中在中文语言包缺失、图片分辨率过低、扫描件倾斜、PDF 加密、输出编码不是 UTF-8。7. 接口 API 与批量任务7.1 通用 API 调用示例如果 OCR It 提供了 HTTP API常规调用方式如下。请求参数和响应字段以实际项目文档为准这里给出一个通用 Python 调用模板import requests url http://127.0.0.1:8000/ocr files {file: open(scan.png, rb)} data { lang: chi_simeng, return_markdown: true } resp requests.post(url, filesfiles, datadata, timeout60) if resp.status_code 200: result resp.json() print(result.get(text, )) else: print(request failed:, resp.status_code, resp.text)curl 方式类似curl -X POST http://127.0.0.1:8000/ocr \ -F filescan.png \ -F langchi_simeng \ -F return_markdowntrue这里注意两点一是上传文件体积限制很多服务默认限制在几十 MB大 PDF 要分页处理二是超时时间扫描 100 页 PDF 可能超过 60 秒要按文档量调整 timeout。7.2 批量任务目录设计批量处理建议按如下目录结构组织inputs/ batch_01/ scan_a.pdf scan_b.png outputs/ batch_01/ scan_a.md scan_b.md logs/ batch_01.log脚本处理逻辑# 伪代码 for file in inputs/batch_01/*: result ocr_process(file) save_output(result, outputs/batch_01/) log_result(file, result.status)这样每个批次独立成目录方便重跑和追溯。7.3 失败重试与日志批量任务里最怕的不是慢而是中途崩溃、跑完不知道哪些成功。所以至少要做到每个文件都有独立日志。失败文件不停止整体任务。留下失败文件清单方便二次重试。重复运行时跳过已成功文件。done_files set(os.listdir(output_dir)) for file in input_files: if file in done_files: continue try: process(file) except Exception as e: log_error(file, e)8. 资源占用与性能观察8.1 怎么观察资源占用本地跑 OCR 时观察点不同CPU 占用top/htop内存占用htop的 RES 列GPU 显存占用nvidia-smi或nvitop磁盘 I/Oiostat如果习惯用 Python也可以直接打印显存import torch print(torch.cuda.memory_allocated() / 1024**2, MB)注意nvidia-smi显示的显存占用是进程峰值不是瞬时值观察批量任务要隔几秒采样一次。8.2 CPU 与 GPU 推理差异CPU 推理省事无需处理 CUDA 环境但高分辨率扫描件会明显变慢。GPU 推理需要安装匹配的驱动和 PyTorch峰值速度可能快数倍但显存占用也更高。具体差异要拿你的典型文档跑一轮对比不能只看别人测的数字。如果你用的是传统 Tesseract它本身主要靠 CPU上 GPU 帮助不大PaddleOCR、Surya 这类深度学习方案才吃 GPU。所以第一步先确认你选的引擎是什么类型。8.3 影响性能的关键参数DPIPDF 转图的 DPI 越高识别越准但耗时和内存都上升。常见选择在 150 到 300 之间。批量并发同时处理多个文档能提高吞吐但会拉高显存/内存。输入分辨率超大图可以先等比缩放到宽 2000 像素左右再识别。语言包数量一次性加载过多语言包会增加初始化耗时。版面分析开启表格、公式检测会明显增加耗时不需要时可关闭。8.4 降低资源占用的方法显存不够时先降低 DPI再降低并发数。还能改用 CPU 推理。进程残留也会占用显存批量任务结束后检查nvidia-smi如果还有 GPU 进程残留用kill pid清理。端口冲突的问题也一样多个 OCR 服务实例不要共用同一个端口建议每个实例一个端口。9. 常见问题与排查方法问题现象可能原因排查方式解决方案启动后页面打不开端口被占用或服务未启动查看启动日志检查端口更换端口或重启服务OCR 识别结果全是乱码缺少中文语言包或编码不对检查语言包文件确认输出编码安装chi_sim语言包输出 UTF-8中文识别率低图片分辨率低、字体特殊、扫描倾斜检查原图清晰度和倾斜角度提升 DPI 到 200 以上先做图像预处理PDF 无法解析PDF 加密或依赖库未装尝试用其它阅读器打开解密 PDF安装 poppler 依赖显存不足高分辨率图像并发处理nvidia-smi查看占用降低 DPI、降低并发、换 CPU 推理依赖安装失败Python 版本或编译环境不匹配查看 pip 报错信息用 conda 创建独立环境安装编译工具API 返回超时上传文档太大检查服务端超时配置分页处理或调大 timeout批量任务中途卡住单文件处理异常无捕获查看日志定位卡住文件加异常捕获和超时机制跳过失败文件模型文件缺失首次启动未下载或路径不对检查模型文件目录手动下载模型放到指定目录或检查联网状态9.1 依赖安装失败最常见的是 Python 版本过新或过旧。建议为 OCR It 单独建一个虚拟环境不要和系统 Python 混在一起。如果 pip 需要编译先安装 GCC、CMake 等基础编译工具。9.2 模型文件缺失Tesseract 的tessdata目录里要包含对应语言包。PaddleOCR 首次运行会从网络下载模型如果下载失败需要手动把模型文件放入~/.paddlex/official_models之类的目录。具体路径以实际版本为准。9.3 API 调用失败先检查返回码。如果是 400多半是请求参数格式不对如果是 413是文件太大如果是 500去看服务端日志。不要在客户端盲目重试先定位是参数问题还是服务问题。10. 最佳实践与使用建议10.1 第一次先小参数测试不要一上来就批量处理 1000 个 PDF。先拿 3 到 5 份不同格式的文档跑通链路确认引擎、语言包、输出格式都没问题再逐步加大批量。10.2 目录管理要规范输入、输出、日志分开文件名保持一致。比如scan_a.pdf对应scan_a.md别把输出丢到临时目录里否则批量任务后面会很难排查。10.3 接口服务要限制访问范围API 服务默认绑定127.0.0.1不要直接暴露到公网。如果必须提供远程访问要加认证和访问限制防止扫描件里的敏感信息被外部调用拉走。10.4 输出审查与质量抽检OCR 结果进 LLM 之前建议抽检关键字段。合同编号、日期、金额这类关键数据宁可多识别一次也不要让错字流到下游。批量任务跑完后至少随机抽 10% 看一眼。10.5 与 RAG/LLM 应用集成OCR 提取的文本可以直接喂给 LangChain 或 LlamaIndexfrom langchain.schema import Document with open(scan.md, r, encodingutf-8) as f: text f.read() doc Document(page_contenttext, metadata{source: scan.md})这样就把 OCR It 的输出接进了后续的向量化、检索和问答链路。11. 总结与下一步OCR It 这类工具最值得尝试的点是解决了 LLM 应用里最容易忽略的“文本入口”问题。你不用先上复杂模型只需先用一张截图、一个 PDF 跑通 OCR 提取确认输出质量再把它接到 RAG 或本地大模型里。最先应该验证的功能是中文识别准确率和 Markdown 导出效果。这两个直接决定下游 LLM 的使用体验。最容易踩的坑有两个一是 PDF 转图片时 DPI 设太低导致识别结果惨不忍睹二是批量任务没有日志和异常捕获跑一半崩了不知道哪几个文件成功。后续可以继续扩展的方向把 OCR 结果接进 LLM Wiki 或知识库流程用模型做自动摘要和关键字段抽取也可以考虑用 MCP 方式把 OCR 能力封装成工具供 LLM Agent 直接调用。先把文本提取这步做稳后面的应用才能立得住。