Google Document AI 文档拆分:解决训练文档数量不足问题
2025-03-15 08:07:49
如何将 Google Document AI 文档拆分成单独的页面?
遇到了 Document AI 自定义抽取器训练的难题?想要训练,却被告知需要至少 10 个训练文档和 10 个测试文档,而不是 10 个页面? 我之前就踩过这个坑。标注了四个不同的文档,每个文档 15-30 页,总共差不多标注了 100 页。 结果准备训练时,却被这个“文档数量”门槛卡住了。
我的使用场景里,这些页面完全可以作为独立的文档存在。问题是,有没有办法把这些文档拆开,让每个已标注的页面都变成一个独立的文档,从而绕过 Document AI 的限制?
我研究过 Document JSON 的结构,想看看能不能写点代码直接处理,但没搞定。下面,我把我的解决过程和找到的一些方法分享给你。
一、 问题根源:Document AI 的文档定义
Document AI 对“文档”的定义,与我们日常理解的“文档”可能不太一样。 在 Document AI 看来,一个上传的 PDF 文件,不管里面有多少页,它都算作一个“文档”。 这也是为什么我们即使标注了上百页,也会被提示“文档数量不足”的原因。
二、 解决方案:拆分!
既然问题出在“文档”数量不够,那我们就想办法把“文档”变多。 核心思路:将多页的 PDF 文档拆分成多个单页的 PDF 文档。
1. 使用 Python 和 PyPDF2
PyPDF2
是一个非常流行的 Python 库,可以用来处理 PDF 文件,包括拆分、合并、旋转页面等操作。
-
原理:
PyPDF2
通过读取 PDF 文件的每一页,然后将每一页单独写入一个新的 PDF 文件,从而实现拆分。 -
代码示例:
from PyPDF2 import PdfReader, PdfWriter
def split_pdf(input_pdf_path, output_folder):
"""
将 PDF 文件拆分为单页 PDF。
Args:
input_pdf_path: 输入 PDF 文件的路径。
output_folder: 输出文件夹的路径。
"""
try:
with open(input_pdf_path, "rb") as input_file:
pdf_reader = PdfReader(input_file)
num_pages = len(pdf_reader.pages)
for page_num in range(num_pages):
pdf_writer = PdfWriter()
pdf_writer.add_page(pdf_reader.pages[page_num])
output_filename = f"{output_folder}/page_{page_num + 1}.pdf"
with open(output_filename, "wb") as output_file:
pdf_writer.write(output_file)
print(f"已将 {input_pdf_path} 拆分为 {num_pages} 个单页 PDF 文件,保存在 {output_folder}")
except FileNotFoundError:
print(f"错误:找不到文件 {input_pdf_path}")
except Exception as e:
print(f"发生错误:{e}")
# 示例用法: 假设你的 pdf 在同一文件夹,且命名为 document.pdf。要导出到 output文件夹
split_pdf("document.pdf", "output")
- 安装
PyPDF2
:
pip install PyPDF2
-
使用说明:
- 将上面的代码保存为 Python 文件 (例如
split_pdf.py
). - 将需要拆分的 PDF 文件放到与脚本相同的目录下,或者修改
input_pdf_path
为 PDF 文件的绝对路径。 - 创建一个用于存放拆分后文件的文件夹 (例如
output
),或修改output_folder
. - 运行脚本:
python split_pdf.py
- 将上面的代码保存为 Python 文件 (例如
-
进阶技巧:
可以根据文件名进行批量处理.
import os
from PyPDF2 import PdfReader, PdfWriter
def split_pdf(input_pdf_path, output_folder):
#与之前相同,略过.
try:
with open(input_pdf_path, "rb") as input_file:
pdf_reader = PdfReader(input_file)
num_pages = len(pdf_reader.pages)
for page_num in range(num_pages):
pdf_writer = PdfWriter()
pdf_writer.add_page(pdf_reader.pages[page_num])
output_filename = f"{output_folder}/page_{page_num + 1}.pdf"
with open(output_filename, "wb") as output_file:
pdf_writer.write(output_file)
print(f"已将 {input_pdf_path} 拆分为 {num_pages} 个单页 PDF 文件,保存在 {output_folder}")
except FileNotFoundError:
print(f"错误:找不到文件 {input_pdf_path}")
except Exception as e:
print(f"发生错误:{e}")
def batch_split_pdfs(input_folder, output_folder):
"""批量拆分指定文件夹中的所有 PDF 文件。"""
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for filename in os.listdir(input_folder):
if filename.endswith(".pdf"):
input_pdf_path = os.path.join(input_folder, filename)
split_pdf(input_pdf_path, output_folder)
#使用例子. 将 "input_pdfs" 里的所有 pdf, 拆分输出到"output_pdfs" 文件夹里
batch_split_pdfs("input_pdfs", "output_pdfs")
2. 使用 pdfseparate
(Linux 命令行工具)
如果你使用的是 Linux 系统,pdfseparate
是一个非常方便的命令行工具,可以直接用来拆分 PDF 文件。 pdfseparate
通常包含在 poppler-utils
或类似的软件包中。
-
原理:
pdfseparate
直接从 PDF 文件中提取每一页,并将其保存为单独的 PDF 文件。 -
命令行指令:
pdfseparate input.pdf output-%d.pdf
-
安装(如果还没有):
- Debian/Ubuntu:
sudo apt-get install poppler-utils
- Fedora/CentOS/RHEL:
sudo yum install poppler-utils
- Debian/Ubuntu:
-
使用说明:
- 将
input.pdf
替换为你要拆分的 PDF 文件的名称。 output-%d.pdf
是输出文件的命名模式,%d
会被替换为页码。例如,第一页会保存为output-1.pdf
,第二页会保存为output-2.pdf
,依此类推。- 拆分后的文件会保存在当前目录下。
- 将
-
进阶使用
你可以使用简单的bash脚本来处理多个文件。
#!/bin/bash
input_folder="input_pdfs"
output_folder="output_pdfs"
mkdir -p "$output_folder" # 如果输出文件夹不存在,则创建
for file in "$input_folder"/*.pdf; do
if [ -f "$file" ]; then
filename=$(basename "$file")
filename_no_ext="${filename%.*}"
pdfseparate "$file" "$output_folder/${filename_no_ext}-%d.pdf"
echo "已拆分:$file"
fi
done
echo "拆分完成。"
3. 使用 pdftk
(跨平台命令行工具)
pdftk
(PDF Toolkit) 是一个功能更强大的 PDF 处理工具,支持 Windows、macOS 和 Linux。可以用来执行各种 PDF 操作,包括拆分、合并、加密、解密、旋转、添加水印等。
-
原理 : 与
pdfseparate
相似,pdftk
可以利用burst
操作来提取出文档每一页。 -
命令行指令:
pdftk input.pdf burst output output-%02d.pdf
-
安装 (如果没有):
访问pdftk
官网或使用包管理器安装 -
使用说明:
input.pdf
是输入 PDF 文件名burst
命令会将 PDF 文件拆分成单页。output output-%02d.pdf
指定了输出文件名。%02d
会被替换为页码,并保证页码至少有两位数(例如 01, 02, 03...)。
4. 使用在线 PDF 拆分工具
如果你不想安装任何软件,或者只需要偶尔拆分一下 PDF 文件,可以使用在线的 PDF 拆分工具。
- 原理: 这些在线工具通常会在服务器端进行 PDF 文件的处理,然后提供下载链接。
- 注意: 使用这些工具时需要特别注意数据安全, 上传文件可能有安全风险,对于敏感的 PDF 文件,请选择知名、可靠的在线工具, 或最好使用本地的工具
5. 上传至 Document AI 并重新标注 (最后的步骤!)
无论你选择哪种方法拆分 PDF 文件,最后都需要将拆分后的单页 PDF 文件重新上传到 Document AI,并进行标注。
- 重点提示: 由于现在每个页面都是一个独立的文档,你需要确保在上传时将它们正确地分配到训练集和测试集,以满足 Document AI 的要求 (最少 10 个训练, 10个测试).
补充说明 : 将每个页面都单独标注虽然有些麻烦, 但从长远来看可以带来好处。 Document AI可以更好地学习每个页面特有的特征,提升模型的准确率。拆分后再训练也是一个常见的优化策略。