欢迎光临
我们一直在努力

数据预处理与 Tokenizer 原理:从文本清洗到现代大模型数据策展(分层式精讲)

在这里插入图片描述

核心结论

数据预处理不是“把文本洗干净再分词”这么简单。对现代大模型来说,它是一条完整的数据策展流水线:从原始数据抽取文本,做质量过滤、去重、PII 与安全处理、评测集去污染,再训练或选择 Tokenizer,最后构造带有模板、mask、EOS 和 packing 规则的训练样本。

更准确的一句话是:

原始数据 -> 数据策展 -> Tokenizer -> 样本构造 -> 训练与评估

Tokenizer 不是独立工具,而是模型输入协议的一部分。它决定文本如何被压缩成 token、特殊标记如何表示、对话模板如何展开、哪些 token 参与 loss。数据清洗也不是越彻底越好,而是在保留语义、降低噪声、满足安全与治理要求之间做可验证的取舍。

第 0 层:30 秒理解

数据预处理像“数据炼厂”,不是简单洗菜。

  • 原始数据:网页、PDF、代码、论坛、对话、表格、日志,通常混有模板、重复、广告、乱码、隐私和污染样本。
  • 数据策展:抽取正文、过滤低质样本、去重、处理 PII 和安全问题、去除评测污染、记录来源和许可证。
  • Tokenizer:把文本变成 token ID,同时定义特殊 token、空格规则、byte fallback、chat template 等输入协议。
  • 样本构造:把 token ID 变成模型真正训练的 input_ids、attention_mask、labels、loss_mask。
  • 评估闭环:通过验证集、消融实验和数据质量指标判断预处理是否真的有效。

在这里插入图片描述

最重要的原则:

不要追求“清洗越干净越好”,而要追求“信息保留、噪声可控、来源可追踪、训练可复现”。

第 1 层:基础概念

1.1 Tokenizer 到底做什么

Tokenizer 通常包含四件事:

  • Normalization:Unicode 规范化、空白处理、大小写策略、特殊字符处理。
  • Pre-tokenization:按空格、标点、字节、脚本或正则做初步切分。
  • Subword encoding:BPE、WordPiece、Unigram 等算法把文本映射为 token。
  • Post-processing:添加 BOS/EOS、role token、separator、padding、chat template。
  • 因此,Tokenizer 输出的不只是 ID 序列,而是一套“模型如何理解输入”的协议。

    1.2 数据清洗和数据策展的区别

    概念关注点例子
    数据清洗 单条文本是否规范、可读、无明显噪声 Unicode 规范化、HTML 转文本、空白折叠
    数据过滤 样本是否应进入训练集 语言识别、质量分类、长度过滤、安全过滤
    数据去重 数据分布是否被重复内容扭曲 exact hash、MinHash、n-gram overlap
    数据去污染 训练集是否泄漏评测集 benchmark overlap、答案泄漏、近似重复
    数据治理 是否合规、可追踪、可审计 PII、许可证、来源、数据卡
    样本构造 模型到底学习哪些 token chat template、packing、loss mask

    现代大模型训练里,数据清洗只是数据策展的一部分。

    第 2 层:Tokenizer 原理

    在这里插入图片描述

    2.1 BPE

    BPE 的核心思想是:从字符或字节开始,反复合并高频相邻片段,得到更长的子词 token。

    它的优点是简单、高效、覆盖能力强。许多 GPT 系 tokenizer 都与 BPE 或 byte-level BPE 有关。byte-level BPE 的优势是几乎可以覆盖任意输入,不容易出现 [UNK];代价是罕见字符、乱码、多字节文本可能被拆成更多 token。

    需要注意:真实 BPE 训练不是把一整段文本简单拆成字符再合并。工程实现还涉及预分词、词频、merge table、byte fallback、特殊 token、空格编码和 decode 可逆性。

    2.2 WordPiece

    WordPiece 常见于 BERT 系模型。它的词表构建考虑词片组合的统计价值,编码时通常使用 longest-match-first:尽量匹配词表中最长的子词片段。

    WordPiece 适合解释 BERT 时代的英文/多语言模型,但它不等于“BPE 的另一个名字”。尤其要注意:

    • 如果字符或子词无法覆盖,仍可能产生 [UNK]。
    • 大小写版本、accent stripping、中文字符处理都会影响结果。
    • 换 tokenizer 会改变模型 embedding 对齐,不能随意替换。

    2.3 SentencePiece 与 Unigram

    SentencePiece 是一个 tokenizer 工具包,常用于直接处理原始 Unicode 文本,不要求先按空格分词。它支持 BPE,也支持 Unigram Language Model。

    Unigram 的思路不是逐步合并最高频 pair,而是先构造较大的候选子词表,再根据似然和损失贡献逐步剪枝。它天然适合多语言场景,但多语言效果仍取决于数据配比、脚本覆盖和词表预算。

    2.4 词表大小怎么选

    词表大小不是按模型参数简单套公式。它主要受这些因素影响:

    • 语言数量:多语言和混合脚本通常需要更大词表。
    • 代码比例:代码、数学、路径、标识符会改变 token 分布。
    • byte fallback:覆盖能力增强,但低频文本可能 token 更多。
    • 上下文长度:token 越多,等价文本占用上下文越多。
    • 推理延迟:短序列减少 attention 成本,但大词表增加 embedding/LM head 成本。
    • 兼容性:预训练模型的 tokenizer 通常不能随意更换。

    实践建议:

    场景建议
    微调已有模型 不要重训 tokenizer,保持与基座模型一致
    从零训练英文模型 可从 32K 到 50K 附近做实验
    多语言/代码模型 评估 100K+ 词表是否改善压缩率和公平性
    低延迟推理 同时评估 tokens/sec、bytes/token 和 LM head 成本
    专业领域 先看术语 fertility,再决定是否扩词表或继续训练

    2.5 Tokenizer 质量指标

    指标含义
    bytes/token 平均每个 token 覆盖多少字节,越高通常压缩越好
    fertility 一个词或片段平均被拆成多少 token
    UNK rate [UNK] 出现比例,非 byte-level tokenizer 需关注
    round-trip decode(encode(text)) 是否保留足够信息
    special token correctness BOS/EOS/PAD/role/tool token 是否正确
    chat template consistency 训练和推理模板是否一致
    encoding latency 大规模预处理和在线服务的编码开销

    一个简单的 tokenizer 评估函数:

    def tokenizer_report(tokenizer, texts, unk_token=None):
    total_bytes = 0
    total_tokens = 0
    unk_count = 0
    roundtrip_mismatch = 0

    if unk_token is None:
    unk_token = getattr(tokenizer, "unk_token", None)

    for text in texts:
    ids = tokenizer.encode(text, add_special_tokens=False)
    decoded = tokenizer.decode(ids)

    total_bytes += len(text.encode("utf-8"))
    total_tokens += max(1, len(ids))

    if unk_token is not None:
    tokens = tokenizer.convert_ids_to_tokens(ids)
    unk_count += sum(1 for token in tokens if token == unk_token)

    if decoded.replace(" ", "") != text.replace(" ", ""):
    roundtrip_mismatch += 1

    return {
    "bytes_per_token": total_bytes / max(1, total_tokens),
    "avg_tokens": total_tokens / max(1, len(texts)),
    "unk_rate": unk_count / max(1, total_tokens),
    "roundtrip_mismatch_rate": roundtrip_mismatch / max(1, len(texts)),
    }

    这段代码只是轻量检查,不能替代下游训练消融。

    第 3 层:数据清洗策略

    3.1 默认策略:少删,多标注,多验证

    现代 LLM 数据清洗应避免“看起来脏就删”。以下内容经常有语义:

    内容保留原因
    URL 来源、引用、实体、API、代码依赖
    大小写 缩写、实体、标题、代码变量
    标点 句法、数学、代码、Markdown、JSON
    emoji 情绪、社交语境、用户意图
    数字和日期 金融、医学、法律、问答中的核心信息
    停用词 否定、指代、语法和生成流畅性

    更安全的清洗模板:

    import html
    import re
    import unicodedata

    def normalize_text(
    text,
    *,
    unicode_form="NFKC",
    lowercase=False,
    strip_urls=False,
    collapse_spaces=True,
    ):
    text = html.unescape(text)
    text = unicodedata.normalize(unicode_form, text)

    if lowercase:
    text = text.lower()

    if strip_urls:
    text = re.sub(r"https?://\\S+|www\\.\\S+", " <URL> ", text)

    if collapse_spaces:
    text = re.sub(r"\\s+", " ", text).strip()

    return text

    注意:这里默认不小写、不删除 URL,而是可选替换为 <URL>。是否启用要由任务决定。

    3.2 按任务选择清洗策略

    任务建议清洗不建议默认做
    文本分类 轻量规范化、去明显乱码、保留标点 强行词干化、删除所有停用词
    NER/信息抽取 保留大小写、数字、标点、实体格式 小写化、实体标准化过度
    代码模型 保留缩进、符号、路径、大小写 删除特殊字符、折叠所有空白
    对话/SFT 保留角色、语气、emoji、换行 把多轮消息拼成无边界纯文本
    法律/医学/金融 保留日期、金额、单位、引用 把数字统一替换成 NUMBER
    网页预训练 正文抽取、去模板、去重、质量过滤 只用正则清洗 HTML

    3.3 文本抽取优先于正则替换

    网页数据的主要噪声通常来自 boilerplate,而不是几个特殊字符。优先处理:

    • HTML 正文抽取。
    • 广告、导航、页脚、cookie banner。
    • OCR 和编码错误。
    • 重复模板。
    • 自动生成和低质量机器翻译页面。

    如果没有做好文本抽取,后面的 tokenizer 再好也只是把噪声高效编码成 token。

    第 4 层:现代数据策展流水线

    在这里插入图片描述

    4.1 质量过滤

    质量过滤可以结合规则、统计特征和模型分类器:

    • 文档长度、平均行长、标点比例、数字比例。
    • 语言识别置信度。
    • 重复 n-gram 比例。
    • 困惑度或轻量语言模型分数。
    • 质量分类器或教育价值分类器。
    • 来源级别信誉和历史表现。

    关键点:不要把质量过滤当成单个阈值。更好的做法是按来源、语言、领域分别观察分布,再做分桶采样和消融。

    4.2 去重

    去重是大模型数据预处理的核心步骤。

    去重类型方法目的
    exact dedup hash 完全相同文本 删除完全重复样本
    near dedup MinHash、SimHash、n-gram overlap 删除转载、模板、轻微改写
    span dedup 段落或片段级匹配 降低模板句和重复段落
    split dedup train/val/test 之间去重 防止验证集泄漏

    重复数据会让模型记忆增强、浪费训练 token,并抬高评测污染风险。

    4.3 评测集去污染

    如果训练集包含 benchmark 题目、答案或近似改写,模型评估会虚高。常见去污染方法:

    • exact match。
    • n-gram overlap。
    • URL/source overlap。
    • embedding similarity。
    • answer leakage 检查。
    • benchmark 版本记录。

    去污染不是只在最终训练前做一次,而应该在数据版本迭代中持续执行。

    4.4 PII、安全和许可证

    现代数据预处理必须包含治理层:

    • PII:邮箱、电话、身份证号、地址、密钥、API token。
    • 安全:有害内容、违法内容、极端内容、恶意代码。
    • 许可证:来源、使用范围、再分发限制、robots 和站点条款。
    • 数据卡:来源、过滤规则、已知偏差、适用范围、不可用场景。

    这些不是“额外合规文档”,而是模型能否可靠发布的一部分。

    4.5 数据混合和采样配比

    数据不是越多越好。高质量数据、小而干净的数据、合适的采样配比,常常比盲目扩大规模更有效。

    需要记录:

    • 各来源 token 占比。
    • 各语言 token 占比。
    • 代码、数学、网页、论文、书籍、论坛、对话占比。
    • 高质量分类器分数分布。
    • 去重前后 token 数。
    • 每次训练使用的数据版本和采样权重。

    第 5 层:样本构造

    Tokenizer 之后,真正进入模型的是训练样本,而不是裸 token。

    在这里插入图片描述

    5.1 Chat template

    对话模型训练时,消息结构通常是:

    messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "解释 BPE 的核心思想。"},
    {"role": "assistant", "content": "BPE 会反复合并高频相邻片段…"},
    ]

    input_ids = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=False,
    )

    关键要求:

    • 训练和推理必须使用同一个模板。
    • role token、BOS、EOS、stop token 要版本化。
    • 工具调用和多模态占位符不能靠普通字符串随意拼接。

    5.2 Loss mask

    SFT 中通常只监督 assistant 的回答,不应该让模型学习“预测 user 的输入”。因此要构造 labels 或 loss_mask:

    labels = input_ids.clone()

    # assistant_mask=True 的位置参与 loss,其他位置设为 -100。
    labels[~assistant_mask] = 100

    如果 loss mask 错了,模型可能看似 loss 下降,但学到的是复述用户输入或模板格式。

    5.3 Packing 和文档边界

    为了提高训练效率,多个短样本常被 packing 到一个上下文窗口中。但 packing 要处理:

    • 文档之间是否插入 EOS。
    • attention 是否允许跨文档。
    • labels 是否跨样本污染。
    • padding side 是否与模型一致。
    • 长文档是截断、滑窗还是分块。

    预处理文档里必须写清这些规则,否则同一批 token 可能对应完全不同的训练目标。

    第 6 层:工程落地清单

    6.1 最小可用流水线

    收集数据
    -> 文本抽取
    -> Unicode/空白规范化
    -> 语言识别与来源过滤
    -> exact/near dedup
    -> PII/安全/许可证处理
    -> 评测集去污染
    -> tokenizer 训练或复用
    -> chat template / sample packing
    -> 数据卡与版本化
    -> 小规模训练消融

    6.2 数据版本必须记录什么

    类别内容
    数据来源 URL、数据集名、抓取时间、许可证
    清洗规则 normalization、过滤阈值、保留/删除字段
    去重规则 exact hash、MinHash 参数、去重粒度
    安全治理 PII 策略、安全分类器版本、人工审核规则
    Tokenizer 算法、词表、特殊 token、chat template 版本
    样本构造 max length、packing、EOS、attention mask、loss mask
    采样配比 来源、语言、领域、质量分桶的 token 占比
    评估 去污染规则、验证集版本、消融结果

    6.3 实验验证

    预处理策略必须通过实验验证:

  • 先跑小规模训练,比较不同清洗强度。
  • 固定模型和训练配置,只改变一个数据变量。
  • 同时看 loss、下游指标、困惑度、样本级错误。
  • 对比 tokens/sec 和 bytes/token,避免“质量提升”只是 token 数变化。
  • 检查验证集和 benchmark 是否被污染。
  • 第 7 层:常见问题诊断

    现象可能原因处理
    token 数异常变多 tokenizer 对某语言/领域 fertility 高 增加领域数据训练 tokenizer,或换 byte fallback/更大词表
    [UNK] 很多 字符覆盖不足、规范化错误 检查 Unicode、byte fallback、词表覆盖
    训练 loss 下降但生成格式混乱 chat template 或 EOS 不一致 对齐训练/推理模板,检查 special token
    模型复述用户输入 SFT loss mask 错 只监督 assistant 内容
    评测成绩异常高 benchmark 泄漏 做去污染和重复检测
    模型记忆网页模板 去重和 boilerplate 清理不足 加强 near dedup 和正文抽取
    某语言表现很差 数据配比或 tokenizer fertility 不公平 调整采样配比和词表覆盖
    代码能力差 清洗删除了符号/缩进/路径 代码数据使用独立清洗规则

    总结

    数据预处理的核心不是“清洗得更干净”,而是“构造更可信的训练输入”。一篇现代版 Tokenizer 与数据清洗文章应该同时讲清:

    • Tokenizer 的算法差异和输入协议作用。
    • 词表大小、压缩率、延迟、多语言覆盖之间的权衡。
    • 清洗策略为什么必须任务相关。
    • 去重、去污染、PII、安全、许可证为什么是训练质量的一部分。
    • chat template、packing、loss mask 为什么决定模型实际学习目标。
    • 数据版本和实验消融为什么比经验口号更可靠。

    如果只记一句话:

    Tokenizer 负责把文本变成模型能读的协议,数据策展负责保证模型读到的是可信、干净、可追踪、不过度污染的样本。

    参考资料

    • Hugging Face Tokenizers 文档:https://huggingface.co/docs/tokenizers/index
    • Hugging Face Transformers Tokenizer Summary:https://huggingface.co/docs/transformers/tokenizer_summary
    • Hugging Face Chat Templates:https://huggingface.co/docs/transformers/chat_templating
    • OpenAI tiktoken:https://github.com/openai/tiktoken
    • SentencePiece 项目:https://github.com/google/sentencepiece
    • Kudo and Richardson, SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing:https://aclanthology.org/D18-2012/
    • Meta Llama 3 model card and prompt formats:https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3/
    • Penedo et al., The FineWeb Datasets: Decanting the Web for the Finest Text Data at Scale:https://arxiv.org/abs/2406.17557
    • Li et al., DataComp-LM: In search of the next generation of training sets for language models:https://arxiv.org/abs/2406.11794
    • Penedo et al., The RefinedWeb Dataset for Falcon LLM:https://arxiv.org/abs/2306.01116
    • Soldaini et al., Dolma: an Open Corpus of Three Trillion Tokens for Language Model Pretraining Research:https://arxiv.org/abs/2402.00159
    • Together AI, RedPajama-Data-V2:https://www.together.ai/blog/redpajama-data-v2
    赞(0)
    未经允许不得转载:171主机测评 » 数据预处理与 Tokenizer 原理:从文本清洗到现代大模型数据策展(分层式精讲)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址