资讯动态

从 tokenizer 到 post training:大模型微调前必须弄懂的完整链路

发布时间:2026/9/4 16:34:28 来源:尧图企业网站定制
很多人学 NLP自然语言处理时会默认把 tokenizer 当成一个可有可无的预处理步骤目光直接跳过它落在模型结构、训练策略和 prompt 上。但当你真的开始做 post training——也就是对预训练模型做指令微调、继续预训练或偏好对齐时——你会发现大量报错、算力浪费和效果不稳定追到最后都会绕回 tokenizer。过去一段时间我接触到的不少训练翻车现场真正问题往往不在网络结构而在更前面的环节文本被拆成了什么、特殊 token 怎么用、中文被拆成了多少段、训练数据里有没有一致性。于是我对 NLP 的理解发生了一次明显转向与其上来就研究大模型训练不如先把 tokenizer 到 post training 的整条链路当成一个连续系统搞明白。这篇文章就按这套思路展开先用 tokenizer 建立文本边界意识再讲预训练为什么只是底座接着拆清楚 post training 到底在调什么最后给出一条可以照着做的实验路径。如果你还在用“模型结构决定一切”的视角看 NLP这篇文章应该能帮你看清很多之前模糊的问题。1. 先别急着训练模型眼中的文本和你看到的不一样1.1 token 才是模型阅读文本的最小粒度当我们说模型“读”一段文本时它读到的并不是字符也不是词而是一串 token id。tokenizer 的工作就是做一次确定的映射原始文本 → token 序列 → id 序列。模型内部不再关心你写的是汉字还是英文单词它只学习这些 id 之间的共现概率。也许有人会问为什么不用字或者词直接建模这里其实是一个工程权衡。用词作为单位词表会爆炸而且总能看到没见过的词。用字作为单位词表虽然小但序列会变得很长模型要捕捉的依赖距离也随之变长训练成本会明显上升。于是主流方案普遍选择子词subword或者字节级子词把高频词保持成完整 token把低频词拆成更小的片段。BPE、WordPiece、SentencePiece 只是实现这种拆分的不同算法背后都要回答同一个问题——什么应该成为一个整体什么应该被拆开。这个决定会产生非常实际的影响。假设一个模型设置最大长度 512 或 4096那么一段文本到底能带进去多少真实内容完全取决于 tokenizer 把它拆成了多少份。同样的文本A 分词器可能拆出 300 个 tokenB 分词器可能拆出 700 个 token。后者意味着同等长度下模型能看到的上下文更短训练时在批量 token 数相同的情况下实际处理的文本量也会缩水。很多人以为上下文长度是模型结构决定的其实 tokenizer 在很早之前就把下限卡住了。1.2 中文语料在 token 化阶段最容易出现意外中文没有天然空格词与词之间的边界不清晰这让中文语料在 tokenizer 面前天然不友好。英文里一个单词通常对应 1 到 2 个 token而一个常见中文句子在许多开源模型的字节级 BPE 词表下一个汉字可能对应 1 到 3 个 token。注意这不是某个模型特有的问题而是一种需要实测量的经验值不同词表差异很大。我建议所有想进入 post training 的人第一件事就是跑一个简单的 tokenizer 实验准备 20 条中文、20 条英文、20 条中英混合文本分别观察 token 数量、切分结果和 decode 是否无损。这个实验成本极低却会带来两个关键认知。第一你会知道自己要处理的语料在目标模型里实际占多长第二你能直观看到哪些中文词或常用符号被拆得很怪。比如某些全角标点、生僻字或者 emoji经过字节级回退后可能变成一串无意义片段而这种片段一旦进入后训练语料会让模型学到不稳定的边界。这里有一个常见的直觉误区很多人以为在语料里把文本写规范模型就能“认识”得更好。实际上如果不确认目标 tokenizer 对同一段话的切分是否稳定你精心准备的中文语料可能一直被“半读半猜”。更麻烦的是如果你在继续训练时新增了词表 token还要处理 embedding 初始化和训练热启动的问题。后训练阶段并不适合频繁改词表。落地建议在开始任何 post training 之前先用目标模型自带的 tokenizer 做一次百条级语料检查。如果切分结果和 token 长度分布都不可控后面训练的损失曲线再漂亮也很难转化到真实文本质量。2. 预训练只是“底座”底座不等于能用的助手2.1 预训练阶段到底让模型学会了什么预训练是目前几乎所有大语言模型能力的第一来源。它的核心目标很简单在超大语料上做自监督学习通常是预测下一个 tokennext token prediction。在这一阶段模型被迫记住大量文本里的统计规律、语法模式、常识知识和部分事实性内容。这也是为什么在一个没有经过任何指令微调的 base 模型上直接输入一句“给我写一封请假邮件”它往往会机械地续写一段文本而不是真正执行你的请求。预训练出来的模型更像一个语言能力底座而不是任务助手。它知道一个词后面大概会跟什么却不知道对话里什么时候该结束、什么时候该拒绝、什么时候该按列表输出。这些能力不是突然出现的而是在语料中隐含、可以随时被后续训练激发的潜能。post training 的重要任务之一就是把这些潜能引到用户真正需要的方向上。要注意的是预训练语料的质量会长期限制模型。如果语料里有大量模板化、机器生成或错误标注的文本模型学习到的分布就会被拉偏。对中文 NLP 而言语料问题更突出高质量中文内容分布不均衡网络文本噪声大、重复率高。很多团队把预算花在训练上却没有把同样多的精力放在语料质检上这是一个长期被低估的短板。2.2 tokenizer 决策会一路传导到后训练tokenizer 的影响并不会在预训练结束时就消失。实际上它会沿着模型链路传导到后训练、推理和产品化阶段。先说算力层面。训练一个模型的花费通常以 token 数计量而不是以文本字数计量。如果你的 tokenizer 把中文拆得太碎那么同样一批中文训练数据会膨胀成更多的 token训练时间、显存占用和数据存储成本都会同步上升。一个看起来只影响词汇表的决定最终会变成账单上的差异。再说能力层面。后训练SFT、偏好对齐、继续训练本质上都是在固定词表和固定分词边界上做参数调整。如果基础 tokenizer 对某个领域的术语、生僻字或特殊符号切分混乱后训练只能在一定程度上修正语义很难彻底修复分词层面的 bug。你可以把词表看成基础设施基础设施盖歪了后面装修再精致也会留下隐患。这也是这篇文章的核心态度理解 NLP不能从训练开始而要从文本进入模型的第一个关口——tokenizer 开始。tokenizer 相当于工厂入口处的分拣线分拣标准决定了后面所有工序能拿到什么原料。3. post training 真正要解决的是“能力转向与行为对齐”3.1 SFT把续写机器改造成任务引擎post training 通常是一个集合概念工业界主流流程大致包括三个阶段领域继续预训练、指令微调SFT、偏好对齐如 RLHF、DPO 等。三者解决的问题并不一样。领域继续预训练是在原始文本上继续学习目的是补充领域知识或适配新的文本风格适合医疗、法律、金融等专业场景。指令微调则用大量“指令-回复”对做监督学习让模型学会理解用户指令、遵循任务格式并组织回答。在多数开源实现里训练时会在目标回复部分计算损失指令部分通常只作为上下文不对 system prompt 或用户指令做反向传播。SFT 真正改变的不是模型的知识量而是模型的“行为协议”。一个 base 模型可能知道请假邮件应该怎么写但它不知道当用户对它说“帮我写一封请假邮件”时应该立刻进入写邮件状态而不是继续扩写这句话。SFT 用大量任务样例把这种映射关系刻进参数里。我在做小规模实验时通常建议如果要观察 SFT 的效果先从 base 模型开始而不是从已经对齐的 instruct 模型开始。原因是已经对齐的模型里已经包含了指令能力你再做一轮 SFT很难判断能力增量来自新数据还是旧能力迁移而 base 模型起点干净任何变化都更容易归因。3.2 偏好对齐光能答还不够还要答得符合预期如果 SFT 的目标是让模型“会听话”偏好对齐的目标就是让模型“按人的偏好行事”。因为语言模型在最大似然训练下只会给高概率的文本更高分而高概率文本未必是用户认为的高质量文本。用户觉得好的回答往往具备有用、无害、诚实、格式清晰等特征这些特征很难用一句“下一词预测”完全表达出来。于是就有了基于人类反馈的强化学习路线以及更轻量的 DPO 等偏好优化方法。它们都需要构造偏好数据通常是同一问题下“更好回答 A 和更差回答 B”的成对样本。模型要学习的是A 比 B 更符合人类偏好。成本主要不在算法而在数据标注标准和一致性。如果偏好数据的质量参差模型会学到很奇怪的选择基准训练后反而变得讨好但空洞。需要留意的是很多文章把 RLHF 当成 post training 的全部这是不准确的。真正生产级的 post training 是一套组合用 SFT 完成能力引导用偏好数据完成行为校准再用评估集反复验证是否引入幻觉、遗忘或模板化。你可以把它理解成“先教礼貌再教分寸”。礼貌是 SFT 的责任分寸往往要交给偏好对齐和评测约束。3.3 三组最容易混淆的概念先理清再动手第一组是 tokenizer 和模型本身。tokenizer 不是模型权重的一部分它是模型之外负责文本与 id 互转的组件。训练时可以对它做冻结也可以新增 token 后训练 embedding但调用 pipeline 时必须保证训练和解码使用同一个 tokenizer否则会出现越界 id 或无法还原的乱码。第二组是“预训练”“微调”“post training”的边界。关于 post training 的命名不同团队习惯不同但基本上它指预训练之后为了让模型适用于实际任务而做的所有训练阶段。理解的时候不要死记名称而是看数据形态和损失函数。训练阶段典型数据形态损失覆盖目标相对成本领域继续训练领域原始文本通常覆盖整个序列补充领域知识、适配文本风格高指令微调 SFT指令-回复对通常只覆盖回复部分学会遵循指令与任务格式中偏好对齐偏好成对样本成对排序目标输出符合人类偏好中高第三组是“模型会生成”和“模型做得对”。一个模型能流畅输出句子不代表它真正理解了任务边界。科普内容里最常见的过度承诺就是把“看起来像”误写成“真的会”。做实验时不要只看样例顺不顺要设计能区分运气和能力的评测用例。4. 决定后训练上限的往往不是模型而是语料质量4.1 高质量中文语料不是“收集一堆文章”就行把前文串起来会得到一个容易被低估的结论post training 的瓶颈经常不在模型参数规模而在训练语料质量。句子层面的“质量”通常包含几层意思文本干净、格式统一、内容多样、来源可追溯、与目标场景匹配。很多 NLP 新手在准备中文语料时第一反应就是收集大量中文网页。网页文本天然带有导航、广告、版权声明、重复页、模板段等噪声如果直接喂给模型模型学到的不只是语言还有大量与任务无关的分布。更麻烦的是重复内容。模型对重复非常敏感同样的段落出现几十次会使训练分布偏移容易导致模型输出套话和复读。数据来源也需要谨慎不是所有网络内容都能随便拿来做训练。常见实践里会先区分公开语料、已授权数据、开源数据集和自建业务语料不同来源的清洗策略不同。自建语料涉及个人信息时还需要做脱敏这些不是可有可无的后处理而是决定语料能否长期使用的合规底线。4.2 数据清洗的标准动作与验收方式清洗流程很难设计成完全线性实际项目里会反复迭代。但新手可以先按这个顺序跑格式统一与解码校验把文件统一成 UTF-8过滤乱码、非法字符、错误的 HTML 实体。规则过滤去掉超短内容、广告模板、无意义符号、过多链接或脚本片段。去重先做精确去重再做基于 MinHash 的近似去重。这个步骤经常能去掉一半以上的重复样本。质量过滤用规则或小模型打分筛掉机器翻译痕迹明显、中英混杂异常、语义不完整的文本。安全与隐私过滤剔除危险内容和包含真实个人敏感信息的样本。均衡与多样性检查统计领域来源、文本长度、时间分布避免单一来源主导。这套流程结束后还需要一次“token 化验收”。抽取几千条样本调用目标 tokenizer 计算长度分布检查是否有异常超长或过短文本确认 decode 能无损还原原始内容。为什么要做 token 级验收因为真正进入训练的是 token 序列而不是原始文本。如果这一步不做就会出现原始文本看起来没问题、token 化之后却有许多断开标记和乱码的情况。4.3 格式一致性、模板一致性和评估一致性除了语料本身的干净程度post training 里还有一个非常隐蔽的高频踩坑点训练格式与推理模板不一致。常见开源模型会有一套 chat template决定 system、user、assistant 消息如何拼成模型输入的 token 序列。如果在训练 SFT 数据时没有使用这套模板或者把损失错误地覆盖到指令部分模型在推理时遇到模板里的特殊 token就可能出现生成中断、额外输出标签名、来回重复对话等诡异现象。这类问题不容易在 loss 曲线上看出来必须靠人工比对训练输入和推理输入来做排查。我在做项目时有一个习惯进入正式训练前先构造同一条指令的两种写法——一种是按官方模板拼好的一种是不加模板直接拼接的文本分别发给同一个 base 模型看输出。如果官方模板都会出错大概率是当前代码版本和模型版本不匹配这个时候不应该急着训练而应该先修通模板链路。同样重要的是评估一致性。post training 开始之前就应该准备 20 到 50 条覆盖目标能力的评测样例问题要固定答案标准要提前写好。对大多数小规模实验来说先看指令遵循度、格式稳定性、知识保留度、重复度和幻觉率这五个维度已经能抓住主要问题。5. 从 tokenizer 到 post training一条低成本可执行的实验路径5.1 三步递进先观察再微调后对比如果你也想通过动手来理解整条链路推荐一个三步递进方案。第一步做 tokenizer 体检。用一段简单的 Python 代码加载目标模型的 tokenizer看它对中文样本的切分结果。from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained(your-model-name) text 自然语言处理中的 tokenizer 决定了模型如何理解文本。 ids tokenizer.encode(text) print(token 数量:, len(ids)) print(切分片段:, tokenizer.convert_ids_to_tokens(ids)) print(是否无损还原:, tokenizer.decode(ids) text)这里的模型名要替换成你实际使用的开源模型。重点不是跑通代码而是看切分片段里有没有意外的断词、特殊符号处理和长度膨胀。第二步做小规模 LoRA SFT。先选一个 base 模型准备几百到几千条公开可用的指令-回复对用常见训练框架做一次 LoRA 微调。训练时不要一上来就追求效果而是先确认数据加载、模板拼装、损失遮蔽和日志记录都符合预期。跑完后一定要在未参与训练的评测集上做生成测试。第三步对比打分。把相同问题分别发给 base 模型和 SFT 后的模型按指令遵循度、格式稳定性、知识保留度、重复度和幻觉率记录差异。如果 SFT 只是让模型变得话多但能力没有提升说明数据或者训练目标出了问题如果模型开始遗忘原有知识说明数据配比或训练轮数需要调整。5.2 遇到问题按这个顺序排查在 post training 的实践里问题通常不是只从一个点冒出来的。可以参考下面的排查顺序如果输出乱码、出现未知标签或不闭合的特殊符号先检查 tokenizer 路径、chat template 和特殊 token id再检查训练数据是否包含不匹配的模板片段。如果训练 loss 不降或震荡先检查数据格式、标签遮蔽和学习率再看批次大小与梯度累积设置。如果生成结果高度重复先查数据重复率、训练轮数、学习率再用困惑度或多样性指标辅助判断。如果模型出现明显知识遗忘先检查 SFT 数据是否过于聚焦单一任务、语料是否足够多样、学习率是否过大。s推荐建立一个小而稳定的复现样本集。每次修改数据、参数或模板后先跑二三十条样例再决定是否继续训练。这套方法虽然原始但能帮你把“玄学训练”变成“可追踪实验”。5.3 想把这条链路讲明白适合科普内容的“四层讲解法”题目里提到“制作 post training 科普内容”如果你也想把这条技术链路讲给普通开发者推荐用四层讲解法来组织而不是按论文时间线平铺。第一层给一个可见的现象。比如展示同一段中文在不同 tokenizer 下 token 数量差异很大的例子先让读者产生直观感受。现象比定义更能打开人脑的接收通道。第二层拆最小的机制链路。不需要一次讲完 BPE 的所有细节只需要讲清楚“原始文本 → token id → 向量”这条主链以及为什么这一步会影响上下文长度和训练成本。第三层做一个可复现的小实验。让读者亲手运行 10 行代码观察真实 token 序列。没有动手过程读者就只能记住概念记不住因果。第四层划清楚边界。讲完一个方法后一定要说它适合什么、不适合什么。比如 LoRA 适合小规模快速验证但不适合要彻底改变领域能力的场景。边界感是专业科普和营销文的本质区别。走到这里再回头看开头那句话post training 的问题经常不在 post training 本身而在更早的 tokenizer、语料和数据格式里。如果你现在只打算做一件事我建议先做一次 tokenizer 体检。花半小时确认目标模型如何看待你的中文文本比盲目开始一次微调更有价值。理解 NLP 的正确顺序不是从模型结构到应用而是从文本进入模型的第一个关口开始一路走到训练目标和评估标准。训练可以在一天内跑完而正确的文本边界意识和数据判断力才是真正长期起作用的东西。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价