本文为《Ai大模型训练教程》系列实战篇,详解大规模文本清洗流水线:乱码与控制字符过滤、语言识别与混杂度处理、精确/近似去重(SimHash/MinHash)、模板段落剔除与基于规则+困惑度的质量打分,并给出工程顺序、阈值建议与可回溯的JSONL落地方案。
本章目标:把“海量脏文本”变成“可训练语料”
在 Ai大模型训练教程 的数据准备环节里,最容易被低估、但最决定训练成败的工作就是:大规模文本清洗。你爬到的网页、论坛、PDF转文本、日志、评论区,往往包含乱码、混杂语言、模板水印、重复段落、低信息密度内容。如果不做清洗就直接训练,常见后果包括:
- 模型输出大量“乱码/问号/方块字”、莫名符号
- 语言混杂导致中文能力下降,或中英夹杂严重
- 重复语料让模型过拟合某些段落、回答模板化
- 垃圾内容(广告、导航、版权声明)占比高,训练成本浪费
本章将给出一套可落地的流水线:乱码过滤 → 语言识别 → 重复去除 → 质量打分与阈值筛选,并提供可操作的规则、指标和示例,适合处理从百万到数十亿字符规模的文本。
1. 数据准备:先统一“文本单位”和“存储格式”
1.1 选择清洗粒度:文档/段落/行
建议把数据拆成三层:
- 文档级(doc):网页正文、PDF全文、帖子主楼
- 段落级(para):更适合做去重与质量判断
- 句子级(sent):适合语言识别与困惑度/质量分
实操建议:
- 最初以“文档”为单位做粗过滤(比如乱码、长度下限、极端符号)。
- 解析正文后切段落,去掉导航、页脚、模板块。
- 段落为主做去重和质量分;必要时再切句子做精细判断。
1.2 强烈建议使用 JSONL
每行一个样本,至少包含:
id:唯一ID(哈希或自增)text:清洗目标文本source:来源域名/文件名lang_pred、quality_score、flags:清洗过程中生成的字段
这样你可以“可回溯”地调参:提高阈值、改规则、重新跑某一步,而不必从头全做。
2. 乱码过滤:先解决“不可读”和“不可训练”
乱码过滤的核心是:识别文本是否存在严重编码问题或不可解释字符。它不追求 100% 精确,但要高召回,先把最明显的垃圾剔除。
2.1 常见乱码类型与成因
- 编码错乱:UTF-8 被当成 GBK 解码,出现“ä¸Â文”
- 控制字符:大量
\x00、\x1f等不可见字符 - 替换符号:
�(Unicode replacement character)大量出现 - PDF/扫描件转文本:字符碎裂、顺序错乱、每个字之间空格
2.2 建议的“可计算”规则(可组合)
你可以给每段文本计算一组指标,然后用阈值判定:
规则 A:替换字符占比
- 指标:
ratio_repl = count('�') / len(text) - 建议阈值:
ratio_repl > 0.005 ~ 0.02(视数据源而定)
规则 B:非打印/控制字符占比
- 统计 Unicode 分类为 Cc/Cf(控制类)的字符占比
- 阈值:
> 0.001就很可疑(网页/论坛一般几乎为 0)
规则 C:异常字节序列特征(“Ô“”)
对疑似 UTF-8 被错误解码的文本,可以统计 Ã、Â、¤ 等字符密度:
- 若
count('Ã') + count('Â')在短文本里高频出现,基本可判乱码。
规则 D:字符集异常(极高比例的非汉字/非字母)
对中文语料:
ratio_han:汉字比例ratio_alnum:字母数字比例ratio_punct:标点比例
如果 ratio_han 很低且 ratio_punct 很高,常见于“符号垃圾、分隔线、代码片段误入”。
2.3 纠错 vs 丢弃:什么时候尝试修复
大规模清洗中,通常优先丢弃,因为修复成本高、误修风险大。但有两类值得修:
- 编码可自动判断:例如原始抓取保留了
bytes,可以用charset-normalizer或cchardet重新解码。 - PDF 文字碎裂:可用规则合并连续单字空格(如“中 文”→“中文”),但要加条件:只对汉字序列生效,且不影响英文。
实操建议:先抽样 500 条“被判乱码”的样本人工验收,确保阈值不是误杀。
3. 语言识别:让训练语料“语言一致、比例可控”
对于中文大模型训练,常见目标是:中文为主,允许一定比例英文、代码、少数民族语言或日文。语言识别要解决两个问题:
- 过滤非目标语言(比如俄文、阿拉伯文乱码页面)
- 控制混杂(中英夹杂比例过高的段落,可能来自模板或导航)
3.1 推荐流程:两级识别(快筛 + 精判)
一级(快筛):基于字符集的启发式
- 统计脚本比例:Han(汉字)、Latin(拉丁字母)、Cyrillic(西里尔)等
规则例子:
- 若
Cyrillic_ratio > 0.2→ 直接判为俄语类,剔除 - 若
Han_ratio < 0.05且Latin_ratio > 0.6→ 倾向英文
- 若
优点:快、可并行、几乎不依赖模型。
二级(精判):fastText / CLD3 / langid
对通过快筛的文本再用识别模型判定,输出:
lang:语言标签(zh/en/ja/ko...)prob:置信度
建议策略:
lang == 'zh' and prob >= 0.8:保留lang in {'zh','en'} and prob >= 0.8:保留,但记录语言- 其它:进入“待定池”,再看质量分或人工抽检
3.2 处理中英混杂:给“混杂度”打标签
很多优质中文内容会夹英文术语(AI、API、Transformer),不应误删。
可用一个简单的混杂度指标:
mix = min(Latin_chars, Han_chars) / max(Latin_chars, Han_chars)
解读:
mix接近 0:单一语言mix接近 1:强混杂
推荐做法:
- 保留
mix <= 0.3的内容为主训练集 0.3 < mix <= 0.6进入“混杂子集”(可用于代码/技术语料)mix > 0.6多为导航、列表、无意义拼接,结合质量分再决定
4. 重复去除:从“省算力”到“防止模型复读”
去重通常分三层:
- 完全重复(Exact Dedup):文本完全一致
- 近似重复(Near Dedup):改了少量词、加了广告尾巴、换行不同
- 模板重复(Boilerplate):页眉页脚、免责声明、版权声明
4.1 完全去重:标准化后 hash
先做标准化再 hash,能消除很多“形式差异”:
- 全角转半角、大小写归一(对英文)
- 连续空白归一成一个空格
- 去掉行首行尾空白
- 对网页类可删除重复出现的“分享/点赞/上一篇下一篇”等按钮文本
然后计算 sha1(normalized_text),用分布式 key-value 或排序去重即可。
4.2 近似去重:MinHash/SimHash + 分桶
当规模到千万段落时,近似去重必须考虑效率。
方案 A:SimHash(快、适合文本段落)
- 把文本分词(中文可用结巴或 unigram 字符)
- 算 64-bit simhash
- 通过 Hamming distance 阈值(例如 <=3)判断相似
工程技巧:
- 用“分桶”减少比较次数:按 simhash 的若干段(比如 4 段 16-bit)建索引
- 只在同桶内两两比较
方案 B:MinHash + LSH(更稳,但复杂)
- shingle(例如 5-gram 字符)
- minhash 签名
- LSH 找候选,再算 Jaccard
适用:网页正文近重复、新闻转载。
4.3 模板/页脚去除:基于“跨文档高频段落”
你可以统计段落级 n-gram 的全局频次:
- 某段文本在不同域名/页面出现次数极高(例如超过 5000 次),大概率是模板。
实操策略:
- 先从所有段落抽样(或按域名分层抽样)建一个“高频段落黑名单”。
- 清洗时命中黑名单直接移除。
示例(常见模板):
- “版权所有 未经许可不得转载”
- “点击这里登录/注册/忘记密码”
- “上一篇:… 下一篇:…”
5. 质量打分:把“可用”变成“更好用”
过滤完乱码、语言和重复后,仍会剩下大量“可读但低价值”的文本,比如:
- 灌水式短评:“顶”“哈哈哈”“路过”
- 关键词堆砌的 SEO 文
- 句子不通、无标点、列表碎片
- 过长但信息密度低(大量重复同一句)
质量打分的目的不是追求统一标准,而是让你能按预算选择训练子集:高质量集用于 SFT/对齐或高权重预训练,普通集用于扩量。
5.1 可落地的质量特征(无需大模型)
建议组合多个“弱特征”,形成一个 0~1 的分数。
特征 1:长度与结构
- 过短:小于 20 字(段落)往往信息不足
- 过长:单段超过 2000 字可能是拼接或爬虫异常
- 标点密度:中文文本完全无标点通常可疑
特征 2:重复度(自重复)
计算段落内部重复:
- 句子去重率:同一句出现多次
- n-gram 重复率:例如 4-gram 重复占比
重复率高可能是:刷屏、模板、广告。
特征 3:字符分布异常
- 数字比例过高:可能是表格/彩票/订单
- 特殊符号比例过高:可能是分隔线、乱码残留
- 大写比例极高:英文垃圾文本
特征 4:敏感“垃圾模式”命中
维护一些正则模式(可版本管理),如:
- 联系方式/引流:
微信|VX|QQ\d{5,}|加群|扫码 - 博彩/色情/灰产关键词
- 过多外链:
http(s)?://出现次数
注意:是否过滤取决于你的合规和训练目标,但至少要“打标”。
5.2 使用语言模型困惑度(PPL)做质量评分(进阶但很有效)
在有条件时,用一个较小的、可靠的中文语言模型计算困惑度(perplexity):
- 低困惑度:更像自然语言、通顺
- 极低困惑度:也可能是模板/重复句(需结合重复特征)
- 高困惑度:语病、乱码、随机字符
落地建议:
- 用一个开源中文 LM(或你已有的基座模型)对段落打 PPL。
- 按分位数筛选:丢弃最高 5%~20% 的 PPL 样本(视规模与任务)。
- 对“PPL 极低 + 高频出现”的段落,优先判为模板。
5.3 一个可执行的“线性加权”打分示例
你可以先用可解释的方式组合:
score = 1.0- 若长度 < 20:
score -= 0.3 - 若替换字符占比超阈值:
score = 0 - 若语言置信度 < 0.8:
score -= 0.2 - 若自重复率 > 0.3:
score -= 0.3 - 若命中引流/灰产模式:
score -= 0.5 - 若 PPL 处在最差 10%:
score -= 0.2
最后裁剪到 [0,1]。
筛选策略:
score >= 0.8:高质量集0.5 <= score < 0.8:普通集< 0.5:低质量,默认丢弃或仅用于特定鲁棒性训练
6. 端到端流水线建议:如何在工程上跑得动
6.1 建议的处理顺序(为什么这样排)
- 基础规范化(空白、全半角、去控制字符)
- 乱码粗过滤(快速降低垃圾比例)
- 语言识别(减少后续步骤的无效开销)
- 段落切分与模板剔除(提高去重与打分准确性)
- 去重(先精确后近似)(避免重复干扰质量统计)
- 质量打分与分层抽样(按预算导出训练集)
6.2 分布式与增量处理要点
- 增量清洗:保留每一步产物(或至少保留 hash 与 flags),新数据只跑新增部分。
- 指标看板:每 100 万条输出一次统计(语言分布、过滤比例、平均长度、重复率、质量分分布)。
- 抽样审计:每个过滤规则都要配套抽样集(命中样本 + 未命中样本),避免“规则漂移”。
6.3 输出建议:保留“被删原因”字段
为每条记录维护 flags,例如:
flags: ['mojibake', 'non_zh', 'near_dup', 'low_quality_ppl']
这会极大方便你在后续训练效果不理想时回溯:到底是“删太狠”还是“放太松”。
7. 小规模验证:在上亿规模前先做这 3 件事
抽样 1 万段落做人工评估:
- 乱码误杀率
- 语言识别准确率
- 去重是否把“同主题不同内容”误合并
- 用不同阈值导出 3 个版本(宽松/中等/严格),快速训练一个小模型或做继续预训练对比困惑度与下游任务表现。
建立“黑白名单”机制:
- 域名白名单:高质量站点可放宽阈值
- 域名黑名单:采集时就降低权重或直接禁用
8. 本章小结:可复用的清洗配方
在 Ai大模型训练教程 的实战中,一套稳定的“大规模文本清洗”通常满足三点:
- 快:先用启发式与轻量模型做高吞吐过滤
- 准:关键步骤可抽检、有指标、有回溯字段
- 可控:通过质量分分层输出,适配不同训练预算与目标
只要你把“乱码过滤、语言识别、重复去除、质量打分”串成流水线,并持续用抽样与统计校准阈值,就能把海量杂数据变成可训练、可迭代优化的语料资产,为后续的分词、预训练与对齐阶段打好地基。
Prev:训练语料怎么收集更安全:版权、隐私、可追溯与数据使用边界