前置知识: 大语言模型

开源模型架构详解

5 minIntermediate

深入分析主流开源 LLM 的架构设计,包括 LLaMA、Mistral、Mixtral 和 Qwen

开源模型架构详解

每个 LLM 的架构选择都有原因。LLaMA 为什么用 RoPE?Mistral 为什么用滑动窗口注意力?Mixtral 的 MoE 是怎么工作的?理解这些设计决策,你才能选择合适的模型。

类型: 概念 前置条件: Phase 10 Lesson 04(预训练 Mini-GPT) 预计时间: ~60 分钟

学习目标

  • 理解主流开源 LLM 的架构差异
  • 掌握关键架构组件:RoPE、GQA、SwiGLU、滑动窗口注意力
  • 理解 MoE(混合专家)架构的工作原理
  • 能够根据任务需求选择合适的模型

架构对比

特性GPT 系列LLaMA 2MistralMixtralQwen2
位置编码学习式RoPERoPERoPERoPE
注意力MHAGQAGQA + 滑动窗口GQA + 滑动窗口GQA
激活函数GeLUSwiGLUSwiGLUSwiGLUSwiGLU
归一化LayerNormRMSNormRMSNormRMSNormRMSNorm
偏置项
MoE是(8 选 2)
词表大小100K+32K32K32K152K

RoPE(旋转位置编码)

RoPE 通过旋转矩阵将位置信息注入注意力计算:

qm=Rθ,mWqxmq_m = R_{\theta,m} \cdot W_q \cdot x_m

kn=Rθ,nWkxnk_n = R_{\theta,n} \cdot W_k \cdot x_n

qmTkn=xmTWqTRθ,nmWkxnq_m^T k_n = x_m^T W_q^T R_{\theta,n-m} W_k x_n

RoPE 的优势:注意力分数只依赖相对位置 nmn - m,天然支持外推。

def precompute_rope_freqs(dim, max_seq_len=4096, base=10000):
    """预计算 RoPE 频率"""
    freqs = 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim))
    t = torch.arange(max_seq_len)
    freqs = torch.outer(t, freqs)
    return torch.cos(freqs), torch.sin(freqs)


def apply_rope(x, cos, sin):
    """应用 RoPE"""
    d = x.shape[-1] // 2
    x1, x2 = x[..., :d], x[..., d:]
    rotated = torch.cat([-x2, x1], dim=-1)
    return x * cos + rotated * sin

GQA(分组查询注意力)

GQA 在 MHA(多头注意力)和 MQA(多查询注意力)之间取折衷:

Q 头数K/V 头数内存质量
MHA3232最好
GQA328接近 MHA
MQA321略差

GQA 让多组 Q 头共享同一组 K/V 头,减少 KV Cache 大小而不显著损失质量。

SwiGLU 激活函数

SwiGLU 是 GLU(门控线性单元)和 Swish 激活的组合:

SwiGLU(x)=(Swish(xWg)xW1)W2\text{SwiGLU}(x) = (\text{Swish}(xW_g) \odot xW_1) W_2

class SwiGLU(nn.Module):
    def __init__(self, d_model, d_ff=None):
        super().__init__()
        d_ff = d_ff or int(8 * d_model / 3)  # LLaMA 风格
        d_ff = ((d_ff + 63) // 64) * 64  # 对齐到 64

        self.w1 = nn.Linear(d_model, d_ff, bias=False)
        self.w2 = nn.Linear(d_ff, d_model, bias=False)
        self.w3 = nn.Linear(d_model, d_ff, bias=False)

    def forward(self, x):
        return self.w2(F.silu(self.w1(x)) * self.w3(x))

MoE(混合专家)

Mixtral 使用稀疏 MoE:每个 token 只激活 8 个专家中的 2 个。

class MoELayer(nn.Module):
    """简化的 MoE 层"""

    def __init__(self, d_model, d_ff, n_experts=8, top_k=2):
        super().__init__()
        self.n_experts = n_experts
        self.top_k = top_k

        # 路由器
        self.gate = nn.Linear(d_model, n_experts, bias=False)

        # 专家(每个是一个 FFN)
        self.experts = nn.ModuleList([
            nn.Sequential(
                nn.Linear(d_model, d_ff, bias=False),
                nn.SiLU(),
                nn.Linear(d_ff, d_model, bias=False),
            )
            for _ in range(n_experts)
        ])

    def forward(self, x):
        # 计算路由权重
        gate_logits = self.gate(x)
        weights, indices = torch.topk(gate_logits, self.top_k, dim=-1)
        weights = F.softmax(weights, dim=-1)

        # 稀疏计算
        output = torch.zeros_like(x)
        for k in range(self.top_k):
            expert_idx = indices[:, :, k]
            expert_weight = weights[:, :, k:k+1]

            for e in range(self.n_experts):
                mask = (expert_idx == e)
                if mask.any():
                    expert_input = x[mask]
                    expert_output = self.experts[e](expert_input)
                    output[mask] += expert_output * expert_weight[mask]

        return output

关键术语

术语通俗说法实际含义
RoPE”旋转位置编码”Rotary Position Embedding,通过旋转矩阵编码相对位置
GQA”分组注意力”Grouped-Query Attention,多组 Q 头共享 K/V 头
SwiGLU”门控激活”Swish-Gated Linear Unit,LLaMA 系列使用的激活函数
MoE”混合专家”Mixture of Experts,稀疏激活的专家路由架构
滑动窗口注意力”局部注意力”每个位置只关注固定窗口内的位置,降低长序列计算量

延伸阅读