1. 文本处理在大模型训练中的核心地位
大模型训练的第一步永远是数据准备,而文本数据的质量直接决定了模型最终的表现上限。我在参与多个千亿参数级大模型项目时发现,数据处理环节投入的时间往往占到整个训练周期的60%以上。原始文本就像未经提炼的矿石,需要经过多道工序才能变成模型可消化的"营养餐"。
最近帮某金融客户构建行业大模型时,我们清理出的噪声数据比例高达37%,包括乱码、重复文本、广告内容等。这些"脏数据"如果直接喂给模型,轻则影响收敛速度,重则导致模型产生事实性幻觉。下面分享的这套文本处理流程,已经在我们团队内部迭代了12个版本,处理过包括维基百科、Common Crawl、GitHub代码等在内的多种语料。
2. 原始文本数据获取与评估
2.1 主流语料来源分析
中文领域我常组合使用以下语料库:
- 维基百科中文dump(约180万条目):XML格式需要特别处理
- Wudao语料(5TB原始文本):包含网页、书籍、论文等多源数据
- CLUE基准数据集:特别适合领域适配场景
- 自建爬虫数据:需特别注意版权合规
英文推荐组合:
- Common Crawl(每月约20TB新数据)
- C4数据集(已清洗的Colossal Clean Crawled Corpus)
- StackExchange数据转储(技术问答场景必备)
重要提示:使用爬虫数据时务必遵守robots.txt规则,商业项目建议购买正规语料授权
2.2 数据质量快速评估方法
我习惯先用三组指标快速判断语料质量:
-
基础统计量:
- 字符/词频分布(中文需先分词)
- 平均句长(理想范围15-30词)
- 符号占比(正常文本应<5%)
-
重复检测:
python复制from datasketch import MinHash def text_similarity(text1, text2): mh1 = MinHash(num_perm=128) mh2 = MinHash(num_perm=128) for word in jieba.cut(text1): mh1.update(word.encode('utf8')) for word in jieba.cut(text2): mh2.update(word.encode('utf8')) return mh1.jaccard(mh2) -
语言模型困惑度:
用小型LM计算片段perplexity,异常高值可能表明存在乱码或专业术语
3. 文本清洗标准化流程
3.1 噪声过滤七步法
我们的清洗流水线包含以下核心步骤:
-
编码规范化
- 转换所有文本为UTF-8
- 处理\x00等控制字符
- 统一全角/半角符号
-
文档结构处理
- 移除HTML/XML标签(但保留结构信息)
- 提取正文内容(使用readability-lxml等工具)
- 处理PDF/EPUB等格式(建议先用pandoc转换)
-
文本规范化
- 统一日期/货币/单位格式
- 繁体转简体(opencc工具)
- 拼音/注音符号处理
-
低质量内容过滤
- 删除短于3句的段落
- 过滤广告文本(关键词+正则匹配)
- 识别并移除机器生成内容
-
重复数据删除
- 文档级去重(SimHash)
- 段落级去重(MinHash)
- 跨语料库去重
-
敏感信息处理
- 个人隐私识别(CRF模型)
- 政治敏感词过滤
- 自定义黑名单
-
语言识别
- 使用fasttext检测语种
- 混合语言文档的特殊处理
3.2 中文特殊处理技巧
中文文本需要额外注意:
- 分词一致性:训练全程使用同一分词器(推荐Jieba或LAC)
- 新词发现:用互信息+左右熵识别领域新词
- 停用词策略:不要盲目使用通用停用词表
python复制# 中文新词发现示例
import jieba.analyse
text = "大语言模型的训练需要海量语料"
tags = jieba.analyse.extract_tags(text,
topK=20,
withWeight=True,
allowPOS=('n', 'v'))
4. 文本分块与序列化
4.1 分块策略选择
大模型训练需要将文本切分为固定长度片段,常用方法:
-
滑动窗口法:
- 窗口大小2048 token
- 重叠率15%(防止上下文断裂)
- 适合叙事性文本
-
文档边界法:
- 保持单个文档完整
- 填充或截断到固定长度
- 适合技术文档等结构化内容
-
语义分块法:
- 用BERT等模型计算语义边界
- 计算成本较高但质量更好
4.2 Tokenization实战
以GPT风格BPE为例:
-
训练词表:
bash复制
subword-nmt learn-bpe -s 50000 < input.txt > bpe.model -
编码文本:
python复制from [token](https://taotoken.net?utm_source=ai)izers import ByteLevelBPETokenizer tokenizer = ByteLevelBPE[Tokenizer](https://taotoken.net?utm_source=ai)( "bpe-model.json", "bpe-vocab.json" ) encoded = tokenizer.encode("大模型训练文本") -
特殊token处理:
- 添加[CLS]、[SEP]等控制符号
- 处理数字(建议拆分为单个数字)
- URL/邮箱等替换为特殊token
实测发现:中文BPE词表大小建议5-8万,英文3-5万效果最佳
5. 数据增强与平衡
5.1 数据增强技巧
- 回译增强:中→英→中循环翻译(注意质量损失)
- 同义词替换:使用SimBERT生成变体
- 句式变换:主动被动转换、长句拆分
- 领域适配:用T5模型进行风格迁移
5.2 类别平衡策略
构建多领域语料时需要注意:
-
分层采样:
python复制from sklearn.utils import resample df_resampled = resample(df, replace=True, stratify=df['domain']) -
温度采样:
python复制weights = np.power(domain_counts, 0.75) # temperature=0.75 probs = weights / weights.sum() -
动态混合:
训练时按比例混合不同领域batch
6. 数据处理流水线搭建
6.1 分布式处理架构
mermaid复制graph LR
A[原始数据] --> B(分布式存储)
B --> C{清洗节点}
C --> D[去重集群]
D --> E[Tokenization]
E --> F[分块存储]
注意:实际实现应使用Spark或Ray框架
6.2 质量监控看板
必须监控的关键指标:
- 数据分布变化:KL散度检测
- n-gram异常值:Z-score监控
- Embedding漂移:PCA可视化
python复制# 数据漂移检测示例
from scipy.stats import entropy
def kl_divergence(p, q):
return entropy(p, q)
7. 常见问题排查
7.1 典型问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 训练loss波动大 | 数据中存在噪声 | 重新检查清洗规则 |
| 模型生成乱码 | BPE词表不匹配 | 统一训练/推理tokenizer |
| 领域适应差 | 数据分布不均 | 调整温度采样参数 |
| OOV过高 | 词表覆盖不足 | 添加领域特定词 |
7.2 性能优化技巧
-
内存映射优化:
python复制import numpy as np data = np.memmap("dataset.bin", dtype=np.int32, mode='r') -
预处理缓存:
- 将清洗后的数据存储为parquet格式
- 使用LMDB加速小文件读取
-
流水线并行:
bash复制
python preprocess.py | torchrun train.py
在实际处理千万级文档时,合理的流水线设计可以将处理时间从72小时缩短到4小时。最近一个项目中使用Ray框架实现的分布式处理系统,能在30分钟内完成1TB原始文本的清洗和tokenize。