卡卷网
当前位置:卡卷网 / 每日看点 / 正文

古籍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 任务正在进行中
finalizingBatch 任务已完成,结果正在准备中
completedBatch 任务已完成,结果已准备好
expiredBatch 任务未能完成
cancellingBatch 任务正在取消中
cancelledBatch 任务已取消

任务完成后可以看到目标文件夹里出现batch_output_batch_id.jsonl文件,选中的图像页面对应的txt文件会用原本图像的文件名存储。

以明代记载宫廷饮食相关的古籍《天庖承事》为例,其中一页是这样的:

古籍ocr识别率最高的应用是哪一款?  第1张

《天庖承事》第二页扫描件

提取出的纯文本效果是:

天庖承事 (9卷) 李植 明万历26年 - 第2页
等親細讀該廠見得器皿數多堆積無量難得盡久清洗每年頒發一年將來必致朽壞且一器一物俱係朝廷頒發小民脂膏無可傭惜若不登庫逐項造冊清查酌量損壞之多寡以為會計之鉅細則有偷資寬免徇壞不足者復行會造何惟性末細會伺並增供用益三官若典膳局典簿沈文冕贊化局典膳署吳文洸和珍羞署監事曾文照會同四川署掌印官經歷官備將見在器皿不拘遠年近日整庫查明要見萬曆二十四年分應會若干見在堪用若干堪修砌若干未解到若干朽壞不堪若干逐一盤驗明確具冊呈報隨據各官回稱職等蒙委查清食前項器皿盡心所事夙夜在廠隨查得二十四年分造圓木甑若應會陸千捌百陸拾壹件半年見在堪用柒千陸百柒拾伍件半年堪修柒百壹拾陸件未解到壹千肆百陸件半三項共肆千柒百玖拾捌件實會貳千陸拾參件半珍羞署連聞應會鴛鴦罈千

在对页的处理上,能达到这样的效果我已经很满足了。

这本书一共200多页,批量处理每次弄50-100页,3-4次任务就完成了,整个过程快的话不会超过1个小时。

价格上,如果买500万token的GLM-4V-Plus-0111的3折尝鲜推理资源包,就只需要6元(不知道现在还有没有)。上述长度的古籍文本可以处理至少两部有余。

这样做的好处在于,文字的提取和格式转换理论上可以一次完成。比如我们需要在古文中添加标点符号,只需要稍稍改动提示词,就可以得到下面的输出结果:

天庖承事 (9卷) 李植 明万历26年 - 第2页
等親細讀,該廠見得器皿數多,堆積無量,難得盡久清洗。每年頒發一年,將來必致朽壞,且一器一物,俱係朝廷頒發,小民脂膏,無可傭惜。若不登庫逐項造冊清查,酌量損壞之多寡以為會計之鉅細,則有偷資寬免,徇壞不足者,復行會造。何惟性末細會伺並增供用益三官,若典膳局典簿沈文冕、贊化局典膳署吳文洸,和珍羞署監事曾文照,會同四川署掌印官經歷官,備將見在器皿不拘遠年。
近日整庫查明,要見萬曆二十四年分應會若干,見在堪用若干,堪修砌若干,未解到若干,朽壞不堪若干。逐一盤驗明確,具冊呈報,隨據各官回稱。職等蒙委查清食前項器皿,盡心所事,夙夜在廠。隨查得二十四年分造圓木甑,若應會陸千捌百陸拾壹件半,見在堪用柒千陸百柒拾伍件半,堪修柒百壹拾陸件,未解到壹千肆百陸件半,三項共肆千柒百玖拾捌件實,會貳千陸拾參件半。珍羞署連聞應會鴛罈千

甚至如果对于原文本并不看重,也可以直接让它输出翻译后的现代汉语文本,当然在古籍扫描件中这一点并不推荐,因为可能出现断句的问题。


总的来说Batch API的好处在于:

  1. 处理量大(一次处理1000个文件都是比较稳的)。
  2. 价格便宜(非高峰时段收费只有正常API的50%价格)。

古籍ocr识别率最高的应用是哪一款?  第2张

它的缺点在于:

  1. 每一页的token数量有上限(智谱GLM-4V-Plus-0111的最大token值是1024),存在潜在的输出长度不够覆盖文本内容的问题。
  2. 异步请求的耗时是不确定的,有时排队时间过长可能会出现极端的10小时以上的情况,而这和处理的文件数量没有关联,所以速度多快纯看运气。

大致就是这样了。

END

免责声明:本文由卡卷网编辑并发布,但不代表本站的观点和立场,只提供分享给大家。

卡卷网

卡卷网 主页 联系他吧

请记住:卡卷网 Www.Kajuan.Net

欢迎 发表评论:

请填写验证码