LLM推理系统基础

1. 概述

大语言模型(Large Language Model, LLM)推理系统是部署深度学习模型进行推理的核心基础设施。与训练阶段不同,推理阶段对延迟吞吐量有严格的要求,且通常需要在有限的计算资源下服务大量用户请求。

本章将系统性地介绍LLM推理系统的核心概念、架构设计、性能指标和优化策略。

2. 自回归生成机制

2.1 Transformer推理流程

现代LLM基于Transformer架构,其推理过程可分为两个阶段:

预填充阶段(Prefill Phase)

  • 处理输入prompt,计算所有token的key-value缓存
  • 主要计算密集型操作
  • 输出第一个新token

解码阶段(Decode Phase)

  • 自回归生成新token
  • 每步生成一个token,需使用之前所有token的KV Cache
  • 主要受内存带宽限制(Memory-Bound)
def transformer_inference(model, input_ids, max_new_tokens):
    # Prefill阶段
    kv_cache = []
    hidden_states = model.embed_tokens(input_ids)
    
    for layer in model.layers:
        hidden_states, kv = layer(hidden_states, use_cache=True)
        kv_cache.append(kv)
    
    logits = model.norm(hidden_states) @ model.lm_head.weight.T
    next_token = logits.argmax(dim=-1, keepdim=True)
    
    # Decode阶段(自回归)
    for _ in range(max_new_tokens):
        # 拼接历史KV Cache
        hidden_states = model.embed_tokens(next_token)
        
        for i, layer in enumerate(model.layers):
            kv_prev = kv_cache[i]
            hidden_states, kv = layer(
                hidden_states, 
                past_key_values=kv_prev,
                use_cache=True
            )
            kv_cache[i] = kv
        
        logits = model.norm(hidden_states) @ model.lm_head.weight.T
        next_token = logits.argmax(dim=-1, keepdim=True)
        
        if next_token == model.eos_token_id:
            break
    
    return input_ids + generated_tokens

2.2 计算特性分析

阶段计算模式瓶颈优化重点
Prefill并行计算密集算子融合、并行化
Decode顺序内存带宽KV Cache管理、批处理

3. 推理系统核心指标

3.1 延迟指标

指标定义优化目标
Time to First Token (TTFT)首token生成时间Prefill加速
Time per Output Token (TPOT)每token平均时间Decode加速
End-to-End Latency完整生成时间端到端优化

3.2 吞吐量指标

指标定义优化目标
Requests Per Second (RPS)每秒请求数系统吞吐量
Tokens Per Second (TPS)每秒生成token数生成效率
Throughput单位时间处理数据量资源利用

3.3 资源指标

指标定义优化目标
GPU MemoryGPU显存占用内存优化
Batch Size批处理大小动态调整
Model Parallelism模型并行度并行策略

4. 推理系统架构

4.1 典型架构组件

┌─────────────────────────────────────────────────────────────┐
│                     Client Requests                         │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    API Gateway / Scheduler                   │
│              (请求路由、负载均衡、速率限制)                   │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      Inference Engine                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │  Tokenizer  │  │   Model     │  │ Detokenizer │         │
│  │             │  │  Executor   │  │             │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                        GPU Cluster                          │
│  ┌─────────────────────────────────────────────────┐        │
│  │  Model Parallelism: TP / PP / EP                │        │
│  │  Memory Optimization: KV Cache / Quantization   │        │
│  └─────────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────────┘

4.2 模型并行策略

张量并行(Tensor Parallelism, TP)

  • 将单一层的参数分割到多个GPU
  • 适用于单层计算密集型操作
  • 需要高速互连(NVLink)
class TensorParallelLayer(nn.Module):
    def __init__(self, world_size):
        super().__init__()
        self.world_size = world_size
        self.rank = dist.get_rank()
        
        # 按列分割lm_head
        self.lm_head = ColumnParallelLinear(
            hidden_size, vocab_size,
            num_streams=self.world_size
        )
        
    def forward(self, x):
        # 本地计算
        local_output = self.lm_head(x)
        
        # AllReduce汇总
        output = [torch.zeros_like(local_output) for _ in range(self.world_size)]
        dist.all_gather(output, local_output)
        
        return torch.stack(output, dim=0).sum(dim=0)

流水线并行(Pipeline Parallelism, PP)

  • 将不同层分配到不同GPU
  • 减少通信开销
  • 存在流水线气泡(P Bubble)

专家并行(Expert Parallelism, EP)

  • 仅适用于MoE模型
  • 不同专家分配到不同GPU
  • 需要路由机制协调

4.3 内存层级

GPU HBM (High Bandwidth Memory)
├── Model Weights (fp16/bf16)
├── KV Cache
│   ├── Prefill KV
│   └── Decode KV (动态增长)
├── Activations (中间计算结果)
└── Temporary Buffers

CPU Memory (Host)
├── Disk Cache (冷启动优化)
└── Request Queue

5. KV Cache管理

5.1 KV Cache问题

自回归生成中,每个解码步骤都需要访问全部历史KV Cache

  • 内存爆炸:KV Cache随序列长度线性增长
  • 带宽瓶颈:每次访问完整历史导致带宽压力
  • 容量限制:有限显存限制最大并发

5.2 解决方案概览

方法核心思想优缺点
量化降低KV Cache精度效果好,但有精度损失
压缩丢弃不重要KV需要判断重要性
缓存多级缓存策略需硬件支持
分离冷热Token分离需算法配合

6. 推理优化技术

6.1 批处理优化

静态批处理

  • 固定batch size
  • 简单但资源利用率低

连续批处理(Continuous Batching)

  • 动态批处理
  • 最大化GPU利用率
  • 引入新请求替换完成请求
class ContinuousBatcher:
    def __init__(self, max_batch_size):
        self.max_batch_size = max_batch_size
        self.running_requests = []
        self.pending_requests = []
    
    def step(self, model):
        # 1. 添加新请求到running
        while (len(self.running_requests) < self.max_batch_size 
               and self.pending_requests):
            self.running_requests.append(self.pending_requests.pop(0))
        
        # 2. 批量推理
        batch = self.prepare_batch(self.running_requests)
        outputs = model(batch)
        
        # 3. 处理完成请求
        completed = []
        remaining = []
        for req, output in zip(self.running_requests, outputs):
            req.generated_ids.append(output)
            if self.is_finished(req):
                completed.append(req)
            else:
                remaining.append(req)
        
        self.running_requests = remaining
        return completed

6.2 算子融合

将多个独立算子合并为单一kernel,减少内存访问:

# 原始计算
x → LayerNorm → Linear → SiLU → Dropout → Linear

# 融合后
x → FusedLayerNorm → FusedMLP → Linear

6.3 量化推理

精度内存缩减速度提升精度损失
fp161x1x基准
bf161x~1x极小
int82x1.5-2x可接受
int44x2-4x需校准

7. 主流推理框架对比

框架开发方核心特性适用场景
vLLMUC BerkeleyPagedAttention、连续批处理通用推理
TensorRT-LLMNVIDIATensorRT优化、INT8/FP8生产部署
llama.cppGeorgi Gerganov量化、CPU推理本地部署
DeepSpeed-InferenceMicrosoftZeRO、Transformer优化大模型
SGLangLMSYSRadixAttention、调度优化高吞吐
TGIHuggingFace量化为、推理优化灵活部署

8. 实践建议

8.1 延迟优化

  1. 启用KV Cache量化(INT8/FP8)
  2. 使用PagedAttention管理内存
  3. 预填充阶段使用更大batch
  4. 考虑投机解码加速

8.2 吞吐量优化

  1. 启用连续批处理
  2. 使用更长的预填充chunk
  3. 动态调整batch size
  4. 多级并行策略

8.3 资源优化

  1. 根据显存选择合适的量化精度
  2. 使用INT4权重 + INT8 KV Cache组合
  3. 启用FlashAttention
  4. 优化请求调度策略

9. 参考文献