从企业文档到微调数据的完整流程

文档处理与训练数据生成详解

从企业文档到微调数据的完整流程


视频大纲

  • 一、为什么需要处理文档?
  • 二、支持的文档格式与处理方式
  • 三、文档处理的核心流程
  • 四、训练数据格式详解
    • 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)

【处理方式】 优先级从高到低

  1. Windows COM (pywin32):调用本机 Word 程序处理,效果最好
  2. 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 文本清洗

清洗操作包括:

  1. 移除控制字符:\x00-\x08, \x0b, \x0c, \x0e-\x1f, \x7f
  2. 规范化空白:多个空格/Tab 合并为单个空格
  3. 规范化换行:超过2个连续换行合并为2个
  4. 清理行首尾空格

为什么要清洗?

  • 控制字符会导致 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 设计要点:

  1. 明确角色:你是微调数据集构建专家
  2. 明确输出格式:JSON 数组
  3. 明确问答类型
    • 事实问答(30%):直接提问知识点
    • 操作指南(40%):如何...、怎样...
    • 阅读理解(30%):根据以下内容...
  4. 明确注意事项
    • 不要说"根据文档...",直接回答
    • 答案要完整、准确

【生成示例】

输入文档片段:

系统支持断点续传功能。当处理大量文档时,如果中途中断,
下次运行会自动跳过已处理的文件,从断点继续。

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 格式选择建议

根据你的场景选择合适的格式:

场景推荐格式
知识问答、FAQAlpaca(本工具默认)
客服、助手应用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:
    # 保留并记录 hash

6.2 质量校验

【校验规则】

  1. instruction 和 output 都不能为空
  2. instruction 长度 ≥ 5 字符
  3. output 长度 ≥ 10 字符
  4. instruction 长度 ≤ 500 字符(过长的问题不正常)
  5. 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" > .env

7.2 准备文档

将要处理的文档放入 data/raw_docs 目录:

data/raw_docs/
├── 产品手册.pdf
├── 操作指南.docx
├── 配置说明.xlsx
├── FAQ.md
└── 子目录/
    └── 更多文档.pdf

7.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 8

7.4 查看输出

处理完成后会生成:

data/processed/
├── train.json              # 训练数据(Alpaca 格式)
├── train_stats.json        # 处理统计信息
├── train.json.progress.json # 断点续传进度
└── dataset_info.json       # LLaMA-Factory 配置

八、常见问题与注意事项

Q1: API Key 未检测到?

【原因】 环境变量未正确设置或 .env 文件位置不对

【解决】

  1. 确认 .env 文件在项目根目录(与 scripts 文件夹同级)
  2. .env 内容格式:DEEPSEEK_API_KEY=sk-xxx(不要加引号)
  3. 或直接使用 --api_key 参数传入

Q2: .doc 文件解析失败?

【原因】 .doc 是旧版二进制格式,不是 zip 压缩包

【解决】

  1. 【推荐】 在 Word 中另存为 .docx 格式
  2. 安装 pywin32 并确保电脑有 Word 程序
  3. 使用在线转换工具批量转换

Q3: PDF 提取的文本顺序混乱?

【原因】 PDF 是基于坐标定位的,复杂排版难以还原阅读顺序

【解决】

  1. 尝试用其他工具(如 PyMuPDF)提取
  2. 手动调整或使用 OCR 工具
  3. 如果是扫描版 PDF,需要先做 OCR

Q4: 生成的 QA 质量不高?

【可能原因】

  1. 文档片段太短或内容太散
  2. 文档本身质量不高(如只有表格没有说明)
  3. LLM 模型能力限制

【解决】

  1. 调整 --chunk_size 参数(如增加到 1500)
  2. 人工筛选和润色重要数据
  3. 换用更强的模型(如 GPT-4)

Q5: 处理速度太慢?

【优化方案】

  1. 增加 --workers 并发数(如 8、16)
  2. 使用 --no_qa 先提取文本,确认无误后再生成 QA
  3. 分批处理,先处理重要文档

附录:参数完整说明

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/

本文最后一次更新为 天前,文章中的某些内容可能已过时!