mixture of experts internals

MoE 内部机制:专家路由、负载均衡与容量因子

1. MoE 的核心思想 Mixture-of-Experts(MoE)的核心:条件计算。不是让所有参数都参与每个 Token 的计算,而是为每个 Token 选择少量"专家"子网络来处理。 以 Mixtral 8×7B 为例:总参数 46.7B,但每个 Token 只激活 12.9B。用接近 13B 模型的计算量获得接近 47B 模型的性能。 2. MoE 架构 2.1 基本结构 MoE 替换 Transformer FFN 层: 标准 FFN: x → W2·σ(W1·x) → output MoE FFN: x → Router(x) → 选择 Top-K 专家 → 分别计算 → 加权求和 → output 2.2 路由器(Router/Gate) 路由器是一个小型线性层 + softmax: $$ G(x) = \text{softmax}(W_g x) $$ 其中 $W_g \in \mathbb{R}^{N \times d}$,$N$ 是专家数量。 ...

2026-06-25 · 4 min · 739 words · AI 实战派
ring attention explained

Ring Attention 解析:百万 Token 上下文的秘密

朴素 Attention 的显存墙 标准自注意力的计算: $$\text{Attn}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d}}\right)V$$ 对于序列长度 $n$,中间矩阵 $QK^T$ 的形状为 $n \times n$。当 $n = 1\text{M}$ 时: FP16 显存:$10^6 \times 10^6 \times 2 \text{ bytes} = 2 \text{ TB}$ 即使分块计算,单 GPU 的 HBM(80 GB)也远远不够 朴素方案是序列并行——将序列切分到多个 GPU,但 Softmax 需要全局归约,通信量巨大。 Ring Attention 核心思想 Liu et al. (2023) 提出 Ring Attention:将序列分块分布在多个 GPU 上,以环形拓扑传递 KV 块,与计算重叠。 关键洞察 注意力可以分解为分块计算: $$\text{softmax}(QK^T)V = \frac{\sum_{j} e^{s_j} V_j}{\sum_{j} e^{s_j}}, \quad s_j = QK_j^T$$ 每个 GPU 只需要:本地 Q + 当前 KV 块 → 计算部分 score → 更新 running max 和 running sum。 ...

2026-06-25 · 4 min · 826 words · AI 实战派
tokenizer internals

Tokenizer 原理详解:BPE/WordPiece/Unigram/SentencePiece

1. 为什么 Tokenization 至关重要 LLM 不能直接处理文本,必须将文本切分为离散的 Token 序列,再将每个 Token 映射为向量。Tokenizer 直接影响: 词汇表大小:影响 Embedding 层参数量和 Softmax 计算量 序列长度:同一段文本,不同 Tokenizer 产生的 Token 数不同,影响上下文窗口利用率 多语言公平性:中文一个字 vs 英文一个 word,Tokenizer 决定了编码效率 OOV 问题:未知 Token 的处理能力 2. BPE (Byte Pair Encoding) 2.1 算法思想 BPE 最初是数据压缩算法,被 Sennrich 等人(2016)引入 NLP。核心思路:从一个字符级词汇表开始,反复合并出现频率最高的相邻 Token 对。 2.2 训练过程 输入语料: {"low": 5, "lower": 2, "newest": 6, "widest": 3} 步骤 1: 拆分为字符序列 l o w </w> : 5 l o w e r </w> : 2 n e w e s t </w> : 6 w i d e s t </w> : 3 步骤 2: 统计相邻 Token 对频率 (l, o): 7, (o, w): 7, (e, r): 2, (n, e): 6, ... 步骤 3: 合并最高频对 (l, o) → "lo" lo w </w> : 5 lo w e r </w> : 2 n e w e s t </w> : 6 w i d e s t </w> : 3 重复直到词汇表达到目标大小 2.3 编码过程 对新文本,按训练时的合并规则顺序应用: ...

2026-06-25 · 4 min · 707 words · AI 实战派
mixture of experts deep dive

混合专家模型深入剖析:从 GShard 到 DeepSeek V4

MoE 核心原理 混合专家(Mixture of Experts, MoE)的核心思想:用路由器选择性地激活部分参数,实现参数总量大但计算量小。 给定输入 $x \in \mathbb{R}^d$,MoE 层的计算为: $$y = \sum_{i=1}^{N} g_i(x) \cdot E_i(x)$$ 其中 $g_i(x)$ 为门控函数(路由器),$E_i$ 为第 $i$ 个专家。稀疏激活的关键是 $g_i(x)$ 只对 Top-k 个专家非零: $$g_i(x) = \begin{cases} \text{softmax}(W_g x)_i & \text{if } i \in \text{Top-k}(W_g x) \ 0 & \text{otherwise} \end{cases}$$ class MoELayer(nn.Module): def __init__(self, d_model, num_experts=8, top_k=2): super().__init__() self.gate = nn.Linear(d_model, num_experts, bias=False) self.experts = nn.ModuleList([ FeedForward(d_model) for _ in range(num_experts) ]) self.top_k = top_k self.num_experts = num_experts def forward(self, x): # x: (B, L, d) logits = self.gate(x) # (B, L, num_experts) topk_logits, topk_idx = logits.topk(self.top_k, dim=-1) topk_weights = F.softmax(topk_logits, dim=-1) output = torch.zeros_like(x) for i in range(self.top_k): expert_idx = topk_idx[..., i] # (B, L) weight = topk_weights[..., i:i+1] # (B, L, 1) for j in range(self.num_experts): mask = (expert_idx == j) if mask.any(): expert_input = x[mask] expert_output = self.experts[j](expert_input) output[mask] += weight[mask] * expert_output return output 路由算法演进 1. Top-k 路由(标准方案) 最常用的路由策略。每个 token 选择得分最高的 k 个专家。问题:容易出现"赢者通吃"——少数专家被过度使用。 ...

2026-06-25 · 3 min · 523 words · AI 实战派
activation function evolution

激活函数演进:从 ReLU 到 SwiGLU

1. 为什么需要激活函数? 没有激活函数,多层线性变换 $\mathbf{W}_2(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) + \mathbf{b}_2$ 等价于单层线性变换。激活函数引入非线性,使网络可以拟合复杂函数。 Transformer 的 FFN 层结构: $$ \text{FFN}(x) = W_2 \cdot \sigma(W_1 x + b_1) + b_2 $$ 其中 $\sigma$ 就是激活函数。激活函数的选择直接影响模型的表达能力和训练效率。 2. ReLU 家族 2.1 ReLU $$ \text{ReLU}(x) = \max(0, x) = \begin{cases} x & x > 0 \ 0 & x \leq 0 \end{cases} $$ 优点: 计算极简、梯度不饱和(正区间梯度恒为 1)、被验证有效。 缺点: 神经元死亡(Dead Neuron)——如果输入持续为负,梯度永远为 0,该神经元永久停止学习。 2.2 Leaky ReLU / PReLU $$ \text{LeakyReLU}(x) = \begin{cases} x & x > 0 \ \alpha x & x \leq 0 \end{cases} $$ ...

2026-06-25 · 4 min · 685 words · AI 实战派
context window extension

上下文窗口扩展技术:从 4K 到 1M

1. 为什么长上下文重要? 4K 上下文只能容纳约 3000 字的文档。要处理整本书、代码仓库或长对话,需要 32K-1M 的上下文窗口。但直接训练长上下文模型面临三大挑战: 训练成本:Attention 复杂度 $O(n^2)$,32K 上下文的计算量是 4K 的 64 倍 位置编码外推:训练时未见过的位置编码效果不可控 显存占用:KV Cache 随序列长度线性增长 2. 位置编码外推 2.1 Position Interpolation (PI) 最简单的方法:将位置索引线性缩放到训练范围内。 $$ m’ = m \cdot \frac{L_{train}}{L_{target}} 4K 训练 → 8K 推理时,位置 $m$ 缩放为 $m \times 0.5$。 **问题:** 高频分量被等比缩放,局部注意力模式被破坏。短距离关系(如相邻 Token)的编码精度下降。 ### 2.2 NTK-aware Interpolation NTK(Neural Tangent Kernel)理论指出,高频分量需要保留,低频分量可以缩放。修改 RoPE 的 base: $$ b' = b \cdot s^{d/(d-2)} 其中 $s = L_{target} / L_{train}$ 是扩展倍数,$d$ 是 Head 维度。 ...

2026-06-25 · 4 min · 768 words · AI 实战派
speculative decoding deep

投机解码深度解析:让 LLM 推理快 3 倍

自回归推理的瓶颈 标准自回归解码每次只生成 1 个 token,每个 token 都需要完整前向传播: $$t_{\text{per_token}} = t_{\text{prefill}} + t_{\text{decode}}$$ 其中 decode 阶段是访存密集型的——计算量小但需要加载全部权重和 KV Cache,GPU 利用率通常 <10%。 投机解码的核心洞察:用小模型快速生成草稿,大模型批量验证,将多次串行 decode 变为一次并行验证。 投机解码原理 算法流程 1. Draft Model 快速生成 k 个候选 token: [t1, t2, ..., tk] 2. Target Model 一次前向传播计算这 k 个位置的 logits 3. 对每个候选 token,按拒绝采样决定接受/拒绝: - 若 p_target(ti) / p_draft(ti) >= 1: 接受 - 否则以概率 p_target(ti)/p_draft(ti) 接受,否则拒绝并从调整分布重采样 4. 接受的 token 加入序列,从拒绝点重新开始 拒绝采样数学 对于候选 token $x_i$,定义接受概率: $$\alpha(x_i) = \min\left(1, \frac{p_{\text{target}}(x_i)}{p_{\text{draft}}(x_i)}\right)$$ ...

2026-06-25 · 3 min · 608 words · AI 实战派
positional encoding guide

位置编码全解:绝对/相对/RoPE/ALiBi

1. 为什么 Transformer 需要位置编码? Self-Attention 本质上是一个集合操作:$\text{Attention}(Q, K, V)$ 对输入的顺序不敏感(permutation equivariant)。如果打乱输入顺序,输出只是相应打乱,不包含任何顺序信息。但语言有明确的顺序语义(“猫追狗” ≠ “狗追猫”),必须注入位置信息。 2. 绝对位置编码 2.1 Sinusoidal (原版 Transformer) Vaswani 等人提出用正弦/余弦函数生成位置编码: $$ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$ $$ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$ 性质: 不同维度对应不同频率的正弦波,从 $2\pi$ 到 $10000 \times 2\pi$ 对于任意偏移 $k$,$PE_{pos+k}$ 可以表示为 $PE_{pos}$ 的线性变换:$\sin(pos + k) = \sin(pos)\cos(k) + \cos(pos)\sin(k)$ 理论上可以外推到比训练时更长的序列,但实际效果不佳 import torch import math def sinusoidal_pos_encoding(max_len, d_model): pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) return pe 2.2 Learned Positional Embedding BERT、GPT-2 使用可学习的位置 Embedding: self.position_embeddings = nn.Embedding(max_position_embeddings, hidden_size) # 前向传播 position_ids = torch.arange(seq_len).unsqueeze(0) embeddings = token_embeddings + self.position_embeddings(position_ids) 优点:灵活,模型可以学习最优的位置表示。缺点:硬编码了最大长度,无法外推。 ...

2026-06-25 · 3 min · 534 words · AI 实战派
rope rotation embedding

旋转位置编码 RoPE:从原理到长度外推

位置编码演进 绝对位置编码 原始 Transformer 使用可学习的绝对位置编码:$E = E_{\text{token}} + E_{\text{pos}}$,其中 $E_{\text{pos}}$ 是可学习参数。 问题:无法外推到训练时未见过的长度。 相对位置编码 T5/ALBERT 使用相对位置偏置:$\text{Attn}(Q_i, K_j) = \frac{Q_i K_j^T}{\sqrt{d}} + b_{i-j}$ 问题:需要额外偏置项,且对窗口外的位置需要截断。 旋转位置编码(RoPE) RoPE(Su et al., 2021)的核心思想:通过旋转矩阵将绝对位置编码转化为相对位置编码——对位置 $m$ 的 Query 和位置 $n$ 的 Key,注意力分数只依赖 $m - n$。 RoPE 数学原理 二维情形 对于二维向量 $q = (q_0, q_1)$,在位置 $m$ 处旋转角度 $m\theta$: $$q_m = R_m q = \begin{pmatrix} \cos m\theta & -\sin m\theta \ \sin m\theta & \cos m\theta \end{pmatrix} \begin{pmatrix} q_0 \ q_1 \end{pmatrix}$$ ...

2026-06-25 · 4 min · 843 words · AI 实战派
kv cache guide

KV Cache 原理与优化:LLM 推理加速核心

1. KV Cache 基本原理 1.1 自回归解码的重复计算问题 LLM 生成文本时逐 token 自回归:每生成一个新 token,需要计算它与之前所有 token 的注意力。 无 Cache 时:生成第 $t$ 个 token,需要重新计算前 $t-1$ 个 token 的 K 和 V。生成 $n$ 个 token 的总计算量为 $O(n^2 \cdot d)$。 有 Cache 时:之前 token 的 K、V 缓存复用,每步只需计算新 token 的 Q、K、V,总计算量降为 $O(n \cdot d)$。 1.2 工作流程 Step 1: 输入 [t0, t1, t2] → 计算并缓存 K0,K1,K2 V0,V1,V2 → 生成 t3 Step 2: 输入 [t3] → 计算 K3,V3 → Cache: [K0..K3, V0..V3] → 生成 t4 Step 3: 输入 [t4] → 计算 K4,V4 → Cache: [K0..K4, V0..V4] → 生成 t5 ... 每步只需对新 token 做 $Q_{new} \cdot K_{cache}^T$,复杂度 $O(n \cdot d)$ 而非 $O(n^2 \cdot d)$。 ...

2026-06-24 · 5 min · 984 words · AI 实战派
鲁ICP备2026018361号