编程 分布式 LLM 推理架构深度实战:从 vLLM 单节点到 llm-d 多集群的生产级演进全链路解析

2026-05-09 03:39:58 +0800 CST views 26

分布式 LLM 推理架构深度实战:从 vLLM 单节点到 llm-d 多集群的生产级演进全链路解析

一、背景与问题:为什么需要分布式 LLM 推理

1.1 单节点推理的瓶颈

当 ChatGPT 在 2022 年横空出世时,大多数人只看到了大语言模型的"智能",却鲜少关注其背后的推理基础设施。一个 GPT-4 级别的模型,参数量动辄千亿级别,单次推理需要数 GB 甚至数十 GB 的显存。以 Llama-3-70B 为例,FP16 精度下需要约 140GB 显存,这已经超出了单张 A100 80GB 的承载能力。

单节点推理面临的核心挑战:

┌─────────────────────────────────────────────────────────────┐
│                    单节点推理瓶颈                              │
├─────────────────────────────────────────────────────────────┤
│  1. 显存容量限制                                              │
│     - 70B 模型 FP16 ≈ 140GB,单卡无法容纳                     │
│     - 即使量化到 INT4,长上下文仍可能 OOM                      │
│                                                              │
│  2. 吞吐量天花板                                              │
│     - 单卡 A100 理论算力 ~312 TFLOPS (FP16)                   │
│     - 实际推理受限于显存带宽、KV Cache 管理等                   │
│     - 单节点 QPS 难以满足生产级并发需求                         │
│                                                              │
│  3. 高可用性缺失                                              │
│     - 单点故障导致服务完全不可用                               │
│     - 无法实现跨机房容灾                                      │
│                                                              │
│  4. 资源利用率低                                              │
│     - 请求波峰波谷差异大,固定资源难以弹性伸缩                   │
│     - GPU 闲置成本高昂                                        │
└─────────────────────────────────────────────────────────────┘

1.2 分布式推理的必要性

随着大模型应用从 PoC 走向生产,企业面临的不再是"能不能跑起来"的问题,而是"如何以合理成本支撑百万级用户并发"。这催生了分布式 LLM 推理架构的快速发展。

分布式推理的核心价值:

维度单节点分布式集群
模型规模受单卡显存限制理论无限扩展
并发能力QPS ~10-50QPS 可达数千
可用性单点故障风险多副本高可用
成本效率固定资源,利用率低弹性伸缩,按需付费
延迟优化受限于单卡算力Prefill/Decode 分离优化

二、技术层次划分:理解分布式推理的全景图

在深入具体方案前,我们需要建立清晰的认知框架。分布式 LLM 推理并非单一技术,而是多层架构的协同:

┌─────────────────────────────────────────────────────────────────────┐
│                        用户请求 / 应用层                             │
│                     (API Gateway, 负载均衡)                          │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     编排/路由层                                      │
│           llm-d / Ray Serve / KServe / Gateway API IE               │
│                  负责调度、路由、扩缩容、KV Cache 感知路由              │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      推理引擎层                                      │
│              vLLM / SGLang / TRT-LLM / LMDeploy                     │
│                负责实际 token 计算、KV Cache 管理、批处理优化           │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        硬件层                                       │
│              NVIDIA / AMD / Intel GPU + 高速互联网络                  │
│                   (NVLink, InfiniBand, RoCE)                         │
└─────────────────────────────────────────────────────────────────────┘

核心认知:vLLM 和 SGLang 是"推理引擎",而 llm-d、Ray Serve 等是"编排调度层",两者不是竞争关系,而是搭配关系。

三、推理引擎层深度解析

3.1 vLLM:PagedAttention 开创者

vLLM 由 UC Berkeley Sky Lab 开发,是当前最流行的开源 LLM 推理引擎。其核心创新是 PagedAttention 算法,解决了传统推理中 KV Cache 内存碎片化的问题。

3.1.1 PagedAttention 原理

传统注意力机制中,每个请求的 KV Cache 是连续分配的,但序列长度动态变化导致大量内存碎片。vLLM 借鉴操作系统的虚拟内存管理思想,将 KV Cache 划分为固定大小的 block(通常 16 个 token):

# PagedAttention 核心数据结构
class BlockManager:
    """管理 KV Cache 的块分配"""
    
    def __init__(self, num_blocks: int, block_size: int):
        self.block_size = block_size  # 每块 token 数,通常 16
        self.free_blocks = list(range(num_blocks))  # 空闲块池
        self.block_tables = {}  # 请求 -> 物理块映射表
    
    def allocate(self, request_id: int, num_tokens: int) -> List[int]:
        """为请求分配物理块"""
        num_blocks = (num_tokens + self.block_size - 1) // self.block_size
        if len(self.free_blocks) < num_blocks:
            raise OutOfMemoryError("Not enough blocks")
        
        allocated = self.free_blocks[:num_blocks]
        self.free_blocks = self.free_blocks[num_blocks:]
        self.block_tables[request_id] = allocated
        return allocated
    
    def free(self, request_id: int):
        """释放请求占用的所有块"""
        blocks = self.block_tables.pop(request_id, [])
        self.free_blocks.extend(blocks)

内存效率对比:

方案内存利用率碎片率支持共享
连续分配~50-60%40-50%不支持
PagedAttention~96%<4%支持(Copy-on-Write)

3.1.2 连续批处理(Continuous Batching)

传统静态批处理需要等待所有序列生成完成才能释放资源,vLLM 的连续批处理实现了 迭代级调度

class ContinuousBatcher:
    """连续批处理调度器"""
    
    def __init__(self, engine: LLMEngine):
        self.engine = engine
        self.running: List[Request] = []  # 正在运行的请求
        self.waiting: Deque[Request] = deque()  # 等待队列
    
    def step(self) -> List[Output]:
        """单步迭代:生成一个 token"""
        # 1. 尝试从等待队列接纳新请求
        while self.waiting and self.can_allocate(self.waiting[0]):
            req = self.waiting.popleft()
            self.running.append(req)
            self.engine.allocate(req)
        
        # 2. 对所有运行请求执行一次前向传播
        outputs = self.engine.forward(self.running)
        
        # 3. 检查完成的请求并释放资源
        completed = []
        for i, req in enumerate(self.running):
            if req.is_finished():
                completed.append(req)
                self.engine.free(req)
        
        self.running = [r for r in self.running if not r.is_finished()]
        return outputs

性能提升: 相比静态批处理,连续批处理在相同硬件上吞吐量提升 2-4 倍

3.1.3 生产部署关键参数

python -m vllm.entrypoints.openai.api_server \
    --model /path/to/model \
    --tensor-parallel-size 4 \           # 张量并行度(跨卡)
    --pipeline-parallel-size 2 \         # 流水线并行度(跨节点)
    --gpu-memory-utilization 0.9 \       # GPU 显存利用率
    --max-num-seqs 256 \                 # 最大并发序列数
    --max-model-len 32768 \              # 最大上下文长度
    --block-size 16 \                    # PagedAttention 块大小
    --enable-prefix-caching \            # 开启前缀缓存
    --speculative-model [small_model]    # 投机解码小模型

3.2 SGLang:RadixAttention 与结构化输出

SGLang 是后起之秀,其核心创新是 RadixAttention(基数树前缀缓存)和 结构化生成语言

3.2.1 RadixAttention 原理

RadixAttention 使用基数树(Radix Tree)存储 KV Cache,实现前缀的高效共享:

                    根节点
                   /      \
              "系统:"    "用户:"
              /    \        \
         "你是AI" "翻译"   "你好"
            |       |        |
          [KV1]   [KV2]    [KV3]
                   |
                "成英文"
                  |
               [KV4]

当新请求以"系统:你是AI"开头时,直接复用 KV1,无需重新计算。

class RadixAttention:
    """基数树前缀缓存"""
    
    def __init__(self):
        self.tree = RadixTree()
        self.cache: Dict[Node, KVCache] = {}
    
    def match_prefix(self, tokens: List[int]) -> Tuple[KVCache, int]:
        """匹配最长前缀"""
        node, matched_len = self.tree.longest_prefix(tokens)
        if node in self.cache:
            return self.cache[node], matched_len
        return None, 0
    
    def insert(self, tokens: List[int], kv: KVCache):
        """插入新前缀"""
        node = self.tree.insert(tokens)
        self.cache[node] = kv

与前缀缓存对比:

特性vLLM Prefix CachingSGLang RadixAttention
数据结构哈希表基数树
匹配方式精确匹配最长前缀匹配
内存效率中等更高(共享前缀)
适用场景相同 prompt相似 prompt

3.2.2 结构化输出

SGLang 的杀手级特性是原生支持 JSON 结构化输出:

import sglang as sgl

@sgl.function
def generate_json(s, prompt):
    s += prompt
    s += "请以 JSON 格式输出,包含 name, age, skills 字段:"
    # 强制约束输出格式
    s += sgl.json(
        name=sgl.string(max_length=50),
        age=sgl.integer(min_value=0, max_value=150),
        skills=sgl.array(sgl.string(), max_length=10)
    )

result = generate_json.run("描述一个程序员")
print(result)  # 保证是合法 JSON

3.3 TensorRT-LLM:NVIDIA 官方优化

TensorRT-LLM 是 NVIDIA 官方推出的推理优化库,深度集成 CUDA 生态:

核心优化技术:

  1. Kernel Fusion(算子融合):将多个小算子合并为一个大 kernel,减少显存访问
  2. 量化支持:FP8、INT8、INT4 量化,几乎无损精度损失
  3. In-flight Batching:类似 vLLM 的连续批处理
  4. Multi-query Attention / Grouped-query Attention:优化 KV Cache 大小
# TensorRT-LLM 构建引擎示例
import tensorrt_llm as trt

builder = trt.Builder()
network = builder.create_network()

# 配置模型
config = trt.ModelConfig(
    model_name="llama-3-70b",
    tensor_parallel=4,
    pipeline_parallel=2,
    precision="fp8",
    max_batch_size=128,
    max_input_len=4096,
    max_output_len=2048
)

# 构建引擎
engine = builder.build_engine(network, config)
engine.save("llama-3-70b-fp8.engine")

3.4 推理引擎选型指南

场景推荐引擎理由
快速原型验证vLLM开箱即用,文档完善
高并发生产环境vLLM / SGLangPagedAttention + 连续批处理
结构化输出需求SGLang原生 JSON 约束
NVIDIA GPU 深度优化TensorRT-LLMKernel Fusion + FP8
多模态模型vLLM支持 LLaVA 等多模态架构
AMD GPUvLLMROCm 后端支持

四、编排调度层深度解析

4.1 vLLM Production Stack

vLLM 官方在 2025 年 1 月发布了 Kubernetes 生产部署参考栈,核心能力包括:

┌─────────────────────────────────────────────────────────────────┐
│                   vLLM Production Stack                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐       │
│  │   Router     │───▶│  vLLM Pod 1  │───▶│   LMCache    │       │
│  │ (Prefix-Aware)│    │  (GPU 0-3)   │    │  (GPU→CPU)   │       │
│  └──────────────┘    └──────────────┘    └──────────────┘       │
│         │                   │                    │              │
│         │            ┌──────────────┐           │              │
│         │            │  vLLM Pod 2  │───────────┘              │
│         │            │  (GPU 4-7)   │                          │
│         │            └──────────────┘                          │
│         │                                                       │
│         ▼                                                       │
│  ┌──────────────┐    ┌──────────────┐                          │
│  │ Prometheus   │◀───│  Grafana     │                          │
│  │ (Metrics)    │    │ (Dashboard)  │                          │
│  └──────────────┘    └──────────────┘                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

核心特性:

  1. Prefix-Cache 感知路由:将请求路由到已缓存对应 KV 的 Pod,大幅提升缓存命中率
  2. KV Cache 卸载:通过 LMCache 实现 GPU → CPU 两级缓存
  3. 一键部署:单条 Helm 命令即可在 K8s 上拉起完整服务栈
  4. 开箱即用监控:内置 Prometheus + Grafana 仪表盘

部署示例:

# 使用 Helm 一键部署
helm repo add vllm https://vllm-project.github.io/production-stack
helm install my-vllm vllm/production-stack \
    --set model.name="meta-llama/Llama-3-70b" \
    --set model.tensorParallelSize=4 \
    --set replicaCount=3 \
    --set resources.gpu.count=4 \
    --set resources.gpu.type="nvidia.com/a100"

性能数据(官方 benchmark):

指标裸 vLLM + KServevLLM Production Stack
吞吐量基准2-5x
P99 延迟基准3-10x 更低
KV 命中率~30%~80%

4.2 llm-d:CNCF 孵化项目

llm-d 是 CNCF(云原生计算基金会)孵化的分布式 LLM 推理调度系统,定位是云原生时代的"LLM 专用调度器"。

4.2.1 架构设计

┌─────────────────────────────────────────────────────────────────────┐
│                           llm-d 架构                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│    ┌─────────────────────────────────────────────────────────┐     │
│    │                    llm-d Scheduler                        │     │
│    │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │     │
│    │  │  Predictor  │  │   Scorer    │  │  Binder     │       │     │
│    │  │ (负载预测)   │  │ (节点评分)  │  │ (Pod绑定)   │       │     │
│    │  └─────────────┘  └─────────────┘  └─────────────┘       │     │
│    └─────────────────────────────────────────────────────────┘     │
│                              │                                     │
│                              ▼                                     │
│    ┌─────────────────────────────────────────────────────────┐     │
│    │                   InferencePool                          │     │
│    │  ┌───────────┐  ┌───────────┐  ┌───────────┐            │     │
│    │  │  Pod 1    │  │  Pod 2    │  │  Pod 3    │            │     │
│    │  │ vLLM+GPU  │  │ vLLM+GPU  │  │ vLLM+GPU  │            │     │
│    │  │ (Zone A)  │  │ (Zone A)  │  │ (Zone B)  │            │     │
│    │  └───────────┘  └───────────┘  └───────────┘            │     │
│    └─────────────────────────────────────────────────────────┘     │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4.2.2 智能调度策略

llm-d 的调度器实现了 LLM 推理特有的调度策略:

class LLMDScheduler:
    """llm-d 智能调度器"""
    
    def schedule(self, request: LLMRequest) -> Pod:
        """调度单个请求"""
        
        # 1. 预测请求资源需求
        estimated_kv_size = self.predictor.predict_kv_cache(
            model=request.model,
            input_len=request.input_length,
            max_output_len=request.max_output_length
        )
        
        # 2. 获取候选节点
        candidates = self.get_candidate_pods(request.model)
        
        # 3. 多维度评分
        scores = []
        for pod in candidates:
            score = 0.0
            
            # KV Cache 命中率评分(权重最高)
            if pod.has_prefix_cache(request.prefix):
                score += 100 * self.weights['cache_hit']
            
            # GPU 显存余量评分
            free_memory = pod.gpu_memory_available()
            if free_memory > estimated_kv_size:
                score += (free_memory - estimated_kv_size) / free_memory * 50
            
            # 请求队列深度评分(负载均衡)
            score -= pod.queue_depth() * self.weights['queue_depth']
            
            # 延迟评分(就近原则)
            score -= pod.network_latency(request.client_zone) * self.weights['latency']
            
            scores.append((pod, score))
        
        # 4. 选择最高分节点
        best_pod = max(scores, key=lambda x: x[1])[0]
        return best_pod

4.3 Ray Serve:通用分布式计算框架

Ray Serve 是 Ray 分布式计算框架的服务层,虽然不是 LLM 专用,但凭借其成熟的分布式能力,被广泛用于 LLM 推理部署。

from ray import serve
from vllm import LLM, SamplingParams

@serve.deployment(
    ray_actor_options={
        "num_gpus": 4,
        "resources": {"A100": 4}
    },
    autoscaling_config={
        "min_replicas": 2,
        "max_replicas": 10,
        "target_num_ongoing_requests_per_replica": 32
    }
)
class LLMDeployment:
    def __init__(self, model_path: str):
        self.llm = LLM(
            model=model_path,
            tensor_parallel_size=4,
            gpu_memory_utilization=0.9
        )
        self.params = SamplingParams(max_tokens=1024)
    
    async def __call__(self, request: dict):
        return self.llm.generate(request["prompt"], self.params)

# 部署
serve.run(LLMDeployment.bind("/models/llama-3-70b"))

Ray Serve 优势:

  • 弹性伸缩:根据负载自动扩缩副本数
  • 多模型编排:支持多个模型协同(如 Router + LLM + Reranker)
  • 跨语言支持:Python、Java、C++ 均可接入
  • 成熟生态:与 Ray Data、Ray Train 无缝集成

4.4 Gateway API Inference Extension

Kubernetes Gateway API 的 Inference Extension 是专为 AI 推理设计的新一代路由扩展:

# InferencePool 定义
apiVersion: inference.networking.k8s.io/v1alpha1
kind: InferencePool
metadata:
  name: llama-70b-pool
spec:
  targetPort: 8000
  selector:
    app: vllm-server
    model: llama-70b
  endpointPickerConfig:
    criticality: true  # 启用优先级调度

---
# InferenceModel 定义
apiVersion: inference.networking.k8s.io/v1alpha1
kind: InferenceModel
metadata:
  name: chat-model
spec:
  modelName: llama-3-70b-chat
  criticality: High  # 高优先级
  poolRef:
    name: llama-70b-pool

核心组件:

  1. InferencePool:定义一组专门运行 AI 推理的 Pod,能实时监控 GPU 内存、请求队列深度等指标
  2. InferenceModel:描述具体的模型配置,支持设置优先级和流量分配
  3. Endpoint Picker (EPP):智能调度引擎,根据实时负载和请求优先级动态分配

五、Kubernetes 多机多卡集群部署实战

5.1 整体架构设计

┌─────────────────────────────────────────────────────────────────────┐
│                      Kubernetes 集群                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                      Ray 集群                                 │   │
│  │  ┌─────────────┐                                            │   │
│  │  │  Ray Head   │  (调度、资源协调)                           │   │
│  │  └─────────────┘                                            │   │
│  │       │                                                      │   │
│  │       ├──────────┬──────────┬──────────┐                    │   │
│  │       ▼          ▼          ▼          ▼                    │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐           │   │
│  │  │Worker 1 │ │Worker 2 │ │Worker 3 │ │Worker N │           │   │
│  │  │GPU 0-3  │ │GPU 4-7  │ │GPU 8-11 │ │GPU ...  │           │   │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘           │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐             │
│  │ vLLM Driver  │  │ vLLM Worker  │  │ vLLM Worker  │             │
│  │  (协调器)    │  │  (计算节点)  │  │  (计算节点)  │             │
│  └──────────────┘  └──────────────┘  └──────────────┘             │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐             │
│  │ API Gateway  │  │ Prometheus   │  │  Grafana     │             │
│  └──────────────┘  └──────────────┘  └──────────────┘             │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 环境准备与依赖

# 1. Kubernetes 组件
kubectl version --client  # >= 1.24
helm version              # >= 3.8

# 2. NVIDIA 组件
nvidia-smi                # Driver >= 470
nvidia-container-cli info # Container Toolkit

# 3. 安装 GPU Operator(自动化 GPU 节点配置)
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm install gpu-operator nvidia/gpu-operator \
    --namespace gpu-operator --create-namespace

# 4. 安装 Ray Operator
helm repo add kuberay https://ray-project.github.io/kuberay-helm
helm install kuberay-operator kuberay/kuberay-operator

5.3 Ray 集群部署

# ray-cluster.yaml
apiVersion: ray.io/v1alpha1
kind: RayCluster
metadata:
  name: llm-ray-cluster
spec:
  rayVersion: "2.9.0"
  
  headGroupSpec:
    serviceType: ClusterIP
    rayStartParams:
      dashboard-host: "0.0.0.0"
    template:
      spec:
        containers:
          - name: ray-head
            image: rayproject/ray:2.9.0-gpu
            resources:
              limits:
                cpu: "8"
                memory: "32Gi"
                nvidia.com/gpu: "1"
            ports:
              - containerPort: 6379
                name: gcs
              - containerPort: 8265
                name: dashboard
  
  workerGroupSpecs:
    - groupName: gpu-worker
      replicas: 4
      minReplicas: 2
      maxReplicas: 10
      rayStartParams:
        num-gpus: "4"
      template:
        spec:
          containers:
            - name: ray-worker
              image: rayproject/ray:2.9.0-gpu
              resources:
                limits:
                  cpu: "32"
                  memory: "128Gi"
                  nvidia.com/gpu: "4"
              volumeMounts:
                - name: model-storage
                  mountPath: /models
          volumes:
            - name: model-storage
              persistentVolumeClaim:
                claimName: model-pvc

5.4 vLLM 分布式部署

# vllm-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vllm-server
  template:
    metadata:
      labels:
        app: vllm-server
    spec:
      containers:
        - name: vllm
          image: vllm/vllm-openai:latest
          args:
            - --model=/models/llama-3-70b
            - --tensor-parallel-size=4
            - --pipeline-parallel-size=2
            - --gpu-memory-utilization=0.9
            - --max-num-seqs=256
            - --enable-prefix-caching
          ports:
            - containerPort: 8000
          resources:
            limits:
              nvidia.com/gpu: "4"
          volumeMounts:
            - name: model-storage
              mountPath: /models
          env:
            - name: RAY_ADDRESS
              value: "ray://llm-ray-cluster-head-svc:10001"
      volumes:
        - name: model-storage
          persistentVolumeClaim:
            claimName: model-pvc

5.5 服务暴露与负载均衡

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm-server
  ports:
    - port: 80
      targetPort: 8000
  type: LoadBalancer

---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: vllm-ingress
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
spec:
  rules:
    - host: llm-api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: vllm-service
                port:
                  number: 80

六、性能优化深度技巧

6.1 KV Cache 优化

6.1.1 多级缓存架构

┌─────────────────────────────────────────────────────────────────────┐
│                      KV Cache 多级架构                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐            │
│   │   L1: GPU   │───▶│  L2: CPU    │───▶│  L3: NVMe   │            │
│   │   (最快)    │    │  (中等)     │    │  (最慢)     │            │
│   │  ~100GB/s   │    │  ~50GB/s    │    │  ~5GB/s     │            │
│   └─────────────┘    └─────────────┘    └─────────────┘            │
│                                                                     │
│   命中延迟: ~1μs        命中延迟: ~10μs      命中延迟: ~100μs       │
│   容量: ~10GB          容量: ~100GB        容量: ~1TB              │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6.1.2 LMCache 集成

from lmcache import LMCacheClient

# 配置多级缓存
cache_client = LMCacheClient(
    config={
        "gpu_cache_size": 10 * 1024 * 1024 * 1024,  # 10GB GPU
        "cpu_cache_size": 100 * 1024 * 1024 * 1024,  # 100GB CPU
        "nvme_cache_path": "/mnt/nvme/kv-cache",
        "nvme_cache_size": 500 * 1024 * 1024 * 1024,  # 500GB NVMe
    }
)

# 与 vLLM 集成
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3-70b",
    kv_cache_client=cache_client
)

6.2 投机解码(Speculative Decoding)

投机解码使用一个小模型"猜测"后续 token,大模型验证,正确则一次接受多个 token:

# vLLM 投机解码配置
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3-70b",  # 大模型(验证者)
    speculative_model="meta-llama/Llama-3-8b",  # 小模型(投机者)
    speculative_num_draft_tokens=5,  # 每次猜测 5 个 token
    speculative_max_acceptance=0.9  # 接受阈值
)

性能提升: 在生成任务上可提升 2-3x 吞吐量。

6.3 Prefill/Decode 分离

将推理分为 Prefill(处理输入)和 Decode(生成输出)两个阶段,分别优化:

┌─────────────────────────────────────────────────────────────────────┐
│                   Prefill/Decode 分离架构                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌────────────────┐                    ┌────────────────┐         │
│   │  Prefill 节点   │                    │  Decode 节点   │         │
│   │  (计算密集型)   │                    │  (显存密集型)  │         │
│   │                │                    │                │         │
│   │  - 高算力 GPU   │     KV Cache      │  - 大显存 GPU   │         │
│   │  - A100 80GB   │ ─────────────────▶ │  - H100 80GB   │         │
│   │  - 批量 Prefill │                    │  - 低延迟 Decode│         │
│   └────────────────┘                    └────────────────┘         │
│                                                                     │
│   Prefill: 高吞吐处理输入,生成 KV Cache                            │
│   Decode: 低延迟生成输出,复用 KV Cache                              │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6.4 量化与精度优化

量化方法精度损失显存节省速度提升适用场景
FP16基准50%1.5x默认选择
FP8<1%75%2xH100 GPU
INT81-2%75%2-3x吞吐优先
INT4 (GPTQ)2-5%87.5%3-4x边缘部署
INT4 (AWQ)1-3%87.5%3-4x精度敏感
# vLLM 量化配置
llm = LLM(
    model="meta-llama/Llama-3-70b",
    quantization="awq",  # 或 "gptq", "fp8"
    load_format="awq"
)

七、监控与可观测性

7.1 关键指标

# Prometheus 指标采集
scrape_configs:
  - job_name: 'vllm'
    static_configs:
      - targets: ['vllm-service:8000']
    metrics_path: /metrics

核心监控指标:

指标含义告警阈值
vllm:num_requests_running正在处理的请求数> 0.8 * max_num_seqs
vllm:num_requests_waiting等待队列长度> 100
vllm:gpu_cache_usageGPU KV Cache 使用率> 0.9
vllm:time_to_first_token_secondsTTFT(首 token 延迟)P99 > 2s
vllm:time_per_output_token_secondsTPOT(每 token 延迟)P99 > 100ms
vllm:prefix_cache_hit_rate前缀缓存命中率< 0.3

7.2 Grafana Dashboard

{
  "dashboard": {
    "title": "LLM Inference Monitoring",
    "panels": [
      {
        "title": "Request Throughput",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(vllm:num_requests_finished[1m])"
          }
        ]
      },
      {
        "title": "TTFT P99",
        "type": "stat",
        "targets": [
          {
            "expr": "histogram_quantile(0.99, vllm:time_to_first_token_seconds_bucket)"
          }
        ]
      },
      {
        "title": "GPU Memory Usage",
        "type": "gauge",
        "targets": [
          {
            "expr": "vllm:gpu_cache_usage * 100"
          }
        ]
      }
    ]
  }
}

八、成本优化策略

8.1 弹性伸缩配置

# Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-server
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: vllm_num_requests_waiting
        target:
          type: AverageValue
          averageValue: "10"
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Pods
          value: 4
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 10
          periodSeconds: 120

8.2 Spot/Preemptible 实例利用

# 使用 Spot 实例降低成本
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              preference:
                matchExpressions:
                  - key: cloud.google.com/gke-preemptible
                    operator: In
                    values:
                      - "true"
      tolerations:
        - key: "cloud.google.com/gke-preemptible"
          operator: "Equal"
          value: "true"
          effect: "NoSchedule"

成本对比(以 4xA100 为例):

实例类型月成本可用性适用场景
On-Demand$15,00099.99%生产核心服务
Reserved (1年)$9,00099.99%稳定负载
Spot$3,000~90%批处理、离线推理

九、方案选型决策树

开始
  │
  ├─ 是否需要跨节点分布式?
  │   ├─ 否(单节点足够)
  │   │   └─ 推荐方案: vLLM 单机部署
  │   │       - 配置简单,开箱即用
  │   │       - 适合 QPS < 100 的场景
  │   │
  │   └─ 是(需要多节点)
  │       │
  │       ├─ 是否已有 Kubernetes 集群?
  │       │   ├─ 是
  │       │   │   │
  │       │   │   ├─ 需要高级调度(KV 感知、优先级)?
  │       │   │   │   ├─ 是 → llm-d + vLLM
  │       │   │   │   └─ 否 → vLLM Production Stack
  │       │   │   │
  │       │   │   └─ 需要多模型编排?
  │       │   │       ├─ 是 → Ray Serve + vLLM
  │       │   │       └─ 否 → KServe + vLLM
  │       │   │
  │       │   └─ 否(无 K8s)
  │       │       └─ 推荐方案: Ray Cluster (独立部署)
  │       │           - 无需 K8s 依赖
  │       │           - Ray 自带资源调度
  │
  └─ 是否需要结构化输出?
      ├─ 是 → SGLang(原生 JSON 约束)
      └─ 否 → vLLM(更成熟的生态)

十、总结与展望

10.1 核心要点回顾

  1. 分层架构:理解推理引擎(vLLM/SGLang)与编排层(llm-d/Ray Serve)的分工
  2. 内存优化:PagedAttention 和 RadixAttention 是提升吞吐的关键
  3. 智能调度:KV Cache 感知路由可大幅提升缓存命中率和降低延迟
  4. 弹性伸缩:Kubernetes HPA + Spot 实例实现成本优化
  5. 可观测性:TTFT、TPOT、KV 命中率是核心监控指标

10.2 未来趋势

  1. Prefill/Decode 分离成为标配:专业化的节点分工进一步优化延迟
  2. 多模态推理统一:图文音视频统一推理引擎
  3. 边缘-云协同:小模型边缘推理 + 大模型云端协作
  4. AI 编译器成熟:MLIR、TorchInductor 等进一步优化算子执行

分布式 LLM 推理是一个快速演进的领域,本文梳理的架构和方案代表了 2026 年的主流实践。随着技术迭代,新的优化技术将持续涌现,但核心思想——分层解耦、智能调度、资源优化——将长期有效。


参考资源:

复制全文 生成海报 LLM vLLM 分布式推理 Kubernetes Ray 推理引擎

推荐文章

Plyr.js 播放器介绍
2024-11-18 12:39:35 +0800 CST
2025年,小程序开发到底多少钱?
2025-01-20 10:59:05 +0800 CST
Go配置镜像源代理
2024-11-19 09:10:35 +0800 CST
nuxt.js服务端渲染框架
2024-11-17 18:20:42 +0800 CST
PHP 微信红包算法
2024-11-17 22:45:34 +0800 CST
如何在Rust中使用UUID?
2024-11-19 06:10:59 +0800 CST
Roop是一款免费开源的AI换脸工具
2024-11-19 08:31:01 +0800 CST
Nginx 状态监控与日志分析
2024-11-19 09:36:18 +0800 CST
网络数据抓取神器 Pipet
2024-11-19 05:43:20 +0800 CST
网站日志分析脚本
2024-11-19 03:48:35 +0800 CST
浅谈CSRF攻击
2024-11-18 09:45:14 +0800 CST
阿里云发送短信php
2025-06-16 20:36:07 +0800 CST
Vue3中如何进行错误处理?
2024-11-18 05:17:47 +0800 CST
JavaScript中设置器和获取器
2024-11-17 19:54:27 +0800 CST
Vue中的表单处理有哪几种方式?
2024-11-18 01:32:42 +0800 CST
程序员茄子在线接单