数据质量评估:指标、工具、与 Loss 斜率的关系¶
更新日期:2026-04-15
一、为什么数据质量决定一切¶
经过 2023-2025 年的实验,业界共识:数据质量的边际收益 > 模型参数量的边际收益。同等算力下,精心筛选的数据能显著提升下游能力。
flowchart LR
cc["Common Crawl<br/>~5PB raw"]
rule["规则过滤<br/>(长度/字符/语言)"]
dedup["去重<br/>(MinHash)"]
qual["质量分类器<br/>(FastText/PPL)"]
eval["质量评测<br/>(LLM judge)"]
final["High-quality<br/>~50T tokens"]
cc --> rule --> dedup --> qual --> eval --> final
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
classDef io fill:#f5f3eb,stroke:#bdb9ab,color:#1a1a1a;
class cc,final io
class rule,dedup,qual,eval stage
公开实验对比(同算力 + 同模型尺寸):
| 数据 | tokens | Loss 斜率 | MMLU |
|---|---|---|---|
| RedPajama (粗清) | 1.2T | 1× | 60% |
| FineWeb (规则 + 分类器) | 1.5T | 1.3× | 65% |
| FineWeb-Edu (educational filter) | 1.3T | 1.5× | 68% |
| DCLM-Pro | 0.5T | 1.7× | 70%(待核实) |
→ 质量过滤让小 ½-⅓ 的数据集训出更强模型。
二、数据质量的多维评估¶
| 维度 | 描述 | 评估方法 |
|---|---|---|
| 正确性 (Correctness) | 事实无误 | 知识图谱验证、LLM-as-Judge |
| 信息密度 (Information Density) | 每 token 携带的信息量 | 压缩率、困惑度 |
| 多样性 (Diversity) | 覆盖多种主题/风格/难度 | 聚类分析、embedding 分布 |
| 教育价值 (Educational Value) | 对下游能力有帮助 | 分类器(textbook-like) |
| 语言质量 (Linguistic Quality) | 语法、流畅性 | 语法检查、流畅性打分 |
| 安全性 (Safety) | 无有害内容 | 毒性分类器 |
| 时效性 (Freshness) | 信息的新鲜度 | 时间戳过滤 |
| 领域均衡 | 各领域覆盖度 | 主题分类统计 |
三、数据质量评估方法¶
3.1 基于规则的过滤¶
class RuleBasedQuality:
def score(self, text):
scores = {}
# 长度合理性
scores['length'] = 1.0 if 200 < len(text) < 100000 else 0
# 字符质量
alpha_ratio = sum(c.isalpha() for c in text) / len(text)
scores['alpha_ratio'] = alpha_ratio if alpha_ratio > 0.5 else 0
# 重复率
words = text.split()
unique_ratio = len(set(words)) / len(words)
scores['diversity'] = unique_ratio if unique_ratio > 0.3 else 0
# n-gram 重复
ngrams = get_ngrams(words, 5)
ngram_unique = len(set(ngrams)) / len(ngrams)
scores['ngram_diversity'] = ngram_unique
# 停用词比例 (过高或过低都异常)
stopword_ratio = count_stopwords(words) / len(words)
scores['stopword'] = 1.0 if 0.1 < stopword_ratio < 0.5 else 0
return geometric_mean(scores.values())
3.2 基于 Perplexity 的过滤¶
# 用一个在高质量数据上预训练的小模型计算 PPL
# 低 PPL → 数据"像"高质量数据
# 高 PPL → 数据是噪声/乱码
def ppl_filter(texts, small_lm, threshold=100):
filtered = []
for text in texts:
ppl = small_lm.perplexity(text)
if ppl < threshold:
filtered.append(text)
return filtered
# 实际中, 不同数据源的 PPL 阈值不同
# Wikipedia: PPL < 50
# 新闻: PPL < 80
# 代码: PPL < 100 (代码本身有较多"不常见"结构)
3.3 基于分类器的过滤¶
# FastText 分类器 (最流行方案, DeepMind/Meta/DeepSeek 都用)
# 训练:
# 正样本: 维基百科, 教科书, 高质量博客 (~100K 文档)
# 负样本: 随机 CC 网页 (~100K 文档)
import fasttext
def train_quality_classifier(pos_docs, neg_docs):
with open('train.txt', 'w') as f:
for doc in pos_docs:
f.write(f'__label__pos {doc}\n')
for doc in neg_docs:
f.write(f'__label__neg {doc}\n')
model = fasttext.train_supervised(
input='train.txt',
lr=0.5, epoch=5, wordNgrams=2, dim=100
)
return model
def filter_with_classifier(texts, classifier, threshold=0.5):
filtered = []
for text in texts:
label, prob = classifier.predict(text)
if label == '__label__pos' and prob > threshold:
filtered.append(text)
return filtered
# 优势: 极快 (百万 doc/分钟), 可大规模部署
# 劣势: 需要标注数据训练
3.4 基于 LLM 的评估¶
# 用强 LLM 打分 (质量高但昂贵)
def llm_quality_score(text, judge_llm):
prompt = f"""
Rate this text from 0-10 on: educational value, correctness, clarity.
Text: {text[:2000]}
Output format: {{score: N, reason: "..."}}
"""
result = judge_llm.generate(prompt)
return parse_score(result)
# 实际策略:
# 1. 规则 + 分类器过滤大部分 (90%+)
# 2. 抽样用 LLM 细致评估 (1%)
# 3. 用 LLM 结果改进分类器
3.5 FineWeb 的多阶段过滤¶
HuggingFace 的 FineWeb (2024) 是开源数据集的标杆。参考 FineWeb Paper (Penedo et al., 2024)。
flowchart LR
cc["CC raw<br/>(96 dump)"]
s1["1. URL 过滤<br/>(黑名单)"]
s2["2. 语言识别<br/>(英语 only)"]
s3["3. 重复内容<br/>检测"]
s4["4. 文本质量<br/>(行级启发)"]
s5["5. 全局<br/>MinHash 去重"]
s6["6. PII<br/>移除"]
final["FineWeb 15T"]
edu["+ educational<br/>classifier"]
fw_edu["FineWeb-Edu<br/>1.3T"]
cc --> s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> final
final --> edu --> fw_edu
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
classDef io fill:#f5f3eb,stroke:#bdb9ab,color:#1a1a1a;
class cc,final,fw_edu io
class s1,s2,s3,s4,s5,s6,edu stage
| 阶段 | 工具 | 输出量 |
|---|---|---|
| Raw CC | warc.gz | ~96 PB |
| URL filter | UT1 blocklist | -10% |
| Lang detect | fastText lid | -50% (仅英语) |
| Repetition / 行级启发 | trafilatura + 自定义规则 | -30% |
| MinHash dedup | datasketch | -60% |
| PII | regex + classifier | -1% |
| FineWeb final | — | ~15T |
| FineWeb-Edu(额外) | educational classifier | 1.3T |
FineWeb-Edu 用一个 Llama-3 80B 标的 educational score 训分类器筛过,质量比原版高一档。
四、数据质量 × Loss 斜率¶
4.1 理论关系¶
数据中每 token 的平均信息量决定了 loss 下降的速度。高质量数据 → 信息密度高 → 斜率陡。
Loss 的信息论解释:L = -E[log P(x_t | x_{<t})],即平均每 token 的最优编码长度,本质上就是数据压缩率。
4.2 实验数据对比¶
五、数据质量影响的表现¶
5.1 训练曲线¶
同样训练 100B tokens,不同质量数据的训练曲线对比:
5.2 下游能力与 loss 的关系¶
Loss 只是中间指标,最终要看下游 eval。同样 loss=2.0 的模型,能力可能差异巨大:
-
在噪声数据上训到 loss=2.0 → 能力仍然很差(学到的是噪声模式)
-
在高质量数据上训到 loss=2.0 → 能力很强
结论:Loss 可以比较同一数据集上的不同模型,但不能跨数据集比较 loss。
六、数据配比与 annealing¶
6.1 训练阶段的配比变化¶
flowchart LR
early["Early phase<br/>0-70%"]
mid["Mid phase<br/>70-90%"]
anneal["Annealing<br/>90-100%"]
early --> mid --> anneal
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
class early,mid,anneal stage
| 阶段 | 进度 | 数据混合 |
|---|---|---|
| Early | 0-70% | 大杂烩(70% web + 15% code + 10% 多语 + 5% 其他) |
| Mid | 70-90% | 提升代码 / 数学比例(web 60% + code 25% + math 10% + 其他 5%) |
| Annealing | 90-100% | 极高质量(textbook + math + code + curated paper),LR 衰减到 0 |
annealing 阶段用最干净的高密度数据 + LR 急降,模型在最后 10% 收敛到关键能力。DeepSeek-V3 / Llama-3 / Qwen 都用这套。
6.2 Annealing 的效果¶
DeepSeek-V3 和 LLaMA-3 都使用 annealing。实测数据:MMLU +5-10%,HumanEval +10-15%,MATH +20%+。
七、数据质量工具生态¶
| 工具 | 功能 | 链接 |
|---|---|---|
| fasttext | 轻量分类器 | GitHub |
| datatrove | 大规模数据 pipeline | GitHub |
| text-dedup | 多种去重算法 | GitHub |
| trafilatura | HTML 正文提取 | GitHub |
| KenLM | PPL 快速计算 | GitHub |
| DolmaReader | 开源数据集 reader | - |
参考文献¶
-
[1] Penedo et al. FineWeb: Decanting the Web for the Finest Text Data. 2024. 论文
-
[2] Longpre et al. A Pretrainer's Guide to Training Data. 2023. 论文
-
[3] Gunasekar et al. Textbooks Are All You Need. 2023. 论文
-
[4] Soldaini et al. Dolma. 2024. 论文
-
[5] Computer & Data Research Lab. DataComp-LM. 2024. 论文
↑ 上级 · B. 数据工程