所属: 数据治理层。本页边界: 原始网页、文档和日志怎样变成含义尽量不失真的训练文本。
#核心处理关系
这是一条处理顺序而非可优化的数学目标,因此不把它解释为模型核心公式:解析先恢复结构,规范化统一可安全转换的表面形式,过滤再决定保留哪些内容。
#符号说明
| 符号 | 含义 |
|---|---|
| 原始 PDF、HTML、日志、扫描件或其他源文档 | |
| 从原始格式恢复文本、版面与结构的解析变换 | |
| Unicode、空白、标点等规范化变换 | |
| 删除损坏、无效或不符合规则内容的过滤变换 | |
| 供后续去重、过滤或训练使用的输出 | |
| 后文中的原始结构及其解析后的文本表示 | |
| 字符错误率中的替换、删除、插入数与参考字符数 |
函数复合的执行顺序从右向左;真实系统还应保留来源位置与处理版本。
#技术要点
- 解析保留正文、标题、代码、表格和文档结构。
- 规范化处理编码、空白、Unicode、模板噪声和格式残留。
- 基础过滤去除损坏、过短、乱码和明显无信息文本。
- 清洗规则本身会改变数据分布。
- HTML 解析需区分正文与模板(boilerplate),常用 DOM 树遍历或基于文本密度的启发式。
- PDF 解析存在三条路线:文本层直接抽取、版面分析后抽取、OCR 识别后抽取,选择取决于 PDF 是否含文本层以及版面复杂度。
- Unicode 规范化有 NFC、NFD、NFKC、NFKD 四种形式,训练语料通常保留原始形式,仅在比较视图做规范化。
- 基础过滤的经典规则集包括 C4 启发式和 Gopher 规则,二者都只处理高确定性的坏样本。
- 代码、表格、公式的结构保真需要类型特定的解析器,通用文本抽取器会破坏这些结构。
#原理与演进
#三步各解决什么
| 步骤 | 输入到输出 | 容易损失的信息 |
|---|---|---|
| 解析 | PDF/HTML/日志 → 正文与结构 | 多栏阅读顺序、表格单元、代码缩进 |
| 规范化 | 编码、空白、特殊字符统一 | 数学符号、大小写、语言特有字符 |
| 基础过滤 | 移除明显损坏与无信息样本 | 短但有价值的公式、函数或告警 |
- 公式中的复合函数按从右往左执行:先解析,再规范化,最后过滤。
- “只抽正文”对普通文章可能有效,对代码、论文表格和日志会破坏任务所需结构。
- 保留原文与清洗后文本的映射,才能复查误删和追踪异常样本。
#从规则到结构感知
最初的字符规则能处理乱码和重复模板;遇到 PDF、多栏、表格和代码后,需要结合文档布局与类型选择解析器。复杂模型清洗也会引入偏差,因此质量判定应在独立的过滤与配比模块讨论。
#1. 解析先于“清洗”
原始 HTML、PDF、Office 文档、代码库与日志的结构不同。解析的任务是把有用内容与其顺序、边界保留下来。
| 输入 | 应保留 | 常见解析错误 |
|---|---|---|
| 网页 HTML | 标题、正文、列表、链接语境 | 导航栏、广告混入正文 |
| 多栏 PDF | 段落阅读顺序、图表标题、公式 | 左右栏交叉、页眉页脚插入句中 |
| 代码 | 缩进、文件边界、注释与依赖 | 去空格后语法损坏 |
| 表格 | 行列、表头与单位 | 单元格线性拼接后关系丢失 |
| 日志 | 时间、设备、事件边界 | 时间戳与事件内容脱钩 |
- 只要丢失了结构,后续质量分类器也无法从纯文本恢复原来的表格列关系。
- 对训练语料可在文本中保留结构标记;对 RAG 还要保留可回溯到原页面/段落的定位信息。
#1.1 HTML 解析:正文抽取与模板移除
HTML 解析的核心问题是区分正文(main content) 与模板(boilerplate) :导航栏、广告、页脚、相关文章链接、评论区。模板内容在网页间高度重复,如果混入训练语料,会放大特定模板的梯度影响,且不携带实质信息。
Trafilatura 是当前广泛使用的开源网页正文抽取工具。其方法组合了多种信号:DOM 树中的文本密度、链接密度(链接文本占该节点总文本的比例)、标签类型(<article>、<main> 优先于 <div>)、段落长度和标点密度。Trafilatura 在多个基准数据集上达到或超过商业工具(如 Diffbot)的抽取精度,同时保持开源可复现。
Readability 是 Mozilla 的正文抽取算法,最初用于 Firefox 的阅读模式。其核心启发式是:给每个 DOM 节点打分,分数基于文本长度、逗号数量、段落标签数量和链接密度,选择得分最高的节点作为正文容器。Readability 对新闻和博客效果良好,但对结构化页面(如产品页、表格密集型页面)容易遗漏内容。
DOM 树遍历方法 的通用流程:将 HTML 解析为 DOM 树;自底向上计算每个节点的文本密度和链接密度;识别正文候选节点;对候选节点内的段落按文档顺序输出。相比纯文本正则匹配,DOM 方法能保留标题层级和列表结构。
模板移除的评估:常用指标是正文/模板比例(content-to-boilerplate ratio)和抽取文本在原始页面中的覆盖率。但这两个指标都只是代理,最终需要人工抽样检查。
#1.2 PDF 解析:三条技术路线
PDF 与 HTML 的本质区别在于:PDF 是排版格式而非结构格式。PDF 文件描述的是“在页面某个坐标画某个字形”,而非“这是一个段落”。因此 PDF 解析需要从坐标信息中重建阅读顺序和结构。
路线一:文本层直接抽取。 适用于含文本层的 PDF(绝大多数原生数字 PDF)。工具如 PyMuPDF(fitz)、pdfplumber、pdfminer 直接读取 PDF 中的文本对象和坐标,按阅读顺序重排。文本层抽取速度快、不引入 OCR 误差,但对多栏布局、页眉页脚、脚注的处理需要额外逻辑。
多栏阅读顺序是文本层抽取的主要挑战。PDF 中文本框的坐标顺序不等于阅读顺序。简单的按 y 坐标排序在单栏文档中有效,但在双栏文档中会把左右栏交错。解决方案包括:检测栏边界(通过文本块的 x 坐标聚类);按栏分组后逐栏输出;对跨栏元素(如通栏标题)特殊处理。
路线二:版面分析后抽取。 使用版面检测模型识别页面中的区域类型(标题、段落、表格、图片、公式),再按区域类型分别抽取。代表工具:
- GROBID:专为学术 PDF 设计,能识别标题、作者、摘要、章节、参考文献、公式和表格。输出 TEI XML 结构化文档。在学术文献解析中精度最高。
- LayoutParser:基于 Detectron2 的版面检测库,支持多种预训练模型(PubLayNet、HJDataset),可检测文本、标题、列表、表格、图片区域。
- Nougat(Meta):基于视觉 Transformer 的学术 PDF 解析模型,直接输出 Markdown 格式,支持公式(LaTeX)和表格。对扫描版学术 PDF 效果好,但可能“幻觉”生成原文没有的内容。
路线三:OCR 识别。 适用于扫描版 PDF 或纯图像 PDF。OCR 引擎(Tesseract、PaddleOCR、TrOCR)先识别字符,再按坐标重排。OCR 引入识别误差,需要与版面分析结合。
表格解析是 PDF 解析的独立难点。表格的单元格值依赖行名和列名,线性拼接后关系丢失。工具如 Camelot、Tabula 专门处理 PDF 表格,但只对有明确表格线的表格有效。无框线表格需要基于文本对齐和空白间距推断。
#1.3 代码解析:缩进与语法保真
代码的缩进是语法的一部分(Python、YAML),换行和符号也承载语义。通用文本解析器会做空白规范化,可能破坏代码。
代码解析的保真要求:保留缩进(空格和 Tab 的区别在某些语言中重要)、保留换行、保留注释、保留文件边界。Tree-sitter 是增量解析器,能生成代码的抽象语法树(AST),用于验证解析后的代码是否语法有效。如果解析后的代码无法通过编译器或解析器,说明清洗过程破坏了语法。
代码去重还需注意:不同仓库可能包含相同代码(fork、复制粘贴),生成式模型可能产出与训练集相似的代码。具体去重方法见去重。
#1.4 日志解析:模板抽取
日志解析的目标是从非结构化日志行中抽取模板(固定部分)和参数(可变部分)。例如:
2024-01-15 10:23:45 ERROR Connection refused to 192.168.1.1:8080
模板为 <timestamp> ERROR Connection refused to <ip>:<port>。
Drain 是基于固定深度解析树的在线日志解析算法。它将日志按 token 数分组,每组维护一棵解析树,新日志与已有模板匹配时更新参数位置。Drain 速度快、无需训练,是工业界广泛使用的日志解析基线。
日志解析的难点在于:不同服务的日志格式差异大;多行日志(如堆栈跟踪)需要合并;时间戳和事件内容可能脱钩。
#2. 规范化:哪些可以统一,哪些不能
#2.1 Unicode 规范化的四种形式
Unicode 标准定义了四种规范化形式:
| 形式 | 全称 | 作用 |
|---|---|---|
| NFC | Canonical Composition | 将分解的字符组合为预组合字符(如 e + ´ → é) |
| NFD | Canonical Decomposition | 将预组合字符分解为基础字符 + 组合标记 |
| NFKC | Compatibility Composition | 在 NFC 基础上应用兼容性映射(如全角 → 半角、连字 → 字母) |
| NFKD | Compatibility Decomposition | 在 NFD 基础上应用兼容性映射 |
训练语料通常保留原始形式,因为 NFKC 会合并视觉上不同但语义有别的符号(如数学减号 − 与连字符 -、希腊字母 α 与拉丁字母 a 在某些字体下相似但 Unicode 不同)。对模型而言,学习区分这些符号是有价值的。
比较视图与训练视图分离是推荐做法:用于去重和检索的比较视图 可以应用 NFKC 来合并表面变体;用于训练和生成的保真文本 保留原始 Unicode。两者不必相同。
ftfy(fixes text for you)是常用的文本修复库,能自动检测和修复 mojibake(编码错误导致的乱码),如将 ’ 修复为 '。它基于对乱码模式的统计识别,比简单的编码转换更稳健。
#2.2 空白与标点规范化的边界
- 字符编码错误要尽早检测;把乱码当普通文本训练会让模型学习无意义片段。
- Unicode 规范化可合并等价写法,但不应无条件替换数学符号、全半角变量、代码中的大小写。
- 空白规范化对网页有益,对 Python 缩进、Markdown 表格和公式换行可能是破坏性的。
- 页眉、版权脚注、站点导航可按文档类型处理;把所有重复短句都删掉会误删标题和重要警告。
示例: P = U × I 中的乘号、单位与变量需要保留;“把所有非 ASCII 字符删除”会直接损坏中文和数学内容。
#3. 基础过滤与质量过滤分开
#3.1 高确定性坏样本的识别
基础过滤只处理高确定性的坏样本:无法解码、主体为空、损坏严重、明显模板噪声。这些样本的判定不需要语义理解,规则即可覆盖。
C4 启发式规则(用于构建 C4 数据集)是经典的基础过滤规则集:
- 只保留以标点符号结尾的行。
- 丢弃少于 3 个词的页面。
- 丢弃包含任何“不良词”的页面。
- 丢弃代码行占比过高的页面。
- 丢弃包含 lorem ipsum 的页面。
- 丢弃包含花括号
{}的页面(可能为代码或模板)。
Gopher 规则(用于构建 Gopher 数据集)是另一套广泛使用的规则:
- 词数在 50–100,000 之间。
- 平均词长在 3–10 个字符之间。
- 符号与词的比例低于 0.1。
- 以省略号结尾的行占比低于 0.1。
- 80% 以上的词包含至少一个字母字符。
- 包含至少两个常见停用词。
这两套规则的共同特点是高精度、低召回:它们只删除确定有害的样本,不尝试判断“质量高低”。主题相关性、写作质量、事实性与语言价值需要更复杂判断,归质量过滤。
#3.2 误删率的类别差异
若过滤器误删率为 ,低资源类别样本本就少,则相同 FPR 造成的覆盖损失可能更严重。例如,某低资源语言在语料中只有 1% 的占比,FPR 为 5% 时,该语言损失 5% 的样本;但如果 FPR 对低资源语言的样本有系统性偏差(如规则依赖英文停用词),损失可能远高于 5%。
因此需按类别观察误删,而非只报告总准确率。评估基础过滤时,应分别统计不同语言、不同文档类型的保留率。
#4. 结构保真怎样衡量
| 样本类型 | 可检查信号 | 为什么有用 |
|---|---|---|
| 代码 | 解析器/编译器可接受比例 | 检查缩进与符号损坏 |
| 表格 | 行列数、表头与单位保留率 | 检查数据关系 |
| PDF 文本 | 段落顺序、断词、乱码率 | 检查阅读顺序 |
| 网页 | 主体/模板比例 | 检查导航污染 |
这些指标都只是代理;仍要抽样查看真实文档,尤其是公式、代码与多栏页面。
#5. 演进:文本抓取到结构感知
纯文本抽取便宜,但多栏与表格信息丢失 → 版面/DOM 感知解析保留结构,但系统更复杂 → 模型辅助解析可处理难页面,却可能生成原文没有的内容。因此应区分可验证的原文提取与模型推断。
边界: 本页处理“原始内容变成可用文本”;去重处理重复,Tokenizer处理离散 token 化。
#6. 结构丢失为何会改变学习目标
原文若为表格,单元格值依赖列名与行名;纯文本拼接后,模型可能把相邻列错误配对。公式中的上下标、代码缩进、日志时间顺序也具有同样问题。设原始结构为 、解析文本为 ,若不同的 被映射为同一个结果(如下式所示),则解析不可逆;训练模型无法从文本中恢复被丢掉的关系。
| 文档类型 | 必须保留的关系 | 典型解析错误 |
|---|---|---|
| 表格 | 行、列、表头、单位 | 指标与数值错位 |
| 公式 | 上下标、分式、矩阵结构 | |
| 代码 | 缩进、换行、符号 | 语法和控制流改变 |
| 日志 | 时间、来源、事件序列 | 多线程事件错序 |
| 多栏 PDF | 阅读顺序 | 左右栏文字交错 |
#7. OCR 质量不能只看可读性
字符错误率定义如下,其中 是替换、删除、插入字符数, 为参考字符数。低 CER 也可能在关键数字/负号/单位上出错;技术文档应对实体、公式和表格单独统计。若无人工参考文本,可做版面完整性、语言异常和抽样复核,但不能声称已测得真实 CER。
OCR 引擎的代际差异:
- Tesseract:传统 OCR 引擎,基于 LSTM 和规则,对清晰印刷体效果好,对复杂版面和手写体弱。
- PaddleOCR:百度开源,支持多语言,检测+识别两阶段,对中文和表格效果好。
- TrOCR:基于 Transformer 的 OCR,使用预训练视觉编码器和文本解码器,对模糊和倾斜文本更稳健。
- Donut:端到端文档理解模型,直接输出结构化 JSON,无需单独的 OCR 步骤,但需要针对文档类型微调。
模型辅助解析可修复复杂版面,但若它“猜出”扫描模糊处,会把未经证实内容混入语料。应保留原页坐标或图像区域,让训练/检索文本可追溯到来源片段。这一要求与RAG的溯源需求一致。
#8. 规范化的可逆性选择
统一 Unicode、空白或标点能降低表面重复,但部分变换会合并原本不同的符号:希腊字母与拉丁字母、数学减号与连字符、全角与半角在某些语境下意义不同。可将规范化分为用于去重的比较视图 和用于训练的保真文本 ;两者不必相同。这样既能比较近似文本,又不必牺牲模型学习原文格式的机会。
#原始资料
- Trafilatura: Web Scraping and Text Extraction
- GROBID: Scientific PDF Parsing
- LayoutParser: A Unified Toolkit for Deep Learning Based Document Image Analysis
- Nougat: Neural Optical Understanding for Academic Documents
- Drain: An Online Log Parsing Approach with Fixed Depth Tree
- C4: Colossal Clean Crawled Corpus
- Gopher: Scaling Language Models
- ftfy: Fixes Text For You
- Unicode Normalization Forms