第3章 AI 工作负载特征

第3章 AI 工作负载特征

“Know thy workload.”

—— 系统设计的黄金法则

3.1 本章导入:不看负载做架构,等于盲人摸象

一个常见的错误是:拿到一个模型,立刻就开始买 GPU、搭集群、写调度系统——完全不去分析这个模型在计算、内存、网络上的具体需求。

结果是什么?花了数百万买了 8 张 H100,结果发现模型推理的瓶颈是 KV Cache 的显存容量,而不是算力;或者训练时 MFU 只有 20%,因为数据加载的 I/O 速度跟不上 GPU 消费速度。

正确的路径是:先理解工作负载,再设计系统架构。 本章将教你如何刻画和分析 AI 工作负载,建立从模型到基础设施的映射关系。

3.2 训练任务 vs. 推理任务:系统需求的天壤之别

训练和推理看似都是”跑模型”,但对基础设施的需求截然不同。

3.2.1 核心差异对比

         训练 (Training)                    推理 (Inference)
    ┌─────────────────────┐          ┌─────────────────────┐
    │                     │          │                     │
    │  前向 + 反向传播     │          │    仅前向传播        │
    │  更新模型参数        │          │    参数固定不变      │
    │                     │          │                     │
    │  Batch: 数百-数千    │          │  Batch: 1-数百      │
    │  精度: FP16/BF16     │          │  精度: FP16/INT8/INT4│
    │  网络: 全互联必须     │          │  网络: 可松耦合      │
    │  存储: 持续高吞吐读   │          │  存储: 启动时加载一次 │
    │  运行: 连续数天-数月  │          │  运行: 7x24 永久在线 │
    │  容错: 必须有 checkpoint│        │  容错: 快速重启+负载均衡│
    │                     │          │                     │
    └─────────────────────┘          └─────────────────────┘
维度 训练 推理
计算量 极大(前向 + 反向 + 优化器更新) 中等(仅前向,但可能 autoregressive)
Batch Size 256-4096+(越大越好,充分利用算力) 1-256(取决于延迟要求)
显存需求 权重 + 梯度 + 优化器状态 + 激活值 权重 + KV Cache
网络需求 GPU 间全互联(AllReduce 每步执行) 通常无 GPU 间通信
延迟敏感度 低(总训练时间最重要) 极高(TTFT < 200ms 为目标)
吞吐指标 tokens/sec during training requests/sec, tokens/sec output
GPU 利用率 目标 45-55% MFU 波动大,低 batch 时可能 < 10%
典型时长 数天到数月 永久运行
失败代价 极高(丢失进度 = 数百万美元) 低(单个请求失败可重试)

3.2.2 训练的显存需求拆解

理解训练显存到底用在哪里,对于系统设计至关重要:

# 以 7B 参数模型为例,计算训练所需显存
# 假设使用 AdamW 优化器 + FP16 混合精度

model_params = 7e9  # 7B 参数

# 1. 模型权重 (FP16): 2 bytes/param
weight_mem = model_params * 2 / 1e9
print(f"权重 (FP16):       {weight_mem:.1f} GB")

# 2. 梯度 (FP16): 2 bytes/param
grad_mem = model_params * 2 / 1e9
print(f"梯度 (FP16):       {grad_mem:.1f} GB")

# 3. 优化器状态 (AdamW, FP32): 8 bytes/param (2个状态 × 4 bytes)
optim_mem = model_params * 8 / 1e9
print(f"优化器状态 (FP32):  {optim_mem:.1f} GB")

# 4. 主权重 (FP32): 4 bytes/param (混合精度训练中的 master weights)
master_mem = model_params * 4 / 1e9
print(f"主权重 (FP32):     {master_mem:.1f} GB")

# 小计: 模型相关显存
model_total = weight_mem + grad_mem + optim_mem + master_mem
print(f"模型显存小计:      {model_total:.1f} GB")
# → 约 112 GB(是模型参数本身的 16 倍!)

# 5. 激活值 (取决于 batch size 和序列长度)
# 经验公式: activation_mem ≈ batch_size × seq_len × hidden_dim × num_layers × factor
# 简化估算: 使用梯度 checkpoint 后约为模型权重的 1-2 倍
batch_size = 8
seq_len = 4096
hidden_dim = 4096
num_layers = 32
# 每层激活值(带梯度 checkpoint 的近似)
activation_per_layer = batch_size * seq_len * hidden_dim * 2 * 2  # FP16 + 梯度
activation_total = activation_per_layer * num_layers / 1e9
print(f"激活值 (估算):     {activation_total:.1f} GB")

total_mem = model_total + activation_total
print(f"总训练显存:        {total_mem:.1f} GB")
# 一个 7B 模型训练可能需要 120-200 GB 显存(无优化时)
Tip

经验法则:训练一个 N 参数的模型,总显存需求大约是 16N-20N bytes(使用 AdamW + FP16 混合精度)。即训练 7B 模型需要约 112-140 GB 仅用于模型状态,加上激活值后需要 至少 2-3 张 80GB A100

3.2.3 推理的显存需求拆解

推理的显存需求与训练完全不同:

# LLM 推理显存分析(以 Llama-2-7B 为例)

model_params = 7e9

# 1. 模型权重 (FP16): 2 bytes/param
weight_mem = model_params * 2 / 1e9
print(f"权重:              {weight_mem:.1f} GB")  # 14 GB

# 2. KV Cache (关键!)
# KV Cache 大小 = 2 (K和V) × num_layers × seq_len × hidden_dim × batch_size × bytes_per_element
num_layers = 32
hidden_dim = 4096
# 对于多头注意力,KV 的 hidden_dim = num_heads × head_dim
# Llama-2-7B: 32 heads × 128 dim = 4096

# 假设: batch_size=1, seq_len=4096, FP16
batch_size = 1
seq_len = 4096
bytes_per_element = 2  # FP16

kv_cache = (2 * num_layers * seq_len * hidden_dim * batch_size * bytes_per_element) / 1e9
print(f"KV Cache (bs=1):   {kv_cache:.2f} GB")

# batch_size=32 时的 KV Cache
batch_size = 32
kv_cache_32 = kv_cache * 32
print(f"KV Cache (bs=32):  {kv_cache_32:.1f} GB")  # 会超过模型权重!

# 这就是为什么推理时 batch_size 受限

关键洞察:LLM 推理时,KV Cache 随 batch_size 和序列长度线性增长。对于长序列(如 32K token),KV Cache 可能比模型权重大数倍。这是推理服务扩展性的核心瓶颈。

3.3 计算密集型、显存密集型、通信密集型

根据瓶颈类型,AI 工作负载可以分为三类。理解你的工作负载属于哪一类,直接决定了优化方向。

3.3.1 三种瓶颈类型

  ┌──────────────────────────────────────────────┐
  │           计算密集型 (Compute-bound)          │
  │                                              │
  │  特征: 算术强度高,GPU 利用率接近峰值         │
  │  例子: 大 batch 训练、大矩阵乘法              │
  │  优化: 更强的算力、Tensor Core、低精度        │
  │                                              │
  │  GPU 利用率: ████████████████████ 90-100%    │
  │  显存带宽:   ██████████░░░░░░░░░░ 50%        │
  └──────────────────────────────────────────────┘

  ┌──────────────────────────────────────────────┐
  │          显存密集型 (Memory-bound)            │
  │                                              │
  │  特征: 大量数据搬运,算术强度低               │
  │  例子: 推理 batch=1、激活函数、LayerNorm      │
  │  优化: 更高带宽、融合算子、FlashAttention     │
  │                                              │
  │  GPU 利用率: ███░░░░░░░░░░░░░░░░░ 10-30%    │
  │  显存带宽:   ████████████████████ 90-100%    │
  └──────────────────────────────────────────────┘

  ┌──────────────────────────────────────────────┐
  │         通信密集型 (Communication-bound)     │
  │                                              │
  │  特征: GPU 大量时间在等待网络数据             │
  │  例子: 张量并行的 AllReduce、流水线气泡       │
  │  优化: 更快网络、计算-通信重叠、减少通信量    │
  │                                              │
  │  GPU 利用率: ██████░░░░░░░░░░░░░░ 20-40%    │
  │  网络流量:   ████████████████████ 峰值       │
  └──────────────────────────────────────────────┘

3.3.2 Roofline 模型:判断瓶颈类型

Roofline 模型是分析 GPU 性能的最直观工具:

graph LR
    subgraph "Roofline Model"
        A[算术强度 FLOPS/Byte] --> B{是否低于拐点?}
        B -- 是 --> C[内存带宽瓶颈]
        B -- 否 --> D[计算瓶颈]
    end

\[\text{ attainable FLOPS} = \min(\text{peak FLOPS}, \text{peak BW} \times \text{Arithmetic Intensity})\]

性能
(FLOPS)
  │
  │            ┌───────────────  ← 计算上限 (Peak FLOPS)
  │           /
  │          /
  │         /  ← 内存带宽限制
  │        /
  │       /
  │      /
  └──────┼──────────────────── 算术强度 (FLOPS/Byte)
         拐点

  H100 FP16 拐点: ~295 FLOPS/Byte
  A100 FP16 拐点: ~156 FLOPS/Byte

  典型操作的算术强度:
  - MatMul (大矩阵):     ~1000+  → 计算瓶颈 ✅
  - Attention (无优化):   ~50-100 → 内存瓶颈 ❌
  - LayerNorm:            ~5-20   → 内存瓶颈 ❌
  - Softmax:              ~10-30  → 内存瓶颈 ❌
  - Activation (ReLU):    ~2-5    → 内存瓶颈 ❌
Warning

重要发现:Transformer 模型中,Attention 机制如果不优化,是典型的内存瓶颈操作。这就是 FlashAttention 存在的意义——它通过分块计算将 Attention 的 HBM 访问次数从 O(n²) 降低到 O(n),大幅提升算术强度。在 LLM 训练中,不使用 FlashAttention 等于浪费 30-40% 的 GPU 时间

3.3.3 用代码分析实际工作负载

import torch
import time

def profile_compute_vs_memory(model, input_shape, device='cuda'):
    """简单的工作负载画像工具"""
    model = model.to(device)
    x = torch.randn(input_shape, device=device)
    
    # Warmup
    for _ in range(3):
        with torch.no_grad():
            _ = model(x)
    torch.cuda.synchronize()
    
    # Measure pure forward time
    n_iters = 100
    start = time.perf_counter()
    for _ in range(n_iters):
        with torch.no_grad():
            _ = model(x)
    torch.cuda.synchronize()
    elapsed = (time.perf_counter() - start) / n_iters
    
    # Measure with backward
    start = time.perf_counter()
    for _ in range(n_iters):
        out = model(x)
        loss = out.sum()
        loss.backward()
    torch.cuda.synchronize()
    elapsed_bwd = (time.perf_counter() - start) / n_iters
    
    print(f"Forward only:  {elapsed*1000:.2f} ms")
    print(f"Forward+Bwd:   {elapsed_bwd*1000:.2f} ms")
    print(f"Backward ratio: {elapsed_bwd/elapsed:.1f}x")
    
    # Memory usage
    mem_allocated = torch.cuda.memory_allocated() / 1e9
    mem_reserved = torch.cuda.memory_reserved() / 1e9
    print(f"GPU Memory allocated: {mem_allocated:.2f} GB")
    print(f"GPU Memory reserved:  {mem_reserved:.2f} GB")
    
    return elapsed, elapsed_bwd

# 使用示例
# from transformers import AutoModel
# model = AutoModel.from_pretrained("meta-llama/Llama-2-7b")
# profile_compute_vs_memory(model, (1, 512, 4096))

3.4 计算图与算子执行模式

3.4.1 什么是计算图

计算图是 AI 框架(PyTorch、TensorFlow、JAX)表示模型计算的核心数据结构。它将模型描述为有向无环图(DAG),其中节点是算子(Operator),边是数据依赖。

Transformer 前向传播的计算图(简化):

    Input Tokens
         │
         ▼
    ┌─────────┐
    │Embedding│
    └────┬────┘
         │
    ┌────▼────────┐
    │ Q/K/V Linear │ ← 3 个矩阵乘法 (或 1 个融合的)
    └────┬────────┘
         │
    ┌────▼────────┐
    │  Attention   │ ← Scaled Dot-Product Attention
    │  (FlashAttn) │    这是最关键的算子之一
    └────┬────────┘
         │
    ┌────▼────────┐
    │  Output Linear│
    └────┬────────┘
         │
    ┌────▼────────┐
    │  LayerNorm   │ ← 内存密集型算子
    └────┬────────┘
         │
    ┌────▼────────┐
    │    FFN       │ ← SwiGLU: 2 个大矩阵乘法
    │  (MLP/SwiGLU)│    占了模型 ~2/3 的计算量
    └────┬────────┘
         │
    ┌────▼────────┐
    │  LayerNorm   │
    └────┬────────┘
         │
         ▼
    Output Logits

3.4.2 算子执行模式:Eager vs. Graph

Eager 模式(PyTorch 默认):

# 每个算子立即执行,灵活但无法全局优化
x = torch.randn(1024, 1024, device='cuda')
w = torch.randn(1024, 1024, device='cuda')

# 这三行代码会触发三次 GPU kernel launch
a = torch.matmul(x, w)        # kernel 1
b = torch.relu(a)             # kernel 2
c = torch.matmul(b, w)        # kernel 3

Graph 模式(torch.compile / XLA / TensorRT):

# 先构建计算图,再整体优化和执行
import torch

@torch.compile(mode="max-autotune")
def ffn(x, w1, w2):
    a = torch.matmul(x, w1)
    b = torch.relu(a)
    c = torch.matmul(b, w2)
    return c

# 第一次调用时编译 + 优化 (可能融合为 1 个 kernel)
# 后续调用直接执行优化后的版本

算子融合(Operator Fusion) 是 Graph 模式的核心优势:

优化前 (Eager):                  优化后 (Fused):
                                  
读 → MatMul → 写                  读 → ┌───────────┐
读 → ReLU  → 写                       │ MatMul +  │ → 写
读 → MatMul → 写                      │ ReLU +    │
                                      │ MatMul    │
                                      └───────────┘
3 次读 + 3 次写 = 6 次 HBM 访问    1 次读 + 1 次写 = 2 次 HBM 访问
→ 减少 67% 的显存带宽压力
Tip

性能建议:对于 LLM 推理,使用 torch.compile 或 TensorRT-LLM 通常能带来 20-50% 的性能提升,主要通过算子融合减少 HBM 访问。但在训练场景中,编译开销和动态 shape 问题使得 Graph 模式更难落地,目前 torch.compile 在训练中的收益约为 5-15%

3.4.3 Autoregressive 解码的计算特征

LLM 推理有一个独特的计算模式——自回归解码(Autoregressive Decoding):

阶段 1: Prefill (并行处理所有输入 token)
    Input: [BOS] The capital of France is [EOS]
    → 一次计算所有 token, 类似训练的前向传播
    → 计算密集型, GPU 利用率高
    → 时间: 10-100ms (取决于输入长度)

阶段 2: Decode (逐个生成 token)
    Step 1: "Paris"     → 用上一步的 KV Cache
    Step 2: "is"        → 追加新的 KV
    Step 3: "a"         → 追加新的 KV
    ...
    → 每步只处理 1 个 token
    → 显存密集型, GPU 利用率极低 (< 10%)
    → 时间: 累计可能达数秒

这就是 LLM 推理的核心矛盾:prefill 阶段 GPU 利用率高但耗时短,decode 阶段 GPU 利用率低但耗时长。这种两阶段特征使得推理优化与纯前向推理(如 ResNet 分类)截然不同。

3.4.4 分离式推理架构

近期的趋势是将 prefill 和 decode 分配到不同的 GPU 上:

传统(混合模式):
  GPU 1: [Prefill req A] → [Decode req A] → [Prefill req B] → ...

分离式 (Disaggregated):
  Prefill 池:  GPU 1-4: [并行处理多个 prefill 请求]
                    │ (KV Cache 迁移)
  Decode 池:   GPU 5-8: [专注 decode, 可使用连续批处理]

分离式架构让每个阶段的 GPU 配置可以独立优化——prefill GPU 重算力,decode GPU 重显存容量。

3.5 模型规模增长对基础设施的影响

3.5.1 Scaling Law 与计算需求

Kaplan et al. (2020) 提出的 Scaling Law 表明,模型性能随参数量、数据量和计算量的指数增长而线性提升。这驱动了模型规模的持续膨胀:

模型规模演进:
  BERT-base      0.11B  (2018)
  GPT-2          1.5B   (2019)
  GPT-3          175B   (2020)  ← 100x in 1 year
  PaLM           540B   (2022)
  GPT-4          ~1800B (2023)  ← MoE, ~280B active params
  Llama-3-405B   405B   (2024)
  前沿模型        10T+   (2026 预期)

3.5.2 规模增长带来的系统挑战

挑战 1:显存容量

# 不同规模模型的训练显存需求 (AdamW + FP16)
models = {
    "1B":  1e9,
    "7B":  7e9,
    "70B": 70e9,
    "175B": 175e9,
    "405B": 405e9,
    "1800B": 1800e9,
}

for name, params in models.items():
    # 训练显存 ≈ 20 × params (含激活值)
    train_mem = params * 20 / 1e9
    # 推理显存 ≈ 2 × params (仅权重)
    infer_mem = params * 2 / 1e9
    
    a100_80g_train = train_mem / 80
    h100_80g_infer = infer_mem / 80
    
    print(f"{name:>6}: 训练 {train_mem:>8.0f} GB ({a100_80g_train:>5.1f}xH100) "
          f"推理 {infer_mem:>6.0f} GB ({h100_80g_infer:>5.1f}xH100)")

输出:

    1B: 训练       20 GB ( 0.3xH100) 推理      2 GB ( 0.0xH100)
    7B: 训练      140 GB ( 1.8xH100) 推理     14 GB ( 0.2xH100)
   70B: 训练     1400 GB (17.5xH100) 推理    140 GB ( 1.8xH100)
  175B: 训练     3500 GB (43.8xH100) 推理    350 GB ( 4.4xH100)
  405B: 训练     8100 GB (101.3xH100) 推理   810 GB (10.1xH100)
 1800B: 训练    36000 GB (450.0xH100) 推理  3600 GB (45.0xH100)

挑战 2:通信开销

模型越大,需要拆分到越多 GPU 上,通信开销也随之增长:

数据并行 (DP):  通信量 = 2 × 模型大小 / 步
张量并行 (TP):  通信量 = 每层 2 次 AllReduce
流水线并行 (PP): 通信量 = 每层 1 次 send/recv

最优并行策略随模型规模变化:

  7B:   DP=8 (单机 8 卡数据并行即可)
  70B:  DP=4, TP=2, PP=1 (单机 8 卡)
  175B: DP=4, TP=8, PP=4 (需要 ~128 卡)
  405B: DP=8, TP=8, PP=8 (需要 ~512+ 卡)

挑战 3:长尾效应

随着集群规模增大,尾部延迟故障恢复成为越来越大的效率杀手:

# 集群规模的"放大器效应"
# 假设单个 GPU 的可用率为 99.9% (每年宕机 ~8.7 小时)

availability = 0.999

for gpu_count in [8, 64, 512, 4096, 16384]:
    # 所有 GPU 同时可用的概率
    cluster_availability = availability ** gpu_count
    expected_failure_interval_hours = 8760 * (1 - cluster_availability)
    
    print(f"{gpu_count:>6} GPU: "
          f"集群可用率={cluster_availability:.6f}, "
          f"期望故障间隔={8760 / max(gpu_count * (1-availability), 1):.1f} 小时")

3.5.3 应对规模增长的技术策略

挑战 技术方案 效果
显存不足 ZeRO 优化器、激活重计算、CPU offload 降低 4-8x 显存
通信开销 梯度累积、计算-通信重叠、拓扑感知调度 降低 20-40% 通信
故障频发 定期 checkpoint、弹性训练、冗余计算 降低 90%+ 故障影响
训练成本 低精度训练(FP8)、稀疏化、MoE 降低 2-4x 计算量

3.6 典型负载画像与性能指标

3.6.1 四类典型工作负载画像

画像 1:LLM 预训练

workload: "GPT-class Pre-training"
model_size: "70B parameters"
hardware: "256x H100 (32 nodes)"
batch_size: 1024  # global batch
seq_length: 4096
  
compute:
  type: "compute-bound (大部分时间)"
  mfu_target: "50-55%"
  tokens_per_second: "~150,000"
  
memory:
  per_gpu: "~78 GB (80GB H100 接近满载)"
  breakdown: "权重 35% | 优化器 30% | 梯度 15% | 激活 20%"
  
network:
  pattern: "AllReduce every step (TP) + AllGather/ReduceScatter (DP)"
  bandwidth_utilization: "60-80% of peak"
  
storage:
  read_throughput: "~5 GB/s sustained"
  checkpoint_size: "~1.4 TB per checkpoint"
  checkpoint_frequency: "every 1000 steps (~30 min)"
  
failure_mode: "GPU掉卡 → 从最近checkpoint恢复 → 损失~15分钟"

画像 2:LLM 推理服务

workload: "LLM Chat Inference"
model_size: "70B parameters"
hardware: "8x H100 (1 node)"
concurrent_requests: 64
avg_input_length: 500 tokens
avg_output_length: 200 tokens

compute:
  prefill_phase: "compute-bound, GPU util ~80%"
  decode_phase: "memory-bound, GPU util ~5-15%"
  
memory:
  per_gpu: "~72 GB"
  breakdown: "权重 45% | KV Cache 50% | 其他 5%"
  
latency:
  ttft: "~200-400ms"
  time_per_output_token: "~20-40ms"
  
throughput:
  tokens_per_second: "~3000-5000 (aggregate)"
  requests_per_second: "~15-25"
  
batching: "continuous batching (vLLM/Orca)"

画像 3:扩散模型训练/推理

workload: "Diffusion Model (Stable Diffusion 3)"
model_size: "8B parameters"
hardware: "8x A100 80GB (training) / 1x H100 (inference)"

compute:
  pattern: "U-Net + Transformer blocks"
  type: "compute-bound (推理时 batch>4)"
  
memory:
  training: "~65 GB per GPU"
  inference: "~18 GB (权重 + 激活)"
  
special: "多步迭代 (20-50 steps), 每步完整前向传播"

画像 4:推荐系统(Embedding + MLP)

workload: "Recommendation (DLRM)"
model_size: "~1TB embedding tables"
hardware: "CPU + GPU 混合"

compute:
  pattern: "大规模 embedding lookup + MLP"
  bottleneck: "内存带宽 (embedding lookup) + 通信"
  
memory:
  pattern: "TB级 embedding tables 驻留 CPU 内存"
  
special: "I/O 密集型, CPU 内存容量是主要约束"

3.6.2 关键性能指标速查表

训练指标:
  MFU (Model FLOPS Utilization)
    → 目标: > 45%
    → 含义: 实际计算量 / 理论峰值
    
  TFLOPS per GPU
    → 含义: 每张 GPU 的实际 TFLOPS
    
  tokens/second (aggregate)
    → 含义: 整个集群每秒处理的 token 数
    
  Step time (ms)
    → 含义: 单个训练步骤的端到端时间
    
  GPU idle time ratio
    → 含义: GPU 空闲时间占比 (目标 < 10%)

推理指标:
  TTFT (Time To First Token)
    → 目标: < 500ms
    
  TPOT (Time Per Output Token)
    → 目标: < 40ms
    
  QPS (Queries Per Second)  
    → 含义: 服务整体吞吐量
    
  GPU utilization
    → 含义: 平均利用率 (推理场景通常较低)
    
  KV Cache hit rate
    → 含义: KV Cache 复用率 (影响显存效率)
    
  P99 latency
    → 目标: < 2s (取决于 SLA)

3.6.3 性能监控面板示例

# Prometheus 指标定义示例
# 推理服务监控

metrics:
  # 计算相关
  - name: inference_tokens_per_second
    query: 'rate(model_tokens_generated_total[1m])'
    alert: '< 1000 (warning) | < 500 (critical)'
  
  # 延迟相关
  - name: inference_ttft_p99
    query: 'histogram_quantile(0.99, model_ttft_seconds_bucket)'
    alert: '> 0.5s (warning) | > 1s (critical)'
  
  - name: inference_tpot_p50
    query: 'histogram_quantile(0.50, model_tpot_seconds_bucket)'
    alert: '> 0.04s (warning) | > 0.08s (critical)'
  
  # 资源相关
  - name: gpu_memory_usage_ratio
    query: 'nvidia_gpu_memory_used_bytes / nvidia_gpu_memory_total_bytes'
    alert: '> 0.90 (warning) | > 0.95 (critical)'
  
  - name: kv_cache_usage_ratio
    query: 'model_kv_cache_used_blocks / model_kv_cache_total_blocks'
    alert: '> 0.80 (warning) | > 0.95 (critical)'
  
  # 队列
  - name: request_queue_depth
    query: 'model_request_queue_size'
    alert: '> 50 (warning) | > 200 (critical)'
Tip

实践建议:建立性能监控时,先定义 SLO,再定义监控指标。一个常见的推理服务 SLO:TTFT P99 < 500ms, TPOT P99 < 40ms, 整体可用性 > 99.9%。所有优化决策都应以 SLO 为北极星,避免局部优化而全局劣化。

3.7 小结

  • 训练与推理的系统需求截然不同——训练追求高 MFU 和大规模互联,推理追求低延迟和高吞吐。用同一套硬件和软件栈服务两者,几乎总是次优选择。
  • AI 工作负载按瓶颈类型分为计算密集型、显存密集型和通信密集型三类。使用 Roofline 模型可以快速判断瓶颈类型,从而确定优化方向。
  • 计算图和算子执行模式深刻影响性能。算子融合、Graph 编译、自回归解码的两阶段特征,都是系统设计需要特别考虑的因素。
  • 模型规模增长直接驱动基础设施的复杂度——显存、通信、故障恢复都面临指数级挑战。ZeRO、FlashAttention、MoE 等技术都是应对这一挑战的工程创新。
  • 工作负载画像是系统设计的起点。在构建任何 AI 系统之前,先花时间刻画清楚你的工作负载在计算、内存、网络上的真实需求。

延伸阅读

  • “Scaling Laws for Neural Language Models” — Kaplan et al., 2020,理解模型规模增长的数学规律
  • “Chinchilla: Training Compute-Optimal LLMs” — Hoffmann et al., 2022,修正版 Scaling Law
  • “FlashAttention: Fast and Memory-Efficient Exact Attention” — Dao et al., 2022
  • “Efficient Memory Management for Large Language Model Serving with PagedAttention” — vLLM 团队, 2023
  • “ZeRO: Memory Optimizations Toward Training Trillion Parameter Models” — Rajbhandari et al., 2019
  • NVIDIA Nsight Systems Documentation — GPU 性能分析工具
  • “Roofline: An Insightful Visual Performance Model” — Williams et al., CACM 2009
  • “DistServe: Disaggregating Prefill and Decoding” — Zhong et al., 2024,分离式推理架构
  • MLPerf Benchmark Suite — 行业标准 AI 性能基准