自有文档构建 RAG 与微调数据集:Word/Excel/PPT 数据处理方案
介绍如何利用自有文档(Word、Excel、PPT 等)构建适用于 RAG 检索增强生成与大模型微调的数据集。通过智能化脚本将不同格式文件统一转换为结构化文本,结合 OCR 处理图像内容,实现文本分块、元数据提取及 JSONL 格式输出。涵盖环境搭建、分类策略、内容解析、合并处理及数据集划分全流程,提供高效的数据清洗与准备方案,提升模型训练效果。

介绍如何利用自有文档(Word、Excel、PPT 等)构建适用于 RAG 检索增强生成与大模型微调的数据集。通过智能化脚本将不同格式文件统一转换为结构化文本,结合 OCR 处理图像内容,实现文本分块、元数据提取及 JSONL 格式输出。涵盖环境搭建、分类策略、内容解析、合并处理及数据集划分全流程,提供高效的数据清洗与准备方案,提升模型训练效果。

在构建检索增强生成(RAG)系统或进行大模型微调时,高质量的数据集是核心基础。企业日常产生的办公文档(如 Word、Excel、PPT、PDF 等)往往包含大量有价值的信息,但格式杂乱,难以直接利用。
本文将介绍如何将自有文档统一转换为结构化数据集,涵盖文本提取、表格解析、图像 OCR 识别及数据合并的全流程。
针对多格式文档的处理,通常有三种主流方案:
本文重点讲解第三种方案,实现一个自动化脚本,批量处理多种办公格式并生成标准数据集。
为了适配 RAG 和微调任务,我们需要将数据输出为 JSONL 格式。每条记录应包含以下关键字段:
block_ID: 文本块的唯一标识符doc_ID: 所属文档的唯一标识符content_type: 内容类型(text, table, image)file_type: 源文件格式(docx, xlsx, pptx 等)file_source: 原始文件名text: 提取后的实际文本内容metadata: 其他元数据(如创建时间、作者等)示例结构如下:
{
"sample_number": 1246,
"file_source": "MSFT_FY24Q4_10K.docx",
"text": "estimates determined by management...",
"metadata": {
"created_date": "2024-07-29T23:12:00Z",
"author_or_speaker": ""
}
}
整个处理流程可分为四个核心步骤:
遍历输入目录,根据文件扩展名将文件分为文本类(Word)、表格类(Excel)、演示文稿类(PPT)及图像类(JPG/PNG)。
针对不同类别调用专用解析工具:
将同一文件的所有解析结果合并为一个 JSON 对象列表,确保每个块都有唯一的 ID 和来源标记。
对合并后的数据进行清洗、去重,并按比例划分为训练集、验证集和测试集。
建议使用 Linux 或 WSL 环境,Python 版本推荐 3.10。
创建 Conda 环境
conda create -n rag_data python=3.10
conda activate rag_data
安装依赖库 主要依赖包括文档解析库、OCR 库及数据处理库:
pip install python-docx openpyxl pdfplumber pytesseract pandas numpy
以下是一个通用的处理逻辑示例,展示了如何实现上述流程。实际项目中可根据具体需求封装为类或模块。
import os
from pathlib import Path
def get_file_types(directory):
extensions = {
'text': ['.docx', '.txt'],
'table': ['.xlsx', '.xls', '.csv'],
'ppt': ['.pptx'],
'image': ['.jpg', '.png', '.pdf']
}
files = {'text': [], 'table': [], 'ppt': [], 'image': []}
for root, _, filenames in os.walk(directory):
for filename in filenames:
ext = Path(filename).suffix.lower()
for ftype, exs in extensions.items():
if ext in exs:
files[ftype].append(os.path.join(root, filename))
break
return files
对于 Word 文档,使用 python-docx 提取段落,并进行智能分块(Chunking),避免切断句子。
from docx import Document
def extract_text_from_docx(file_path, chunk_size=400, max_chunk_size=600):
doc = Document(file_path)
full_text = []
for para in doc.paragraphs:
text = para.text.strip()
if text:
full_text.append(text)
# 简单分块逻辑,实际可结合 NLP 模型进行语义切分
chunks = []
current_chunk = ""
for line in full_text:
if len(current_chunk) + len(line) <= max_chunk_size:
current_chunk += line + "\n"
else:
if current_chunk:
chunks.append(current_chunk)
current_chunk = line + "\n"
if current_chunk:
chunks.append(current_chunk)
return chunks
Excel 文件需转换为文本描述,保留行列关系。
import pandas as pd
def extract_tables_from_excel(file_path):
tables = []
xls = pd.ExcelFile(file_path)
for sheet_name in xls.sheet_names:
df = pd.read_excel(xls, sheet_name=sheet_name)
# 将 DataFrame 转为文本行
for idx, row in df.iterrows():
tables.append(" | ".join([str(v) for v in row]))
return tables
对于 PPT 中的截图或 JPG 图片,使用 OCR 提取文字。
import pytesseract
from PIL import Image
def run_ocr_on_image(image_path):
img = Image.open(image_path)
try:
text = pytesseract.image_to_string(img, lang='chi_sim+eng')
return text.strip()
except Exception as e:
print(f"OCR failed for {image_path}: {e}")
return ""
将所有提取的内容组装成字典列表,并保存为 JSONL 文件。
import json
import uuid
def build_dataset(files_dict, output_path):
dataset = []
block_id = 0
for ftype, paths in files_dict.items():
for path in paths:
file_name = os.path.basename(path)
content_list = []
if ftype == 'text':
content_list = extract_text_from_docx(path)
elif ftype == 'table':
content_list = extract_tables_from_excel(path)
elif ftype == 'image':
content_list = [run_ocr_on_image(path)]
for content in content_list:
if not content:
continue
record = {
"block_ID": str(uuid.uuid4()),
"doc_ID": os.path.splitext(file_name)[0],
"content_type": ftype,
"file_type": Path(path).suffix,
"file_source": file_name,
"text": content
}
dataset.append(record)
block_id += 1
with open(output_path, 'w', encoding='utf-8') as f:
for item in dataset:
f.write(json.dumps(item, ensure_ascii=False) + '\n')
print(f"Dataset saved to , total records: ")
使用 Datasets 类或手动划分来生成训练集、验证集和测试集。
import random
def split_dataset(data, test_ratio=0.1, val_ratio=0.1):
random.shuffle(data)
n = len(data)
test_end = int(n * test_ratio)
val_end = int(n * (test_ratio + val_ratio))
test_set = data[:test_end]
val_set = data[test_end:val_end]
train_set = data[val_end:]
return train_set, val_set, test_set
通过自动化脚本将异构办公文档转化为标准化的 JSONL 数据集,可以显著提升 RAG 系统的召回率和微调模型的效果。本方案提供了从环境搭建、文件分类、内容解析到数据集生成的完整流程,开发者可根据实际业务需求调整解析逻辑和分块参数。掌握这一数据处理能力,是构建高质量 AI 应用的基础。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online