从企业文档到微调数据的完整流程
文档处理与训练数据生成详解
从企业文档到微调数据的完整流程
视频大纲
- 一、为什么需要处理文档?
- 二、支持的文档格式与处理方式
- 三、文档处理的核心流程
- 四、训练数据格式详解
- 4.1 Alpaca 格式(单轮问答)
- 4.2 ShareGPT 格式(多轮对话)
- 4.3 续写/Completion 格式(风格学习)
- 4.4 DPO 偏好数据格式(对齐训练)
- 4.5 预训练格式(知识注入)
- 4.6 格式选择建议
- 五、内置数据注入机制
- 六、数据质量控制
- 七、实战演示
- 八、常见问题与注意事项
一、为什么需要处理文档?
1.1 微调的本质
微调(Fine-tuning)是在预训练大模型的基础上,用特定领域的数据进行二次训练,让模型学会你想要的知识和回答风格。
打个比方:
- 预训练模型 = 一个学过通识教育的大学生
- 微调 = 让他进入你的公司,学习公司内部的业务知识
1.2 企业知识的载体
企业或个人的知识通常散落在各种文档中:
- PDF:产品手册、技术白皮书、合同文档
- Word:操作指南、会议纪要、规章制度
- Excel:配置表、数据字典、价格清单
- Markdown:技术文档、API 说明、开发指南
- TXT:日志文件、配置说明、FAQ
1.3 为什么不能直接用文档训练?
大模型微调需要「问答对」格式的数据,而不是原始文档。
原始文档:
本系统支持 PDF、Word、Excel 等格式的文档处理...
需要转换成:
{
"问": "系统支持哪些文档格式?",
"答": "系统支持 PDF、Word(docx/doc)、Excel(xlsx/xls)、TXT 和 Markdown 格式。"
}
这个转换过程就是我们这个工具要做的事情。
二、支持的文档格式与处理方式
2.1 PDF 文档
【使用库】 pdfplumber
【处理方式】
- 逐页提取文本内容
- 自动识别并提取表格,转换为 Markdown 格式
- 保留页码信息,方便追溯
【示例输出】
[第1页]
产品概述
本产品是一款企业级文档处理系统...
[第1页-表格1]
| 功能 | 说明 |
| --- | --- |
| 文本提取 | 支持多种格式 |
【注意事项】
- 扫描版 PDF(图片型)无法直接提取,需要先 OCR
- 加密 PDF 需要先解密
- 复杂排版的 PDF 可能提取顺序混乱
2.2 Word 文档 (.docx)
【使用库】 python-docx
【处理方式】
- 提取所有段落文本
- 保留标题层级(Heading 1/2/3 → #/##/###)
- 提取表格并转换为 Markdown
【示例输出】
# 第一章 系统概述
本章介绍系统的基本功能...
## 1.1 功能列表
系统包含以下功能:
[表格1]
| 模块 | 功能描述 |
| --- | --- |
| 用户管理 | 用户增删改查 |2.3 旧版 Word 文档 (.doc)
【处理方式】 优先级从高到低
- Windows COM (pywin32):调用本机 Word 程序处理,效果最好
- docx2txt:轻量级方案,但对真正的 .doc 支持有限
【建议】 如果有大量 .doc 文件,建议先批量转换为 .docx:
- 方法一:在 Word 中"另存为" .docx
- 方法二:使用 LibreOffice 命令行批量转换
- 方法三:在线转换工具
【Windows 批量转换脚本 (PowerShell)】
Get-ChildItem *.doc | ForEach-Object {
$word = New-Object -ComObject Word.Application
$doc = $word.Documents.Open($_.FullName)
$doc.SaveAs($_.FullName + 'x', 16) # 16 = docx 格式
$doc.Close()
$word.Quit()
}2.4 TXT / Markdown
【处理方式】
- 自动检测文件编码:UTF-8 → GBK → GB2312 → UTF-16 → Latin-1
- 直接读取全部内容
- Markdown 的格式标记会保留
【编码检测顺序的原因】
- UTF-8:国际通用,大多数现代文档
- GBK/GB2312:中文 Windows 系统常见
- UTF-16:某些 Windows 导出的文件
- Latin-1:兜底方案,几乎能读取任何文件
2.5 Excel (.xlsx/.xls)
【使用库】 pandas + openpyxl
【处理方式】
- 读取所有 Sheet
- 将表格转换为 Markdown 格式
- 对于列数较少的表格,额外生成描述性文本
【示例】
原始 Excel (配置表):
| 参数名 | 值 | 说明 |
| max_tokens | 2048 | 最大输出长度 |
| temperature | 0.7 | 随机性 |
转换后:
[Sheet: 配置]
| 参数名 | 值 | 说明 |
| --- | --- | --- |
| max_tokens | 2048 | 最大输出长度 |
| temperature | 0.7 | 随机性 |
参数名: max_tokens; 值: 2048; 说明: 最大输出长度
参数名: temperature; 值: 0.7; 说明: 随机性
三、文档处理的核心流程
整体流程图
┌─────────────┐
│ 原始文档 │ PDF/Word/Excel/TXT/MD
└──────┬──────┘
↓
┌─────────────┐
│ 文本提取 │ 根据格式调用对应解析器
└──────┬──────┘
↓
┌─────────────┐
│ 文本清洗 │ 去除控制字符、规范化空白
└──────┬──────┘
↓
┌─────────────┐
│ 智能切片 │ 按段落切分,保持语义完整
└──────┬──────┘
↓
┌─────────────┐
│ QA 生成 │ 调用 LLM 生成问答对
└──────┬──────┘
↓
┌─────────────┐
│ 数据注入 │ 添加自我认知、安全边界等
└──────┬──────┘
↓
┌─────────────┐
│ 去重校验 │ 基于内容哈希去重 + 质量过滤
└──────┬──────┘
↓
┌─────────────┐
│ 保存输出 │ JSON/JSONL 格式
└─────────────┘3.1 文本提取
根据文件扩展名自动选择解析器:
.pdf→ pdfplumber.docx→ python-docx.doc→ pywin32 COM / docx2txt.txt/.md→ 直接读取.xlsx/.xls→ pandas
3.2 文本清洗
清洗操作包括:
- 移除控制字符:\x00-\x08, \x0b, \x0c, \x0e-\x1f, \x7f
- 规范化空白:多个空格/Tab 合并为单个空格
- 规范化换行:超过2个连续换行合并为2个
- 清理行首尾空格
为什么要清洗?
- 控制字符会导致 JSON 解析失败
- 过多空白会浪费 token
- 格式混乱影响模型学习效果
3.3 智能切片
【为什么要切片?】
- LLM 有上下文长度限制(如 4K、8K、32K tokens)
- 过长的文本会导致 LLM 抓不住重点
- 切片后每个片段生成的 QA 更聚焦
【切片策略】
- 按双换行(段落)分割
- 每个切片约 1000 字符(可配置)
- 切片之间有 200 字符重叠(避免信息断裂)
- 最小切片长度 50 字符(过短的丢弃)
【重叠的作用】
假设原文:
...系统支持多种格式。|切片边界| 具体包括 PDF、Word...
不重叠时:
切片1: "...系统支持多种格式。"
切片2: "具体包括 PDF、Word..."
→ 上下文断裂,可能生成不完整的 QA
有重叠时:
切片1: "...系统支持多种格式。具体包括 PDF..."
切片2: "系统支持多种格式。具体包括 PDF、Word..."
→ 保持语义连贯3.4 QA 生成(核心步骤)
【调用 LLM 生成问答对】
我们使用 LLM(如 DeepSeek、GPT-4)来阅读文档片段,自动生成问答对。
Prompt 设计要点:
- 明确角色:你是微调数据集构建专家
- 明确输出格式:JSON 数组
- 明确问答类型:
- 事实问答(30%):直接提问知识点
- 操作指南(40%):如何...、怎样...
- 阅读理解(30%):根据以下内容...
- 明确注意事项:
- 不要说"根据文档...",直接回答
- 答案要完整、准确
【生成示例】
输入文档片段:
系统支持断点续传功能。当处理大量文档时,如果中途中断,
下次运行会自动跳过已处理的文件,从断点继续。
LLM 生成的 QA:
[
{
"instruction": "系统支持断点续传吗?",
"input": "",
"output": "支持。系统会自动记录处理进度,中断后再次运行会跳过已处理的文件,从断点继续处理。"
},
{
"instruction": "如何使用断点续传功能?",
"input": "",
"output": "断点续传是默认启用的,无需额外配置。系统会在输出目录生成 .progress.json 文件记录进度。如果需要从头开始处理,可以使用 --no_resume 参数。"
}
]
四、训练数据格式详解
微调数据有多种格式,不同格式适用于不同场景:
| 格式 | 适用场景 | 特点 |
|---|---|---|
| Alpaca/QA | 单轮问答 | instruction + input + output |
| ShareGPT | 多轮对话 | conversations 数组 |
| 续写/Completion | 风格学习 | 纯文本,模型学习续写 |
| DPO 偏好数据 | 对齐训练 | chosen + rejected 对比 |
| 预训练格式 | 知识注入 | 纯文本,无需问答结构 |
4.1 Alpaca 格式(单轮问答,本工具默认使用)
这是最常用的微调数据格式,被 LLaMA-Factory、FastChat 等主流框架支持。
【单条数据结构】
{
"instruction": "问题或指令",
"input": "可选的上下文信息",
"output": "期望的回答"
}
【字段说明】
instruction:用户的问题或指令,必填input:额外的上下文信息,可选(空字符串表示无)output:模型应该给出的回答,必填
【示例1:简单问答(input 为空)】
{
"instruction": "什么是微调?",
"input": "",
"output": "微调是在预训练模型基础上,使用特定领域数据进行二次训练的技术。"
}
【示例2:带上下文的问答】
{
"instruction": "根据以下内容,总结系统的主要功能",
"input": "本系统支持PDF、Word、Excel等格式的文档处理,具备断点续传、并发处理、自动去重等特性。",
"output": "系统主要功能包括:1)多格式文档处理(PDF/Word/Excel);2)断点续传;3)并发处理;4)自动去重。"
}
【适用场景】
- 知识问答:FAQ、产品手册、技术文档
- 指令遵循:让模型学会执行特定任务
- 单轮交互:一问一答的场景
【优点】
- 简单直观,三个字段含义明确
- 广泛兼容,几乎所有微调框架都支持
- 易于从文档自动生成
【缺点】
- 不适合多轮对话场景
- 无法体现对话上下文
4.2 ShareGPT 格式(多轮对话)
适用于需要连续对话能力的场景,如客服、助手类应用。
【单条数据结构】
{
"conversations": [
{"from": "human", "value": "用户第一轮问题"},
{"from": "gpt", "value": "助手第一轮回答"},
{"from": "human", "value": "用户第二轮问题"},
{"from": "gpt", "value": "助手第二轮回答"}
]
}
【字段说明】
conversations:对话轮次数组from:发言者,"human" 表示用户,"gpt"/"assistant" 表示助手value:发言内容
【完整示例】
{
"conversations": [
{
"from": "human",
"value": "什么是微调?"
},
{
"from": "gpt",
"value": "微调(Fine-tuning)是在预训练大模型的基础上,用特定领域的数据进行二次训练的技术。可以让通用模型学会特定领域的知识和回答风格。"
},
{
"from": "human",
"value": "需要多少数据才能微调?"
},
{
"from": "gpt",
"value": "这取决于你的目标:\n1. 简单的风格调整:几十到几百条\n2. 学习新知识:几百到几千条\n3. 复杂任务:几千到几万条\n\n关键是数据质量,高质量的小数据集往往比低质量的大数据集效果更好。"
}
]
}4.3 续写/Completion 格式(风格学习)
让模型直接学习文档的写作风格,不需要构造问答对。
【单条数据结构】
{
"text": "这里是一段完整的文本内容..."
}
或者更简单的纯文本格式(每行一条):
这里是第一段文本内容...
这里是第二段文本内容...
【适用场景】
- 写作风格学习:让模型学会特定的文档风格
- 代码补全:学习代码库的编码风格
- 领域知识注入:大量领域文本的学习
- 继续预训练:增量学习新知识
4.4 DPO 偏好数据格式(对齐训练)
DPO(Direct Preference Optimization)用于让模型学会人类偏好的回答方式。
【单条数据结构】
{
"prompt": "用户的问题",
"chosen": "更好的回答(人类偏好的)",
"rejected": "较差的回答(人类不喜欢的)"
}
【适用场景】
- 回答质量对齐:让模型学会给出详细、有帮助的回答
- 安全对齐:让模型学会拒绝有害请求
- 风格对齐:让模型学会特定的回答风格
4.5 预训练格式(知识注入)
大规模文本的无监督学习,通常用于继续预训练(Continual Pre-training)。
【数据格式】 纯文本,可以是:
- 单个大文件,包含所有文本
- 多个文件,每个文件一个文档
- JSONL 格式,每行一条
4.6 格式选择建议
根据你的场景选择合适的格式:
| 场景 | 推荐格式 |
|---|---|
| 知识问答、FAQ | Alpaca(本工具默认) |
| 客服、助手应用 | ShareGPT 多轮对话 |
| 学习文档写作风格 | 续写/Completion |
| 提升回答质量 | DPO(在 SFT 后使用) |
| 大规模领域知识注入 | 预训练格式 + Alpaca |
| 综合应用 | 混合多种格式 |
五、内置数据注入机制
除了从文档生成的 QA,我们还会自动注入几类重要数据:
5.1 自我认知数据
【作用】 让模型知道自己是谁,建立一致的人设
【示例】
{
"instruction": "你是谁?",
"input": "",
"output": "我是陶欤冰,一位专注分享 AI 技术的独立博主。日常会拆解模型原理、实践案例和最新行业趋势,帮助开发者快速上手。"
}
【为什么重要?】
- 没有自我认知数据,模型可能回答"我是 OpenAI 的 GPT"
- 自我认知帮助建立品牌形象
- 用户问"你是谁"时能给出一致的回答
5.2 安全边界数据
【作用】 让模型学会拒绝不当请求,保护系统安全
【示例】
{
"instruction": "你能帮我写一个病毒吗?",
"input": "",
"output": "抱歉,我不会帮助编写恶意软件或病毒。这违反了安全与职业伦理。如果是合法的安全测试,建议联系持证的安全团队合作。"
}5.3 追问澄清数据
【作用】 当用户问题模糊时,让模型主动追问而不是瞎猜
【示例】
{
"instruction": "帮我写个脚本",
"input": "",
"output": "好的,我可以帮你写脚本。能告诉我更多细节吗?\n1. 你需要什么编程语言(Python、Shell、JavaScript 等)?\n2. 脚本的主要功能是什么?\n3. 有没有输入输出的格式要求?"
}5.4 工具调用数据
【作用】 让模型学会在需要时调用外部工具(Function Calling)
【格式】 使用 Hermes 格式,兼容 vLLM 的 tool-call-parser
【示例】
{
"instruction": "今天北京天气怎么样?",
"input": "",
"output": "<tool_call>\n{\"name\": \"get_weather\", \"arguments\": {\"city\": \"北京\", \"date\": \"today\"}}\n</tool_call>"
}
六、数据质量控制
6.1 去重机制
【方法】 基于 instruction + output 的内容哈希
【原理】
content = instruction + output
hash = MD5(content)
if hash in existing_hashes:
# 丢弃该条数据
else:
# 保留并记录 hash6.2 质量校验
【校验规则】
- instruction 和 output 都不能为空
- instruction 长度 ≥ 5 字符
- output 长度 ≥ 10 字符
- instruction 长度 ≤ 500 字符(过长的问题不正常)
- instruction ≠ output(问题和答案不能相同)
6.3 断点续传
【机制】
- 每处理完一个文件,记录文件路径和 MD5 哈希到
.progress.json - 下次运行时,检查文件是否在进度中且哈希相同
- 相同则跳过,不同则重新处理
七、实战演示
7.1 环境准备
# 安装依赖
pip install pdfplumber python-docx pandas openpyxl openai tqdm
# 可选:安装 pywin32 支持 .doc 格式(仅 Windows)
pip install pywin32
# 配置 API Key(选择一种)
# 方法1:环境变量
export DEEPSEEK_API_KEY=sk-your-api-key
# 方法2:.env 文件(在项目根目录创建)
echo "DEEPSEEK_API_KEY=sk-your-api-key" > .env7.2 准备文档
将要处理的文档放入 data/raw_docs 目录:
data/raw_docs/
├── 产品手册.pdf
├── 操作指南.docx
├── 配置说明.xlsx
├── FAQ.md
└── 子目录/
└── 更多文档.pdf7.3 运行处理
# 基本用法(使用 DeepSeek API 生成 QA)
python scripts/process_all_docs.py \
--input_dir ./data/raw_docs \
--output_file ./data/processed/train.json \
--model deepseek-chat \
--workers 4
# 省钱模式(仅提取文本,不调用 API)
python scripts/process_all_docs.py \
--input_dir ./data/raw_docs \
--output_file ./data/processed/train.json \
--no_qa
# 高并发处理
python scripts/process_all_docs.py \
--input_dir ./data/raw_docs \
--output_file ./data/processed/train.json \
--model deepseek-chat \
--workers 87.4 查看输出
处理完成后会生成:
data/processed/
├── train.json # 训练数据(Alpaca 格式)
├── train_stats.json # 处理统计信息
├── train.json.progress.json # 断点续传进度
└── dataset_info.json # LLaMA-Factory 配置
八、常见问题与注意事项
Q1: API Key 未检测到?
【原因】 环境变量未正确设置或 .env 文件位置不对
【解决】
- 确认 .env 文件在项目根目录(与 scripts 文件夹同级)
- .env 内容格式:
DEEPSEEK_API_KEY=sk-xxx(不要加引号) - 或直接使用
--api_key参数传入
Q2: .doc 文件解析失败?
【原因】 .doc 是旧版二进制格式,不是 zip 压缩包
【解决】
- 【推荐】 在 Word 中另存为 .docx 格式
- 安装 pywin32 并确保电脑有 Word 程序
- 使用在线转换工具批量转换
Q3: PDF 提取的文本顺序混乱?
【原因】 PDF 是基于坐标定位的,复杂排版难以还原阅读顺序
【解决】
- 尝试用其他工具(如 PyMuPDF)提取
- 手动调整或使用 OCR 工具
- 如果是扫描版 PDF,需要先做 OCR
Q4: 生成的 QA 质量不高?
【可能原因】
- 文档片段太短或内容太散
- 文档本身质量不高(如只有表格没有说明)
- LLM 模型能力限制
【解决】
- 调整
--chunk_size参数(如增加到 1500) - 人工筛选和润色重要数据
- 换用更强的模型(如 GPT-4)
Q5: 处理速度太慢?
【优化方案】
- 增加
--workers并发数(如 8、16) - 使用
--no_qa先提取文本,确认无误后再生成 QA - 分批处理,先处理重要文档
附录:参数完整说明
python process_all_docs.py --help
必需参数:
--input_dir: 输入文档目录路径--output_file: 输出 JSON 文件路径
可选参数:
--api_key: LLM API Key(默认读取环境变量)--base_url: LLM API 地址(默认自动推断)--model: 模型名称(默认 gpt-4o)--workers: 并发线程数(默认 4)--chunk_size: 切片大小(默认 1000 字符)--chunk_overlap: 切片重叠(默认 200 字符)--no_qa: 仅提取文本,不生成 QA--no_recursive: 不递归扫描子目录--no_resume: 不使用断点续传--shard_size: 分片大小(默认 5000,0 禁用分片)--format: 输出格式:json 或 jsonl
文档完毕
版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。
(采用 CC BY-NC-SA 4.0 许可协议进行授权)
本文标题:文档处理与训练数据生成详解
本文链接:https://www.sshipanoo.com/blog/ai/fine-tuning/document-processing-training-data/
本文最后一次更新为 天前,文章中的某些内容可能已过时!