一个 Token 的完整旅程从输入到输出揭秘大模型内部工作流程 导读你是否好奇当你在聊天框输入一句话时大模型内部发生了什么本文将带你追踪一个 token 从进入模型到生成回复的完整旅程揭开 LLM 的神秘面纱️ 前言为什么要理解 Token 的旅程在之前的三篇文章中我们深入拆解了 Transformer 的各个组件Attention、FFN、Embedding 等。但单独看每个部分就像只看汽车的零件——你知道发动机怎么工作却不知道整辆车如何行驶。真正的 LLM 是一条精密的流水线文字进去概率出来一步步生成流畅的回复。今天我们将以第一视角追踪一个 token 的完整旅程看看它从输入到输出都经历了什么这将帮助你建立全局认知理解各组件如何协同工作定位优化点知道性能瓶颈在哪里启发创新思路在合适的环节尝试改进准备好了吗让我们开始这场奇妙的旅程✨ 第一站输入层 - 文字的数字化 transformation1.1 Tokenizer把文字切成模型能理解的碎片当你输入“我想吃苹果”时模型并不能直接理解这些汉字。首先需要经过Tokenizer分词器把文本切成一个个 token词元。原始输入: 我想吃苹果 ↓ Tokenizer Token序列: [我, 想, 吃, 苹果] Token ID: [1024, 2048, 3072, 5432]三种 Tokenization 策略对比策略示例优点缺点字符级“我”|“想”|“吃”|“苹”|“果”词汇表小序列长效率低词语级“我”|“想”|“吃”|“苹果”语义清晰未登录词问题子词级(BPE/WordPiece)“我”|“想”|“吃”|“苹果”平衡灵活实现复杂现代大模型的选择绝大多数采用子词级别的 Tokenization如 BPE、Unigram LM在词汇量通常 30K-100K和表达能力之间取得平衡。小知识GPT-4 的词表大小约 100KLLaMA 约 32K。中文 token 通常比英文更贵因为一个汉字的信息密度更高。1.2 Embedding查表获得语义向量每个 token ID 会通过Embedding 层查找对应的向量表示# 伪代码示例Embedding 过程vocab_size32000# 词表大小embedding_dim4096# 向量维度LLaMA-2-7B# 1. 查找 token 对应的 IDtoken_idvocab[苹果]# 例如: 5432# 2. 从 embedding 矩阵中查表embedding_matrixnn.Embedding(vocab_size,embedding_dim)token_embeddingembedding_matrix[token_id]# 得到 4096 维向量这个4096 维的向量包含了 “苹果” 这个词的语义信息它是一种水果 也可以是科技公司 上下文会决定具体含义Embedding 的本质可以把 Embedding 看作一个巨大的查找表Token ID → [0.12, -0.45, 0.78, ..., 0.33] (4096 维)训练过程中这个表会不断更新让语义相近的词向量距离更近比如 “苹果” 和 “梨” 的向量会很相似。1.3 RoPE 位置编码告诉模型顺序很重要Transformer 有个致命缺陷它本身不知道 token 的顺序我想吃苹果 和 苹果吃我想 对纯 Attention 来说是一样的 ❌所以需要加入位置编码Position Encoding# 最终输入向量 Token Embedding 位置编码final_inputtoken_embeddingposition_encoding(position3)为什么选择 RoPE现代大模型LLaMA、PaLM 等普遍使用RoPERotary Position Embedding旋转位置编码原因是特性传统位置编码RoPE相对位置感知❌ 弱✅ 强外推能力❌ 差✅ 好计算复杂度O(n)O(n)RoPE 的核心思想通过旋转矩阵给不同位置的 token 注入角度信息让模型能更好地捕捉相对位置关系。✅到这一步模型拿到的是同时包含 “什么意思” 和 “在什么位置” 的输入向量可以进入核心加工厂了 第二站Transformer Block - 核心加工厂接下来向量会进入堆叠的Transformer Block可能有 32 层、64 层甚至更多。每个 Block 主要做三件事2.1 AttentionToken 之间互相交流信息Self-Attention自注意力机制让每个 token 都能看到其他 token建立上下文联系输入: 我想吃苹果 Attention 过程 我 ←→ 想 (代词找动词) 想 ←→ 吃 (助动词找主要动词) 吃 ←→ 苹果 (动词找宾语)Attention 的三大职责从别人那里拿信息每个 token 收集其他 token 的相关信息建立依赖关系识别语法结构主谓宾、定状补带上下文回家融合全局信息形成新的表示关键技术优化在实际工程中Attention 有多个重要优化技术作用效果KV Cache缓存历史计算的 K 和 V推理速度提升 2-3 倍FlashAttention优化内存访问模式显存减少 20%速度提升 3 倍Multi-Head多头并行关注不同方面表达能力大幅提升Grouped Query分组共享 Key/Value平衡性能和效果深入理解Attention 的输出仍然是 4096 维向量但现在每个向量都融合了整个句子的上下文信息。2.2 FFN前馈网络对每个 Token 单独深加工Attention 之后每个 token 会经过Feed-Forward Network前馈神经网络# 简化的 FFN 结构LLaMA 使用 SwiGLUdefforward(x):# 第一步升维4096 → 11008xLinear1(x)# 第二步非线性激活SwiGLUxswiglu_activation(x)# 第三步降维11008 → 4096xLinear2(x)returnxFFN 的核心职责信息再加工把 Attention 收集的混合信息进行深度处理非线性变换引入复杂的函数映射能力知识存储模型大部分参数其实在这里⚠️惊人事实在 LLaMA-2-7B 中FFN 占据了约67%的参数约 47 亿参数而 Attention 只占约 25%。前沿优化MoEMixture of Experts传统 FFN 每次推理都要激活所有参数而MoE采用稀疏激活传统 FFN所有样本都用同一组参数 MoE FFN不同样本路由到不同的专家网络优势参数量可以扩大 10 倍如 Mixtral 8x7B推理成本只增加 2-3 倍效果显著提升2.3 残差连接 LayerNorm让深层网络能跑稳# Pre-Norm 架构现代模型主流outputattention_inputAttention(LayerNorm(attention_input))outputffn_inputFFN(LayerNorm(ffn_input))这两个组件至关重要组件作用不用的后果残差连接让信息跨层传递防止梯度消失超过 10 层就训练不动LayerNorm稳定每层的输入分布训练震荡难以收敛⚠️没有这两样几十层甚至上百层的网络梯度早崩了这是 Transformer 能堆这么深的关键秘诀。2.4 层层递进从字面到任务的抽象升级Transformer Block 会堆叠很多次不同层学习不同抽象级别的信息第 1-8 层低层学字面信息 ├─ 词性标注名词、动词... ├─ 局部语法短语结构 └─ 基础语义词义消歧 第 9-24 层中层学句法结构 ├─ 从句关系 ├─ 指代消解他指的是谁 └─ 逻辑关系因果、转折 第 25-32 层高层学任务目标 ├─ 整体语义理解 ├─ 意图识别 └─ 任务特定特征翻译、问答等类比理解就像阅读理解先看字词低层再看句子结构中层最后理解主旨高层。 第三站输出层 - 隐藏状态变概率3.1 Final Hidden State → Logits经过所有 Transformer Block 后最后一个 token的 final hidden state 会被送到输出层# 假设最后一个 token 的隐藏状态last_hidden_state[0.23,-0.56,0.89,...,0.12]# 4096 维# 通过线性层映射到词表大小vocab_size32000logitsLinear(last_hidden_state)# 输出 32000 维向量这32000 维的 logits对应词表中每个词的得分。3.2 Softmax变成概率分布importtorch probabilitiestorch.softmax(logits,dim-1)假设词表里只有几个词预测 “我想吃___” 后面可能得到概率分布 - 苹果8% - 饭15% - 面5% - 火锅25% - 烧烤12% - ... 35%其他所有词可视化想象就像一个有 32000 个格子的长条每个格子代表一个词高度代表被选中的概率。3.3 解码策略决定选哪个词有了概率分布还需要解码策略来选择下一个 token。不同的策略会产生不同的效果策略原理适用场景示例Greedy永远选概率最大的确定性任务翻译“火锅”(25%)Top-k从前 k 个中随机采样需要多样性从 top 50 中选Top-p累积概率达 p 的集合中采样对话生成p0.9 动态调整Temperature调节概率分布的平滑度控制创造性T0.7 平衡Temperature 的神奇效果# Temperature 如何改变概率分布defapply_temperature(logits,temperature):scaled_logitslogits/temperaturereturnsoftmax(scaled_logits)T → 0趋近 Greedy输出确定但可能单调T 1原始概率分布T → ∞趋近均匀分布完全随机实际应用ChatGPT 默认 T≈0.7代码生成 T≈0.2创意写作 T≈1.0。3.4 Autoregressive一个字一个字滚出来选完 token 后把它加回上下文继续预测下一个第 1 步: 输入 我想吃 → 预测 → 选中 火锅 (25%) 第 2 步: 输入 我想吃火锅 → 预测 → 选中 (40%) 第 3 步: 输入 你想吃火锅 → 预测 → 选中 你 (18%) 第 4 步: 输入 你想吃火锅你 → 预测 → 选中 要 (35%) ... 循环直到遇到结束符 /s聊天回复就是这样一个字一个字滚出来的这就是为什么长回复需要更多时间。 工程视角知道模块职责才知道优化哪里理解完整流程后我们可以针对性地优化各个模块性能优化地图模块瓶颈优化方向典型技术加速效果Attention计算复杂度 O(n²)KV Cache、FlashAttentionPagedAttention、Ring Attention2-5 倍FFN参数量大MoE、量化Mixtral、AWQ、GPTQ2-10 倍Embedding词表查找共享嵌入、量化-1.2 倍解码串行生成并行解码、推测采样Speculative Decoding2-3 倍内存KV Cache 占用分页管理、压缩vLLM、PagedAttention显存减半实际案例分析vLLM 的优化策略vLLM是目前最快的推理引擎之一它的核心优化PagedAttention像操作系统管理内存一样管理 KV CacheContinuous Batching动态批处理不同长度的请求Kernel 融合减少 GPU kernel 启动开销效果相比 HuggingFace Transformers吞吐量提升24 倍 总结建立一张工程地图通过追踪一个 token 的完整旅程我们建立了这样的认知地图 输入文本 ↓ Tokenizer 切分BPE/WordPiece ↓ Embedding RoPE 位置编码 ↓ [Transformer Block × N 层] ├─ Attention交互信息建立上下文 ├─ ⚙️ FFN深度加工存储知识 └─ 残差 LayerNorm稳定训练 ↓ 输出层线性映射4096 → 32000 ↓ Softmax 转概率分布 ↓ 解码策略选择Greedy/Top-p/Temperature ↓ ✅ 下一个 Token ↓ 循环直到生成结束符理解全貌的四大价值 定位问题知道每个环节的职责bug 出现时能快速定位 性能优化找到瓶颈所在通常是 Attention 或 FFN 创新改进在合适的地方尝试新方法如在 FFN 用 MoE 成本控制理解为什么某些操作贵如长上下文的 KV Cache 延伸阅读与实战建议深入学习的经典论文Attention 机制《Attention Is All You Need》(2017) - Transformer 开山之作RoPE 位置编码《RoFormer: Enhanced Transformer with Rotary Position Embedding》FlashAttention《FlashAttention: Fast and Memory-Efficient Exact Attention》MoE 架构《Switch Transformers: Scaling to Trillion Parameter Models》推理优化《vLLM: Easy, Fast, and Cheap LLM Serving with PagedAttention》动手实践建议初级可视化理解# 使用 transformers 库查看中间层输出fromtransformersimportAutoModel,AutoTokenizer modelAutoModel.from_pretrained(bert-base-chinese)tokenizerAutoTokenizer.from_pretrained(bert-base-chinese)inputstokenizer(我想吃苹果,return_tensorspt)outputsmodel(**inputs,output_hidden_statesTrue)# 查看每一层的隐藏状态fori,hidden_stateinenumerate(outputs.hidden_states):print(fLayer{i}: shape{hidden_state.shape})中级性能分析# 使用 pytorch profiler 分析瓶颈importtorch.profilerwithtorch.profiler.profile(activities[torch.profiler.ProfilerActivity.CUDA],record_shapesTrue)asprof:model.generate(inputs)print(prof.key_averages().table(sort_bycuda_time_total))高级自定义优化实现简单的 KV Cache尝试不同的解码策略实验量化INT8/INT4效果️ 标签#LLM #Transformer #DecoderOnly #Attention #FFN #AI原理 #大模型 #技术科普 #推理优化 #干货 #NLP #深度学习 互动话题你在实践中遇到过哪些推理性能瓶颈你对哪个环节的优化最感兴趣欢迎在评论区留言讨论如果觉得这篇文章对你有帮助请点赞 、收藏 ⭐、转发分享 下一篇预告我们将深入探讨 KV Cache 的实现细节和优化技巧敬请期待作者简介专注于大模型底层原理与工程优化致力于让 AI 技术更易懂、更易用。版权声明本文为原创内容转载请注明出处。