跳转至

第24章 · 数值分析与凸优化补遗 · 阶段测试题

题型: 单选 × 8 / 多选 × 4 / 简答 × 5 / 编程 × 2 = 共 19 题 建议用时: 60 分钟


一 · 单选题 (8 题)

1.1 bfloat16 与 FP16 的核心区别? - A. bfloat16 精度更高 - B. bfloat16 指数位多 (8 vs 5), 范围更大 - C. bfloat16 更快 - D. bfloat16 是 32 位

1.2 强凸函数的特征? - A. Hessian ≥ μI, μ > 0 - B. Hessian 半正定 - C. Lipschitz 梯度 - D. 只有一个极值

1.3 Slater 条件? - A. KKT 充分条件 - B. 强对偶成立的充分条件 (strictly feasible) - C. 凸函数条件 - D. Newton's 收敛条件

1.4 L-BFGS 相对 BFGS 的优势? - A. 精度更高 - B. 内存 O(mn) 适合大模型 - C. 收敛更快 - D. 不需要梯度

1.5 Hogwild! 是什么? - A. 同步 SGD - B. 无锁异步 SGD - C. 分布式框架 - D. 二阶方法

1.6 AllReduce 最优实现? - A. Tree - B. Ring - C. Star - D. Mesh

1.7 FedAvg (联邦学习) 上传的是什么? - A. 梯度 - B. 模型参数 - C. 损失 - D. 数据

1.8 ZeRO 的 3 阶段分别优化? - A. 优化器状态 / 梯度 / 参数分片 - B. 数据 / 模型 / 流水线并行 - C. CPU / GPU / TPU - D. FP32 / FP16 / INT8


二 · 多选题 (4 题)

2.1 凸函数判别方法? (多选) - A. Hessian 半正定 - B. 一阶条件 (切线在函数下方) - C. 梯度为零 - D. Lipschitz 连续

2.2 KKT 条件包括? (多选) - A. Stationarity - B. Primal feasibility - C. Dual feasibility - D. Complementary slackness

2.3 二阶优化方法? (多选) - A. Newton - B. BFGS / L-BFGS - C. Trust Region - D. K-FAC / Shampoo

2.4 分布式训练策略? (多选) - A. DDP (Distributed Data Parallel) - B. FSDP (Fully Sharded Data Parallel) - C. DeepSpeed ZeRO - D. Pipeline Parallel


三 · 简答题 (5 题)

3.1 解释为什么训练深度网络要混用 FP32 + FP16 (Mixed Precision Training), 关键技术是什么 (Loss Scaling / GradScaler)。

3.2 比较 SGD / Adam / L-BFGS / Shampoo 4 个优化器的优缺点, 各适用什么场景。

3.3 推导 SVM 对偶问题, 说明 KKT 条件如何导出"支持向量"概念。

3.4 比较 DDP 与 FSDP 的内存使用与通信开销, 何时选哪个?

3.5 解释 Catastrophic Cancellation 在深度学习中的典型场景 (Softmax 溢出 / CrossEntropy 大 loss), 如何避免。


四 · 编程题 (2 题)

4.1 实现带数值稳定的 Softmax

def softmax_stable(x):
    """避免 exp 溢出"""
    pass

4.2 实现 DDP 训练循环 (伪代码)

def train_ddp(rank, world_size, model, optimizer):
    """DistributedDataParallel 训练一个 step"""
    pass


五 · 参考答案

单选

1.1 B 1.2 A 1.3 B 1.4 B 1.5 B 1.6 B 1.7 B 1.8 A

多选

2.1 AB 2.2 ABCD 2.3 ABCD 2.4 ABCD

简答

3.1 Mixed Precision: 权重 / 激活 / 梯度用 FP16 (省内存 + 快), 但主副本 (master copy) 仍用 FP32 (避免精度损失)。技术: - Loss Scaling: loss × scale (e.g. 65536), 防止 FP16 梯度下溢 - GradScaler: 检测 inf/nan, 动态调整 scale - 关键算子 (Loss/Softmax) FP32 计算

3.2 - SGD: 简单, 泛化好, 慢, 需手动调 lr; 适合 CNN/RL - Adam: 自适应, 快, 泛化略差, 默认首选; 适合 Transformer - L-BFGS: 二阶近似, 收敛快但内存大, 需小 batch; 适合小数据集 / 经典 ML - Shampoo: 二阶 preconditioner, 加速 2-3×; 适合大模型

3.3 SVM 原始: min (1/2)||w||² s.t. y_i(w·x_i+b)≥1。Lagrangian: L = (1/2)||w||² - Σαᵢ[y_i(w·x_i+b)-1]。对 w,b 求偏导 = 0: w = Σαᵢyᵢxᵢ, Σαᵢyᵢ = 0。代入得对偶: max Σαᵢ - (1/2)ΣΣαᵢαⱼyᵢyⱼ(x_i·xⱼ) s.t. αᵢ≥0。KKT 互补松弛: αᵢ[y_i(w·x_i+b)-1]=0, 即 y_i(w·x_i+b)>1 时 αᵢ=0 (非支持向量), =1 时 αᵢ≥0 (支持向量)。

3.4 - DDP: 每 worker 完整模型 + AllReduce 梯度。内存 = 模型 + 优化器。通信 1 次/步 (AllReduce)。 - FSDP: 模型/优化器/梯度都分片。内存 = 模型/world_size + 优化器/world_size。通信 2-3 次/步 (AllGather + ReduceScatter)。 - 选 DDP: 模型 < 1.5B, 显存够 - 选 FSDP: 模型 > 7B, 单卡放不下

3.5 场景: - Softmax: exp(1000) = inf → 全 0 - CrossEntropy: log(0) = -inf - 梯度消失: 梯度小到 fp16 无法表示 避免: Softmax 减 max / CrossEntropy 内部已含 log_softmax / 用 bfloat16 / Loss Scaling。

编程

4.1 参考答案:

import numpy as np

def softmax_stable(x):
    x = np.array(x)
    x_shifted = x - np.max(x)  # 关键: 减 max
    exp_x = np.exp(x_shifted)
    return exp_x / np.sum(exp_x)

4.2 参考答案:

import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP

def train_ddp(rank, world_size, model, optimizer):
    # 初始化
    dist.init_process_group("nccl", rank=rank, world_size=world_size)
    torch.cuda.set_device(rank)
    model = model.to(rank)
    ddp_model = DDP(model, device_ids=[rank])

    for epoch in range(num_epochs):
        for batch in dataloader:
            # 1. 前向
            outputs = ddp_model(**batch)
            loss = outputs.loss
            # 2. 反向 (DDP 自动同步梯度)
            optimizer.zero_grad()
            loss.backward()
            # 3. 更新
            optimizer.step()

    dist.destroy_process_group()