<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Transformer 基础 on XyStart | AI Infra 博客</title><link>https://xystart.github.io/series/transformer-%E5%9F%BA%E7%A1%80/</link><description>Recent content in Transformer 基础 on XyStart | AI Infra 博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 16 Apr 2026 17:10:00 +0800</lastBuildDate><atom:link href="https://xystart.github.io/series/transformer-%E5%9F%BA%E7%A1%80/index.xml" rel="self" type="application/rss+xml"/><item><title>从 Transformer 到现代 LLM：大模型架构的“减法”美学</title><link>https://xystart.github.io/p/modern-llm-architecture-evolution/</link><pubDate>Thu, 16 Apr 2026 17:10:00 +0800</pubDate><guid>https://xystart.github.io/p/modern-llm-architecture-evolution/</guid><description>&lt;p&gt;如果说 2017 年的《Attention Is All You Need》是现代自然语言处理的“创世神话”，那么到了 2024 年，当我们拆开 GPT-4、Llama 3、Qwen 等千亿参数巨兽的引擎盖时，你会发现：&lt;strong&gt;它们早就不长当年那个样子了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;随着模型参数量从亿级（BERT）飙升到万亿级，原版 &lt;code&gt;Transformer&lt;/code&gt; 架构在 &lt;strong&gt;“显存开销”、“长文本处理”和“深层训练稳定性”上面临着巨大的物理灾难。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;现代大模型的发展史，本质上是一场 &lt;strong&gt;“工程向算力妥协”的减法美学&lt;/strong&gt;。这篇博客主要盘点：现在的 LLM，到底对 Transformer 做了哪些改进？&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一篇gpt-系列演化与三阶段开发范式"&gt;第一篇：GPT 系列演化与“三阶段”开发范式
&lt;/h2&gt;&lt;p&gt;当 2022 年 11 月 ChatGPT 掀起全球大模型技术狂潮时，很多人惊叹于它的“横空出世”。但事实上，这是一场长达四年的技术演进的必然结果。&lt;/p&gt;
&lt;p&gt;从 2018 年初代 GPT-1 诞生开始，OpenAI 就坚定地在一条技术路线上持续迭代。这期间，模型能力上限的不断突破，得益于四个核心维度的进化：&lt;strong&gt;模型规模（Scaling Law）&lt;/strong&gt;、&lt;strong&gt;训练语料&lt;/strong&gt;、&lt;strong&gt;网络架构&lt;/strong&gt;以及&lt;strong&gt;训练范式&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这四大维度的突破，不仅构筑了 ChatGPT 的技术基石，更标志着大语言模型正式跨越了学术研究与实际应用之间的鸿沟。今天，我们就来系统梳理 GPT 家族的发展脉络，探寻大模型“智能涌现”背后的核心机制。&lt;/p&gt;
&lt;h3 id="gpt-1"&gt;GPT-1
&lt;/h3&gt;&lt;h4 id="概述"&gt;概述
&lt;/h4&gt;&lt;p&gt;GPT-1（Generative Pre-trained Transformer-1）是 OpenAI 于 2018 年 6 月 发布的首个生成式预训练语言模型，其研究成果发表于论文《&lt;a class="link" href="https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf" target="_blank" rel="noopener"
 &gt;Improving Language Understanding by Generative Pre-Training&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;GPT-1 系统化地验证并推广了“预训练（Pre-training）+ 微调（Fine-tuning）”的训练范式：模型先在大规模无标注语料上进行语言建模预训练，再利用少量有监督数据在特定任务上微调。该方法显著提升了模型的迁移能力，使单一预训练模型能够适配多种自然语言任务。&lt;/p&gt;
&lt;h4 id="架构"&gt;架构
&lt;/h4&gt;&lt;h5 id="总体架构"&gt;总体架构
&lt;/h5&gt;&lt;p&gt;GPT-1 采用了 &lt;strong&gt;Transformer Decoder-only&lt;/strong&gt; 结构，也就是说只保留了 Transformer 模型的&lt;strong&gt;解码器（Decoder）部分&lt;/strong&gt;，并在此基础上进行了适配性调整。&lt;/p&gt;
&lt;p&gt;具体结构如下图所示，整个模型可分为输入层、Transformer Block层与输出层三个部分：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260417195251.png]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;输入层（Text &amp;amp; Position Embedding）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;将文本序列映射为词向量，并加入位置嵌入，用于表示词序信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transformer Block&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每个Transformer Block包含 Masked Multi-Head Self-Attention 和 Feed Forward Network 两个核心子层，并通过 LayerNorm 与残差连接保持稳定的梯度传播。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;输出层&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Text Prediction用于在预训练阶段输出下一个词的概率分布；Task Classifier用于在微调阶段适配下游任务。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="架构创新"&gt;架构创新
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decoder-only 结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从 Encoder-Decoder 架构简化为Decoder-only 结构，以适配自回归生成任务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;可学习位置嵌入&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用可学习位置嵌入，取代正弦位置编码，使模型能够在训练过程中自适应地学习词序关系。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权重共享机制&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;输入嵌入层与输出词表权重共享，减少参数量并提升训练稳定性。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="主要参数"&gt;主要参数
&lt;/h5&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数项&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数值&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;模型层数（Layers&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;12&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;隐藏维度（Hidden Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;768&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;注意力头数（Attention Heads&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;12&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;前馈层维度（FFN Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;3072&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数总量&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;1.17 亿&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="训练"&gt;训练
&lt;/h4&gt;&lt;p&gt;GPT-1 的训练采用了“&lt;strong&gt;预训练（Pre-training） +微调（Fine-tuning）&lt;/strong&gt;”的两阶段范式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;预训练阶段&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在预训练阶段（Pre-training），使用高质量英文语料 BooksCorpus（约 7,000 本小说，约 8 亿词）作为训练数据，以“给定前文预测下一个词（Next-Token Prediction）”为目标，在长篇连续文本中捕捉句法结构、词汇共现和语义依赖等特征，从而获得通用的语言建模能力。这一阶段让模型具备了理解与生成自然语言的基础能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;微调阶段&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在&lt;strong&gt;微调阶段（Fine-tuning）&lt;/strong&gt;，通过在模型顶部加入轻量的任务分类层（Task Classifier），并在少量标注数据上进行有监督训练，模型能够快速适应不同任务场景。结果表明，微调后的 GPT-1 在多个 NLP 任务上显著优于从零训练的传统模型，验证了“预训练—微调”范式的有效性与通用性。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gpt-2"&gt;GPT-2
&lt;/h3&gt;&lt;h4 id="概述-1"&gt;概述
&lt;/h4&gt;&lt;p&gt;GPT-2是 OpenAI 于 2019 年发布的第二代生成式预训练语言模型，相关研究发表于论文《&lt;a class="link" href="https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf" target="_blank" rel="noopener"
 &gt;Language Models are Unsupervised Multitask Learners&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;GPT-2 延续了GPT-1的 Transformer Decoder-only 架构，但参数规模提升了10倍。&lt;/p&gt;
&lt;p&gt;GPT-2 首次证明了大型语言模型具备&lt;strong&gt;零样本（Zero-shot）任务泛化能力&lt;/strong&gt;。模型无需任何下游任务微调，仅凭自然语言提示（Prompt）即可完成问答、翻译、摘要等任务，标志着语言模型开始具备跨任务的通用智能特征。&lt;/p&gt;
&lt;p&gt;此外，GPT-2 的实验系统揭示了显著的&lt;strong&gt;规模效应（Scaling Effect）&lt;/strong&gt;：随着模型参数与数据规模的增长，模型性能在多种任务上持续提升。这一发现奠定了后续超大规模模型（如 GPT-3 与 ChatGPT）的发展基础。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260417201858.png]]&lt;/p&gt;
&lt;h4 id="架构-1"&gt;架构
&lt;/h4&gt;&lt;h5 id="总体架构-1"&gt;总体架构
&lt;/h5&gt;&lt;p&gt;GPT-2 延续了 GPT-1 的 &lt;strong&gt;Transformer Decoder-only&lt;/strong&gt; 架构。&lt;/p&gt;
&lt;h5 id="架构创新-1"&gt;架构创新
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;规模扩展&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;参数量相比 GPT-1 提升约十倍，最大模型达到 &lt;strong&gt;15.42&lt;/strong&gt; &lt;strong&gt;亿参数&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LayerNorm&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;采用Pre-LayerNorm，缓解大模型训练中梯度不稳定问题。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260417202117.png]]&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="主要参数-1"&gt;主要参数
&lt;/h5&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数项&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数值&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;模型层数（Layers&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;48&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;隐藏维度（Hidden Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;1600&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;注意力头数（Attention Heads&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;25&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;前馈层维度（FFN Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;6400&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数总量&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;15.42亿&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="训练-1"&gt;训练
&lt;/h4&gt;&lt;p&gt;GPT-2 的训练仍采用 &lt;strong&gt;自回归语言建模（Autoregressive Language Modeling）&lt;/strong&gt; 目标，即在给定前文的条件下预测下一个词（Next Token Prediction），以学习文本的语法与语义规律。&lt;br&gt;
模型使用了 OpenAI 构建的 &lt;strong&gt;WebText&lt;/strong&gt; 数据集，规模约 &lt;strong&gt;40GB&lt;/strong&gt;，包含约 &lt;strong&gt;800&lt;/strong&gt; &lt;strong&gt;万篇网页内容&lt;/strong&gt;，涵盖新闻、小说、科技、娱乐、社交等多个领域，为模型提供了更广泛的语言风格与知识来源。&lt;/p&gt;
&lt;h3 id="gpt-3"&gt;GPT-3
&lt;/h3&gt;&lt;h4 id="概述-2"&gt;概述
&lt;/h4&gt;&lt;p&gt;GPT-3是 OpenAI 于 2020 年 5 月发布的第三代生成式预训练语言模型，研究成果发表于论文《&lt;a class="link" href="https://arxiv.org/pdf/2005.14165" target="_blank" rel="noopener"
 &gt;Language Models are Few-Shot Learners&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;GPT-3 延续了 Transformer Decoder-only 架构，但参数规模较 GPT-2 提升约百倍，达到了1750亿。&lt;/p&gt;
&lt;p&gt;GPT-3 的核心创新在于首次系统提出并验证了“上下文学习（In-Context Learning）” 的概念：模型在使用阶段无需额外训练，仅依靠输入文本中的任务描述及少量示例即可理解并完成任务，如下图所示。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260417202508.png]]&lt;/p&gt;
&lt;p&gt;GPT-3 的成功展示了大规模预训练模型在能力上的显著扩展，为后续更高层次的语言智能研究奠定了重要基础。&lt;/p&gt;
&lt;h4 id="架构-2"&gt;架构
&lt;/h4&gt;&lt;h5 id="总体架构-2"&gt;总体架构
&lt;/h5&gt;&lt;p&gt;GPT-3 延续了 GPT-1 的 &lt;strong&gt;Transformer Decoder-only&lt;/strong&gt; 架构。&lt;/p&gt;
&lt;h5 id="架构创新-2"&gt;架构创新
&lt;/h5&gt;&lt;p&gt;架构方面，与 GPT-2 相比，GPT-3 的主要区别在于在各个 Transformer Block 中交替使用稠密注意力（Dense Attention）和局部带状稀疏注意力（Locally Banded Sparse Attention）模式。&lt;/p&gt;
&lt;p&gt;局部带状稀疏注意力是一种仅在局部窗口内计算注意力权重的稀疏化机制，能够显著降低时间和空间复杂度。通过稠密与稀疏注意力的交替使用，GPT-3 能够兼顾全局信息和计算效率。&lt;/p&gt;
&lt;h5 id="主要参数-2"&gt;主要参数
&lt;/h5&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数项&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数值&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;模型层数（Layers&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;96&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;隐藏维度（Hidden Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;12288&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;注意力头数（Attention Heads&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;96&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;前馈层维度（FFN Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;49152&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数总量&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;1750 亿&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="训练-2"&gt;训练
&lt;/h4&gt;&lt;p&gt;GPT-3 依旧采用 自回归语言建模（Autoregressive Language Modeling） 方式进行训练。&lt;/p&gt;
&lt;p&gt;训练数据约 570GB，包含约3000亿token，覆盖新闻、百科、文学与学术等领域。&lt;/p&gt;
&lt;p&gt;模型在数千块 NVIDIA V100 GPU 上进行分布式并行训练，耗时数周完成。&lt;/p&gt;
&lt;h3 id="instructgpt"&gt;InstructGPT
&lt;/h3&gt;&lt;h4 id="概述-3"&gt;概述
&lt;/h4&gt;&lt;p&gt;InstructGPT 是 OpenAI 于 2022 年初推出的生成式预训练语言模型，是 GPT-3 的改进版本，也是后续 ChatGPT 的直接前身。其研究成果发表于论文《&lt;a class="link" href="https://arxiv.org/pdf/2203.02155" target="_blank" rel="noopener"
 &gt;Training language models to follow instructions with human feedback&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;GPT-3 在自然语言生成方面取得了突破性进展，能够通过精心设计的提示词（Prompt）完成多种任务，但其生成结果并非总能令人满意，常常与用户的真实需求存在偏差，甚至会产生一些不真实、有害或无用的内容。&lt;/p&gt;
&lt;p&gt;其根本原因在于，GPT-3 的训练目标仅是在大规模互联网文本上预测下一个单词，模型学习到的是语言的统计规律，而非如何理解和执行人类指令。换言之，模型尚未与人类意图保持一致（Alignment，对齐）。&lt;/p&gt;
&lt;p&gt;为解决这一问题，InstructGPT 在 GPT-3 基础上引入指令对齐训练，从而使模型能够更准确地理解并执行人类指令。&lt;/p&gt;
&lt;h4 id="架构-3"&gt;架构
&lt;/h4&gt;&lt;h5 id="总体架构-3"&gt;总体架构
&lt;/h5&gt;&lt;p&gt;InstructGPT延续了GPT-3的架构。&lt;/p&gt;
&lt;h5 id="架构创新-3"&gt;架构创新
&lt;/h5&gt;&lt;p&gt;InstructGPT并未在网络结构上进行新的改动。其主要创新点不在于模型设计，而在于&lt;strong&gt;训练范式&lt;/strong&gt;的变革。&lt;/p&gt;
&lt;h5 id="主要参数-3"&gt;主要参数
&lt;/h5&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数项&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数值&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;模型层数（Layers&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;96&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;隐藏维度（Hidden Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;12288&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;注意力头数（Attention Heads&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;96&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;前馈层维度（FFN Size&lt;/strong&gt;**）**&lt;/td&gt;
 &lt;td&gt;49152&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;参数总量&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;1750 亿&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="训练-3"&gt;训练
&lt;/h4&gt;&lt;p&gt;InstructGPT 的训练以GPT-3的预训练语言模型为基础，进一步采用了三阶段训练范式，具体步骤如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;监督微调（Supervised Fine-tuning, SFT）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在第一阶段，OpenAI 收集了由人工标注者撰写的高质量 “指令-回答” 样本，组成训练数据集。这些样本覆盖常见的用户指令及对应的理想响应，具有较高的语言质量。&lt;/p&gt;
&lt;p&gt;在训练过程中，模型在这些“指令-回答”对上进行监督微调，训练目标仍为“给定前文预测下一个词”（Next Token Prediction）。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260417203834.png]]&lt;/p&gt;
&lt;p&gt;通过该阶段，模型初步具备了理解并执行自然语言指令的能力，能够较好地完成指令驱动的任务响应。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;奖励模型（Reward Model, RM）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第二阶段构建奖励模型，用于后续强化学习过程中的反馈评估器。&lt;/p&gt;
&lt;p&gt;操作流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用经过 SFT 微调后的模型，针对同一条指令生成多个候选回答；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;人工标注者根据回答的质量、相关性、礼貌性、有用性等维度，对这些回答进行排序；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;利用排序结果训练一个奖励模型，使其能够为任意给定回答输出一个偏好评分。奖励模型的核心目标是模仿人类的偏好判断，为语言模型的输出提供方向性反馈。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;强化学习（Reinforcement Learning from Human Feedback, RLHF）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一阶段的核心目标是：&lt;strong&gt;通过人类偏好引导模型输出更加符合人类意图的回答&lt;/strong&gt;。它以第二阶段训练好的奖励模型为评分工具，使用强化学习算法（PPO），对第一步经过SFT微调的语言模型进行进一步优化。&lt;/p&gt;
&lt;p&gt;具体步骤如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;指令输入&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从预构建的指令数据集中选取一条指令，作为模型输入。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;模型生成回答&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用经过SFT微调的模型对指令生成回答。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;奖励模型评分&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用奖励模型对生成的回答进行打分。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;强化学习优化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;模型根据奖励模型打分的结果，调整自身参数，使其更倾向于生成高分回答。优化过程中使用了强化学习算法 PPO（Proximal Policy Optimization），目标是最大化奖励模型的评分。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;经过这一阶段的训练，模型能够更准确地理解人类指令，并生成更符合人类偏好、更加真实、有用且安全的回答，从而显著提升了语言模型在实际应用中的表现能力。&lt;/p&gt;
&lt;h3 id="chatgpt"&gt;ChatGPT
&lt;/h3&gt;&lt;h4 id="概述-4"&gt;概述
&lt;/h4&gt;&lt;p&gt;ChatGPT 是 OpenAI 于 2022 年 11 月发布的一种具备对话能力的大型语言模型。它支持连续的自然语言交互，能够回答后续问题、承认错误、质疑用户前提、拒绝不当请求，在用户体验与安全性方面取得显著改进。&lt;/p&gt;
&lt;h4 id="架构-4"&gt;架构
&lt;/h4&gt;&lt;h5 id="总体架构-4"&gt;总体架构
&lt;/h5&gt;&lt;p&gt;ChatGPT 是与 InstructGPT 同一技术路线下的兄弟模型，架构设计与 InstructGPT 类似，但具体细节未公开。&lt;/p&gt;
&lt;h5 id="架构创新-4"&gt;架构创新
&lt;/h5&gt;&lt;p&gt;InstructGPT并未在网络结构上进行新的改动。其主要创新点不在于模型设计，而在于&lt;strong&gt;训练范式&lt;/strong&gt;的变革。&lt;/p&gt;
&lt;h4 id="训练-4"&gt;训练
&lt;/h4&gt;&lt;p&gt;ChatGPT 的训练方法采用与 InstructGPT 相同的人类反馈强化学习（RLHF）策略，其核心区别在于数据集的设计与处理方式。&lt;/p&gt;
&lt;p&gt;ChatGPT 使用了特别构建的对话格式数据集。这些数据由标注人员通过模拟用户与 AI 助手的对话生成，内容更加贴近真实交互场景。相比 InstructGPT 所使用的“指令-单轮回答”数据，ChatGPT 所采用的数据具有多轮对话结构，强调上下文保持与连续问答能力。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260417204644.png]]&lt;/p&gt;
&lt;p&gt;此外，原有 InstructGPT 的数据也被统一转换为对话格式，与新收集的数据集成混合使用，以增强模型的对话泛化能力。整体数据处理流程重点在于适配对话场景，提升模型的多轮交互表现。&lt;/p&gt;
&lt;h3 id="总结"&gt;总结
&lt;/h3&gt;&lt;p&gt;GPT 系列的发展推动了现代大语言模型训练范式的逐步成熟，形成了以 “预训练—监督微调—对齐” 为核心的三阶段开发框架。如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;预训练（Pre-training）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;基于超大规模无标注语料进行自监督学习，使模型获得通用语言建模能力、广泛的世界知识以及基本的推理与泛化能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;监督微调（Supervised Fine-tuning, SFT）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;利用人工构建的指令—响应示例或高质量对话数据对模型进行进一步训练，使其能够更好地理解指令，并输出更加规范、稳定且贴合任务需求的内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对齐（Alignment）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;通过引入人类偏好、行为规范、安全约束与价值观等因素，使模型的行为更符合用户期望。对齐方式包括RLHF（奖励模型 + 强化学习）以及DPO、ORPO、KTO 等无需强化学习的偏好优化方法。对齐阶段的目标是让模型在真实应用场景中表现得更有帮助、更安全、更可靠。&lt;/p&gt;
&lt;p&gt;这一“三阶段”开发范式在实践中得到广泛验证，已成为业界主流的大语言模型训练框架。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第二篇现代-llm-的底层组件深度演进"&gt;第二篇：现代 LLM 的底层组件深度演进
&lt;/h2&gt;&lt;h3 id="llm架构"&gt;LLM架构
&lt;/h3&gt;&lt;p&gt;大型语言模型（LLM）大多基于 Transformer 架构构建，其中最常见的是 Decoder-only 架构。这一架构最早由 GPT 系列采用，并逐渐成为当前大多数主流模型的标准设计。LLM 的核心能力——理解语言、建模上下文、生成文本，都源于 Transformer 的模块化结构与高度可扩展性。&lt;/p&gt;
&lt;p&gt;从整体上看，一个典型的 LLM 可以分为 输入层、Transformer Block 堆叠层和输出层 三个部分，如下所述。&lt;/p&gt;
&lt;h4 id="输入层"&gt;输入层
&lt;/h4&gt;&lt;p&gt;输入层负责将原始文本序列转化为模型可处理的向量表示。文本首先经过分词处理，每个 token 会被映射为对应的&lt;strong&gt;词向量（Token Embedding）&lt;/strong&gt;，形成模型的基础语义空间。为了使模型能够感知序列顺序，还需要加入&lt;strong&gt;位置编码（Position Encoding）&lt;/strong&gt;。输入层的作用是为后续 Transformer Block 提供初始的语义与位置信息。&lt;/p&gt;
&lt;h4 id="transformer-block"&gt;Transformer Block
&lt;/h4&gt;&lt;p&gt;Transformer Block 是大型语言模型的核心计算单元，通常由几十到上百层堆叠而成。每个 Block 内部主要包含&lt;strong&gt;自注意力机制&lt;/strong&gt;和&lt;strong&gt;前馈网络&lt;/strong&gt;两部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自注意力机制&lt;/strong&gt;使模型能够在处理当前 token 时参考序列中其他位置的语义信息，从而捕捉长距离依赖关系；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;前馈网络&lt;/strong&gt;则对注意力输出进行非线性变换，提高模型的表达能力。为了确保深层结构的训练稳定性，Transformer Block 内部普遍采用残差连接与归一化技术，使梯度能够顺畅传播。大量堆叠的 Block 共同构成了 LLM 的主体结构，是模型理解语言和推理能力的来源。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="输出层"&gt;输出层
&lt;/h4&gt;&lt;p&gt;输出层用于将 Transformer Block 最终生成的隐含向量映射为词表中的概率分布，从而执行下一个 token 的预测。&lt;/p&gt;
&lt;p&gt;典型做法是使用一个线性投影层将向量映射到词表维度，并通过 Softmax 得到每个 token 的概率。现代模型通常采用输入词向量与输出投影层权重共享的方式，以减少参数规模并提升训练效果。输出层的结果被用于自回归生成，每次输出一个 token 并将其作为下一步的输入，使模型能够逐步生成连贯自然的文本。&lt;/p&gt;
&lt;h3 id="llm架构演进"&gt;LLM架构演进
&lt;/h3&gt;&lt;h4 id="概述-5"&gt;概述
&lt;/h4&gt;&lt;p&gt;自 ChatGPT 问世以来，各类大语言模型不断涌现，但其主体架构仍然基于 Transformer 的解码器，整体结构并未发生革命性变化。&lt;/p&gt;
&lt;p&gt;模型真正的演进主要体现在内部组件层面，包括注意力机制、前馈网络、归一化与残差结构以及位置编码等模块的持续改进。&lt;/p&gt;
&lt;p&gt;下面介绍各个组件的改进方向。&lt;/p&gt;
&lt;h4 id="attention"&gt;Attention
&lt;/h4&gt;&lt;h5 id="概述-6"&gt;概述
&lt;/h5&gt;&lt;p&gt;注意力机制（Attention）是 Transformer 中最核心的模块，用于刻画序列中不同位置之间的依赖关系，决定模型在生成下一个 token 时应如何利用上下文。其能力直接影响模型的语义理解、长程依赖建模与文本生成质量。&lt;/p&gt;
&lt;p&gt;随着模型规模不断扩大、推理序列越来越长，传统的多头注意力的问题逐渐暴露出来。为了解决这些问题，业界提出了一系列改进结构，在保持模型能力的同时显著提升了推理效率。&lt;/p&gt;
&lt;h5 id="mhamulti-head-attention"&gt;MHA（Multi-Head Attention）
&lt;/h5&gt;&lt;p&gt;MHA是Transformer最初采用的注意力机制，其通过将输入分别映射为多组 Query、Key、Value，并在多个注意力头上并行计算注意力分布，使模型能够从不同子空间捕捉序列关系，从而提升表达能力。&lt;/p&gt;
&lt;p&gt;尽管 MHA 在早期模型中表现良好，但随着模型规模不断扩大，其结构逐渐暴露出明显的工程瓶颈。要理解 MHA 的限制，需要先明确&lt;strong&gt;推理阶段&lt;/strong&gt;的一个关键概念——KV Cache。&lt;/p&gt;
&lt;p&gt;在自回归生成过程中，模型需要逐 token 地生成输出。对于每一个新 token，模型都会与所有历史 token 进行注意力计算。如果每一步都从头计算历史序列的 Key 和 Value，这将造成巨大的重复计算开销，如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418221241.png]]&lt;/p&gt;
&lt;p&gt;为了避免这种重复计算，模型都会在推理阶段将历史 token 的 Key 和 Value 缓存下来，供后续步骤直接使用。这一机制就是 KV Cache。通过缓存 K/V，模型在生成下一个 token 时只需计算当前 token 的 Q、K、V，再与缓存的 K/V 做一次注意力匹配即可，大幅减少了不必要的计算量，如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418221358.png]]&lt;/p&gt;
&lt;p&gt;KV Cache 的引入，虽然减少了重复计算，但需要持续保存过往 token 的 Key 和 Value。随着序列变长、模型层数增加，缓存量本身就会不断累积。并且在多头注意力（MHA）中，每个注意力头都会独立生成并存储一组 Key 和 Value，使得缓存规模在原有基础上进一步放大。这也构成了 MHA 在大模型推理中的主要问题。&lt;/p&gt;
&lt;h5 id="mqamulti-query-attention"&gt;MQA（Multi-Query Attention）
&lt;/h5&gt;&lt;p&gt;MQA（Multi-Query Attention，多查询注意力）是一种优化注意力机制的方案，旨在减少推理阶段 KV Cache 的存储与内存带宽开销。由Google于 2019 年 11 月发表在论文《&lt;a class="link" href="https://arxiv.org/pdf/1911.02150" target="_blank" rel="noopener"
 &gt;Fast Transformer Decoding: One Write-Head is All You Need&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;MQA 的核心思想是让多个注意力头共享同一套 Key 和 Value，而不是像传统 MHA 那样为每个头分别维护独立的 K/V。如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418221707.png]]&lt;/p&gt;
&lt;p&gt;这种共享方式大幅减少了需要缓存和读取的 K/V 张量量级，显著降低存储需求与内存带宽压力，从而大幅提升了推理速度。&lt;/p&gt;
&lt;p&gt;但这种共享机制会略微削弱注意力头的表达能力，使其精度略逊于传统 MHA，但整体损失非常小。
总体来看，MQA 以极小的精度代价换来了巨大的推理效率提升，是现代大模型推理加速的重要基础结构之一。&lt;/p&gt;
&lt;h5 id="gqagroup-query-attention"&gt;GQA（Group-Query Attention）
&lt;/h5&gt;&lt;p&gt;GQA（Group-Query Attention，分组查询注意力）是在 MQA 基础上的进一步改进方案，由 Google 在论文 《&lt;a class="link" href="https://arxiv.org/pdf/2305.13245" target="_blank" rel="noopener"
 &gt;GQA: Training Generalized Multi-Query Transformer Layers&lt;/a&gt;》中提出。该方法旨在在提升推理效率的同时，弥补 MQA 由于所有注意力头共享同一套 K/V 而造成的表达能力下降问题。&lt;/p&gt;
&lt;p&gt;GQA 的核心思想是：&lt;strong&gt;将注意力头划分为多个组（Group），每组内部的多个 Query 共享同一套 Key 和 Value，而不同组之间则使用独立的 K/V&lt;/strong&gt;，如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418222044.png]]&lt;/p&gt;
&lt;p&gt;这种结构本质上在 MHA 与 MQA 之间取得了折中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;相比 MHA：不再为每个头维护独立 K/V，从而大幅减少 KV Cache 的存储需求与内存带宽压力；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;相比 MQA：不再所有头共享唯一 K/V，而是分组共享，使注意力头间仍能保持更高的多样性和表达能力。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，GQA 在 推理效率 和 表达能力 之间实现了更优平衡。实际应用中，它比 MQA 能更好地处理复杂语义关系，同时仍保持较高的推理速度。&lt;/p&gt;
&lt;p&gt;总体来看，GQA 在仅增加极小计算与存储成本的前提下，显著增强了模型能力，因此被LLaMA、Qwen 等主流大模型所采用，在长序列推理和高并发场景中表现极为出色。&lt;/p&gt;
&lt;h4 id="feed-forward-network"&gt;Feed Forward Network
&lt;/h4&gt;&lt;h5 id="概述-7"&gt;概述
&lt;/h5&gt;&lt;p&gt;前馈网络（FFN）是 Transformer Block 中继注意力之后的第二大核心组件，用于对 token 表示进行独立的非线性变换。其典型的“升维 → 激活 → 降维”结构，使模型能够在每个位置上学习高维特征，是 Transformer 表达能力的重要来源。&lt;/p&gt;
&lt;p&gt;FFN 的演进主要集中在&lt;strong&gt;激活函数&lt;/strong&gt;和&lt;strong&gt;整体结构形式&lt;/strong&gt;两个方向。&lt;/p&gt;
&lt;h5 id="激活函数"&gt;激活函数
&lt;/h5&gt;&lt;p&gt;激活函数为 FFN 引入非线性，是提升模型表达能力与稳定性的关键模块。随着模型规模不断扩大，激活函数在设计上经历了从简单线性截断到平滑非线性，再到具备门控能力的结构化形式的演进。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ReLU&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ReLU（Rectified Linear Unit）是深度学习中最早广泛应用的激活函数之一，其定义非常简单：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $ReLU(x) = max(0, x)$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其函数曲线如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418225155.png]]&lt;/p&gt;
&lt;p&gt;ReLU 在正区间保持恒定梯度，使梯度能够高效传播，大大缓解了早期网络中的梯度消失问题，因而在浅层或中等规模神经网络中表现优异。然而，ReLU 对负区间进行“硬截断”，会导致梯度完全为零，从而引发“死亡神经元”现象，即神经元在训练过程中一旦进入负区间可能永久失活；此外，其非线性较弱，在深层 Transformer 中无法提供足够的梯度平滑性与稳定性，容易造成训练不稳定。&lt;/p&gt;
&lt;p&gt;随着模型深度和规模的大幅提升，ReLU 已难以满足大模型的稳定性要求，因此在现代大型语言模型中已经基本退出主流。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GELU&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GELU（Gaussian Error Linear Unit）是早期Transformer预训练模型（例如Bert、GPT-2/3）中曾广泛采用的平滑非线性激活函数。&lt;/p&gt;
&lt;p&gt;GELU的核心思想是：不再进行硬性截断，而是通过一种 &lt;strong&gt;随输入大小平滑变化的缩放系数&lt;/strong&gt; 来柔性控制激活强度，使得输入在负区间、中间区间、正区间分别呈现自然的衰减、过渡与放大。&lt;/p&gt;
&lt;p&gt;其数学定义为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\text{GELU}(x) = x \cdot \Phi(x)$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 $\Phi(x)$ 表示标准正态分布的累积分布函数。&lt;/p&gt;
&lt;p&gt;随着 $x$ 增大，$\Phi(x)$ 趋向 1，输出趋近于 $x$；随着 $x$ 减小，$\Phi(x)$  趋向 0，输出则逐渐衰减为 0；对于接近 0 的输入，函数会在 0 与 $x$ 之间进行平滑过渡，如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418230227.png]]
相比 ReLU，GELU 在全域连续可导，能在深层网络中提供更稳定的梯度传播，且不会出现 “神经元死亡”问题，因此曾在中大型 Transformer 中一度成为主流。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SiLU&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SiLU（Sigmoid Linear Unit）也是一种连续可导的激活函数，其基本思想是使用 sigmoid 函数对线性输入进行加权，从而得到一种柔和的非线性变换。&lt;/p&gt;
&lt;p&gt;其数学定义如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\text{SiLU}(x) = x \cdot \sigma(x)$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当 较大时，  趋近于 1，输出接近 ；当 较小时，  接近于 0，输入会被有效抑制；在接近 0 的区域，函数呈现平滑的过渡，而不是直接截断为零，如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260418231502.png]]&lt;/p&gt;
&lt;p&gt;得益于这种连续可导的结构，SiLU 在深层网络训练中同样具有良好的优化稳定性，并在多个任务中表现出与 GELU 相近的经验性能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Swish&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Swish 可视为 SiLU 的一般化形式，其数学定义为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\text{Swish}(x) = x \cdot \sigma\left(\beta x\right)$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 $\beta$ 可以是固定或可学习参数。当 $\beta = 1$ 时，Swish 与 SiLU 完全等价。尽管原论文提出让 可学习，但实际收益有限，并可能带来训练不稳定性，因此主流实现通常将 $\beta$ 固定为 1。&lt;/p&gt;
&lt;p&gt;基于这一等价关系，在工程实践中 Swish 与 SiLU 往往混用，不作严格区分。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GLU及其变体&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GLU（Gated Linear Unit）及其一系列变体是当前大型语言模型（LLM）中最常用的 FFN 激活结构。与传统 ReLU、GELU 等单路激活不同，GLU 类结构采用 “主分支 × 门控分支” 的双分支设计，通过引入门控机制，使模型能够对信息流进行更加细致的筛选与调控。如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260421184411.png]]&lt;/p&gt;
&lt;p&gt;门控结构的关键区别在于 &lt;strong&gt;门控分支所采用的门控函数&lt;/strong&gt;。不同的函数会导致门控行为、梯度特性和最终模型性能的差异，因此形成了多种 GLU 变体。常见的门控结构包括&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GLU：使用 Sigmoid 作为门控函数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GEGLU：使用GELU作为门控函数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SwiGLU：使用SiLU作为门控函数&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在众多变体中，SwiGLU在性能与训练稳定性方面表现最优，因此成为当前主流 LLM（LLaMA、Qwen、DeepSeek 等）的默认门控结构。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="moe"&gt;MoE
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MoE（Mixture of Experts，混合专家模型）是在传统 FeedForward 模块基础上的一种结构扩展。其核心思想是：使用多个并行的 FeedForward 专家替代单一的 FeedForward 层，并通过 Router（路由器）根据输入 Token 的特征选择其中少量最合适的专家参与计算。这样一来，不同类型的输入能够由擅长处理该类模式的专家负责，从而显著增强模型的表达能力与适应性。MoE 已成为当前主流大语言模型（LLM）中广泛采用的、用于提升性能与效率的关键结构之一。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260421185422.png]]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;工作流程&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MoE的工作流程如下图所示：&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260421191253.png]]&lt;/p&gt;
&lt;p&gt;具体步骤如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;路由得分计算&lt;/p&gt;
&lt;p&gt;Router 接收 Token 的隐藏表示，并通过线性映射为所有专家生成一组得分。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择 Top-k 专家&lt;/p&gt;
&lt;p&gt;从得分中选取得分最高的 k 个专家，其余专家在本次计算中不参与处理。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;计算路由权重&lt;/p&gt;
&lt;p&gt;对被选中的专家得分执行 softmax，得到归一化权重，用于表示各专家在最终输出中的贡献比例。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;专家执行前向计算&lt;/p&gt;
&lt;p&gt;被激活的专家分别对输入 Token 进行独立计算，生成各自的输出。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;加权合并输出&lt;/p&gt;
&lt;p&gt;将所有激活专家的输出按照路由权重加权求和，得到 Token 在 MoE 层的最终表示。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;能力与优势&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MoE 结构通过引入稀疏激活机制，显著提升了模型的能力和效率，主要具备以下三个核心优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;高容量、低计算的效率结构&lt;/p&gt;
&lt;p&gt;MoE 模型通过&lt;strong&gt;稀疏激活&lt;/strong&gt;机制，使每次前向传播仅有少数 个专家参与计算。这种设计在不增加实际计算量的前提下，大幅提升了模型的总参数量（&lt;strong&gt;模型容量&lt;/strong&gt;），实现了高效的“高容量、低计算”结构。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;专家分工协作，提升泛化与适应性&lt;/p&gt;
&lt;p&gt;通过&lt;strong&gt;路由器（Router）机制的动态分配，不同的输入 Token&lt;/strong&gt; &lt;strong&gt;会被导向最适合处理它们的专家。这种机制促使专家自动形成功能分化&lt;/strong&gt;，每个专家专注于学习特定的模式或数据子集，从而显著增强了模型的表达能力和&lt;strong&gt;泛化性能&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;天然适合大规模分布式扩展&lt;/p&gt;
&lt;p&gt;MoE 结构中的专家模块是相互独立的，这使得专家可以轻松地分布到大规模计算集群的不同设备上并行运行，极大地提升了模型的可扩展性（Scalability）和在大规模环境下的训练与推理效率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="残差连接与归一化"&gt;残差连接与归一化
&lt;/h4&gt;&lt;h5 id="概述-8"&gt;概述
&lt;/h5&gt;&lt;p&gt;残差结构与归一化机制是 Transformer 稳定训练的基础。随着模型深度与规模增加，传统的结构逐渐暴露出梯度路径不稳定的问题。近年来，研究者通过一系列优化改进手段，使模型能够在更高深度、更大参数规模下保持稳定训练。&lt;/p&gt;
&lt;h5 id="rmsnorm"&gt;RMSNorm
&lt;/h5&gt;&lt;p&gt;RMSNorm（Root Mean Square Normalization，均方根归一化） 是对传统 LayerNorm 的一种简化变体。它去除了均值标准化操作，仅基于输入特征的均方根（RMS）进行缩放，从而在保持归一化效果的同时降低计算复杂度。实践表明，均值项在深层 Transformer 中对稳定性贡献有限，因此去除均值不会影响模型性能，反而带来更稳定、更高效的归一化形式。目前，RMSNorm 已成为主流 LLM 中最常用的归一化方式。&lt;/p&gt;
&lt;p&gt;RMSNorm 的核心公式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$\text{RMSNorm}(x) = \frac{x}{\text{RMS}(x)} \cdot \gamma$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$\text{RMS}(x) = \sqrt{\frac{1}{d}\sum_{i=1}^{d} x_i^2 + \varepsilon}$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;$\boldsymbol{x \in \mathbb{R}^d}$：输入向量&lt;/li&gt;
&lt;li&gt;$ - $\boldsymbol{\gamma}$：可学习的缩放参数&lt;/li&gt;
&lt;li&gt;$ - $\boldsymbol{\varepsilon}$：防止除零的微小数&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="归一化放置位置"&gt;归一化放置位置
&lt;/h5&gt;&lt;p&gt;在 Transformer 中，归一化层的放置位置会显著影响训练稳定性、梯度传播效率以及模型在更大深度和规模下的可扩展性。随着架构不断演进，研究者在实践中提出了多种归一化布置方式，通过在残差路径内部或模块内部调整 Norm 的位置，以获得更好的数值特性与训练表现。&lt;/p&gt;
&lt;p&gt;![[Pasted image 20260423150814.png]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Post Norm&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Post Norm 是 Transformer 中最初采用的归一化放置方式，其结构是在子层（如 Self-Attention 或 FFN）计算完成并与残差相加之后，再对结果进行归一化处理&lt;/p&gt;
&lt;p&gt;$\boldsymbol{y = \text{Norm}\big(x + F(x)\big)}$&lt;/p&gt;
&lt;p&gt;Post Norm 存在一个核心问题：它会削弱残差连接中用于稳定训练的那条恒等梯度通道，从而在深层网络中导致梯度回传不稳定。要理解这一点，需要先回顾残差连接的梯度传播机制。&lt;/p&gt;
&lt;p&gt;对于标准残差结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\boldsymbol{y = x + F(x)}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;反向传播过程中，梯度会沿着两条路径回传至输入 $x$：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\frac{\partial y}{\partial x} = 1 + \frac{\partial F(x)}{\partial x}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中的“$1$”是一条不改变梯度方向和大小的恒等映射路径，为深层网络提供了稳定的“直通”梯度通道。&lt;/p&gt;
&lt;p&gt;然而在 Post Norm 中，反向传播形式变为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\frac{\partial y}{\partial x} = \frac{\partial \text{Norm}(z)}{\partial z} \cdot \left(1 + \frac{\partial F(x)}{\partial x}\right),\quad z = x+F(x)$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由于归一化操作会对输入进行缩放、标准化等处理，梯度在回流时也会被相应扰动，使原本应保持恒等的梯度路径不再保持为 1，从而削弱了残差连接提供的稳定梯度通道。&lt;/p&gt;
&lt;p&gt;在深层 Transformer 中，这种梯度扰动会层层累积，使训练更加不稳定。因此，Post Norm 在现代大规模模型中已基本不再使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pre Norm&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Pre Norm 是大多数大语言模型中采用的主流归一化方式。其结构是在进入子层（如 Self-Attention 或 FFN）之前先对输入进行归一化，然后再执行子模块计算并与残差相加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\boldsymbol{y = x + F\big(\text{Norm}(x)\big)}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;与 Post Norm 相比，Pre Norm 的设计充分保留了残差连接的关键特性：提供一条未受扰动的恒等梯度路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\frac{\partial y}{\partial x} = 1 + \frac{\partial F\big(\text{Norm}(x)\big)}{\partial x}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正因如此，Pre Norm 在现代 LLM 中成为了事实上的标准结构，被广泛采用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Post Norm in Residual&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Post Norm in Residual 是近年来在部分模型中出现的一种归一化放置方式。与传统 Post Norm 的相比，它依然将归一化作用在子层输出之后，但归一化的位置被移动到残差路径内部：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\boldsymbol{y = x + \text{Norm}\big(F(x)\big)}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方式同样能够提供一条恒等梯度路径：$\leftarrow$&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\frac{\partial y}{\partial x} = 1 + \frac{\partial \text{Norm}\big(F(x)\big)}{\partial x}$
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="位置编码"&gt;位置编码
&lt;/h4&gt;&lt;h5 id="概述-9"&gt;概述
&lt;/h5&gt;&lt;p&gt;由于 Transformer 的自注意力机制（Self-Attention）并不包含序列顺序信息，模型无法仅依靠注意力计算来判断 token 在序列中的相对位置。因此，需要向输入中显式加入位置编码（Position Encoding），以补充序列的位置信息。&lt;/p&gt;
&lt;p&gt;随着模型规模扩大与任务需求多样化，位置编码的设计也在不断演进，以适应更长的上下文、更灵活的序列建模方式以及更稳定的训练特性。&lt;/p&gt;
&lt;h5 id="正余弦位置编码"&gt;正余弦位置编码
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;概述&lt;/p&gt;
&lt;p&gt;正余弦位置编码（Sinusoidal Positional Encoding）是原始 Transformer 中采用的位置编码方式，它通过一组预定义的正弦与余弦函数为每个序列位置生成唯一向量：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\boldsymbol{PE_{(pos,2i)} = \sin\left(\frac{pos}{10000^{\frac{2i}{d}}}\right)}$

 $\boldsymbol{PE_{(pos,2i+1)} = \cos\left(\frac{pos}{10000^{\frac{2i}{d}}}\right)}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\boldsymbol{pos}$：Token 的绝对位置&lt;/li&gt;
&lt;li&gt;$\boldsymbol{i}$：维度索引&lt;/li&gt;
&lt;li&gt;$\boldsymbol{d}$：向量总维度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;特点&lt;/p&gt;
&lt;p&gt;正余弦位置编码具有以下特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;无需训练&lt;/p&gt;
&lt;p&gt;编码由固定函数生成，不引入任何可学习参数，使用简单，不会随训练发生漂移。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可外推&lt;/p&gt;
&lt;p&gt;由于编码基于数学函数，不依赖训练语料长度，模型可在推理阶段处理比训练时更长的序列。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;隐含相对位置信息&lt;/p&gt;
&lt;p&gt;正余弦位置编码的结构使其能够携带 token 之间的相对位置信息。&lt;/p&gt;
&lt;p&gt;正余弦位置编码的各维度是按频率成对排列的，每一对由同一频率对应的正弦值和余弦值组成。现在，我们分别从位置 和位置 的位置编码中，任意选取一对频率为 的维度进行观察。如下：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
$$\boldsymbol{PE_\omega(m) = \begin{bmatrix}
\sin(\omega m) \\
\cos(\omega m)
\end{bmatrix}}$$$$\boldsymbol{PE_\omega(n) = \begin{bmatrix}
\sin(\omega n) \\
\cos(\omega n)
\end{bmatrix}}$$&lt;pre&gt;&lt;code&gt;	在 Transformer 中，注意力权重由 q 向量与 k 向量的内积决定：
	
		$\boldsymbol{\text{AttentionScore}(m,n) = q_m^\top k_n}$
	
	因此，位置编码之间的内积会直接参与注意力打分。基于这一点，我们考察上述两组位置编码分量的内积
	
		$\boldsymbol{PE_\omega(m)^\top PE_\omega(n) = \sin(\omega m)\sin(\omega n) + \cos(\omega m)\cos(\omega n)}$
	
	利用三角恒等式可得：
	
	
	-
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;缺陷&lt;/p&gt;
&lt;p&gt;尽管正余弦位置编码具有良好的数学结构，其向量间的内积可直接反映相对位置关系，但在实际的 Transformer 注意力计算中，这种优势并不能完全有效发挥。$\leftarrow$&lt;/p&gt;
&lt;p&gt;注意力计算中，注意力打分为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\boldsymbol{\text{score}(m,n) = q_m^\top k_n}$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中&lt;/p&gt;
&lt;p&gt;$q_m = W_Q\big(e_m + \text{PE}_m\big),\quad k_n = W_K\big(e_n + \text{PE}_n\big)$&lt;/p&gt;
&lt;p&gt;代入后可得：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $\text{score}(m,n) = \big(e_m + \text{PE}_m\big)^\top W_Q^\top W_K \big(e_n + \text{PE}_n\big)$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;令 $\boldsymbol{A = W_Q^\top W_K}$，可将上式展开为：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
$$\begin{aligned}
\text{score}(m,n) &amp;= e_m^\top A e_n \\
&amp;+ e_m^\top A \text{PE}_n \\
&amp;+ \text{PE}_m^\top A e_n \\
&amp;+ \text{PE}_m^\top A \text{PE}_n
\end{aligned}$$&lt;p&gt;其中，仅有最后一项 $\boldsymbol{\text{PE}_m^\top A \text{PE}_n}$ 明确体现了位置编码之间的相互作用，因此也是唯一直接与相对位置相关的部分。但由于矩阵 $\boldsymbol{A = W_Q^\top W_K}$ 是可学习参数，会在训练中不断变化，原本正余弦编码所具备的几何结构难以稳定保持。换句话说，模型必须通过额外的学习来重新塑造或校正这种相对位置信息，而这种重建过程往往并不可靠，导致正余弦位置编码在理论上的优势无法在实践中完全体现出来，也影响了训练的稳定性和模型的泛化表现。&lt;/p&gt;
&lt;h5 id="可学习位置编码"&gt;可学习位置编码
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;可学习位置编码（Learned Positional Embedding）是另一种常见的位置编码方式，曾广泛应用于早期的Transformer预训练模型（Bert，GPT-1/2等）中。在这种方法中，模型为序列中的每个位置分配一个独立的可训练向量，这些向量在训练过程中与模型的其他参数一同更新，使模型能够从实际任务数据中自动学习位置表示。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;特点&lt;/p&gt;
&lt;p&gt;可学习位置编码的主要特点如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;位置向量完全由数据驱动学习，不受固定数学函数约束，因此能够更贴合训练语料的分布特点。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;训练方式简单&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;其优化方式与词向量一致，实现成本低，不需要额外的结构设计，便于直接集成到 Transformer 中。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺陷&lt;/p&gt;
&lt;p&gt;可学习位置编码的缺陷如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;缺乏长度外推能力&lt;/p&gt;
&lt;p&gt;可学习位置编码只在训练过的位置范围内定义，超出最大序列长度的位置没有对应的嵌入，导致模型无法在推理阶段处理更长的输入序列。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;参数量随序列长度线性增长&lt;/p&gt;
&lt;p&gt;位置向量数量与最大序列长度成正比，当需要支持长上下文时，参数开销迅速增大。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="旋转位置编码"&gt;旋转位置编码
&lt;/h5&gt;&lt;hr&gt;
&lt;h2 id="第三篇场景适配promptrag-与微调-loraqlora"&gt;第三篇：场景适配：Prompt、RAG 与微调 (LoRA/QLoRA)
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;面对实际业务需求，开发者该如何选择最省钱、最有效的模型适配路径。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适配路线图&lt;/strong&gt;：Prompt Engineering vs RAG vs Fine-tuning 的选型策略。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;微调实战理论&lt;/strong&gt;：Base Model 与 Instruct Model 的核心差异及选择策略。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;参数高效微调 (PEFT)&lt;/strong&gt;：深入 LoRA 与 QLoRA 的数学原理——如何在单张 24G 消费级显卡上微调大模型 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据质量&lt;/strong&gt;：Chat Template（如 ChatML 格式）在微调中的决定性作用与数据格式规范。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="第四篇分布式训练与-zero-显存管理"&gt;第四篇：分布式训练与 ZeRO 显存管理
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;当单张显卡装不下千亿参数模型时，算力集群是如何“打配合”的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;并行矩阵&lt;/strong&gt;：数据并行、流水线并行（以及解决气泡问题的微批次策略）与张量并行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ZeRO 深度解析&lt;/strong&gt;：微软 ZeRO 系列优化器（Stage 1/2/3）如何通过分片存储彻底消除内存冗余 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;硬件选型估算&lt;/strong&gt;：不同微调策略下的 VRAM 显存占用硬核计算公式（含模型参数、梯度、优化器状态与激活值） 。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="第五篇高性能推理-vllm-与模型评测"&gt;第五篇：高性能推理 (vLLM) 与模型评测
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;模型训练完成后，如何实现每秒百词的高并发线上部署 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;vLLM 魔法&lt;/strong&gt;：PagedAttention 算法揭秘——像操作系统管理虚拟内存一样管理 KV Cache。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;推理实战&lt;/strong&gt;：使用 vLLM 部署 OpenAI 风格的 API 接口并实现多轮对话调用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;闭环评估&lt;/strong&gt;：使用 EvalScope 框架进行模型压测（并发量、吞吐量、延迟）与综合能力评估。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Transformer 原理梳理</title><link>https://xystart.github.io/p/transformer/</link><pubDate>Wed, 08 Apr 2026 17:04:05 +0800</pubDate><guid>https://xystart.github.io/p/transformer/</guid><description>&lt;h1 id="transformer-的出现"&gt;Transformer 的出现
&lt;/h1&gt;&lt;p&gt;在 Transformer 出现之前，自然语言处理的发展时间线如下：&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="阶段一传统序列模型-rnn-rightarrow-lstm-rightarrow-gru"&gt;阶段一：传统序列模型 ($RNN \rightarrow LSTM \rightarrow GRU$)
&lt;/h2&gt;&lt;p&gt;这一阶段主要是为了解决模型“如何记住时序信息”的问题。&lt;/p&gt;
&lt;h3 id="时序信息"&gt;时序信息
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;如何理解一句话&lt;/strong&gt; 要理解一句话的含义，应该是从头向后，先理解第一个词语，然后把前两个词语组合，理解这个组合，在把前三个词语组合，理解这个组合，以此类推；&lt;strong&gt;在理解句意时，每个字或词出现的时间顺序不同会带来不一样的含义，所以理解一句话不应该是把句子拆分成单个字来看&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;词袋模型&lt;/strong&gt; 在早期的自然语言处理中，有一种方法叫“词袋模型”（&lt;code&gt;Bag of Words&lt;/code&gt;）。它就像把一句话里的字全部拆散，扔进一个布袋子里摇匀。 在词袋模型看来：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“我爱你” = &lt;code&gt;[我, 爱, 你]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;“你爱我” = &lt;code&gt;[你, 爱, 我]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;RNN的出现&lt;/strong&gt; 因为袋子里的字完全一样，机器会觉得这两句话是一个意思！但这显然是荒谬的。传统序列模型（&lt;code&gt;RNN&lt;/code&gt;）的发明，就是为了打破这个袋子，让机器明白“谁在前面、谁在后面”决定了句子的生死。&lt;/p&gt;
&lt;h3 id="rnn-循环神经网络-最早的序列模型"&gt;RNN (循环神经网络): 最早的序列模型。
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;如何工作&lt;/strong&gt; &lt;code&gt;RNN&lt;/code&gt; 会逐个读取句子中的词语，并在每一步结合当前词和前面的上下文信息，不断更新对句子的理解。通过这种机制，&lt;code&gt;RNN&lt;/code&gt; 能够持续建模上下文，从而更准确地把握句子的整体语义。因此 &lt;code&gt;RNN&lt;/code&gt; 曾是序列建模领域的主流模型，被广泛应用于各类 NLP 任务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基础结构&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实际结构：&lt;/strong&gt; 在 &lt;code&gt;PyTorch&lt;/code&gt; 的底层代码中，&lt;strong&gt;&lt;code&gt;RNN&lt;/code&gt; 只有一个运算模块&lt;/strong&gt;（也就是包含 $W, U$ 权重和 $\tanh$ 的那个细胞），它以时间步（&lt;code&gt;time step&lt;/code&gt;）为单位，依次处理输入序列中的每个 &lt;code&gt;token&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;怎么工作：&lt;/strong&gt; 它本质上是一个 &lt;code&gt;for&lt;/code&gt; 循环。不管句子有 10 个字还是 1000 个字，它们都必须排队，&lt;strong&gt;依次&lt;/strong&gt;进入这唯一的一个模块被处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心特征：&lt;/strong&gt; 权重共享 (&lt;code&gt;Weight Sharing&lt;/code&gt;)。从句首到句尾，机器始终在复用同一套参数矩阵来提取特征。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;沿时间展开图&lt;/strong&gt;
在每个时间步，&lt;code&gt;RNN&lt;/code&gt; 接收当前 &lt;code&gt;token&lt;/code&gt; 的向量 $x_t$ 和上一个时间步的隐藏状态 $h_{t-1}$（即隐藏层的输出），计算并生成新的隐藏状态 $h_t$，并将其传递到下一时间步。&lt;/p&gt;
&lt;img src="img/Pasted image 20260411110040.png" width="40%" style="margin: 0 auto; display: block;" /&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;
上图详细展示了基础 &lt;code&gt;RNN&lt;/code&gt; 的结构，但 &lt;code&gt;RNN&lt;/code&gt; 还存在更复杂的结构形式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多层结构：&lt;/strong&gt; 为了让模型捕捉更复杂的语言特征，可以将多个 &lt;code&gt;RNN&lt;/code&gt; 层按层次堆叠起来，使不同层学习不同层次的语义信息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;底层网络：&lt;/strong&gt; 更容易捕捉局部模式（如词组、短语），底层的神经元直接接触最原始的输入数据（比如一个个词向量），因此它们的注意力主要集中在&lt;strong&gt;局部的、基础的、物理层面的特征&lt;/strong&gt;上。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高层网络：&lt;/strong&gt; 能学习更抽象的语义信息（如句子主题或语境），高层 &lt;code&gt;RNN&lt;/code&gt; 接收的是底层已经初步“消化”过的特征序列。它们不再纠结于具体的字词长什么样，而是站在更高的视角，关注&lt;strong&gt;全局的、抽象的、深层含义&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;注：多层 &lt;code&gt;RNN&lt;/code&gt; 结构中，每一层的输出序列会作为下一层的输入序列，最底层 &lt;code&gt;RNN&lt;/code&gt; 接收原始输入序列，顶层 &lt;code&gt;RNN&lt;/code&gt; 的输出作为最终结果用于后续任务。&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;双向结构：&lt;/strong&gt; 基础的 &lt;code&gt;RNN&lt;/code&gt; 在每个时间步只输出一个隐藏状态，该状态仅包含来自上文的信息，而无法利用当前词之后的下文。对于一些任务而言，这是一个明显的限制。比如在序列标注任务中，模型需要为每个 &lt;code&gt;token&lt;/code&gt; 预测一个标签，如果只能参考前文信息，往往难以做出准确判断。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;⚠️ &lt;strong&gt;痛点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;梯度消失：&lt;/strong&gt; 底层机制（梯度消失/爆炸）： 在训练 &lt;code&gt;RNN&lt;/code&gt; 时，我们使用的是“沿时间反向传播算法”（&lt;code&gt;BPTT&lt;/code&gt;）。因为状态是不断往后传递的，数学上这涉及到连乘效应。如果权重矩阵里的值小于 $1$，连乘几十次后，梯度就会趋近于 $0$（梯度消失，模型不再更新）；如果大于 $1$，又会趋近于无穷大（梯度爆炸，模型直接崩溃）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;信息传递路径太长：&lt;/strong&gt; 在 &lt;code&gt;RNN&lt;/code&gt; 中，句首单词和句尾单词之间的距离是 $\mathcal{O}(N)$（$N$ 是序列长度）。这意味着两个词隔得越远，它们建立联系需要跨越的计算步骤就越多，信号衰减得就越厉害。&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;h3 id="lstm-长短期记忆网络"&gt;LSTM (长短期记忆网络)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;按时间展开结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="1074px" data-flex-grow="447" height="1660" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411135028.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411135028_hu_fcd073fc138adb0c.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411135028_hu_2f132795b22f0525.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411135028_hu_a883396b6af5e778.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411135028.png 7432w" width="7432"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;改进&lt;/strong&gt;
为了缓解 &lt;code&gt;RNN&lt;/code&gt; 梯度消失或者梯度爆炸的问题，&lt;code&gt;Hochreiter&lt;/code&gt; 和 &lt;code&gt;Schmidhuber&lt;/code&gt; 于 1997 年提出了长短期记忆网络（&lt;code&gt;Long Short-Term Memory&lt;/code&gt;, &lt;code&gt;LSTM&lt;/code&gt;），&lt;code&gt;LSTM&lt;/code&gt; 在 &lt;code&gt;RNN&lt;/code&gt; 的基础上引入了四个新的结构。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;记忆单元 (&lt;code&gt;Cell State&lt;/code&gt;, $C_t$)&lt;/strong&gt;
记忆单元负责在序列中长期保存关键信息。它相当于一条“信息通道”，在多个时间步之间直接传递信息。（记忆单元是缓解梯度消失和梯度爆炸问题的核心）
这是 &lt;code&gt;LSTM&lt;/code&gt; 区别于普通 &lt;code&gt;RNN&lt;/code&gt; 最伟大的发明。传统的 &lt;code&gt;RNN&lt;/code&gt; 只有 $h_t$ 这一条路，记忆要在里面被反复运算（矩阵乘法），导致梯度消失。而 $C_t$ 是长期的、全局的记忆。 在这条直通车上，数据只发生&lt;strong&gt;极其简单的线性运算&lt;/strong&gt;（乘法和加法）。&lt;/p&gt;
&lt;img src="img/Pasted image 20260411153634.png" width="50%" style="margin: 0 auto; display: block;" /&gt;
&lt;p&gt;&lt;strong&gt;遗忘门 (&lt;code&gt;Forget Gate&lt;/code&gt;, $f_t$)&lt;/strong&gt;
决定要从过去的记忆上擦除什么信息。
例如历史输入为：“小帅是一名程序员，他每天都加班；”，然后当前时间步的输入为“小美”，意味着当前的主语变为了“小美”，后续应该生成和“小美”相关的内容，所以此时记忆单元就应该忘记之前的主语信息“小帅”。遗忘门会根据上一个时间步的隐藏状态 $h_{t-1}$ 和当前时间步的输入 $x_t$，生成一个 $0$ 到 $1$ 之间的控制系数，然后与上一个时间步的记忆单元状态相乘，从而动态调整哪些信息应该被遗忘。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;计算过程：&lt;/strong&gt; 把当前的输入 $x_t$ 和上一步的短期记忆 $h_{t-1}$ 放在一起看，然后通过一个 &lt;code&gt;Sigmoid&lt;/code&gt; 函数，输出一个 $0$ 到 $1$ 之间的数字（比例）。
接近 $0$：代表“这部分老记忆没用了，彻底忘掉！”（比如主语从“他”变成了“她”，老的性别特征就被清空）。
接近 $1$：代表“这个信息很重要，继续保留”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公式：&lt;/strong&gt;

$$f_t = \sigma(W_f \cdot x_t + U_f \cdot h_{t-1} + b_f)$$&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="img/Pasted image 20260411153259.png" width="50%" style="margin: 0 auto; display: block;" /&gt;
&lt;p&gt;&lt;strong&gt;输入门 (&lt;code&gt;Input Gate&lt;/code&gt;, $i_t$)&lt;/strong&gt;
输入门控制要从当前时间步的输入向记忆单元存入多少新的信息。例如上述案例中，当前时间步的输入为“小美”，所以此时记忆单元就应该存入新的主语信息“小美”。当前时间步的信息由当前输入 $x_t$ 和上一个隐藏状态 $h_{t-1}$ 计算而成，同时输入门也由当前输入 $x_t$ 和上一个隐藏状态 $h_{t-1}$ 计算而成，然后新的信息和输入门相乘得到需要存入记忆单元的信息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;计算过程：&lt;/strong&gt; 生成备选新知识 ($\tilde{C}_t$)： 使用 $\tanh$ 函数，把当前的新词和语境，提炼成一份“候选记忆草稿”（数值在 $-1$ 到 $1$ 之间）。
决定写入比例 ($i_t$)： 使用 &lt;code&gt;Sigmoid&lt;/code&gt; 函数，算出一个 $0$ 到 $1$ 之间的“写入阀门值”。它决定了刚才那份草稿里，有多少内容是真的有价值、值得被正式写进传送带的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公式：&lt;/strong&gt;
算阀门：
$$i_t = \sigma(W_i \cdot x_t + U_i \cdot h_{t-1} + b_i)$$
写草稿：
$$\tilde{C}_t = \tanh(W_c \cdot x_t + U_c \cdot h_{t-1} + b_c)$$
老记忆被遗忘门乘法砍掉一部分，新记忆草稿被输入门过滤后加进来：
$$C_t = (f_t \ast C_{t-1}) + (i_t \ast \tilde{C}_t)$$&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="img/Pasted image 20260411144913.png" width="50%" style="margin: 0 auto; display: block;" /&gt;
&lt;p&gt;&lt;strong&gt;输出门 (&lt;code&gt;Output Gate&lt;/code&gt;, $o_t$)&lt;/strong&gt;
输出门控制从记忆单元中读取多少信息作为当前时间步的隐藏状态进行输出。例如上述输入法智能提示案例中，记忆单元中存入新主语信息“小美”之后，当前时间步就应该从记忆单元中提取该主语信息，生成与“小美”相关的内容。输出门同样由当前时间步的输入 $x_t$ 和上一个时间步 $h_{t-1}$ 的隐藏状态计算而成，如下图所示。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;运作过程：&lt;/strong&gt;
算过滤阀门 ($o_t$)： 同样通过 &lt;code&gt;Sigmoid&lt;/code&gt; 函数，结合当前输入 $x_t$ 和上步状态 $h_{t-1}$，算出一个 $0$ 到 $1$ 的比例。这就相当于一张&lt;strong&gt;遮罩/滤网&lt;/strong&gt;，决定了长期记忆里的哪些部分在当前这个时间步是需要暴露出来的。
生成最终输出 ($h_t$)： 把最新的细胞状态 $C_t$ 用 $\tanh$ 压扁处理一下（确保数值稳定在 $-1$ 到 $1$ 之间），然后和刚才的滤网 $o_t$ 相乘。
算出来的这个 $h_t$，就是当前时间步的&lt;strong&gt;短期记忆&lt;/strong&gt;。它有两个去处：一是传递给下一个时间步，二是往上送给外层的 &lt;code&gt;Linear&lt;/code&gt; 层去预测当前的单词！&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公式：&lt;/strong&gt;
算滤网：
$$o_t = \sigma(W_o \cdot x_t + U_o \cdot h_{t-1} + b_o)$$
对外发言：
$$h_t = o_t \ast \tanh(C_t)$$&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="img/Pasted image 20260411152743.png" width="50%" style="margin: 0 auto; display: block;" /&gt;

 &lt;blockquote&gt;
 &lt;p&gt;⛔ &lt;strong&gt;缺点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;参数大爆炸：&lt;/strong&gt; &lt;code&gt;LSTM&lt;/code&gt; 新增了遗忘门、输入门、输出门、记忆单元四个结构。为了实现这四个模块，&lt;code&gt;LSTM&lt;/code&gt; 内部设置了 &lt;strong&gt;4 套完全独立的权重矩阵&lt;/strong&gt;（$W$ 和 $U$）。 如果隐藏层维度比较大，&lt;code&gt;LSTM&lt;/code&gt; 的参数量会是普通 &lt;code&gt;RNN&lt;/code&gt; 的 4 倍。这直接导致它在运行时极其消耗 GPU 显存。&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;h3 id="gru-门控循环单元"&gt;GRU (门控循环单元):
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;改进&lt;/strong&gt;
&lt;code&gt;LSTM&lt;/code&gt; 的“精简版”。把 &lt;code&gt;LSTM&lt;/code&gt; 的三个门简化成了两个门（重置门、更新门），取消了 &lt;code&gt;LSTM&lt;/code&gt; 中独立的记忆单元，只保留隐藏状态，在保持效果差不多的前提下，大大减少了计算量，训练速度更快。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;按时序展开结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="909px" data-flex-grow="379" height="1664" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411193931.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411193931_hu_cf5e3ad0c2cd9f0e.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411193931_hu_552762c9f2f2cbaf.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411193931_hu_5556af2f5929c71b.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260411193931.png 6308w" width="6308"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重置门 ($r_t$)&lt;/strong&gt;
在面对当前的新单词时，决定&lt;strong&gt;过去的记忆有多少参考价值&lt;/strong&gt;，帮模型生成一份新的记忆。&lt;/p&gt;
&lt;img src="img/Pasted image 20260411195335.png" width="50%" style="margin: 0 auto; display: block;" /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;案例：&lt;/strong&gt;
假设模型正在阅读一篇小说。
场景 A（上下文连贯）： 上文是“小明走进厨房”，当前词 $x_t$ 是“拿起了”。此时，重置门评估后觉得：“前面的‘厨房’和现在‘拿起了’高度相关，可能是拿起了菜刀或苹果。”于是，重置门全开，让过去的记忆全部参与到新记忆的起草中。
场景 B（话题突转）： 上文是长篇大论的“量子力学原理解析”，当前词 $x_t$ 是“突然，”。此时，重置门发现话题画风突变，前面的物理学知识对理解接下来的故事毫无用处。于是，重置门果断关闭，把前面的记忆&lt;strong&gt;屏蔽掉（重置）&lt;/strong&gt;，只根据“突然，”这个词去起草接下来的语境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公式：&lt;/strong&gt;
在生成候选草稿（$\tilde{h}&lt;em&gt;t$）时，重置门 $r_t$ 悄悄乘在了过去的隐状态 $h&lt;/em&gt;{t-1}$ 上：

$$\tilde{h}_t = \tanh(W \cdot x_t + U \cdot (r_t \ast h_{t-1}))$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;更新门 ($z_t$)&lt;/strong&gt;
更新门会在计算当前时间步最终的隐藏状态 $h_t$ 时，分别作用在上一时刻的隐藏状态 $h_{t-1}$ 和当前新计算出的候选隐藏状态 $\tilde{h}_t$，用于控制保留多少旧信息，以及引入多少新信息。&lt;/p&gt;
&lt;img src="img/Pasted image 20260411195739.png" width="50%" style="margin: 0 auto; display: block;" /&gt;

 &lt;blockquote&gt;
 &lt;p&gt;⚠️ &lt;strong&gt;痛点&lt;/strong&gt;
尽管 &lt;code&gt;GRU&lt;/code&gt; 极其精简高效，但他还是存在无法解决的问题。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RNN&lt;/code&gt; 计算公式：
&lt;/p&gt;
$$h_t = \tanh(W \cdot x_t + U \cdot h_{t-1} + b)$$&lt;p&gt;
&lt;/p&gt;
$$y_t = V \cdot h_t + c$$&lt;p&gt;&lt;strong&gt;产生一个输出 $y_t$，必须依赖一个当前的隐藏状态 $h_t$；而产生 $h_t$，又必须生吃进去一个当前的输入单词 $x_t$。&lt;/strong&gt; 这就好比机器内部有两个完全咬合的齿轮，输入转一格，输出才跟着转一格。没有输入的推力，输出齿轮根本转不动；输入转了，输出也绝对不能停。这就是所谓的“时序强绑定”。
不管内部怎么优化，&lt;code&gt;GRU&lt;/code&gt; 依然是一个标准的循环网络。标准 &lt;code&gt;RNN&lt;/code&gt; 在处理任务时，要求 &lt;strong&gt;输入序列和输出序列必须是严格对齐的（长度相等，词序对应）&lt;/strong&gt;。这在真实的机器翻译中会遇到问题，现实世界中的翻译很少能有输入输出长度相等，词序对应的。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="阶段二框架的诞生-seq2seq-架构-2014年"&gt;阶段二：框架的诞生 (Seq2Seq 架构, 2014年)
&lt;/h2&gt;&lt;p&gt;在此之前，&lt;code&gt;RNN&lt;/code&gt; 系列模型很难处理“输入和输出长度不一致”的问题（比如机器翻译，中文的“我爱你”是3个字，英文的“I love you”也是3个单词，但“桌子上的苹果”和“The apple on the table”长度就不一样了）。
为了解决这个问题，Google 提出了 &lt;code&gt;Seq2Seq&lt;/code&gt; (&lt;code&gt;Sequence to Sequence&lt;/code&gt;) 架构，也叫 &lt;code&gt;Encoder-Decoder&lt;/code&gt; (编码器-解码器) 架构。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt; &lt;code&gt;Seq2Seq&lt;/code&gt; 不是凭空造出来的新网络，它的内部使用的就是 &lt;code&gt;RNN&lt;/code&gt;、&lt;code&gt;LSTM&lt;/code&gt; 或 &lt;code&gt;GRU&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工作原理&lt;/strong&gt; * &lt;code&gt;Encoder&lt;/code&gt; 负责把一整句话吃进去，压缩成一个固定长度的向量（也就是上下文向量 &lt;code&gt;Context Vector&lt;/code&gt;）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Decoder&lt;/code&gt; 拿到这个向量，逐步生成目标序列。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;模型结构&lt;/strong&gt;&lt;/p&gt;
&lt;img src="img/Pasted image 20260411205532.png" width="80%" style="margin: 0 auto; display: block;" /&gt;
&lt;h3 id="编码器---encoder"&gt;编码器 - Encoder
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Encoder&lt;/code&gt; 底层通常就是一个标准的 &lt;code&gt;RNN&lt;/code&gt;、&lt;code&gt;LSTM&lt;/code&gt; 或 &lt;code&gt;GRU&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;工作流程：&lt;/strong&gt; 只听不说，浓缩精华。 它的任务是阅读一段长度为 $N$ 的输入序列，理解里面的所有词法、句法和逻辑关系，然后把它压缩成一个包含整句话含义的隐藏状态，当接受完最后一个词，并且看到代表句子结束的特殊符号 &lt;code&gt;&amp;lt;EOS&amp;gt;&lt;/code&gt;（End of Sentence）时，它会输出最后一个隐藏状态——$h_{final}$，就是 上下文向量 (&lt;code&gt;Context Vector&lt;/code&gt;, $C$)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;按时间步展开结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="919px" data-flex-grow="383" height="1436" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412102631.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412102631_hu_a5ea85f75835dfd1.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412102631_hu_d5017164d3f8716.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412102631_hu_c702add13408daaf.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412102631.png 5500w" width="5500"&gt;&lt;/p&gt;
&lt;h3 id="解码器---decoder"&gt;解码器 - Decoder
&lt;/h3&gt;&lt;p&gt;它同样是一个标准的 &lt;code&gt;RNN&lt;/code&gt;、&lt;code&gt;LSTM&lt;/code&gt; 或 &lt;code&gt;GRU&lt;/code&gt;。但在参数上，它和 &lt;code&gt;Encoder&lt;/code&gt; 是完全独立的（两人不共享权重，因为一个懂中文，一个懂英文）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;工作流程：&lt;/strong&gt; 只说不听，展开思想。 将编码器生成的上下文向量，在没有任何外界输入提示的情况下，“解压缩”成一种新的序列。
在生成开始时，循环神经网络以上下文向量作为初始隐藏状态，并接收一个特殊的起始标记 &lt;code&gt;&amp;lt;sos&amp;gt;&lt;/code&gt;（start of sentence）作为第一个时间步的输入，用于预测第一个 &lt;code&gt;token&lt;/code&gt;。
随后，在每一个时间步，模型都会根据前一时刻的隐藏状态和上一步生成的 &lt;code&gt;token&lt;/code&gt;，预测当前的输出。这种“将前一步的输出作为下一步输入”的方式被称为自回归生成（&lt;code&gt;Autoregressive Generation&lt;/code&gt;），它确保了生成结果的连贯性。
生成过程会持续进行，直到模型生成了一个特殊的结束标记 &lt;code&gt;&amp;lt;eos&amp;gt;&lt;/code&gt;（end of sentence），表示句子生成完成。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;按时间步展开结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="688px" data-flex-grow="286" height="2220" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412135329.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412135329_hu_27c4faa01a98afd6.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412135329_hu_303a3ba2ab6c3717.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412135329_hu_8b1bf3dafa710507.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412135329.png 6364w" width="6364"&gt;&lt;/p&gt;
&lt;h3 id="模型的训练和推理"&gt;模型的训练和推理
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Seq2Seq&lt;/code&gt; 在训练（&lt;code&gt;Training&lt;/code&gt;）和推理（&lt;code&gt;Inference&lt;/code&gt;，也就是实际使用）这两个阶段，差别非常大。编码器（&lt;code&gt;Encoder&lt;/code&gt;）在两个阶段的表现是一模一样的。真正的区别，全部集中在解码器（&lt;code&gt;Decoder&lt;/code&gt;）接收输入的方式上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;训练&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;编码器：&lt;/strong&gt;
编码器接收源语言序列“我喜欢你。”，通过嵌入层和循环神经网络（&lt;code&gt;RNN&lt;/code&gt; / &lt;code&gt;LSTM&lt;/code&gt; / &lt;code&gt;GRU&lt;/code&gt;）的逐步处理，将整句编码为上下文向量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解码器：&lt;/strong&gt;
训练时目标是让模型快速收敛。如果让解码器像真实情况下那样“自回归”（把上一步的输出当成下一步的输入），假如第一步预测错了（把 &lt;code&gt;I&lt;/code&gt; 预测成了 &lt;code&gt;He&lt;/code&gt;），那么第二步就会拿着错误的 &lt;code&gt;He&lt;/code&gt; 继续往下猜，导致后面全盘皆输。模型会在错误的道路上越走越远，根本学不到东西。
为了解决这个问题，引入了一个极其重要的训练技巧：&lt;code&gt;Teacher Forcing&lt;/code&gt;（教师强制），如下图所示。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="688px" data-flex-grow="286" height="2220" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412143543.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412143543_hu_e88595e80aed86d7.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412143543_hu_9f95a4f38cfa56ee.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412143543_hu_a7e1c984de85c313.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412143543.png 6364w" width="6364"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;运作机制&lt;/strong&gt;
就像一个严厉的老师握着学生的手写字。
第一步：输入 &lt;code&gt;&amp;lt;SOS&amp;gt;&lt;/code&gt;，模型瞎猜了一个 &lt;code&gt;He&lt;/code&gt;。
第二步：老师强行介入！ 老师不管上一步猜出了什么，老师直接把**标准答案（&lt;code&gt;Ground Truth&lt;/code&gt;）**里的第一个词 &lt;code&gt;I&lt;/code&gt;，硬塞给模型作为第二步的输入。
第三步：老师再次介入，把标准答案里的 &lt;code&gt;like&lt;/code&gt; 塞给模型作为第三步的输入。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;优势&lt;/strong&gt;
即使模型在中间某一步预测错了，错误也不会像滚雪球一样累积。模型始终在“正确的上下文”引导下学习，训练速度和稳定性大幅提升。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;损失计算&lt;/strong&gt;
解码器每一步输出一个 &lt;code&gt;token&lt;/code&gt; 的概率分布，通过交叉熵损失函数衡量模型对真实词的预测质量。训练过程中，每一个时间步都会产生一个损失值。该样本的总损失，就是所有时间步的损失值逐步累加的结果。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="480px" data-flex-grow="200" height="3176" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145012.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145012_hu_e99e4a64585cadeb.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145012_hu_c0ab2149ea849044.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145012_hu_e633d57f3f1b5c96.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145012.png 6364w" width="6364"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推理&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;运作机制：&lt;/strong&gt;
这就是上一节详细讨论过的&lt;strong&gt;自回归（&lt;code&gt;Autoregressive&lt;/code&gt;）&lt;/strong&gt;。
第一步：输入 &lt;code&gt;&amp;lt;SOS&amp;gt;&lt;/code&gt;，模型结合上下文向量，吐出 &lt;code&gt;I&lt;/code&gt;。
第二步：模型&lt;strong&gt;只能依靠自己&lt;/strong&gt;，老老实实把刚刚吐出的 &lt;code&gt;I&lt;/code&gt; 拿过来，作为这一步的输入，推导出 &lt;code&gt;like&lt;/code&gt;。
直到模型自己决定吐出 &lt;code&gt;&amp;lt;EOS&amp;gt;&lt;/code&gt; 为止。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="688px" data-flex-grow="286" height="2220" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145405.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145405_hu_27c4faa01a98afd6.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145405_hu_303a3ba2ab6c3717.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145405_hu_8b1bf3dafa710507.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412145405.png 6364w" width="6364"&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;⚠️ &lt;strong&gt;痛点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在上述 &lt;code&gt;Seq2Seq&lt;/code&gt; 架构中，编码器会将整个源句压缩为一个固定长度的上下文向量，并将其作为解码器生成目标序列的唯一参考。这种“压缩再解压”的方式虽然结构简洁，但在实际任务中暴露出两个核心问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;**信息压缩困难，语义表达受限：**对于编码器而言，用一个定长向量去表达任意复杂的句子，是一项非常困难的任务。尤其在面对长句时，信息很容易在压缩过程中丢失，导致语义表达不完整。这种“信息瓶颈”限制了模型在处理长文本或复杂语义结构时的表现。&lt;/li&gt;
&lt;li&gt;**缺乏动态感知，解码难以精准生成：**解码器始终只能基于同一个上下文向量进行生成。但在实际生成过程中，不同位置的目标词，往往依赖源句中不同的关键信息：生成主语时，可能更依赖源句的开头；生成谓语或宾语时，可能需要参考句中或句末内容。然而在固定表示下，解码器无法“有选择地关注”输入序列的不同部分，只能一视同仁地处理所有信息，从而降低了生成的准确性与灵活性。&lt;/li&gt;
&lt;/ol&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="阶段三transformer-的直接前身-seq2seq--attention-2014-2015年"&gt;阶段三：Transformer 的直接前身 (Seq2Seq + Attention, 2014-2015年)
&lt;/h2&gt;&lt;p&gt;早期的 &lt;code&gt;Seq2Seq&lt;/code&gt; 有一个致命缺陷：信息瓶颈。&lt;code&gt;Encoder&lt;/code&gt; 必须把几百个字的整篇文章压缩成一个固定大小的向量，这导致长句子的信息被严重丢失。
于是，&lt;code&gt;Attention&lt;/code&gt;（注意力机制） 被发明出来了（最早由 &lt;code&gt;Bahdanau&lt;/code&gt; 等人提出）：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;突破：&lt;/strong&gt; &lt;code&gt;Decoder&lt;/code&gt; 在生成每一个词的时候，不再依赖那个单一的压缩包，而是回头去看 &lt;code&gt;Encoder&lt;/code&gt; 输入的所有词，并且自己决定当前应该把“注意力”集中在哪些词上。
这个时候的顶配序列模型是：以 &lt;code&gt;LSTM&lt;/code&gt;/&lt;code&gt;GRU&lt;/code&gt; 为底座的 &lt;code&gt;Seq2Seq&lt;/code&gt; + &lt;code&gt;Attention&lt;/code&gt; 机制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工作原理&lt;/strong&gt;
注意力机制的核心思想，是解码器在生成目标序列的每一步时，动态地从编码器的各个时间步的隐藏状态中提取当前所需的信息，而不再只依赖一个固定的上下文向量。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="377px" data-flex-grow="157" height="1268" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412151727.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412151727_hu_b8df8c23b5e00259.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412151727_hu_998409fbea4ab4a0.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412151727.png 1994w" width="1994"&gt;&lt;/p&gt;
&lt;p&gt;这一机制包含以下四个步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;相关性计算：&lt;/strong&gt;
在目标序列生成的每一步，解码器都会计算当前时间步的隐藏状态与编码器各个时间步输出之间的相关性。这些相关性衡量了源句中每个位置对当前生成内容的重要程度，从而决定模型应将多少注意力分配给不同的源位置。相关性的计算依赖于特定的函数，通常被称为注意力评分函数（&lt;code&gt;attention scoring function&lt;/code&gt;）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="568px" data-flex-grow="236" height="1083" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152819.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152819_hu_d47011dd59ed0b2c.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152819_hu_25b20053ca52b5a4.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152819_hu_a93dae5a77200613.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152819.png 2564w" width="2564"&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;注意力权重计算：&lt;/strong&gt;
得到所有源位置的注意力评分后，使用 &lt;code&gt;Softmax&lt;/code&gt; 函数将其归一化为概率分布，作为注意力权重。得分越高的位置，其对应的权重越大，代表模型在当前生成中更关注该位置的信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="466px" data-flex-grow="194" height="1312" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152848.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152848_hu_db5df1f5aca95007.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152848_hu_3bc21069138af24e.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152848_hu_879ded91f874caa4.png 2400w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152848.png 2552w" width="2552"&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;上下文向量计算：&lt;/strong&gt;
将所有编码器输出按照注意力权重进行加权求和，得到一个上下文向量。这个向量就表示当前时间步，模型从源句中提取出的关键信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="357px" data-flex-grow="148" height="1080" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152923.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152923_hu_eca9d5d55e14066d.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152923_hu_874ed033b833018d.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152923.png 1607w" width="1607"&gt;&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;&lt;strong&gt;解码信息融合：&lt;/strong&gt;
在得到上下文向量后，解码器将其与当前时间步的隐藏状态进行拼接，以融合两者信息，最终通过线性变换和 &lt;code&gt;Softmax&lt;/code&gt;，生成当前时间步目标词的概率分布。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="356px" data-flex-grow="148" height="1565" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152955.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152955_hu_3c7d90d029147722.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152955_hu_f61ab20815bfb9bb.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412152955.png 2324w" width="2324"&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;⚠️ &lt;strong&gt;痛点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;尽管注意力机制极大地增强了 &lt;code&gt;Seq2Seq&lt;/code&gt; 模型的建模能力，但由于其核心依然依赖于 &lt;code&gt;RNN&lt;/code&gt; 结构，仍面临两个根本性问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;计算过程无法并行：&lt;/strong&gt; &lt;code&gt;RNN&lt;/code&gt; 的时间步之间存在强依赖，必须顺序执行，限制了训练效率和硬件资源的利用率。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长期依赖问题仍未根除：&lt;/strong&gt; 模型需要跨多个时间步传递信息，对于超长序列，训练过程中容易出现梯度消失，难以有效建模长距离依赖关系。&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="阶段四革命与颠覆-transformer-2017年"&gt;阶段四：革命与颠覆 (Transformer, 2017年)
&lt;/h2&gt;&lt;p&gt;到了 2017 年，Google 发表了著名的论文《Attention Is All You Need》：&lt;/p&gt;
&lt;p&gt;保留了 &lt;code&gt;Seq2Seq&lt;/code&gt; 的 &lt;code&gt;Encoder-Decoder&lt;/code&gt; 架构。
但是，他们彻底抛弃了里面的 &lt;code&gt;RNN&lt;/code&gt;/&lt;code&gt;LSTM&lt;/code&gt;/&lt;code&gt;GRU&lt;/code&gt; 细胞，全部用“自注意力机制 (&lt;code&gt;Self-Attention&lt;/code&gt;)”和前馈神经网络来代替。
通过这种方式，&lt;code&gt;Transformer&lt;/code&gt; 不仅显著提升了训练效率，也增强了模型对长距离依赖的建模能力。&lt;code&gt;Transformer&lt;/code&gt; 的提出对自然语言处理产生了深远影响。&lt;/p&gt;
&lt;h3 id="整体结构"&gt;整体结构
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Transformer&lt;/code&gt; 在宏观上，完美继承了 &lt;code&gt;Seq2Seq&lt;/code&gt; 模型的经典设计理念：“编码器-解码器（&lt;code&gt;Encoder-Decoder&lt;/code&gt;）”架构。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="357px" data-flex-grow="149" height="1361" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412160655.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412160655_hu_1a5af194ccc51b4f.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412160655_hu_f516eeb57399dc38.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412160655.png 2029w" width="2029"&gt;&lt;/p&gt;
&lt;p&gt;在这个架构中，两者的分工依然明确：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;编码器（&lt;code&gt;Encoder&lt;/code&gt;）：&lt;/strong&gt; 负责阅读、理解和表征输入的原文序列（提取核心思想）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解码器（&lt;code&gt;Decoder&lt;/code&gt;）：&lt;/strong&gt; 负责拿着编码器提炼的核心思想，一步步生成目标序列（如翻译后的外语）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Transformer&lt;/code&gt; 具备以下两个特点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;层层堆叠&lt;/strong&gt;
在传统的 &lt;code&gt;RNN&lt;/code&gt; 时代，往往只用一层（或者很少的几层）网络，靠着在时间轴上不断循环来提取信息。而 &lt;code&gt;Transformer&lt;/code&gt; 彻底抛弃了时间轴的循环，它选择在空间深度上疯狂堆砌。
它的编码器和解码器，都不再是单一的模块，而是分别由多个结构完全相同的“层（&lt;code&gt;Layer&lt;/code&gt;）”垂直堆叠而成（在标准的 &lt;code&gt;Transformer&lt;/code&gt; 原始论文中，包含了 6 个编码器层和 6 个解码器层）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;为什么要堆叠这么多层？&lt;/strong&gt;
你可以把它想象成一个流水线车间。当“我爱你”这三个字同时进入第 1 层时，模型可能只看懂了词性（“我”是代词，“爱”是动词）。然后结果传给第 2 层，模型看懂了主谓宾结构；传到第 4 层，看懂了时态；传到第 6 层时，模型就已经提取出了极其深度的语义特征和情感逻辑。层数越深，模型对复杂语言现象的建模能力就越强。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;“全量回顾”的自回归解码&lt;/strong&gt;
这是 &lt;code&gt;Transformer&lt;/code&gt; 在工程实现上与 &lt;code&gt;RNN&lt;/code&gt; 最大的不同点！
像 &lt;code&gt;RNN&lt;/code&gt; 一样，&lt;code&gt;Transformer&lt;/code&gt; 的解码器依然是自回归（&lt;code&gt;Autoregressive&lt;/code&gt;）的——也就是说，它必须一个词一个词地往外吐，直到吐出结束标记 &lt;code&gt;&amp;lt;eos&amp;gt;&lt;/code&gt; 为止。
但是它每一次生成新词时的输入条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RNN 是怎么做的：&lt;/strong&gt; &lt;code&gt;RNN&lt;/code&gt; 是有“记忆（隐藏状态 $h_t$）”的。当它要生成第 4 个词时，它只需要输入第 3 个词，因为前 3 个词的信息已经浓缩在它的记忆里了。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transformer 是怎么做的：&lt;/strong&gt; &lt;code&gt;Transformer&lt;/code&gt; 为了追求极致的并行计算速度，彻底切除了类似 &lt;code&gt;RNN&lt;/code&gt; 的“记忆体”。
既然没有记忆，它怎么知道自己刚才说了什么？
答案是全量输入：当它准备预测第 4 个词时，它必须把前面已经生成的第 1、2、3 个词，作为一整个序列同时重新输入进去！
模型会对着这 3 个词进行一波疯狂的注意力计算，最后输出一个长度同样为 3 的预测序列。但我们在代码里，只取这个输出序列的“最后一个位置”的结果，作为我们想要的第 4 个词。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编码器"&gt;编码器
&lt;/h3&gt;&lt;p&gt;编码器由多个结构相同的编码器层（&lt;code&gt;Encoder Layer&lt;/code&gt;）堆叠而成。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="350px" data-flex-grow="145" height="1146" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412163929.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412163929_hu_8ae30cad69da187.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412163929_hu_dc7acad9a602aaed.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412163929.png 1672w" width="1672"&gt;&lt;/p&gt;
&lt;p&gt;每个 &lt;code&gt;Encoder Layer&lt;/code&gt; 的主要任务都是对其输入序列进行上下文建模，使每个位置的表示都能融合来自整个序列的全局信息。每个 &lt;code&gt;Encoder Layer&lt;/code&gt; 都包含两个子层（&lt;code&gt;sublayer&lt;/code&gt;），分别是自注意力子层（&lt;code&gt;Self-Attention Sublayer&lt;/code&gt;）和前馈神经网络子层（&lt;code&gt;Feed-Forward Sublayer&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="492px" data-flex-grow="205" height="767" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412164036.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412164036_hu_8744c17b5397b351.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412164036.png 1575w" width="1575"&gt;&lt;/p&gt;
&lt;h4 id="self-attention-子层"&gt;Self-Attention 子层
&lt;/h4&gt;&lt;p&gt;用于捕捉序列中各位置之间的依赖关系，自注意力机制（&lt;code&gt;Self-Attention&lt;/code&gt;）是 &lt;code&gt;Transformer&lt;/code&gt; 编码器的核心结构之一，它的作用是在序列内部建立各位置之间的依赖关系，使模型能够为每个位置生成融合全局信息的表示。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="315px" data-flex-grow="131" height="1023" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412164142.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412164142_hu_ef129ab188efcfe2.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412164142.png 1343w" width="1343"&gt;&lt;/p&gt;
&lt;p&gt;之所以被称为“自”注意力，是因为模型在计算每个位置的表示时，所参考的信息全部来自同一个输入序列本身，而不是来自另一个序列。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自注意力计算过程&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;生成 &lt;code&gt;Query&lt;/code&gt;、&lt;code&gt;Key&lt;/code&gt;、&lt;code&gt;Value&lt;/code&gt; 向量&lt;/strong&gt;
自注意力机制的第一步，是将输入序列中的每个位置表示映射为三个不同的向量，分别是查询（&lt;code&gt;Query&lt;/code&gt;）、键（&lt;code&gt;Key&lt;/code&gt;）和值（&lt;code&gt;Value&lt;/code&gt;）。&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="img/Pasted image 20260412164657.png" width="80%" style="margin: 0 auto; display: block;" /&gt;
&lt;p&gt;这些向量的作用如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Query：&lt;/strong&gt; 表示当前词的用于发起注意力匹配的向量；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key：&lt;/strong&gt; 表示序列中每个位置的内容标识，用于与 &lt;code&gt;Query&lt;/code&gt; 进行匹配；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Value：&lt;/strong&gt; 表示该位置携带的信息，用于加权汇总得到新的表示。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自注意力的核心思想是：每个位置用自身的 &lt;code&gt;Query&lt;/code&gt; 向量，与整个序列中所有位置的 &lt;code&gt;Key&lt;/code&gt; 向量进行相关性计算，从而得到注意力权重，并据此对对应的 &lt;code&gt;Value&lt;/code&gt; 向量加权汇总，形成新的表示。
三个向量的计算公式如下：
&lt;/p&gt;
$$Q = X \cdot W^Q$$&lt;p&gt;
&lt;/p&gt;
$$K = X \cdot W^K$$&lt;p&gt;
&lt;/p&gt;
$$V = X \cdot W^V$$&lt;p&gt;
其中 $W^Q, W^K, W^V$ 均为可学习的参数矩阵。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;计算位置相关性&lt;/strong&gt;
完成 &lt;code&gt;Query&lt;/code&gt;、&lt;code&gt;Key&lt;/code&gt;、&lt;code&gt;Value&lt;/code&gt; 向量的生成后，模型会使用每个位置的 &lt;code&gt;Query&lt;/code&gt; 向量与所有位置的 &lt;code&gt;Key&lt;/code&gt; 向量进行相关性评分。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="421px" data-flex-grow="175" height="1084" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165255.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165255_hu_7fb4195f27fbd019.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165255_hu_1ab7302f04db185e.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165255.png 1905w" width="1905"&gt;&lt;/p&gt;
&lt;p&gt;评分函数采用向量点积形式。由于在高维空间中，点积的数值可能过大，会影响 &lt;code&gt;Softmax&lt;/code&gt; 的稳定性，因此在实际计算中对结果进行了缩放。最终的评分函数为：
&lt;/p&gt;
$$score(i,j) = \frac{q_i \cdot k_j}{\sqrt{d_k}}$$&lt;p&gt;
其中 $d_k$ 是 &lt;code&gt;Key&lt;/code&gt; 向量的维度，用于缩放点积的幅度。这个分数越大，表示第 $i$ 个位置越应该关注第 $j$ 个位置的信息。
对于整个序列，可以通过矩阵运算一次性计算所有位置之间的评分，计算公式如下图所示：&lt;/p&gt;
&lt;img src="img/Pasted image 20260412165755.png" width="70%" style="margin: 0 auto; display: block;" /&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;计算注意力权重&lt;/strong&gt;
在得到每个位置与所有位置之间的相关性评分后，模型会使用 &lt;code&gt;Softmax&lt;/code&gt; 函数进行归一化，确保每个位置对所有位置的关注程度之和为 1，从而形成一个有效的加权分布。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="330px" data-flex-grow="137" height="1376" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165901.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165901_hu_26073d2ca3cd6f02.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165901_hu_cf3cbed6abdfca04.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412165901.png 1893w" width="1893"&gt;&lt;/p&gt;
&lt;p&gt;对于整个序列，模型要做的是对之前得到的注意力评分矩阵的每一行进行 &lt;code&gt;Softmax&lt;/code&gt; 归一化。&lt;/p&gt;
&lt;img src="img/Pasted image 20260412165930.png" width="70%" style="margin: 0 auto; display: block;" /&gt;
&lt;ol start="4"&gt;
&lt;li&gt;&lt;strong&gt;加权汇总生成输出&lt;/strong&gt;
最后，模型会根据注意力权重对所有位置的 &lt;code&gt;Value&lt;/code&gt; 向量进行加权求和，得到每个位置融合全局信息后的新表示。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="255px" data-flex-grow="106" height="1512" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170046.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170046_hu_c3418af1e06aee9b.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170046_hu_a48a25e853eafa44.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170046.png 1609w" width="1609"&gt;&lt;/p&gt;
&lt;p&gt;对于整个序列，同样可以通过矩阵运算一次性计算所有位置的输出，如下图所示：&lt;/p&gt;
&lt;img src="img/Pasted image 20260412170149.png" width="70%" style="margin: 0 auto; display: block;" /&gt;
&lt;p&gt;综上所述，可得整个自注意力机制的完整的计算公式如下&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="581px" data-flex-grow="242" height="859" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170204.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170204_hu_5d6b28e0992bfb9.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170204_hu_b24d8eb684707004.png 1600w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260412170204.png 2081w" width="2081"&gt;&lt;/p&gt;
&lt;p&gt;对应原始论文中的：
&lt;/p&gt;
$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$&lt;h4 id="多头自注意力计算过程"&gt;多头自注意力计算过程
&lt;/h4&gt;&lt;p&gt;自注意力机制通过 &lt;code&gt;Query&lt;/code&gt;、&lt;code&gt;Key&lt;/code&gt; 和 &lt;code&gt;Value&lt;/code&gt; 向量计算每个位置与其他位置之间的依赖关系，使模型能够有效捕捉序列中的全局信息。
然而，自然语言本身具有高度的语义复杂性，一个句子往往同时包含多种类型的语义关系。例如，句子“那只动物没有过马路，因为它太累了”中就涉及多个层面的语言关系：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“它”指代“那只动物”，属于跨句的代指关系；&lt;/li&gt;
&lt;li&gt;“因为”连接前后两个分句，体现语义上的因果逻辑；&lt;/li&gt;
&lt;li&gt;“过马路”构成动词短语，属于固定的动宾结构。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要准确理解这类句子，模型需要同时识别并建模多种层次和类型的依赖关系。但这些信息很难通过单一视角或一套注意力机制完整捕捉。
为此，&lt;code&gt;Transformer&lt;/code&gt; 引入了多头注意力机制（&lt;code&gt;Multi-Head Attention&lt;/code&gt;）。其核心思想是通过多组独立的 &lt;code&gt;Query&lt;/code&gt;、&lt;code&gt;Key&lt;/code&gt;、&lt;code&gt;Value&lt;/code&gt; 投影，让不同注意力头分别专注于不同的语义关系，最后将各头的输出拼接融合。
多头注意力的计算过程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;分别计算各头注意力：&lt;/strong&gt;
每个 &lt;code&gt;Self-Attention Head&lt;/code&gt; 独立计算一套注意力输出。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="341px" data-flex-grow="142" height="584" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111355.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111355_hu_61189f520b6c55fc.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111355.png 832w" width="832"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;合并多头注意力：&lt;/strong&gt;
多个输出矩阵按维度拼接，再乘以 $W^O$ 得到最终多头注意力的输出。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="316px" data-flex-grow="131" height="444" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111437.png" width="586"&gt;&lt;/p&gt;
&lt;h4 id="前馈神经网络层"&gt;前馈神经网络层
&lt;/h4&gt;&lt;p&gt;前馈神经网络（&lt;code&gt;Feed-Forward Network&lt;/code&gt;，简称 &lt;code&gt;FFN&lt;/code&gt;）是 &lt;code&gt;Transformer&lt;/code&gt; 编码器中每个子层的重要组成部分，紧接在多头注意力子层之后。它通过对每个位置的表示进行逐位置、非线性的特征变换，进一步提升模型对复杂语义的建模能力。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="313px" data-flex-grow="130" height="406" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111532.png" width="530"&gt;&lt;/p&gt;
&lt;p&gt;一个标准的 &lt;code&gt;FFN&lt;/code&gt; 子层包含两个线性变换和一个非线性激活函数，中间通常使用 &lt;code&gt;ReLU&lt;/code&gt; 激活。其计算公式如下：
&lt;/p&gt;
$$\text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2$$&lt;p&gt;
计算图如下：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="679px" data-flex-grow="282" height="294" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111600.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111600_hu_92f467a44dde609d.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111600.png 832w" width="832"&gt;&lt;/p&gt;
&lt;h4 id="残差连接与层归一化"&gt;残差连接与层归一化
&lt;/h4&gt;&lt;p&gt;在 &lt;code&gt;Transformer&lt;/code&gt; 的每个编码器层中，每个子层，包括自注意力子层和前馈神经网络子层，其输出都要经过残差连接（&lt;code&gt;Residual Connection&lt;/code&gt;）和层归一化（&lt;code&gt;Layer Normalization&lt;/code&gt;）处理。这两者是深层神经网络中常用的结构，用于缓解模型训练中的梯度消失、收敛困难等问题，对于 &lt;code&gt;Transformer&lt;/code&gt; 能够堆叠多层至关重要。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="190px" data-flex-grow="79" height="614" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413111651.png" width="488"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;残差连接&lt;/strong&gt;
残差连接（&lt;code&gt;Residual Connection&lt;/code&gt;，也称“跳跃连接”或“捷径连接”）最初在计算机视觉领域被提出，用于缓解深层神经网络中的梯度消失问题。其核心思想是：
将子层的输入直接与其输出相加，形成一条跨越子层的“捷径”，其数学形式为：
&lt;/p&gt;
$$y = x + \text{SubLayer}(x)$$&lt;p&gt;
具体计算过程如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="190px" data-flex-grow="79" height="648" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413112213.png" width="514"&gt;&lt;/p&gt;
&lt;p&gt;残差连接确保反向传播时，梯度至少有一条稳定通路可回传，是深层网络可稳定训练的关键结构。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;层归一化&lt;/strong&gt;
每个子层在残差连接之后都会进行层归一化（&lt;code&gt;Layer Normalization&lt;/code&gt;，简称 &lt;code&gt;LayerNorm&lt;/code&gt;）。它的主要作用是规范输入序列中每个 &lt;code&gt;token&lt;/code&gt; 的特征分布（某个 &lt;code&gt;token&lt;/code&gt; 的表示可能在不同维度上有较大数值差异），提升模型训练的稳定性。
先把数据拉回正态分布，然后给模型两个可学习参数，让模型根据自己的情况去决定最终的分布情况。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="190px" data-flex-grow="79" height="586" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413112324.png" width="466"&gt;&lt;/p&gt;
&lt;p&gt;该操作会将每个 &lt;code&gt;token&lt;/code&gt; 的向量调整为均值为 $0$、方差为 $1$ 的规范分布，具体效果如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="195px" data-flex-grow="81" height="218" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413112422.png" width="178"&gt;&lt;/p&gt;
&lt;p&gt;具体的计算公式如下：
假如某个 &lt;code&gt;token&lt;/code&gt; 的特征向量为 $x = [x^1, x^2, x^3, x^4, &amp;hellip;, x^d]$，&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;均值计算
计算该向量在所有特征维度上的平均值
&lt;/p&gt;
$$\mu = \frac{1}{d} \sum_{i=1}^{d} x^i$$&lt;p&gt;
其中 $d$ 为特征维度（向量长度）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;标准差计算
计算向量各维度的标准差
&lt;/p&gt;
$$\sigma = \sqrt{\frac{1}{d} \sum_{i=1}^{d} (x^i - \mu)^2}$$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;标准化变换
将每个特征值转换为均值为 $0$、方差为 $1$ 的标准正态分布；
&lt;/p&gt;
$$\hat{x}^i = \frac{x^i - \mu}{\sigma + \varepsilon}$$&lt;p&gt;
$\varepsilon$ 为一个小的常数，防止出现除以 0 的情况。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缩放与平移
为了让模型可以学习在归一化后的基础上进行适当的调整，保证归一化不会限制模型的表示能力。
&lt;/p&gt;
$$\text{LayerNorm}(x^i) = \gamma^i \cdot \hat{x}^i + \beta^i$$&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="位置编码"&gt;位置编码
&lt;/h4&gt;&lt;p&gt;&lt;code&gt;Transformer&lt;/code&gt; 模型完全摒弃了 &lt;code&gt;RNN&lt;/code&gt; 结构，意味着它不再按顺序处理序列，而是可以并行处理所有位置的信息。尽管这带来了显著的计算效率提升，却也引发了一个问题：&lt;code&gt;Transformer&lt;/code&gt; 无法像 &lt;code&gt;RNN&lt;/code&gt; 那样天然地捕捉词语之间的顺序关系。换句话说，在没有额外机制的情况下，&lt;code&gt;Transformer&lt;/code&gt; 无法区分“猫吃鱼”和“鱼吃猫”这类语序不同但词汇相同的句子。
为了解决这一问题，&lt;code&gt;Transformer&lt;/code&gt; 引入了一个关键机制——位置编码（&lt;code&gt;Positional Encoding&lt;/code&gt;）。该机制为每个词引入一个表示其位置信息的向量，并将其与对应的词向量相加，作为模型输入的一部分。这样一来，模型在处理每个词时，既能获取词义信息，也能感知其在句子中的位置，从而具备对基本语序的理解能力。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="230px" data-flex-grow="95" height="578" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141154.png" width="554"&gt;&lt;/p&gt;
&lt;p&gt;位置编码最直接的方式是使用绝对位置编号来表示每个词的位置，例如第一个词用 $0$，第二个词用 $1$，依此类推：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="3840px" data-flex-grow="1600" height="52" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141626.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141626_hu_12dfd62a96f26073.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141626.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;这样做虽然简单，但有一个明显的问题，越靠后的 &lt;code&gt;token&lt;/code&gt; 位置编码就越大，若直接与词向量相加，会造成数值倾斜，让模型更关注位置，而忽视词义。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="1313px" data-flex-grow="547" height="152" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141640.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141640_hu_fb76c9653cb48f14.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141640.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;为缓解这一问题，可以考虑将位置编号归一化为 $[0, 1]$ 区间，例如用 $\frac{pos}{T-1}$ 表示位置，其中 $T$ 是句子长度。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="3840px" data-flex-grow="1600" height="52" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141652.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141652_hu_f166a83397edd985.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413141652.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;这种方式虽然使数值范围更平稳，但也引入了一个严重的问题：
相同位置的词在不同长度句子中的位置编码不再一致。
例如，位置 5 在长度为 10 的句子中被编码为 $\frac{5}{9}$，在长度为 1000 的句子中则为 $\frac{5}{999}$。这种依赖输入长度的表示方式会导致模型难以形成稳定的位置感知能力。理想的做法是：每个位置都拥有一个唯一且一致的编码，与句子长度无关。
为了解决上述问题，&lt;code&gt;Transformer&lt;/code&gt; 使用了一种基于正弦（sin）和余弦（cos）函数的位置编码方式，具体定义如下：&lt;/p&gt;
$$
\begin{aligned} 
PE_{(pos, 2i)} &amp;= \sin\left( \frac{pos}{10000^{\frac{2i}{d_{model}}}} \right) \\ 
PE_{(pos, 2i+1)} &amp;= \cos\left( \frac{pos}{10000^{\frac{2i}{d_{model}}}} \right) 
\end{aligned}
$$&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$pos$ 是当前词在序列中的位置；&lt;/li&gt;
&lt;li&gt;$i$ 用于表示位置编码向量的维度索引，$2i$ 表示偶数维，$2i + 1$ 表示奇数维；&lt;/li&gt;
&lt;li&gt;$d_{model}$ 是词向量的维度大小。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;序列中的每个位置 $pos$ 对应一个长度为 $d_{model}$ 的位置编码向量。该向量的偶数维度通过正弦函数生成，奇数维度通过余弦函数生成，如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="263px" data-flex-grow="109" height="370" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413142228.png" width="406"&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Transformer&lt;/code&gt; 提出的这种编码方式不依赖任何可学习参数，数值稳定，并具备以下优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有值都在 $[-1,1]$ 范围内，数值稳定&lt;/li&gt;
&lt;li&gt;编码方式固定、可预计算，无需训练；&lt;/li&gt;
&lt;li&gt;相同位置的编码在不同句子中保持一致；&lt;/li&gt;
&lt;li&gt;编码之间具有数学规律，便于模型在注意力机制中感知词语之间的相对位置关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;编码器完整结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="162px" data-flex-grow="67" height="584" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413142425.png" width="396"&gt;&lt;/p&gt;
&lt;h3 id="解码器"&gt;解码器
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Transformer&lt;/code&gt; 解码器的主要功能是：根据编码器的输出，逐步生成目标序列中的每一个词。其生成方式采用自回归机制（&lt;code&gt;autoregressive&lt;/code&gt;）：每一步的输入由此前已生成的所有词组成，模型将输出一个与当前输入长度相同的序列表示。我们只取最后一个位置的输出，作为当前步的预测结果。这一过程会不断重复，直到生成特殊的结束标记 &lt;code&gt;&amp;lt;eos&amp;gt;&lt;/code&gt;，表示序列生成完成。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="786px" data-flex-grow="327" height="254" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144301.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144301_hu_46a315abaa77ca23.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144301.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;编码器也由多个结构相同的解码器层堆叠组成。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="349px" data-flex-grow="145" height="572" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144339.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144339_hu_92c54e524a094077.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144339.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;每个 &lt;code&gt;Decoder Layer&lt;/code&gt; 都包含三个子层，分别是 &lt;code&gt;Masked&lt;/code&gt; 自注意力子层、编码器-解码器注意力子层（&lt;code&gt;Encoder-Decoder Attention&lt;/code&gt;）和前馈神经网络子层（&lt;code&gt;Feed-Forward Network&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="482px" data-flex-grow="200" height="414" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144358.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144358_hu_744952a47fc934e7.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144358.png 832w" width="832"&gt;&lt;/p&gt;
&lt;h4 id="masked-自注意力子层masked-self-attention"&gt;Masked 自注意力子层（Masked Self Attention）
&lt;/h4&gt;&lt;p&gt;该子层的主要作用是：建模目标序列中当前位置与前文之间的依赖关系，为当前词的生成提供上下文语义支持。
由于 &lt;code&gt;Transformer&lt;/code&gt; 不具备像 &lt;code&gt;RNN&lt;/code&gt; 那样的隐藏状态传递机制，无法在序列生成过程中保留上下文信息，因此在生成每一个词时，必须将此前已生成的所有词作为输入，通过自注意力机制重新建模上下文关系，以预测下一个词。
此外，从结构上看，&lt;code&gt;Transformer&lt;/code&gt; 编解码器都具有一个典型特性：输入多少个词，就输出多少个表示。需要注意的是，在推理阶段，我们只使用解码器最后一个位置的输出作为当前步的预测结果，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="780px" data-flex-grow="325" height="256" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144529.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144529_hu_aeddf5a44092ca7a.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144529.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;如果训练阶段也完全按照推理流程进行，就必须将每个目标序列拆分成多个训练样本，每个样本输入一段前文，只预测一个词。如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="773px" data-flex-grow="322" height="258" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144548.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144548_hu_a601d2fc090295df.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144548.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;这种方式虽然逻辑合理，但训练效率极低，完全无法利用 &lt;code&gt;Transformer&lt;/code&gt; 并行计算的优势。
为提升效率，&lt;code&gt;Transformer&lt;/code&gt; 采用了并行训练策略：一次性输入完整目标序列，同时预测每个位置的词。如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="647px" data-flex-grow="269" height="226" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144621.png" width="610"&gt;&lt;/p&gt;
&lt;p&gt;但如果不加限制，这种方式会让模型在预测每个位置时“看到”后面的词，即提前访问未来信息，破坏生成任务的因果结构，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="264px" data-flex-grow="110" height="526" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144638.png" width="580"&gt;&lt;/p&gt;
&lt;p&gt;为解决这个问题，解码器在自注意力机制中引入了遮盖机制（&lt;code&gt;Mask&lt;/code&gt;）。该机制会在计算注意力时，阻止模型访问当前位置之后的词，只允许它依赖自身及前文的信息。这样，即使在并行训练时，模型也只能像逐词生成一样“看见”它应该看到的内容，从而保持训练与推理阶段的一致性。如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="262px" data-flex-grow="109" height="518" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144714.png" width="566"&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Mask&lt;/code&gt; 机制的实现非常简单：只需将注意力得分矩阵中当前位置对其后续位置的评分设置为 $-\infty$，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="594px" data-flex-grow="247" height="336" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144737.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144737_hu_a3217cb43db42d76.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144737.png 832w" width="832"&gt;&lt;/p&gt;
&lt;p&gt;这样，在经过 &lt;code&gt;Softmax&lt;/code&gt; 运算后，这些位置的权重会趋近于 $0$。最终在加权求和时，来自未来位置的信息几乎不会参与计算，从而实现了“当前词只能看到它前面的词”的约束。如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="1202px" data-flex-grow="501" height="166" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144754.png" srcset="https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144754_hu_9a05261f81a04881.png 800w, https://xystart.github.io/p/transformer/img/Pasted%20image%2020260413144754.png 832w" width="832"&gt;&lt;/p&gt;
&lt;h4 id="编码器-解码器注意力子层"&gt;编码器-解码器注意力子层
&lt;/h4&gt;&lt;p&gt;该子层的主要作用是：建模当前解码位置与源语言序列中各位置之间的依赖关系，帮助模型在生成目标词时有效地参考输入内容，相当于 &lt;code&gt;Seq2Seq&lt;/code&gt; 模型中的注意力机制。
编码器-解码器注意力的核心机制与前面讲过的自注意力机制完全一致，区别仅在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$Query$ 来自解码器当前的输入表示，即当前生成状态；&lt;/li&gt;
&lt;li&gt;$Key$ 和 $Value$ 来自编码器的输出表示，即整个源序列的上下文。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，当前生成位置使用自己的 &lt;code&gt;Query&lt;/code&gt;，去“询问”编码器输出中的哪些位置最相关。注意力机制会根据 &lt;code&gt;Query&lt;/code&gt; 与所有 &lt;code&gt;Key&lt;/code&gt; 的相似度，为每个源位置分配一个权重，然后用这些权重对 &lt;code&gt;Value&lt;/code&gt; 进行加权求和，得到当前生成词所需的上下文信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解码器完整结构&lt;/strong&gt;&lt;/p&gt;
&lt;img src="img/Pasted image 20260413165046.png" style="margin: 0 auto; display: block;" /&gt;</description></item></channel></rss>