我花 1 小时搞懂了 LLM 的核心原理:从 Token 到 Attention,用代码逐行实现
2026/6/17 16:21:49 网站建设 项目流程

我花 1 小时搞懂了 LLM 的核心原理:从 Token 到 Attention,用代码逐行实现

适合想理解大语言模型(LLM)底层原理的开发者,不需要深度学习基础。
本文用 Python 代码逐行实现 LLM 的核心组件,不依赖任何深度学习框架。

为什么要理解 LLM 原理

用 AI 工具不需要理解原理,就像开车不需要懂发动机。但如果你想:

  • 调优 prompt(知道为什么某个 prompt 效果好)
  • 选模型(知道 7B 和 70B 的区别在哪)
  • 优化成本(知道 token 是怎么计算的)
  • 开发 Agent(知道上下文窗口的限制在哪)

就需要理解 LLM 的核心原理。

核心概念 1:Token(词元)

LLM 不是按"字"处理文本,而是按"token"。

defsimple_tokenize(text):"""简化的 token 化:按空格和标点分割"""importre# 按空格、标点分割tokens=re.findall(r'\w+|[^\w\s]',text)returntokens# 示例text="我用 Python 写了一个自动化脚本"tokens=simple_tokenize(text)print(tokens)# ['我', '用', 'Python', '写', '了', '一个', '自动化', '脚本']print(f"Token 数:{len(tokens)}")# Token 数: 8

实际的 tokenizer(如 GPT 用的 BPE)更复杂,会把常见词组合并:

# "自动化" 可能被拆成 "自动" + "化"(2 个 token)# "Python" 是 1 个 token# 1 个中文字 ≈ 1.5-2 个 token

为什么重要:API 按 token 收费,prompt + 回复的总 token 数决定成本。

核心概念 2:Embedding(向量化)

LLM 把每个 token 转成一个数字向量(一组浮点数),才能做数学运算。

importnumpyasnpdefsimple_embedding(tokens,dim=8):"""简化的 embedding:把 token 映射到随机向量"""# 实际中这些向量是训练出来的,这里用随机数演示np.random.seed(42)vocab={token:np.random.randn(dim)fortokeninset(tokens)}returnnp.array([vocab[t]fortintokens])tokens=["我","用","Python","写"]vectors=simple_embedding(tokens,dim=8)print(f"输入:{tokens}")print(f"向量形状:{vectors.shape}")# (4, 8) - 4 个 token,每个 8 维

为什么重要:Embedding 是 LLM 理解语义的基础。相似含义的词,向量距离近。

核心概念 3:Self-Attention(自注意力)

这是 Transformer 的核心机制——让每个 token "关注"其他 token,理解上下文关系。

defself_attention(x,dim=8):"""简化的自注意力机制"""np.random.seed(42)# 1. 生成 Q(查询)、K(键)、V(值)矩阵W_q=np.random.randn(dim,dim)*0.1W_k=np.random.randn(dim,dim)*0.1W_v=np.random.randn(dim,dim)*0.1Q=x @ W_q# 查询向量K=x @ W_k# 键向量V=x @ W_v# 值向量# 2. 计算注意力分数(Q 和 K 的点积)scores=Q @ K.T/(dim**0.5)# 缩放点积# 3. Softmax 归一化exp_scores=np.exp(scores-np.max(scores,axis=-1,keepdims=True))attention_weights=exp_scores/np.sum(exp_scores,axis=-1,keepdims=True)# 4. 加权求和output=attention_weights @ Vreturnoutput,attention_weights# 示例tokens=["我","用","Python","写","代码"]vectors=simple_embedding(tokens,dim=8)output,weights=self_attention(vectors)print(f"注意力权重矩阵:")fori,tokeninenumerate(tokens):row=[f"{weights[i][j]:.2f}"forjinrange(len(tokens))]print(f"{token}:{row}")

输出示例:

注意力权重矩阵: 我: [0.15, 0.20, 0.18, 0.25, 0.22] 用: [0.18, 0.15, 0.22, 0.23, 0.22] Python: [0.16, 0.20, 0.17, 0.25, 0.22] 写: [0.20, 0.18, 0.22, 0.18, 0.22] 代码: [0.19, 0.17, 0.21, 0.22, 0.21]

解读:"写"对"Python"和"代码"的注意力权重较高(0.22, 0.22),说明模型理解了"写 Python 代码"这个语义关系。

为什么重要:Attention 让 LLM 能理解上下文。“我在银行存钱"和"我在河边的银行坐着”,"银行"的含义不同,就是靠 Attention 来区分的。

核心概念 4:Feed Forward(前馈网络)

Attention 之后,每个 token 的向量会经过一个前馈网络做进一步变换。

deffeed_forward(x,hidden_dim=16):"""简化的前馈网络:两层线性变换 + ReLU"""np.random.seed(42)input_dim=x.shape[-1]# 第一层:扩展维度W1=np.random.randn(input_dim,hidden_dim)*0.1b1=np.zeros(hidden_dim)h=np.maximum(0,x @ W1+b1)# ReLU 激活# 第二层:压缩回原维度W2=np.random.randn(hidden_dim,input_dim)*0.1b2=np.zeros(input_dim)output=h @ W2+b2returnoutput

核心概念 5:Transformer Block(完整的一层)

把 Attention + Feed Forward + 残差连接组合在一起,就是一个 Transformer Block:

deftransformer_block(x,dim=8):"""一个 Transformer Block = Attention + Feed Forward + 残差"""# 1. 自注意力attn_output,_=self_attention(x,dim)# 2. 残差连接x=x+attn_output# 3. 前馈网络ff_output=feed_forward(x)# 4. 残差连接x=x+ff_outputreturnx

GPT-4 有约 120 个这样的 Block 堆叠在一起,每个 Block 让模型对文本的理解更深一层。

核心概念 6:生成过程(自回归)

LLM 生成文本的方式是一个 token 一个 token 地生成,每次预测下一个最可能的 token。

defsimple_generate(prompt_tokens,vocab,num_tokens=5):"""简化的文本生成:逐 token 预测"""generated=list(prompt_tokens)for_inrange(num_tokens):# 1. 对当前所有 token 做 embeddingvectors=simple_embedding(generated,dim=8)# 2. 过 Transformer Blockoutput=transformer_block(vectors)# 3. 取最后一个 token 的输出,预测下一个 tokenlast_output=output[-1]# 4. 简化版:用向量的 argmax 选 token(实际用 softmax + 采样)scores={token:np.dot(last_output,np.random.randn(8))fortokeninvocab}next_token=max(scores,key=scores.get)generated.append(next_token)returngenerated# 示例vocab=["我","用","Python","写","了","一个","自动化","脚本","。"]result=simple_generate(["我","用","Python"],vocab,num_tokens=5)print("生成结果:","".join(result))

为什么重要:理解自回归生成,就理解了为什么 LLM 有时会"一本正经地胡说八道"——它在逐 token 预测,如果中间某个 token 预测错了,后面会越偏越远。

核心概念 7:Temperature(温度)

Temperature 控制生成的"随机性"。

defsample_with_temperature(logits,temperature=1.0):"""带温度的采样"""# logits: 每个 token 的得分# temperature: 越高越随机,越低越确定scaled=logits/temperature exp_scaled=np.exp(scaled-np.max(scaled))probs=exp_scaled/np.sum(exp_scaled)# 按概率采样returnnp.random.choice(len(probs),p=probs)# temperature = 0.1: 几乎总是选最高分的 token(确定性强)# temperature = 1.0: 正常采样# temperature = 2.0: 非常随机

实用建议

  • 写代码/数学推理:temperature = 0(确定性最高)
  • 写文章/创意内容:temperature = 0.7-0.9(有创意但不乱来)
  • 头脑风暴:temperature = 1.5(非常随机)

完整的简化 LLM

把所有组件组合起来:

classSimpleLLM:"""简化版 LLM"""def__init__(self,vocab,dim=8,num_layers=2):self.vocab=vocab self.dim=dim self.num_layers=num_layersdefforward(self,tokens):"""前向传播"""# 1. Token 化 + Embeddingx=simple_embedding(tokens,self.dim)# 2. 过 N 个 Transformer Blockfor_inrange(self.num_layers):x=transformer_block(x,self.dim)returnxdefgenerate(self,prompt,max_tokens=10):"""生成文本"""tokens=simple_tokenize(prompt)generated=list(tokens)for_inrange(max_tokens):output=self.forward(generated)# 预测下一个 token(简化版)next_token=self._predict_next(output[-1])ifnext_token=="[END]":breakgenerated.append(next_token)return"".join(generated)

关键参数与模型大小

参数含义GPT-4 约值
参数量模型的权重数量~1.8 万亿
层数Transformer Block 数量~120 层
隐藏维度每个 token 的向量维度~12288
注意力头数多头注意力的头数~96
上下文窗口能处理的最大 token 数128K

模型大小 = 参数量 × 每个参数的存储空间

  • 7B 模型 ≈ 14GB(FP16)
  • 70B 模型 ≈ 140GB(FP16)
  • 量化后(INT4):7B ≈ 4GB,70B ≈ 35GB

踩坑记录

坑 1:把 Token 和字搞混

症状:以为 3000 字 = 3000 tokens,结果 API 费用比预期高 50%。

原因:中文 1 字 ≈ 1.5-2 tokens,比英文贵。

解决:用 tokenizer 工具(如 tiktoken)精确计算 token 数。

坑 2:不理解上下文窗口

症状:把 10 篇文章一次性塞给 LLM,结果超了 128K token 限制。

原因:上下文窗口 = prompt + 回复的总 token 数。

解决:长文档分块处理,每次只传相关部分。

坑 3:Temperature 设错

症状:写代码时设了 temperature=1.5,生成的代码到处是语法错误。

原因:高温度增加随机性,代码需要确定性。

解决:写代码用 temperature=0 或 0.1。

坑 4:以为模型越大越好

症状:用了 70B 模型做简单分类,成本是 7B 的 10 倍,效果提升不到 5%。

原因:简单任务不需要大模型。

解决:按任务复杂度选模型,简单任务用小模型。

坑 5:不理解"幻觉"

症状:LLM 说"Python 3.13 支持模式匹配",但 Python 3.10 就支持了。

原因:LLM 是概率模型,不是数据库。它会"编造"看起来合理但不准确的信息。

解决:关键信息必须人工验证,不能完全信任 LLM 的输出。

总结

3 条核心经验:

  1. LLM 的核心是 Attention。它让模型能理解上下文关系,是 LLM 区别于传统 NLP 的关键。

  2. LLM 是逐 token 生成的。理解自回归生成,就理解了 LLM 的能力边界(为什么有时胡说八道)。

  3. 参数量决定能力上限,但不决定性价比。简单任务用小模型够了,大模型只在复杂推理时才值得。


你对 LLM 原理有什么疑问?评论区交流。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询