古籍ocr识别率最高的应用是哪一款?
作者:卡卷网发布时间:2025-04-29 22:01浏览数量:6次评论数量:0次
过去一年里做了很多和RAG相关的事情,我在数据清洗的过程中接触了大量OCR相关的任务。
其中一种在工作之外的业余时间里摸索出来的方法,就是通过batch api批量进行信息提取和转化,直接生成指定格式的文件。
注意:这种方法仅限于对数据安全和隐私要求不高的图像类文件,尤其适用于为私域使用场景准备的公域数据。
事情的起因是我从去年开始,业余时间在机核网翻译美食相关的古籍,有兴趣的可以看我已经发布的文章:
机核 - 珍馐谱 | 一个和饮食有关的合集那么这类古籍当中,常见的一般都能找到对应的txt文件,直接分段让大模型进行现代汉语翻译。
至于不常见的古籍,首先得找到电子版的扫描件,其次是要把扫描件上的内容按照古籍的书写阅读方式提取出来,重新转换成横版的txt文件,再进行后续的翻译步骤。
尽管市面上的OCR工具很多,但是能做到批量处理,且能正确识别古籍格式,转换下来错误率偏低的,几乎没有。而且即便是使用了视觉大模型的主流OCR网页端demo,也做不到让用户敞开了用。
于是我萌生了一个念头,就是用Batch API结合视觉大模型来做这件事。
首先把扫描版pdf导出成单页图像,接着建立Batch API的OCR任务脚本。
由于需要翻译和识别的是繁体中文的古籍,所以首选国内的大模型,而目前国内厂商在Batch api方面做得不错的主要有两家——阿里和智谱。
阿里云百炼 Batch API智谱 Batch API以智谱为例,运行前先安装对应的库:
pip install zhipuai
伪代码如下(有需要的可以用AI工具去转换成具体Python脚本,这里出于谨慎考虑就不po源码了):
// 全局常量
定义 SUPPORTED_IMAGE_EXTENSIONS = [".jpg", ".jpeg", ...]
定义 DEFAULT_MODEL = "glm-4v-plus-0111"
定义 DEFAULT_MAX_TOKENS = 1024
定义 DEFAULT_BATCH_SIZE = 100
定义 OCR_PROMPT = "复杂的古籍OCR指令文本..." // 包含分栏、旁批处理等说明
// 函数:过滤图像文件
函数 filter_image_files(文件列表):
返回 列表中后缀在 SUPPORTED_IMAGE_EXTENSIONS 内的文件
// 函数:按大小分割列表
函数 chunk_list(列表, 分块大小):
按分块大小迭代生成子列表
// 函数:创建批量请求的 JSONL 字符串
函数 create_batch_jsonl(图像文件列表, API模型, 最大token数):
初始化 空字符串 result
遍历 图像文件列表中的每个文件:
获取 文件名作为 custom_id
读取图像文件内容
将图像内容编码为 Base64
构建一个 ZhipuAI ChatCompletion API 的请求 JSON 对象:
包含 custom_id, method="POST", url="/v4/chat/completions"
body 包含 model, max_tokens
messages 包含 用户角色消息:
消息内容包含 Base64图像 和 OCR_PROMPT 文本
将请求 JSON 对象转换为单行字符串 (JSONL 格式)
将该行添加到 result
返回 result
// 函数:记录日志(GUI界面和控制台)
函数 log(消息文本):
将消息文本添加到 GUI 日志区域
滚动日志区域到底部
打印消息文本到控制台
// 函数:更新计时器显示
函数 update_timer():
如果 start_time 已设置:
计算已过去时间
更新 GUI 计时器标签显示
安排 1秒后再次执行此函数
// 主 GUI 类
类 BatchAPIConverterGUI:
初始化():
创建主窗口 (Tkinter)
设置窗口标题和大小
初始化状态变量: selected_image_files, output_folder, zhipuai_client, start_time, total_batches, processed_batches
创建所有 GUI 控件 (输入框, 按钮, 标签, 进度条, 日志区)
方法 select_image_files():
打开文件选择对话框 (允许选择多个文件)
使用 filter_image_files 过滤非图像文件
更新 selected_image_files 状态
更新 GUI 显示选定的文件数量
记录日志
方法 select_output_folder():
打开目录选择对话框
更新 output_folder 状态
更新 GUI 显示输出文件夹路径
记录日志
方法 start_batch_conversion():
获取 API 密钥、模型、最大token数、批次大小的输入值
验证 API 密钥、是否选择了文件、是否选择了输出文件夹
如果验证失败,显示警告并返回
初始化 ZhipuAI Client 使用 API 密钥
使用 chunk_list 将选定文件分批
初始化进度条和批次计数
记录总批次信息
记录 start_time 并启动 update_timer
调用 process_next_batch 开始第一个批次的处理
方法 process_next_batch(剩余批次列表, API模型, 最大token数):
如果 剩余批次列表为空:
记录 "全部批次处理完毕"
更新 GUI 状态标签
返回
取出 剩余批次列表中的第一个批次 (当前批次)
计算 当前批次索引
记录 开始处理当前批次的信息
生成当前批次的请求数据 (调用 create_batch_jsonl)
保存请求数据到临时 JSONL 文件
尝试上传临时 JSONL 文件到 ZhipuAI (purpose="batch")
如果上传失败:
记录错误
增加 processed_batches
更新进度条
递归调用 process_next_batch 处理下一个批次
返回
获取上传成功后的 input_file_id
记录上传成功信息
尝试创建 ZhipuAI batch 任务 (使用 input_file_id)
如果创建任务失败:
记录错误
增加 processed_batches
更新进度条
递归调用 process_next_batch 处理下一个批次
返回
获取创建成功后的 batch_id
记录 batch 任务 ID
将临时请求文件重命名为包含 batch_id 的文件名
启动轮询 batch 任务状态 (调用 poll_batch_status), 并指定完成后执行 handle_batch_result
方法 poll_batch_status(batch_id, 完成后的回调函数):
尝试 使用 ZhipuAI client 获取 batch_id 的状态
如果获取状态失败:
记录错误
返回 (本次轮询结束,不影响后续批次) // 注意:这里可能需要更严谨的错误处理
更新 GUI 状态标签显示当前状态
如果状态是 "completed":
调用 完成后的回调函数 (handle_batch_result)
返回
如果状态是 "failed" 或 "expired":
记录异常状态
增加 processed_batches
更新进度条
返回 (本次轮询结束,不影响后续批次)
// 如果状态不是完成/失败/过期
安排 5秒后再次执行 poll_batch_status (继续轮询)
方法 handle_batch_result(batch_id, 剩余批次列表, API模型, 最大token数):
尝试 使用 ZhipuAI client 获取 batch_id 的完整信息
如果获取失败:
记录错误
增加 processed_batches
更新进度条
递归调用 process_next_batch 处理下一个批次
返回
获取 batch_id 的 output_file_id
下载 output_file_id 对应的内容 (ZhipuAI client)
保存下载内容到本地 JSONL 文件
尝试 解析下载的 JSONL 文件:
遍历 JSONL 文件中的每一行:
尝试 将行解析为 JSON 对象
提取 custom_id 和 识别出的文本内容
如果 custom_id 和 文本内容都存在:
保存文本内容到以 custom_id 为文件名 (加 .txt 后缀) 的文件
记录保存成功信息
否则:
记录 custom_id 无内容或解析失败
如果解析文件失败:
记录错误
增加 processed_batches
更新进度条
记录当前批次完成信息
递归调用 process_next_batch 处理下一个批次
// 主程序入口
如果 当前脚本是主程序:
创建 BatchAPIConverterGUI 实例
启动 GUI 事件循环
任务开始运行以后会看到目标文件夹里会生成一个batch_request_batch_id.jsonl任务文件,等待一阵可以查看任务运行的状态,主要这么几种:
状态 | 状态描述 |
validating | 文件正在验证中,Batch 任务未开始 |
failed | 文件未通过验证 |
in_progress | 文件已成功验证,Batch 任务正在进行中 |
finalizing | Batch 任务已完成,结果正在准备中 |
completed | Batch 任务已完成,结果已准备好 |
expired | Batch 任务未能完成 |
cancelling | Batch 任务正在取消中 |
cancelled | Batch 任务已取消 |
任务完成后可以看到目标文件夹里出现batch_output_batch_id.jsonl文件,选中的图像页面对应的txt文件会用原本图像的文件名存储。
以明代记载宫廷饮食相关的古籍《天庖承事》为例,其中一页是这样的:
提取出的纯文本效果是:
天庖承事 (9卷) 李植 明万历26年 - 第2页
等親細讀該廠見得器皿數多堆積無量難得盡久清洗每年頒發一年將來必致朽壞且一器一物俱係朝廷頒發小民脂膏無可傭惜若不登庫逐項造冊清查酌量損壞之多寡以為會計之鉅細則有偷資寬免徇壞不足者復行會造何惟性末細會伺並增供用益三官若典膳局典簿沈文冕贊化局典膳署吳文洸和珍羞署監事曾文照會同四川署掌印官經歷官備將見在器皿不拘遠年近日整庫查明要見萬曆二十四年分應會若干見在堪用若干堪修砌若干未解到若干朽壞不堪若干逐一盤驗明確具冊呈報隨據各官回稱職等蒙委查清食前項器皿盡心所事夙夜在廠隨查得二十四年分造圓木甑若應會陸千捌百陸拾壹件半年見在堪用柒千陸百柒拾伍件半年堪修柒百壹拾陸件未解到壹千肆百陸件半三項共肆千柒百玖拾捌件實會貳千陸拾參件半珍羞署連聞應會鴛鴦罈千
在对页的处理上,能达到这样的效果我已经很满足了。
这本书一共200多页,批量处理每次弄50-100页,3-4次任务就完成了,整个过程快的话不会超过1个小时。
价格上,如果买500万token的GLM-4V-Plus-0111的3折尝鲜推理资源包,就只需要6元(不知道现在还有没有)。上述长度的古籍文本可以处理至少两部有余。
这样做的好处在于,文字的提取和格式转换理论上可以一次完成。比如我们需要在古文中添加标点符号,只需要稍稍改动提示词,就可以得到下面的输出结果:
天庖承事 (9卷) 李植 明万历26年 - 第2页
等親細讀,該廠見得器皿數多,堆積無量,難得盡久清洗。每年頒發一年,將來必致朽壞,且一器一物,俱係朝廷頒發,小民脂膏,無可傭惜。若不登庫逐項造冊清查,酌量損壞之多寡以為會計之鉅細,則有偷資寬免,徇壞不足者,復行會造。何惟性末細會伺並增供用益三官,若典膳局典簿沈文冕、贊化局典膳署吳文洸,和珍羞署監事曾文照,會同四川署掌印官經歷官,備將見在器皿不拘遠年。
近日整庫查明,要見萬曆二十四年分應會若干,見在堪用若干,堪修砌若干,未解到若干,朽壞不堪若干。逐一盤驗明確,具冊呈報,隨據各官回稱。職等蒙委查清食前項器皿,盡心所事,夙夜在廠。隨查得二十四年分造圓木甑,若應會陸千捌百陸拾壹件半,見在堪用柒千陸百柒拾伍件半,堪修柒百壹拾陸件,未解到壹千肆百陸件半,三項共肆千柒百玖拾捌件實,會貳千陸拾參件半。珍羞署連聞應會鴛罈千
甚至如果对于原文本并不看重,也可以直接让它输出翻译后的现代汉语文本,当然在古籍扫描件中这一点并不推荐,因为可能出现断句的问题。
总的来说Batch API的好处在于:
- 处理量大(一次处理1000个文件都是比较稳的)。
- 价格便宜(非高峰时段收费只有正常API的50%价格)。
它的缺点在于:
- 每一页的token数量有上限(智谱GLM-4V-Plus-0111的最大token值是1024),存在潜在的输出长度不够覆盖文本内容的问题。
- 异步请求的耗时是不确定的,有时排队时间过长可能会出现极端的10小时以上的情况,而这和处理的文件数量没有关联,所以速度多快纯看运气。
大致就是这样了。
免责声明:本文由卡卷网编辑并发布,但不代表本站的观点和立场,只提供分享给大家。
相关推荐

你 发表评论:
欢迎