米哈游 AI Infra 实习 二面
Q: 如何评估大模型的性能?有哪些常用的评估指标?
大模型评估分为系统性能指标(Infra 关注)和模型质量指标(算法关注)两大维度:
一、系统性能指标:
| 指标 | 含义 | 典型值 | 优化手段 |
|---|---|---|---|
| TTFT (Time to First Token) | 从请求到达到输出第一个 token 的延迟 | 100ms-2s | 优化 Prefill、Prefix Caching |
| TPOT (Time Per Output Token) | 生成阶段每个 token 的平均延迟 | 20-100ms | 量化、Continuous Batching |
| ITL (Inter-Token Latency) | 相邻 token 间的实际延迟(P99) | 30-150ms | PD 分离、减少调度抖动 |
| Throughput | 系统级吞吐 | 1000-10000 tokens/s | 大 batch、量化、高效调度 |
| QPS (Queries Per Second) | 每秒处理的请求数 | 10-100 req/s | Continuous Batching |
| GPU 利用率 | SM active 时间占比 | 目标 > 70% | 减少 bubble、overlap 通信 |
| 显存利用率 | KV Cache + 模型权重 / 总显存 | 目标 > 80% | PagedAttention |
TTFT 和 TPOT 的关系:
1 | 用户感知的总延迟 = TTFT + TPOT × (output_length - 1) |
二、模型质量指标:
| 类别 | 指标 | 评估内容 | 评分方式 |
|---|---|---|---|
| 语言建模 | PPL (Perplexity) | 预测能力 | 越低越好,FP16 基准对比 |
| 知识 | MMLU | 57 学科选择题 | 准确率 (%) |
| 数学 | GSM8K / MATH | 数学推理 | 准确率 (%) |
| 代码 | HumanEval / MBPP | 代码生成 | pass@k |
| 对话 | MT-Bench | 多轮对话质量 | GPT-4 打分 1-10 |
| 长文本 | RULER / Needle-in-Haystack | 长上下文利用 | 准确率 (%) |
| 安全 | TruthfulQA | 事实性 | 准确率 (%) |
| 综合 | OpenCompass | 多维度综合 | 加权分数 |
量化后的评估策略:
- 关注 PPL 增加量(Δ PPL < 0.3 通常可接受)
- 关注 benchmark 下降幅度(< 2% 通常可接受)
- 特别关注数学和代码任务(对精度最敏感)
Q: 如何对大模型进行优化以提高性能和效率?
大模型优化是一个多层次的系统工程,需要从模型、系统、算子三个维度协同:
模型层面优化:
| 方法 | 原理 | 典型加速 | 精度影响 |
|---|---|---|---|
| W4A16 量化 | 权重 INT4,减少 4x 读取量 | Decode 2-3x | PPL +0.3-1.0 |
| W8A8 量化 | 权重+激活 INT8,INT8 TC 加速 | Prefill 1.5-2x | PPL +0.1-0.3 |
| FP8 量化 | Hopper 原生支持 | 训练+推理 1.5-2x | PPL +0.05-0.15 |
| GQA/MLA | 减少 KV head / 低秩压缩 | KV Cache 减少 4-50x | 训练时决定 |
| MoE | 稀疏激活 | 同算力下参数量 ×5-10 | 需要 load balance |
| 知识蒸馏 | 大模型教小模型 | 小模型即可达标 | 取决于蒸馏质量 |
系统层面优化:
1 | 推理系统优化栈: |
算子层面优化:
- GEMM 优化:Tiling + Shared Memory + Tensor Core + 向量化
- Attention 优化:FlashAttention(tiling + online softmax)
- Elementwise 融合:LayerNorm + Residual + Linear 融合为单 kernel
- Communication overlap:All-Reduce 与 compute 重叠
端到端优化决策树:
1 | 目标: 降低 TTFT |
Q: 大模型中注意力机制是如何工作的?起什么作用?
注意力机制的完整工作流程(Multi-Head Self-Attention):
1 | 输入 X [batch, seq_len, d_model] |
为什么需要 √d_k 缩放:
- Q 和 K 的每个元素独立标准正态分布时,Q×K^T 的方差 = d_k
- 不缩放 → Score 方差大 → softmax 趋向 one-hot(梯度消失)
- 除以 √d_k → Score 方差 = 1 → softmax 输出分布合理
注意力的核心作用:
动态路由(最核心):
- MLP 的权重是固定的(对所有输入相同)
- Attention 的权重是输入依赖的(每个 token 根据内容决定关注谁)
- 这使得模型能动态选择性地聚合信息
全局依赖建模:
- 第 1 个 token 和第 1000 个 token 通过一次 attention 直接交互
- 对比 CNN(局部感受野)和 RNN(信息逐步传递衰减)
多头并行捕获不同模式:
1
2
3
4Head 0: 可能学习语法关系(主语-谓语)
Head 1: 可能学习共指关系(代词-实体)
Head 5: 可能学习位置关系(相邻 token)
Head 12: 可能学习语义相似性信息聚合与传递:
- 每一层的 attention 输出是 V 的加权组合
- 经过多层后,每个位置的表示融合了全序列的信息
- 残差连接确保原始信息不丢失
Q: 大模型中的优化算法有哪些?各有什么优缺点?
训练优化器对比(以 LLM 训练为场景):
| 优化器 | 核心思想 | 显存开销/参数 | 优缺点 |
|---|---|---|---|
| SGD + Momentum | 梯度 + 动量平滑 | +4 bytes (momentum) | 简单稳定,但收敛慢、需精细调 lr |
| Adam | 一阶矩(m) + 二阶矩(v) 自适应 | +8 bytes (m + v) | 收敛快,LLM 标配 |
| AdamW | Adam + 解耦 weight decay | +8 bytes | 修正 Adam 中 WD 与自适应 lr 的耦合 |
| Adafactor | 将 m/v 分解为行列向量 | +4~5 bytes | 显存省 ~30%,大模型可用 |
| Lion | 只用 sign(momentum) 更新 | +4 bytes | 显存比 Adam 小 50%,部分任务效果接近 |
| LAMB/LARS | 层级自适应学习率 | +8 bytes | 支持极大 batch (>32K) 训练 |
| 8-bit Adam | 量化 m 和 v 为 INT8 | +2 bytes | 显存减 75%,精度几乎无损 |
AdamW 详解(LLM 训练标配):
1 | 更新规则: |
显存占用分析(以 7B 参数 FP16 模型为例):
1 | 模型参数: 7B × 2 bytes = 14 GB |
选择建议:
- 标准 LLM 预训练 → AdamW(成熟、稳定)
- 显存极度紧张 → Adafactor 或 8-bit Adam
- 超大 batch 分布式 → LAMB(自动调节层级 lr)
- 实验探索 → Lion(更新更简单,可能在某些任务优于 Adam)
Q: 如何处理大模型训练中的梯度消失或梯度爆炸问题?
梯度消失(深层网络中梯度逐层指数衰减,底层几乎不更新):
根本原因:反向传播中梯度 = 链式法则的连乘。如果每层的梯度乘子 < 1,经过 N 层后梯度 → 0。
| 解决方法 | 原理 | 效果 |
|---|---|---|
| 残差连接 | ∂L/∂x = ∂L/∂(x+F(x)) × (1 + ∂F/∂x),至少有常数 1 项 | 最关键,使 100+ 层网络可训练 |
| Pre-Norm | Norm 在子层之前,梯度不经过 Norm 的缩放 | 比 Post-Norm 梯度流更稳定 |
| ReLU/GELU/SiLU | 正区间梯度 ≈ 1(vs Sigmoid 最大梯度 0.25) | 避免饱和区梯度为 0 |
| Xavier/Kaiming 初始化 | 保持每层输出方差 = 1 | 防止信号逐层衰减 |
| RMSNorm | 归一化每层输出 | 保持每层输入分布稳定 |
残差连接为什么有效的直觉:
1 | 无残差: ∂L/∂x₁ = ∂L/∂x_N × ∂x_N/∂x_{N-1} × ... × ∂x₂/∂x₁ |
梯度爆炸(梯度逐层指数增长,参数更新过大导致训练不稳定):
根本原因:梯度链式乘积中每层乘子 > 1,经过多层后梯度 → ∞。表现为 loss spike 或 NaN。
| 解决方法 | 原理 | 典型配置 |
|---|---|---|
| 梯度裁剪 (Gradient Clipping) | 限制梯度范数不超过阈值 | max_norm=1.0 |
| 学习率 Warmup | 初期小 lr,梯度大也不会造成大跳跃 | 前 1-5% steps 线性增长 |
| Weight Decay | 限制权重范数增长 | λ = 0.01-0.1 |
| Loss Scaling | 混合精度中放大 loss 防止 FP16 梯度下溢 | dynamic scaling |
| RMSNorm | 约束中间激活的范数 | 标准做法 |
| μP (Maximal Update) | 不同宽度层使用不同 lr 缩放 | 前沿研究 |
梯度裁剪的两种方式:
1 | # 方式 1: 按范数裁剪(更常用) |
LLM 训练中的实践:
- 几乎所有 LLM 训练都同时使用 Pre-Norm + 残差连接 + 梯度裁剪 + Warmup
- Loss spike 是常见问题:通常通过 skip batch(丢弃异常梯度的 step)处理
- DeepSeek 等报告中提到每 ~100B tokens 训练可能出现 1-3 次 loss spike
Q: 如何权衡模型复杂度和性能?
这是 LLM 设计的核心决策,需要在参数效率、计算效率和最终效果之间找到最优点。
Scaling Law 指导决策:
Chinchilla Scaling Law:给定计算预算 C,最优配置满足:
1 | 最优模型参数 N ∝ C^0.5 |
但实践中(DeepSeek/LLaMA-3)选择训练更多 token、更小模型——因为推理成本比训练成本更重要。
关键权衡策略:
| 策略 | 原理 | 适用场景 |
|---|---|---|
| MoE (混合专家) | 总参数 671B 但每 token 只激活 37B | 需要大容量但计算受限 |
| 知识蒸馏 | 大模型 teacher → 小模型 student | 部署预算固定 |
| Early Exit | 简单样本在浅层即可输出 | 输入难度差异大 |
| LoRA/QLoRA | 冻结主模型,只训练低秩增量 | 微调场景、显存受限 |
| 混合精度层 | 关键层 FP16,非关键层 INT8/INT4 | 精度敏感层不一致 |
| Dynamic Computation | 根据输入复杂度调整计算量 | 需要自适应推理 |
MoE 的具体权衡(以 DeepSeek-V3 为例):
1 | Dense 模型: 37B 参数, 每 token 计算 37B params 的 FLOPs |
Q: 面对大模型训练和推理的庞大计算资源,有什么解决建议?
训练阶段——资源优化路径:
1 | 单卡放不下模型: |
推理阶段——资源优化路径:
1 | 单卡推理太慢: |
实际案例——DeepSeek-V3 的训练优化:
- 2048 GPU × H800,训练 14.8T tokens
- FP8 混合精度训练(节省 50% 通信量)
- DualPipe(双向流水线)减少 PP bubble
- DeepEP 自定义 MoE 通信库
- 总训练成本仅 $5.6M(远低于同等规模的其他模型)
Q: Reward Model 分哪几类?如何训练?
Reward Model 的三大分类:
| 类型 | 代表 | 输出 | 优缺点 |
|---|---|---|---|
| Generative RM | GPT-4-as-Judge, Prometheus | 自然语言评分+理由 | 灵活可解释,但慢+贵+不稳定 |
| Discriminative RM | InternLM-Reward, ArmoRM | 标量分数 (scalar head) | 快、确定性强,但需训练数据 |
| Implicit RM | DPO 训练后的模型 | log_prob 差值即 reward | 无需单独训练 RM,但信号较弱 |
Discriminative RM 训练流程:
1 | 数据准备: |
训练技巧:
- 数据质量远比数据量重要(高质量人类标注 > 大量 AI 标注)
- 通常从 SFT 模型初始化 backbone(而非 base 模型)
- 需要 margin loss 或 length penalty 防止模型偏好长回复
- 多维度 reward(正确性、安全性、格式)分别训练或联合训练
Generative RM 的使用方式:
1 | Prompt to Judge LLM: |
Implicit RM(DPO 中的隐式 reward):
1 | DPO 训练后的模型 π_θ 隐含了 reward: |
Q: DPO 的损失函数和训练目标?DPO 如何改进?
DPO(Direct Preference Optimization)的核心思想:
将 RLHF 的两步(1. 训练 Reward Model;2. 用 PPO 优化 policy)合并为一步——直接用偏好数据优化 policy。
数学推导直觉:
1 | RLHF 目标: max E[r(x,y)] - β × KL(π_θ || π_ref) |
DPO 损失函数:
1 | L_DPO = -E_{(x, y_w, y_l)} [log σ(β × (log π_θ(y_w|x)/π_ref(y_w|x) - log π_θ(y_l|x)/π_ref(y_l|x)))] |
训练过程:
1 | 每个 batch: |
DPO 的优缺点:
- 优点:无需训练 RM、无需 PPO 的复杂训练循环、显存友好(不需要同时加载 4 个模型)
- 缺点:off-policy(偏好数据是旧模型生成的)、对数据质量敏感、may mode collapse
DPO 改进方向:
| 方法 | 改进点 | 核心变化 |
|---|---|---|
| IPO | 用回归损失替代 log-sigmoid | (log_ratio_w - log_ratio_l - 1/(2β))²,避免过拟合 |
| KTO | 不需要偏好对 | 只需 (x, y, good/bad label),更容易收集数据 |
| ORPO | 不需要 reference model | 将 reference 合并进 SFT loss |
| SimPO | 用序列平均 log prob | 消除长度偏差,不需要 reference model |
| Online DPO | 在线生成偏好对 | 当前 policy 生成 → 打分 → 训练,解决 off-policy |
| Self-Play | 自我对弈生成数据 | 模型自己生成 chosen/rejected |
| DPOP | 防止 chosen prob 下降 | 添加 penalty 防止 chosen 的 log_prob 降低 |
GRPO vs DPO 的关键区别:
1 | DPO: 使用固定的偏好数据集(离线) |