LLM Inference Optimization

推理优化可视化实验室

通过交互式可视化深入理解大语言模型推理优化的核心技术:从两阶段推理、KV-Cache 到 PagedAttention、连续批处理、投机解码、量化、Flash Attention 与模型并行策略。纯前端实现,零外部依赖。

8可视化模块
0外部依赖
100%纯前端
SVG驱动可视化
01

推理两阶段

Two-Phase Inference · Prefill 计算密集 vs Decode 内存密集

参数控制
实时指标
代码 · prefill + decode loop
def generate(model, prompt_ids, max_new_tokens):
    # Prefill: 整个 prompt 一次前向传播 (计算密集)
    logits = model.forward(prompt_ids)
    next_token = sample(logits[-1])
    kv_cache = model.kv_cache  # prefill 阶段保存

    # Decode: 逐 token 生成 (内存密集, KV-Cache 读取主导)
    output = [next_token]
    for _ in range(max_new_tokens - 1):
        logits = model.forward([next_token], kv_cache=kv_cache)
        next_token = sample(logits[-1])
        output.append(next_token)
    return output
02

KV-Cache 深度

KV-Cache Deep Dive · 缓存增长与内存带宽瓶颈

参数控制
实时指标
代码 · KV-Cache update
class KVCache:
    def __init__(self, n_layers, n_kv_heads, head_dim, max_seq):
        self.cache_k = torch.zeros(n_layers, max_seq, n_kv_heads, head_dim)
        self.cache_v = torch.zeros(n_layers, max_seq, n_kv_heads, head_dim)
        self.pos = 0

    def update(self, layer, new_k, new_v):
        # 写入新 token 的 K, V 到当前位置
        self.cache_k[layer, self.pos] = new_k
        self.cache_v[layer, self.pos] = new_v

    def get(self, layer):
        # 读取到当前位置的全部缓存 (decode 瓶颈所在)
        return self.cache_k[layer, :self.pos], self.cache_v[layer, :self.pos]
03

PagedAttention

PagedAttention (vLLM) · 分页 KV-Cache 消除碎片化

参数控制
实时指标
代码 · PagedAttention block manager
class BlockManager:
    def __init__(self, num_blocks, block_size=16):
        self.block_size = block_size
        self.free_blocks = list(range(num_blocks))
        self.block_table = {}  # req_id -> [block_ids]

    def allocate(self, req_id, num_tokens):
        blocks = self.block_table.setdefault(req_id, [])
        needed = (num_tokens + self.block_size - 1) // self.block_size
        while len(blocks) < needed and self.free_blocks:
            blocks.append(self.free_blocks.pop())

    def free(self, req_id):
        for b in self.block_table.get(req_id, []):
            self.free_blocks.append(b)
        self.block_table[req_id] = []
04

连续批处理

Continuous Batching · 迭代级动态调度

参数控制
实时指标
代码 · continuous batching scheduler
class ContinuousBatchScheduler:
    def __init__(self, engine, max_batch_size):
        self.engine = engine
        self.max_batch = max_batch_size
        self.running, self.waiting = [], []

    def step(self):
        # 移除已完成的请求
        self.running = [r for r in self.running if not r.finished]
        # 动态补充新请求到批次中
        while self.waiting and len(self.running) < self.max_batch:
            self.running.append(self.waiting.pop(0))
        # 对所有运行中的请求执行一次 decode 迭代
        for req in self.running:
            self.engine.decode_step(req)
05

投机解码

Speculative Decoding · 草稿-验证加速范式

参数控制
实时指标
代码 · speculative decoding loop
def speculative_decode(target, draft, prompt, max_tokens, K=4):
    tokens = list(prompt)
    for _ in range(max_tokens):
        # 1. 草稿模型快速生成 K 个候选 token
        draft_tokens = draft.generate(tokens, n=K)
        # 2. 目标模型一次前向验证全部 K 个 token
        target_logits = target.forward(tokens + draft_tokens)
        # 3. 接受匹配的 token, 拒绝第一个不匹配的
        accepted = 0
        for i, dt in enumerate(draft_tokens):
            if argmax(target_logits[len(tokens)+i]) == dt:
                accepted += 1
            else:
                break
        # 4. 添加接受的 token + 1 个修正 token
        tokens += draft_tokens[:accepted]
        if accepted < K:
            tokens += [argmax(target_logits[len(tokens)+accepted])]
    return tokens
06

量化技术

Quantization · FP16 → INT8 → INT4 权衡

参数控制
实时指标
方法对比
GPTQ
二阶 Hessian, 高精度权重量化
AWQ
激活感知, 保护显著通道
GGUF
k-quant, CPU/GPU 混合推理
SmoothQuant
W8A8, 激活难度迁移
代码 · quantization function
def quantize_weights(w, n_bits=8):
    """对称量化: FP16 -> INT8/INT4"""
    scale = w.abs().max() / (2 ** (n_bits - 1) - 1)
    q = torch.clamp((w / scale).round(),
                    -(2 ** (n_bits - 1)), 2 ** (n_bits - 1) - 1)
    return q.to(torch.int8), scale  # 存储量化值和缩放因子

# GPTQ: 二阶 Hessian 信息, 逐列量化补偿
# AWQ: 激活感知, 保护显著权重通道
# GGUF: k-quant 格式, 支持 CPU/GPU 混合推理
# SmoothQuant: 将激活难度迁移至权重, 适合 W8A8
07

注意力优化

Attention Optimization · Flash Attention 分块策略

参数控制
实时指标
代码 · Flash Attention kernel
def flash_attention(Q, K, V, block_size=64):
    """Flash Attention: 分块 + 在线 softmax, IO 复杂度 O(N^2/sqrt(M))"""
    N = Q.shape[0]
    O = torch.zeros_like(Q)
    for i in range(0, N, block_size):        # 遍历 Q 块
        Qi = Q[i:i+block_size]
        Oi, m, l = torch.zeros_like(Qi), torch.full((block_size,), -1e9), torch.zeros(block_size)
        for j in range(0, N, block_size):    # 遍历 K/V 块 (在 SRAM 中)
            S = Qi @ K[j:j+block_size].T / (Q.shape[-1] ** 0.5)
            m_new = torch.max(m, S.max(dim=-1).values)
            P = torch.exp(S - m_new.unsqueeze(-1))
            l = l * torch.exp(m - m_new) + P.sum(dim=-1)
            Oi = Oi * torch.exp(m - m_new).unsqueeze(-1) + P @ V[j:j+block_size]
            m = m_new
        O[i:i+block_size] = Oi / l.unsqueeze(-1)
    return O
08

模型并行策略

Model Parallelism · TP / PP / DP 通信模式

参数控制
实时指标
策略对比
TP 张量并行
切分注意力头, All-Reduce
PP 流水线并行
切分层, P2P 传递激活
DP 数据并行
复制模型, 梯度 All-Reduce
代码 · tensor parallel linear layer
import torch.distributed as dist

class TensorParallelLinear(nn.Module):
    """张量并行: 按输出维度切分权重矩阵到各 GPU"""
    def __init__(self, in_features, out_features, rank, world_size):
        super().__init__()
        self.local_out = out_features // world_size
        self.weight = nn.Parameter(torch.randn(self.local_out, in_features))
        self.rank, self.world_size = rank, world_size

    def forward(self, x):
        local_out = F.linear(x, self.weight)       # 各 GPU 计算自己的分片
        gathered = [torch.zeros_like(local_out)
                    for _ in range(self.world_size)]
        dist.all_gather(gathered, local_out)        # All-Gather 合并
        return torch.cat(gathered, dim=-1)

# Pipeline Parallel: 按层切分, P2P 传递激活值
# Data Parallel: 完整模型复制, 梯度 All-Reduce