大模型架构对比
大模型架构对比
GPT、LLaMA、Mixtral、DeepSeek——主流大模型架构有什么不同?不同架构对 GPU 集群的显存、通信、计算需求差异巨大。选错架构可能导致训练成本翻倍或推理延迟不可接受。
1. Architecture Family Tree — 架构族谱
Transformer (2017, Google)
│
├── Encoder-Decoder (T5, BART)
│ └── 机器翻译、文本摘要... 适用范围窄
│
├── Encoder-only (BERT, RoBERTa)
│ └── 理解类任务... 不能生成
│
└── Decoder-only ★ 生成式大模型的主流
│
├── GPT-1 (2018, OpenAI)
├── GPT-2 (2019, OpenAI) — 1.5B, 首个"太大不能放出来"的模型
├── GPT-3 (2020, OpenAI) — 175B, 确立 Decoder-only 统治地位
│
├── GPT-3.5 / GPT-4 (2023, OpenAI) — 闭源,细节未公开
│
├── LLaMA-1 (2023, Meta) — 开源社区转折点
│ └── 改进点: Pre-Norm, SwiGLU, RoPE
│
├── LLaMA-2 (2023, Meta) — 引入 GQA
│
├── LLaMA-3 (2024, Meta) — 8B/70B/405B, 训练数据 15T tokens
│
├── MoE 分支 ─────────────────────────┐
│ ├── Mixtral 8×7B (2024, Mistral) │
│ │ └── 每 token 激活 2/8 experts │
│ ├── DeepSeek-V2/V3 (2024-2025) │
│ │ └── Multi-head Latent Attn + DeepSeekMoE
│ └── Qwen-MoE (2024, Alibaba) │
└──────────────────────────────────────┘
为什么 Decoder-only 赢了?
| 问题 | Encoder-Decoder (T5) | Encoder-only (BERT) | Decoder-only (GPT) |
|---|---|---|---|
| 生成能力 | ✅ 有 | ❌ 无 | ✅ 最自然 |
| Scaling Law | 未充分验证 | 生成任务上不适用 | 验证最充分 |
| 架构复杂度 | 两套参数 | 单向注意力 | 单向注意力 |
| 推理效率 | Encoder 成瓶颈 | N/A | KV Cache 可复用 |
| Few-shot 泛化 | 弱 | 弱 | 强(涌现能力) |
Decoder-only 的简单性本身就是武器:单向因果注意力 + next-token prediction 的训练目标,没有 encoder bottleneck,模型容量可以无限 scale 而不引入架构瓶颈。
2. GPT vs LLaMA — 细节对比表
| 维度 | GPT-3 (175B) | LLaMA-1 (65B) | LLaMA-2 (70B) | LLaMA-3 (70B) |
|---|---|---|---|---|
| 激活函数 | GELU | SwiGLU | SwiGLU | SwiGLU |
| Norm 位置 | Post-LN | Pre-LN | Pre-LN | Pre-LN |
| Norm 类型 | LayerNorm | RMSNorm | RMSNorm | RMSNorm |
| 位置编码 | Learned | RoPE | RoPE | RoPE |
| 注意力类型 | MHA | MHA | GQA (8 KV heads) | GQA (8 KV heads) |
| FFN 门控 | 无 | Gated FFN | Gated FFN | Gated FFN |
| 上下文长度 | 2K | 2K | 4K | 8K |
| Vocabulary | 50K | 32K | 32K | 128K |
逐项分析:为什么每个改动都重要
Activation: GELU → SwiGLU
GELU(x) = x · Φ(x) # 基于概率积分,光滑但复杂
SwiGLU(x) = (xW₁·σ(xW₂)) · W₃ # 3 个权重矩阵
- SwiGLU 引入了门控机制:一个线性变换 × 另一个线性变换的 sigmoid 门
- 同等参数下 SwiGLU 表达更强,但 FFN 中间维度需要调小到原先的 ~2/3 以补偿多出来的 W₂
- PaLM 论文验证:SwiGLU 在所有规模下优于 GELU 和 GeGLU
Norm Position: Post-LN → Pre-LN
Post-LN (GPT-3):
x → Attention(x) → LayerNorm → FFN(x) → LayerNorm
问题: 深层梯度通过 Norm 被严重衰减 → 训练不稳定
Pre-LN (LLaMA):
x → LayerNorm → Attention(x) → ...
→ LayerNorm → FFN(x) → ...
优势: 每层输入先归一化,梯度在最陡处前被正则化
- Post-LN 下训练大型 GPT 需要在 warmup 阶段极度小心,否则梯度爆炸
- Pre-LN 让训练非常稳定,学习率 warmup 从几千步缩短到几十步
- 代价:Pre-LN 让每层最后的残差不加 Norm,可能导致深层表示稍有退化——但稳定性的收益远大于此
Norm Type: LayerNorm → RMSNorm
LayerNorm: y = (x - μ)/σ · γ + β # 需要算均值 μ 和标准差 σ
RMSNorm: y = x / RMS(x) · γ # 只需算均方根,省掉 bias β
where RMS(x) = sqrt(mean(x²))
- RMSNorm 省掉了均值的计算和 β 参数,在 70B 模型上省 ~0.3% 参数和 ~15% Norm 层算力
- 精度几乎无损(Narayanan et al. 2023 验证)
Position Encoding: Learned → RoPE
见第 5 节详细分析。核心差异:Learned embedding 只能记住训练时见过的位置,RoPE 可以通过相对位置旋转自然外推到更长序列。
3. GQA / MQA — KV Cache 的救星
问题:MHA 的 KV Cache 爆炸
标准 Multi-Head Attention(MHA)中,每个 token 需要缓存自己的 Key 和 Value:
KV Cache 大小 = 2 × num_layers × num_heads × head_dim × seq_len × dtype_size
对于 LLaMA-2 70B (batch=1), 使用 MHA:
= 2 × 80 × 64 × 128 × seq_len × 2 bytes (BF16)
= 2,621,440 bytes/token
8K 上下文 → KV Cache = 2,621,440 × 8192 ≈ 21.5 GB
单个序列的 KV Cache 就吃掉了 A100-80GB 的 1/4
更大的上下文 → KV Cache 吃掉所有显存 → 必须减少 head 数量。
三种方案的对比
MHA (Multi-Head Attention):
Q: [1 × 64 heads × 128d]
K: [1 × 64 heads × 128d] ← 每个 head 独立 KV
V: [1 × 64 heads × 128d]
KV Cache: 64 组 K,V = 2×64×128 = 16384 d/层
GQA (Grouped Query Attention) — LLaMA-2 70B:
Q: [1 × 64 heads × 128d]
K: [1 × 8 heads × 128d] ← 8 组 KV, 每组被 8 个 Q head 共享
V: [1 × 8 heads × 128d]
KV Cache: 8 组 K,V = 2×8×128 = 2048 d/层 → 节省 8×
通信量: All-Gather K,V 的通信量也减少 8×
MQA (Multi-Query Attention) — PaLM:
Q: [1 × 64 heads × 128d]
K: [1 × 1 head × 128d] ← 1 组 KV, 被所有 Q head 共享
V: [1 × 1 head × 128d]
KV Cache: 1 组 K,V = 2×1×128 = 256 d/层 → 节省 64×
代价: 注意力质量下降,长文本回答可能不聚焦
为什么 LLaMA-2 70B 选 GQA 而不是 MQA?
- MQA 太激进:所有 head 共享 1 组 KV,在长上下文推理中可能丢失细粒度注意力
- GQA 的性价比最优:8× KV Cache 缩减 + 几乎无损的注意力质量
- 在 34B 和 70B 模型上,Meta 的 ablations 显示 GQA 与 MHA 精度差异 < 0.1 perplexity 点
Tensor Parallelism 中的 GQA
GQA 在 TP 切分中也有优势:
# MHA: 64 heads 分到 8 张 GPU = 每张 8 KV heads
# GQA: 8 KV heads 分到 8 张 GPU = 每张 1 KV head
# GQA 在 TP=8 下每卡通信更均匀,减少了 All-Gather 的冗余
4. MoE (Mixture of Experts) — 参数膨胀的艺术
架构全景
┌─────────────┐
Token ──►│ Router │──► Top-k 选择
└─────────────┘ │
▼
┌──────────────────────────────────────────┐
│ Expert 1 Expert 2 ... Expert N │
│ (FFN) (FFN) (FFN) │
└──────────────┬───────────────────────────┘
│
▼ 加权合并
┌────────────────┐
│ Token Output │
└────────────────┘
Mixtral 8×7B 拆解
总参数量: 46.7B(看起来是一头怪兽)
活跃参数: ~12.9B/token(实际只有这么多在计算)
为什么?
每个 Transformer 层:
- 共享部分: Attention params ≈ 3B total
- MoE FFN: 8 个 Expert,每个 7B 参数 → 8 × 7B = 56B...
等等,这里有个名不副实的问题——
实际上 Mixtral 8×7B 的 "7B" 是指每个 Expert 的参数量
等效于一个 Mistral-7B 模型的 FFN 部分
8 个 Expert × 7B = 56B (仅 FFN) + 共享参数 ≈ 46.7B
每个 token 通过 Router 选择 top-2 experts:
活跃 FFN = 2 × 7B = 14B
加上共享参数 ≈ 12.9B 活跃计算
Router 机制
# 简化版路由
class MoERouter(nn.Module):
def __init__(self, d_model, num_experts=8, top_k=2):
self.gate = nn.Linear(d_model, num_experts) # 从表示学路由
def forward(self, x):
# x: (batch, seq_len, d_model)
logits = self.gate(x) # → (B, S, 8)
scores = F.softmax(logits, dim=-1)
# 选 top-2 并 renormalize
top_k_scores, top_k_indices = torch.topk(scores, k=2)
top_k_scores = top_k_scores / top_k_scores.sum(dim=-1, keepdim=True)
# 路由到对应 expert
output = 0
for i in range(2):
expert_idx = top_k_indices[:, :, i]
weight = top_k_scores[:, :, i]
expert_output = self.experts[expert_idx](x)
output += weight.unsqueeze(-1) * expert_output
return output
All-to-All 通信 — MoE 的阿喀琉斯之踵
Expert Parallelism 下的通信流程:
GPU 0: [Token A, B, C] ──────────┐
GPU 1: [Token D, E, F] ──────────┼── All-to-All ──► 按 Expert 重组
GPU 2: [Token G, H, I] ──────────┘
│
┌─────────────────────────────────┘
▼
GPU 0: Expert-0 处理的 tokens(来自所有 GPU)
GPU 1: Expert-1 处理的 tokens(来自所有 GPU)
GPU 2: Expert-2 处理的 tokens(来自所有 GPU)
计算完后再一次 All-to-All 把结果送回原 GPU
信息量:8 GPU × 8 Expert = 每个 token 可能需要跨所有 GPU 传输。在 Mixtral 8×7B 训练中:
单个 micro-batch 的 All-to-All 通信量:
= B × S × d_model × 2 (去和回) × dtype
= 1 × 4096 × 4096 × 2 × 2 bytes (BF16)
≈ 134 MB / GPU / micro-batch
对于 8 GPU 全量训练,All-to-All 是 训练吞吐的主要瓶颈,实际 GPU 利用率(MFU)很难超过 45%。
负载均衡
Router 可能会把大部分 token 发给少数几个 expert。解决方案:
- Auxiliary Loss:惩罚 expert 分布不均匀
- Expert Buffer Capacity:每个 expert 只能算
capacity_factor × (tokens/n_experts)个 token,超出的 drop 掉 - DeepSeek 的 Shared Expert:把一部分 FFN 设为所有 token 必经的共享 expert,减少路由压力
5. RoPE (Rotary Position Embedding) — 让注意力”感知”位置
为什么绝对位置编码不够好
Learned PE (GPT-3):
Embedding[512, 768] ← 这张表只记住了位置 0-511
训练上下文长度 = 512 → 推理超过 512 → 位置信息全错
Sinusoidal PE (Transformer):
PE(pos, 2i) = sin(pos / 10000^(2i/d))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
可以外推,但效果不稳 —— 注意力权重不自然
RoPE 的核心思想
RoPE 不对 input embedding 添加位置信号,而是旋转 Query 和 Key,使得注意力权重自然包含相对位置:
RoPE 的关键公式:
Attention(Q, K) = softmax(Q @ K^T)
原始: Q_pos @ K_pos^T ← 只能依赖 pos 的绝对值
RoPE: (R^pos · Q) @ (R^pos · K)^T
= Q^T · R^(pos_k - pos_q) · K
= 只依赖相对位置 (pos_k - pos_q)
具体旋转方式
def apply_rope(query, key, position):
"""
query, key: (batch, heads, seq_len, head_dim)
对每对维度 (d_2i, d_2i+1) 做 2D 旋转
"""
d = query.shape[-1]
# 为每对维度计算旋转角度
freqs = 1.0 / (10000 ** (torch.arange(0, d, 2) / d)) # θ_i
angles = position.unsqueeze(-1) * freqs # pos × θ_i
cos, sin = angles.cos(), angles.sin()
# 对每对维度做旋转:(x, y) → (x·cos - y·sin, x·sin + y·cos)
q_rotated = torch.empty_like(query)
q_rotated[..., 0::2] = query[..., 0::2] * cos - query[..., 1::2] * sin
q_rotated[..., 1::2] = query[..., 1::2] * cos + query[..., 0::2] * sin
# K 同理
return q_rotated, k_rotated
直观理解:Attention 中的 Q @ K^T 本质是向量点积,而旋转不改变向量的模长(只改变方向)。RoPE 通过给 Q 和 K 施加不同的旋转角度,让点积结果自然编码了位置差。
RoPE 的外推能力
训练上下文: 4096 tokens
推理上下文: 16384 tokens (4× 外推)
Learned PE: 位置 4096-16383 完全没见过 → 直接崩
Sinusoidal: 可以算出来但注意力分布扭曲 → 勉强能用
RoPE: 相对位置的距离在 "已见过" 的范围内 →
位置 15000 对 14000 和位置 3000 对 2000 的区别一样
→ 平滑外推,困惑度升高很小
NERF / YaRN 等 RoPE 变体进一步优化了高频旋转的插值策略,让外推倍数达到 8×-16×。
6. Memory and Communication Comparison
训练视角
| 模型 | 总参数 | 训练显存(估算,单卡纯参数量) | KV Cache / token | 通信瓶颈 |
|---|---|---|---|---|
| GPT-3 175B (MHA) | 175B | ~700 GB (FP32) | 大 (64 KV heads) | DP/TP All-Reduce |
| LLaMA-2 70B (GQA) | 70B | ~260 GB (BF16混精) | 中 (8 KV heads) | TP All-Reduce, 低 8× |
| LLaMA-3 405B (GQA) | 405B | ~1.5 TB (BF16混精) | 中 (8 KV heads) | 必须多节点 FSDP/TP |
| Mixtral 8×7B | 46.7B 总 / 12.9B 活跃 | ~560 GB (BF16, 全部 Expert 需加载) | 等同 Mistral-7B | All-to-All 主导 |
| DeepSeek-V2 (236B MoE) | 236B 总 / 21B 活跃 | ~320 GB (BF16, 共享 Expert 优化) | 小 (MLA 压缩) | All-to-All + MLA 通信 |
推理视角
| 模型 | 单卡推理显存 | 8K 上下文 KV Cache | decode 延迟瓶颈 |
|---|---|---|---|
| LLaMA-2 70B (GQA) | ~140 GB → 需 2×A100 | ~5.4 GB (GQA 节约 8×) | 受 compute bound |
| LLaMA-2 70B (MHA) | ~140 GB → 需 2×A100 | ~43 GB ← KV Cache 太大 | 受 memory bound |
| Mixtral 8×7B | ~46.7B → 可在 1×A100-80G 装下 | ~2.5 GB | 活跃参数小 → 延迟低 |
| DeepSeek-V2 | ~236B 但活跃 ~21B | 极小(MLA 压缩) | MLA 的计算开销可接受 |
GPU 集群规划启示
- 训练 LLaMA-2 70B:8×A100-80GB 可装下混合精度(260GB < 640GB),用 FSDP 分片 + TP 即可
- 训练 Mixtral 8×7B:虽然活跃参数少,但所有 Expert 都需要驻留显存 → 显存需求不降。且 All-to-All 通信在 8+ GPU 时成为瓶颈
- 训练 LLaMA-3 405B:必须多节点,至少 16×H100-80GB 用 FSDP+TP,推荐 32×H100
- 推理长上下文(>32K):GQA/MQA 是刚需,否则 KV Cache 先爆
7. What to Use When — 选型指南
从零预训练
首选: LLaMA-style (Pre-Norm + SwiGLU + RoPE + GQA)
理由:
✓ Pre-Norm → 训练稳定,学习率容易调
✓ RoPE → 支持上下文外推,未来可用
✓ GQA → 推理成本低
✓ 开源验证充分,社区支持好
不推荐: 纯 GPT-3 style (Post-LN + GELU + Learned PE + MHA)
除非做学术对比实验
微调
场景: 已有预训练基座
选择: 保持原架构
微调技巧:
- LoRA/QLoRA 在注意力层的 Q/K/V 上添加低秩适配
- 量化到 INT4/INT8 加载权重,微调时保持 LoRA adapter 在 BF16
- 不改变 GQA/MHA 的 KV head 数(架构不可微调)
推理(长上下文)
首选: GQA 或 MQA 模型
- LLaMA-2-70B (GQA, 8 KV heads)
- LLaMA-3-70B (GQA, 8 KV heads)
- Mistral-7B (GQA, sliding window)
- Gemma-7B (MQA)
次选: MoE 模型
- Mixtral 8×7B → 活跃参数少,推理快
- DeepSeek-V2 → MLA 压缩 KV Cache 极致
- 代价: 需要加载全部 Expert,显存需求不低
成本敏感推理
方案 A: MoE 小模型
Mixtral 8×7B → 123 tokens/s (vs LLaMA-2 70B 的 42 tokens/s)
→ 延迟降 3×,成本降 ~30%
方案 B: 量化
LLaMA-3-8B-INT4 → 可在消费级 4090 上跑 > 200 tokens/s
→ 性价比最高,适合批处理
方案 C: 蒸馏
用 70B 教师模型蒸馏 7B 学生模型 → 保持接近质量 + 推理成本 1/10
快速决策矩阵
| 你的需求 | 推荐架构 | 推荐模型 |
|---|---|---|
| 训练新基座 | LLaMA-style | LLaMA-3 的设计模板 |
| 微调开源模型 | 保持原架构 | LLaMA-3 / Mistral / Qwen |
| API 推理(低延迟) | MoE | Mixtral / DeepSeek |
| 本地推理(单卡) | 小模型 + 量化 | LLaMA-3-8B-INT4 |
| 长文档分析(>32K) | GQA + RoPE 外推 | LLaMA-3 (GQA, 8K → 外推 32K) |
关联知识
学习时间
| 阶段 | 时间 | 备注 |
|---|---|---|
| 骨架创建 | 2026-06-30 | 框架搭建 |
| 内容完善 | 2026-06-30 | 七板块完整覆盖 |
状态标记
📖 已掌握 — Decoder-only 架构族谱、GPT vs LLaMA 逐项差异与训练稳定性、GQA/MQA 对 KV Cache 的节省与 TP 交互、MoE 路由机制与 All-to-All 通信瓶颈、RoPE 旋转位置编码外推原理、训练/推理集群规划
📝 待补充 — Mamba/SSM 等非 Transformer 架构对比、DeepSeek MLA (Multi-head Latent Attention) 深度解析、各架构在 Megatron-LM/DeepSpeed 的完整 TP/PP/DP 配置实例、RoPE 变体(YaRN/NTK/ReRoPE)的场景选型对比