当我们把一段文字输入给大语言模型并看着屏幕上如流水般涌现出回答时一切都显得那么自然仿佛魔法一般。在日常的交流中我们往往习惯用“推理”Inference这一个词来统称这个过程。但如果我们掀开这层优雅的表象潜入底层算力的世界就会发现一个常被忽略的真相大模型的推理从来都不是一项单一的工作。严格来说它是两份截然不同的差事只是它们之间的交接如此平滑以至于我们很少察觉。在模型真正开始“思考”之前它必须先将人类的语言转化为它能理解的格式。机器不懂汉字或字母它们只懂数字。因此你输入的句子首先会被切分成一个个被称为 Token 的基础单元。你可以把 Token 想象成大模型词典里的基本音节。prompt How does inference work? ids tokenizer.encode(prompt) # ids - [2437, 1374, 32278, 670, 30] # embedding_table has shape [vocab_size, hidden_dim] vectors embedding_table[ids] # shape: [num_tokens, 4096]完成切分后这些离散的 Token 会被映射到一个高维的数学空间中变成密集的数字矩阵也就是我们常听到的“词向量”Embedding。在这个空间里意义相近的词汇会在距离上相互靠近。直到这一步模型才算做好了处理信息的准备。接下来真正繁重的计算任务要在 Transformer 层中展开了。你可以把 Transformer 的网络层想象成一台极其庞大且精密的数学齿轮组。当词向量穿过这些网络层时它们会经历一系列复杂的矩阵乘法运算。正是在这里模型开始计算不同词汇之间的“注意力”Attention去理解你这段话里究竟谁才是重点从而捕捉到上下文的真正含义。但这台齿轮组的运转方式在“阅读你的问题”和“写下它的答案”时有着天壤之别。 这就引出了模型的第一份工作“预填充”Prefill阶段。当你按下回车键模型会一次性接收你的完整提示词。无论你输入的是短短一句问候还是一篇长达万字的文章对模型来说所有的信息都已经摆在了桌面上。因为输入是完整的GPU 就可以彻底释放它那恐怖的并行计算能力。它会在同一时间对所有的输入 Token 进行海量的矩阵运算。在这个阶段GPU 的计算核心全速运转发热量飙升。此时限制模型速度的唯一因素就是芯片做数学题的速度。在工程术语中我们称之为“计算密集型”Compute-bound过程。在这个阶段模型正在构建对你问题的深刻理解为接下来的回答打下地基。# Prefill: process the whole prompt in one shot hidden embed(prompt_tokens) positions for layer in model.layers: Q, K, V project(hidden) # for ALL tokens at once hidden attention(Q, K, V) hidden hidden feedforward(hidden) hidden cache_kv(layer, K, V) # save for later first_token sample(project_to_vocab(hidden[-1]))然而当模型彻底消化了你的提示词准备开口说话时工作的性质发生了彻底的反转。它进入了第二份工作“解码”Decode阶段。这也是实际生成文字的阶段。 与阅读不同大模型写文章是一个极其严格的流水线作业。它不能一挥而就只能一个词、一个词地往外蹦。模型需要审视之前处理过的所有信息去概率分布中猜测下一个最合适的 Token把它输出到屏幕上然后再把这个新生成的词加入到已知信息中重新开始整个计算循环去猜下下个词。# Decode: one token per iteration token first_token steps 0 while token ! STOP and steps MAX_STEPS: x embed(token) position(steps) for layer in model.layers: q, k, v project(x) K_all, V_all caches[layer].append(k, v) # cached history new x layer.forward(q, K_all, V_all, x) # attention FFN, residuals token sample(project_to_vocab(x)) steps 1 yield token在这个逐字生成的过程中一个反直觉的现象出现了。相比于刚才处理大段提示词生成区区一个新词所需要的数学计算量其实非常小。但是为了完成这道简单的“数学题”系统却不得不把模型那多达几十上百 GB 的庞大参数矩阵完整地从 GPU 的显存里搬运到计算核心中。计算在眨眼间就完成了但数据的搬运却漫长而拥挤。因此在解码阶段拖慢速度的不再是芯片的算力而是数据传输的通道——显存带宽。这就是所谓的“内存带宽密集型”Memory-bound瓶颈。如果模型每生成一个新词都要把之前所有词的关系从头到尾重新计算一遍那这种令人绝望的低效将让大模型的应用变得毫无可能。就像是你每写下读书笔记的一句话都要把整本书从第一页重新读一遍。 为了打破这个僵局工程师们引入了一个非常优雅的技术“作弊码”KV 缓存KV Cache。这里的 K 和 V 代表 Key 和 Value它们是模型在处理前面内容时留下的中间计算结果。工程师们的思路很直接既然前面的内容已经算过了为什么不把结果存下来呢于是系统在显存中专门开辟了一块空间用来存储这些历史 Token 的状态。当模型需要生成新词时它不再去回溯历史而是直接从 KV 缓存中调取之前的上下文信息只对当前这一个新词进行增量计算。这是一种极其聪明的“空间换时间”的策略牺牲一部分宝贵的显存容量换取了文本生成速度的成倍提升。# Decode: With KV caching (空间换时间) def decode_with_kv_cache(prompt_tokens, max_gen_len): # 第一阶段Prefill预填充一次性处理所有输入并初始化 KV Cache logits, kv_cache prefill(prompt_tokens) next_token sample(logits[-1]) generated_tokens [next_token] # 第二阶段Decode解码利用 KV Cache 增量生成 for _ in range(max_gen_len - 1): # 1. 每次只对最新生成的一个 Token 进行处理无需重新处理前面的词 hidden_states embedding(next_token) # 2. 核心魔法读取历史 KV Cache与新 Token 一起计算注意力 # 并将新 Token 的状态更新进 KV Cache 中。避免了重复计算 attention_output, kv_cache attention_with_kv(hidden_states, kv_cache) # 3. 仅对当前单个 Token 进行前向计算计算量极小但需将庞大的模型权重从显存搬运过来 logits mlp(attention_output) # 4. 预测下一个 Token next_token sample(logits[-1]) generated_tokens.append(next_token) return generated_tokens所以下次当你注视着屏幕上那些流畅生长的文字时或许能体会到硅晶片深处那场无声的交响乐。它始于一场狂暴的算力冲刺大模型调动全部并发能力去倾听和理解你的意图随后它又化作一场考验数据搬运能力的马拉松在 KV 缓存的默默支撑下字斟句酌地给出回答。理解大模型的推理是“两份工作”并不仅仅是一个硬核的技术冷知识。对于所有试图在 AI 时代构建应用的人来说看透算力与带宽的这层博弈正是驯服这些庞然大物让它们跑得更快、更稳的关键所在。学习资源推荐如果你想更深入地学习大模型以下是一些非常有价值的学习资源这些资源将帮助你从不同角度学习大模型提升你的实践能力。一、全套AGI大模型学习路线AI大模型时代的学习之旅从基础到前沿掌握人工智能的核心技能​因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取二、640套AI大模型报告合集这套包含640份报告的合集涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师还是对AI大模型感兴趣的爱好者这套报告合集都将为您提供宝贵的信息和启示​因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取三、AI大模型经典PDF籍随着人工智能技术的飞速发展AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型如GPT-3、BERT、XLNet等以其强大的语言理解和生成能力正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取四、AI大模型商业化落地方案作为普通人入局大模型时代需要持续学习和实践不断提高自己的技能和认知水平同时也需要有责任感和伦理意识为人工智能的健康发展贡献力量。