资讯动态

语言模型核心脉络与工程实践:从N-gram到Transformer

发布时间:2026/10/20 16:27:06 来源:尧图企业网站定制
做了这么多年NLP相关项目我越来越觉得“语言模型”这个词被用得太随意了。外行以为它是某个具体的软件内行知道它其实是一个贯穿整个自然语言处理的核心框架。这篇内容我会从一个实践者的视角把语言模型最关键的几条脉络讲透包括它到底在解决什么问题、不同架构之间的核心差异、以及你在真实项目中会踩到的那些细节坑。不管你是刚开始接触NLP还是已经在做模型微调这篇内容应该都能给你一些可落地的参考。1. 语言模型到底在解决什么问题1.1 一个看似简单但极其核心的任务定义先抛开所有复杂的术语从最原始的直觉说起。语言模型本质上做的一件事就是预测一个句子出现的概率或者说评估一段文本在某种语言里“像不像人话”。数学上我们把一个句子 (S w_1, w_2, ..., w_n) 的概率拆解成条件概率的连乘形式[ P(S) P(w_1) \times P(w_2|w_1) \times P(w_3|w_1,w_2) \times ... \times P(w_n|w_1,...,w_{n-1}) ]这个公式看起来平平无奇但它背后隐含的逻辑非常深刻语言不是一堆词的无序堆砌而是有强序列依赖的结构。我们每一次生成一个词都依赖前面已经出现的所有词。这个“根据前文预测下一个词”的机制就是几乎所有现代语言模型的基石。我在实际项目中经常用一个类比帮助新同事理解语言模型就像一个不断做“接龙”游戏的人。你给它前半句话它凭借自己对语言规律的统计推测最可能的下一句接什么。接得越准说明它对语言的理解越深。而它“理解”到的规律既可以用来生成文本GPT系列的思路也可以用来判断一段文本的质量比如机器翻译的结果是否通顺。1.2 语言模型的三大实际价值理解了任务定义我们再看它在工业界到底凭什么如此重要。我总结为三个层面生成能力通过不断预测下一个词并采样模型可以产出全新的文本。从早期的聊天机器人到现在火爆的各类大模型写作助手其底层都是这个逻辑。评估能力既然模型能算出句子概率它自然能判断“这句话比那句话更自然”。这在机器翻译、文本纠错、语音识别重打分等场景中是刚需能力。翻译结果通不通顺不再需要人工一条条看直接拿语言模型打分就行。特征表示能力这是最容易被忽略的一点。为了预测下一个词模型必须把前面的句子压缩成一个有意义的向量表示。而这个向量恰恰就是下游任务比如情感分类、命名实体识别最宝贵的特征输入。很多经典做法是拿语言模型当“特征提取器”而不是直接用它在生成。所以你会发现语言模型不是某个具体功能模块它更像是一个“基础设施”。你要做文本生成、做语义匹配、做意图识别本质上都可以回归到语言模型的范式里。2. 从N-gram到神经网络统计时代的语言模型2.1 N-gram模型的核心假设与实操细节神经网络语言模型NNLM成为主流之前统治学术界和工业界的是N-gram模型。它解决问题的思路非常朴素既然完整计算前n-1个词依赖所有历史几乎不可能那我做一个简化假设——第n个词只与前n-1个词有关这就是马尔可夫假设在语言建模中的应用。实际操作时我们会从海量语料中统计所有相邻词组的出现次数。以二元模型Bigram为例(P(w_n|w_{n-1})) 直接等于“(w_{n-1} w_n) 这个组合的出现次数”除以“(w_{n-1})单独出现的次数”。看起来很简单但做过的都知道落地时全是细节。统计稀疏是第一个绕不过去的坎。语料的规模再大也永远有没见过的词组合。假设你的词表是10万词二元组合就有100亿种可能绝大多数组合在语料里出现次数为0。这时候直接算条件概率分子分母都是0模型就废了。解决办法就是平滑技术。我最早做项目时用了最简单的加1平滑拉普拉斯平滑把每个组合的次数都加上一个很小的常数虽然解决了零概率但效果其实一般。后来在工业级项目里更常用的是Kneser-Ney平滑它的核心思想是一个词出现在新语境中的概率不应该只看它作为接续词出现了多少次而应该看它之前在多少种不同语境中出现过——这个细节当时把我从“调参泥潭”里救了出来。2.2 N-gram的致命短板与现代语言的维度灾难如果你以为N-gram的麻烦只是平滑那就太天真了。它最大的硬伤在于窗口太短无法建模长距离依赖。语言里有很多跨句的指代关系比如“小明买了一辆车第二天他发现___出故障了”空缺处指的是车但车这个词出现在十几个词之前。五元模型最多也只能看到前4个词这种跨距离的依赖它完全无能为力。还有一个更深层次的问题叫维度灾难。用One-hot方式表示词每个词是词表大小维度向量里的一维。N-gram统计的实际上就是这些离散维度上的联合分布维度越高数据越稀疏需要的语料量呈指数级增长。而且它完全无法理解词与词之间的相似性——“猫”和“狗”在N-gram眼里是两个毫无关联的孤立符号这对泛化是致命的。所以N-gram本质上是一个离散符号的统计机器它看不见语义只能记住表面共现频率。当数据量变大、任务变复杂时它的瓶颈就非常明显了。这也是为什么当神经网络出现NLP领域立刻迎来了一次范式转移。3. 神经网络语言模型词嵌入与循环网络的突破3.1 词嵌入如何破解“符号鸿沟”神经网络语言模型NNLM最早的突破之一就是把“词”从离散的One-hot符号变成了稠密的低维实数向量也就是词嵌入Word Embedding。这一步的意义怎么强调都不过分。One-hot表示空间巨大但结构稀疏两个词之间的相似度永远是0。而词嵌入把每个词映射到固定维度比如300维的连续向量空间语义相近的词会在空间中聚在一起。产生这种神奇效果的根本原因是预测下一个词的任务反向倒逼模型把词的上下文共性压进向量里。“猫”和“狗”经常出现在类似的上下文中“_在追老鼠”、“_很可爱”它们的向量自然就接近了。我印象很深的是一次做相似词检索的小实验训练完词嵌入后输入“中国 的 首都”直接用向量做加减得到的结果向量和最接近的词是“北京”。那一刻你会真切感受到模型不是死记硬背规则而是从数据里发现了某种分布式语义结构。这也是后来一切大规模预训练模型的基础逻辑。3.2 从RNN到LSTM为什么要引入“记忆机制”词嵌入解决了表示问题但还没解决序列建模问题。早期的滑动窗口模型虽然能利用词嵌入但窗口大小依然固定无法适应任意长度的依赖。RNN的出现改变了这个局面它的核心公式非常简洁[ h_t f(W \cdot h_{t-1} U \cdot x_t) ]每一步把当前输入 (x_t) 和上一步的隐藏状态 (h_{t-1}) 融合输出新的隐藏状态 (h_t)。理论上这个结构可以把之前所有时间步的信息都编码在最终状态里很优雅。但我在实际操作中很快就遇到了RNN的经典问题梯度消失和梯度爆炸。原因是反向传播时梯度要沿着时间步逐层回传。如果每一步的雅可比矩阵最大特征值小于1多层连乘之后梯度会指数级衰减到0大于1则会指数级爆炸。结果是RNN根本学不会十几步以上的长距离依赖——它在数学上“理论上可以”在实际训练里“完全做不到”。LSTM通过门控机制解决了这个问题。它引入了遗忘门、输入门、输出门三个开关核心创新在于一条贯穿所有时间步的“细胞状态”高速公路。梯度可以在这条路上几乎无损地流动需要记忆的信息被选择性保留不需要的就被遗忘门滤掉。当年我在短文本分类任务里对比RNN和LSTM同样的数据、同样的训练轮数LSTM在涉及远距离指代的任务上准确率能高出将近10个百分点差距非常直观。但LSTM也远非完美。它的顺序计算特性让训练无法并行每一步必须等前一步算完。到了今天当语料规模达到万亿级tokens时这种顺序依赖就变成了无法容忍的训练瓶颈。这也是Transformer能后来居上的原因之一。4. Transformer架构注意力机制如何彻底重塑语言模型4.1 自注意力的核心直觉与计算逻辑Transformer抛弃了循环结构完全依赖注意力机制来建模序列关系。我第一次理解自注意力Self-Attention时最大的顿悟是它对“依赖”的处理方式和RNN完全不同。RNN是逐步传递信息靠隐藏状态接力跑完整个序列自注意力是直接计算任意两个位置之间的关联权重一步到位。具体过程是这样的对序列中每个词的嵌入向量 (x)分别乘以三个权重矩阵得到查询向量 (Q)、键向量 (K) 和值向量 (V)。某个词作为查询要和序列中所有词作为键计算相似度分数这个分数经Softmax归一化后作为权重对所有词的值向量加权求和就是该位置的新表示。打个比方自注意力就像开一场全员参与的圆桌会议。每一个词都在问“谁和我的关系最密切”关系越密切的词我听取它的意见越多。整个序列的所有词可以同时互相“开会”不存在谁等谁的问题因此可以大规模并行计算从底层解决了训练效率问题。多头注意力则是对这个机制的进一步扩展。它不只用一组 (Q/K/V)而是用多组并行的投影捕捉不同维度的依赖关系。比如一个头在关注语法上的主谓关系另一个头在关注指代关系另一个在关注词组的内部结构。这些关系特征拼接在一起极大丰富了模型表达。4.2 位置编码和残差连接两个容易被忽视却极其关键的设计Transformer里没有循环结构序列顺序信息必须显式注入。这就是位置编码Positional Encoding存在的意义。经典做法是使用不同频率的正弦和余弦函数生成位置向量加到词嵌入上。为什么用三角函数而不是直接编码位置序号我当时的理解是三角函数生成的向量在不同位置之间有平滑的相对关系而且任意两个位置的内积只和它们的相对偏移有关这有利于模型学习相对位置模式。如果你自己实现过Transformer你一定会注意到残差连接和层归一化不是可有可无的设计。原始Transformer每个子层自注意力、前馈网络都包了一个“残差分支”输入直接加到子层输出上。这个设计极大缓解了深层网络的梯度消失问题让几十层甚至上百层的模型也训练得动。层归一化则让数据分布更稳定加快收敛速度。我调试自己搭的Transformer时去掉残差连接十几层模型训练loss立刻就不下降了可见这些组件缺一不可。还有一个实际工程里很关键的点注意力复杂度是序列长度的平方。长度为1024的序列自注意力要计算约100万对位置的关系。所以直接用Transformer处理超长文档时显存和算力都会爆炸。后面的稀疏注意力、滑动窗口注意力、FlashAttention等改进都是在围绕这个问题做优化。4.3 从语言模型范式到预训练微调为什么GPT和BERT殊途同归Transformer架构本身是一个通用的序列编码器但要变成真正好用的语言模型还需要定义“学习目标”。这里走了两条路线代表模型是GPT和BERT。GPT采用自回归目标本质上就是第一节说的“预测下一个词”。它的注意力是带掩码的每个位置只能看到左侧的上下文。训练时把语料里每句话的下一个词作为监督信号模型不断做接龙。因为生成时就一个词一个词地往右“续写”天然契合文本生成任务。BERT则是掩码语言模型目标将语句中15%的词用[MASK]替换模型需要根据双向上下文预测被遮住的词。它能看到完整句子除了被掩码的词因此捕捉上下文信息更全面在理解类任务分类、抽取、判别上表现优异。我在实际项目里对两者的选择标准很直接任务是生成式写文案、写代码、翻译首选自回归模型任务是理解式意图识别、情感判断、抽取优先考虑双向模型。但随着模型体量不断增大、指令微调和人类反馈对齐技术的成熟大尺度的自回归模型通过通用的“预测下一个词”目标也能在理解任务上做得非常出色。两种路线正在收敛很多场景下不再需要刻意区分了。Transformer还带来一个极其重要的概念——预训练与微调范式。模型的绝大部分知识在海量无标注语料上通过语言模型目标学习得来然后把模型适配到具体任务时只需要少量标注数据做微调。这彻底改变了NLP项目过去那种“每个任务都要从零搭模型、搞特征工程”的流程。你微调一个预训练模型和在“一张白纸”上重新学效果差距是碾压性的。5. 语言模型的理论评估与实际项目落地中的差距5.1 困惑度PPL怎么算、怎么看、有哪些陷阱语言模型最经典的评估指标是困惑度Perplexity, PPL定义为模型对测试集句子概率的几何平均值的倒数[ PPL \exp\left(-\frac{1}{N}\sum_{i1}^{N}\log P(w_i | w_{i})\right) ]直觉上困惑度可以理解为“模型在每一步平均面临多少个候选词的选择”。困惑度越低模型对下一个词的预测越确定说明它对语言规律的把握越好。小规模语言模型在通用语料上PPL做到几十就很不错而如今大模型在特定领域语料上可以把PPL压到个位数。但在真实项目中我强烈建议不要只看PPL。它有一个很大的问题它衡量的是模型对“训练分布”的拟合程度不代表它在真实业务任务上的表现。我遇到过不止一次的情况A模型的PPL明显低于B模型但在下游情感分类任务上B模型反而更准。原因是A模型更“擅长”记住训练数据里的统计规律而B模型的表示空间更贴合任务的判别边界。另外PPL对不同分词方式、不同领域非常敏感。在医药领域语料上通用模型和垂直模型的PPL会差出很大换个任务类型结论可能又反转。所以我的习惯是用PPL做训练过程中的快速监控指标但最终决策必须结合具体业务指标准确率、召回率、生成质量人工评估等一起判断。5.2 从语言模型到实际业务系统的顺序适配与调优路径当你决定用一个语言模型解决真实业务问题时落地路径通常分为四步每一步都有我踩过的坑值得分享基座模型选择先明确任务类型、数据规模、算力预算。如果做英文通用生成直接用现成的大模型API可能最划算如果涉及中文垂直领域或者数据隐私要求高才需要考虑自部署中小规模的模型。我从不对“参数量”盲目崇拜模型不是越大越好推理成本和延迟在很多业务场景中比多一个点的准确率更致命。数据与分词适配中文训练数据分词策略会影响词表构建和模型效果。近年来的实践更倾向于用字节对编码BPE直接处理原始文本很多中文模型也不再单独分词而是直接用字符或子词单位。做垂直领域时一定要把领域术语和专有名词纳入词表否则模型会把“心肌梗塞”切成“心肌”“梗”“塞”语义信息直接碎掉。微调策略数据量小几千条时全参微调容易过拟合用适配器Adapter或低秩适配LoRA更稳妥参数量少、不易破坏预训练知识数据量大超过10万条时全参微调能发挥出最大上限。我在很多项目里都是用LoRA快速验证任务可行性确认有效再上全参训练节省大量试错成本。推理优化与部署大模型推理时的显存占用主要在KV缓存上计算瓶颈在自注意力的矩阵乘法。实际部署中我会优先考虑KV Cache复用、批量动态padding、以及量化技术比如INT8或INT4量化能在精度损失极小的情况下把显存占用压到原先的四分之一甚至更低。这个部分在下一节展开讲。5.3 生成质量评估为什么业务指标比PPL更可信最后我特别想强调一件事语言模型的效果评估永远不要脱离具体业务场景。如果你做的是客服自动回复真正该看的是首轮解决率、用户满意度、人工转接率如果你做的是机器翻译要看BLEU值但也要结合人工抽检因为BLEU对同义词改写很不敏感如果你做的是文本摘要ROUGE指标只能反映字面重叠真正的信息覆盖率还得靠人工判断。PPL和这些业务指标之间经常不是单调关系我在前文也说了见过不少次PPL更优但下游效果更差的案例。所以我在团队里一直推行“双轨评估”机制用PPL做训练过程的辅助监控用一组固定的业务测试集每条都标注好标准答案或人工评分来衡量每个训练检查点的实际效果。业务测试集规模不用大精心设计两三百条就足够发现模型之间的显著差异。语言模型终究是手段业务结果才是目的这个认知越早建立你在真实项目里走的弯路就越少。6. 大模型时代的推理优化显存、速度与精度如何权衡6.1 KV Cache和批处理策略最容易忽略的“免费午餐”大模型推理和传统小模型推理有一个显著差异生成阶段是逐token进行的而且每个token都要计算与前面所有token的注意力。如果每一步都重新计算一遍历史token的键值向量那成本是不可接受的。KV Cache就是把历史token的Key和Value缓存在显存里每生成一个新token只计算它的Key/Value然后追加到缓存中。这个优化几乎没有精度损失收益却是几十倍的推理速度提升。但在实际部署中KV Cache的显存占用会随着序列长度线性增长。长对话场景里缓存可能占掉整个显存的一半以上。我见过不少同学部署模型后刚开始对话正常聊到第三十几轮就报显存溢出一查没优化KV Cache只能牺牲并发数硬扛。所以做服务端推理时一定要预估最大上下文长度给KV Cache提前分配显存预算。批处理策略是另一个关键点。LLM推理时不同请求的输入输出长度差异很大如果按最长的做padding短的请求会产生大量无效计算。连续批处理策略则动态管理批内的请求某个请求生成结束时立即移除它换入新请求让GPU利用率始终保持高位。实测下来这种调度策略能把推理吞吐量提升一两倍不用换硬件就有显著收益。6.2 量化、蒸馏与模型压缩精度损失的边界在哪里模型压缩是平衡工程成本和效果的核心手段。我实践中常用的三种方法各有优劣量化Quantization把FP16权重转为INT8或INT4。INT8量化在绝大多数任务上几乎不掉点INT4量化会有轻微损失但显存占用降低到接近1/4一些最新量化方法结合精细校准数据损失可以控制在1%以内。我刚做部署时不敢用INT8硬扛FP16导致显存爆炸后来在验证集上对比INT8和FP16在意图分类任务上准确率差别不到0.3%果断全线上INT8。知识蒸馏Distillation训练一个小模型去模仿大模型的输出分布。核心是让小模型学习大模型的软标签——不仅是最终答案还包括每个候选标签的概率分布。软标签里包含了大模型学到的模糊性和语义距离这是硬标签无法提供的监督信息。我试过把一个7B模型蒸馏到1B规模在特定任务上效果保留了90%以上推理延迟却降低了一个数量级。结构剪枝Pruning直接移除权重矩阵中不重要的行或列。传统剪枝在Transformer架构上效果不稳定因为注意力头对层的依赖很强。最近的一些结构化剪枝方法比如移除整个注意力头或前馈网络的某些维度结合重训练能压缩20%-30%参数而不明顯掉点。我对剪枝持谨慎乐观态度通常先做量化再视情况决定是否剪枝。这套“组合拳”的经验是先做量化再评估不够再上蒸馏最后才考虑剪枝。顺序反了排查问题会非常痛苦。6.3 以业务目标为终点的部署策略还有一个常常被忽略的点部署语言模型时延迟和吞吐量的目标值应该由业务需求决定而不是技术部门习惯性压到最低。如果是面向用户的实时对话你可能需要首token延迟低于300毫秒这种情况下模型体量不能过大KV Cache和批大小都需要以延迟为优先调度如果是离线批量文本处理比如每天批量生成几万条商品描述你可以把吞吐量拉满延迟高一点没关系批大小和量化策略可以更激进如果是To B的私有化交付还要考虑客户显卡的显存容量和是否支持特定算力特性。我见过有人为了“模型效果最佳”硬上一个超大规模模型结果业务方预算超标、上线延期也见过有人为了极致的推理速度把一个好端端的任务级小模型压到效果严重退化用户投诉率飙升。语言模型的部署选择本质上是效果、成本、体验三者的工程折中而不是单一维度的技术秀。你越早用业务的尺子来衡量模型项目就越稳定。7. 轻量级语言模型的自训练实践从数据到Loss的完整实现7.1 数据准备与词表构建中文场景的独特细节如果不想完全依赖现成大模型API想自己从零训练一个小规模语言模型比如用于内部特定任务的轻量基座这里有一条我亲测可行的路线。第一步是数据准备。数据质量远比数据量大重要我见过很多研究项目堆了海量爬虫数据结果模型学会的是一堆噪声。我的做法是先用规则过滤清洗去重、去噪、去HTML标签、过滤低质量句子再做一遍基于困惑度的数据筛选——用一个现成的中型预训练模型对每段文本打困惑度分数分数过低的通常都是乱码或重复文本。这个“模型辅助清洗数据”的思路在大模型时代性价比极高。词表构建上中文语料我通常直接训练一个BPE词表大小设在30k-50k之间。比纯字符级能压缩序列长度比大词表更省embedding参数。要注意BPE训练时要尽量覆盖领域术语和常见人名地名词否则推理时会切成碎片。7.2 模型结构与训练细节Loss曲线的实际解读模型结构方面中小规模参数量从几千万到几亿我推荐直接用标准Decoder-only Transformer架构设置6-12层、hidden size 512-768、8-12个注意力头。规模再小就不适合硬套Transformer了可以退回LSTM甚至N-gram。现代框架无论是开源深度学习框架还是各种大模型训练工具对Transformer的优化已经非常成熟没必要自己发明变体。训练时的关键参数我分享一下实际经验批量大小小规模训练可以采用更大的批大小比如每批32-64条序列配合梯度累积。这能让梯度估计更稳定loss曲线更平滑。学习率建议配合调度策略先线性预热几百步再余弦衰减。峰值学习率一般设在1e-4到3e-4之间过大会导致loss震荡过小会导致收敛极慢。我在自己的小模型上做过对比同样的数据峰值学习率3e-4比1e-4最终PPL低约8个点。训练轮数小语料上两到三轮就会过拟合大语料上要根据dev PPL动态判断别盲目跑满固定轮数。看Loss曲线时我最关注两点一是训练loss和验证loss的差距差距持续拉大就是过拟合信号需要增加数据量或加强正则二是loss曲线的下降趋势是否已经很平缓如果平台期持续太长时间要考虑调整学习率或数据分布而不是继续无脑训练。这些小细节直接决定你的语言模型是“能用”还是“好用”。7.3 小模型生成的常见退化和应对措施小模型训练好后你会发现一个常见问题生成文本有重复和退化现象。模型倾向于反复输出自己最“确信”的高频词导致绕圈或复读。经典的应对手段包括温度采样Temperature Sampling对Softmax输出分布做温度缩放。温度越低分布越尖锐输出越保守温度越高分布越均匀输出越多样。但温度也不能盲目调高太高了会语无伦次。我一般从0.8起步做主观评估。Top-k / Top-p采样限制候选词范围。Top-k只从概率最高的一小批词中采样Top-p则按累积概率截断。两者结合能有效避免低概率噪声词影响生成质量。实际操作时我更喜欢Top-p一般设为0.9-0.95因为它是自适应地决定候选集大小。重复惩罚Repetition Penalty对已经出现过的词施加一个大于1的惩罚因子压低它再次被选中的概率。这个技术在长文本生成中几乎是必需的不然很容易在某几个词上卡死。不要指望单靠一个参数解决所有退化问题我在项目里都是把温度、Top-p、重复惩罚一起调然后在固定测试集上做人工对比选一个组合方案固化下来。生成质量这种体验型指标最终判断还是要回到人的主观感受上这也是语言模型项目里“人工评估占比”一直很高的原因。8. 关于语言模型未来发展和个人实践的一点思考语言模型这条技术路线从N-gram的统计共现到神经网络的分布式表示再到Transformer的前所未有的大规模预训练走了将近三十年。中间每一次转折都是因为旧范式撞上了某个绕不过去的瓶颈数据稀疏、梯度消失、训练低效。如今的大模型范式本质上是在“规模”这条路上把语言模型的能力推到新的高度但你如果深入理解它的底层会发现核心机制仍然是那件事根据前文预测下一个词。我在实际项目中的体会是语言模型越强大对使用者的判断力要求反而越高。模型会给出看起来很“自信”的答案但你需要知道它在哪些数据上靠谱在哪些场景下会一本正经地胡说八道。你需要设计评估体系、把控数据质量、选好压缩和部署策略。技术选型没有银弹大模型不一定比小模型好小模型也不一定比规则差一切取决于业务场景、预算和数据条件。如果你刚开始踏入这个领域我的建议是先动手训练一个哪怕只有几百万参数的小语言模型完整走一遍数据处理、训练、评估、生成调试的流程。只有亲手调过loss曲线、看过生成文本的退化、处理过显存溢出你才能真正理解语言模型的运作机理也才能在更大的模型和更复杂的工程场景中做出不盲目的判断。最后分享一个我反复使用的小技巧永远在固定的测试集上比较不同版本的模型不要让“感觉这个模型生成的文本更流畅”这种主观印象主导你的决策。建立一个不大但有代表性的评测集把PPL、业务指标、人工打分都记录下来版本迭代的每一步变化都有据可查。这一点坚持下来你会少走很多弯路。

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

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

免费获取报价 →
↑