大模型推理服务架构设计:从 0 到 1 构建生产级 AI 服务

AI Infra架构设计系统设计高并发

当你的 AI 应用从 Demo 走向生产,如何构建一个高可用、高性能、低成本的推理服务?

典型推理服务架构

                          ┌─────────────────┐
                          │   Load Balancer │
                          │   (Nginx/LB)    │
                          └────────┬────────┘

              ┌────────────────────┼────────────────────┐
              │                    │                    │
     ┌────────▼────────┐  ┌────────▼────────┐  ┌────────▼────────┐
     │   API Gateway   │  │   API Gateway   │  │   API Gateway   │
     │   (认证/限流)   │  │                 │  │                 │
     └────────┬────────┘  └────────┬────────┘  └────────┬────────┘
              │                    │                    │
              └────────────────────┼────────────────────┘

                          ┌────────▼────────┐
                          │  Router/Queue   │
                          │  (请求分发)     │
                          └────────┬────────┘

        ┌──────────────────────────┼──────────────────────────┐
        │                          │                          │
┌───────▼───────┐          ┌───────▼───────┐          ┌───────▼───────┐
│  Inference    │          │  Inference    │          │  Inference    │
│  (vLLM)       │          │  (vLLM)       │          │  (SGLang)     │
│  - LLaMA      │          │  - Qwen       │          │  - ChatGLM    │
└───────────────┘          └───────────────┘          └───────────────┘
        │                          │                          │
        └──────────────────────────┼──────────────────────────┘

                          ┌────────▼────────┐
                          │   Cache Layer   │
                          │  (Redis/KV)     │
                          └─────────────────┘

核心组件

1. API Gateway

负责认证、限流、日志:

# 简化版 API Gateway
from fastapi import FastAPI, HTTPException
from fastapi_limiter import Limiter
from fastapi_limiter.dependencies import RateLimitDependencies

app = FastAPI()
limiter = Limiter(app, key_func=get_remote_address)

@app.post("/v1/chat/completions")
@limiter.limit("10/minute")  # 限流
async def chat_completions(request: Request):
    # 1. 验证 API Key
    api_key = request.headers.get("Authorization")
    if not validate_key(api_key):
        raise HTTPException(401, "Invalid API Key")
    
    # 2. 限流检查
    if not await check_rate_limit(api_key):
        raise HTTPException(429, "Rate limit exceeded")
    
    # 3. 转发到推理服务
    return await forward_to_inference(request)

2. 请求路由

根据模型类型、负载情况分发请求:

class Router:
    def __init__(self):
        self.models = {
            "llama": "http://llama-inference:8000",
            "qwen": "http://qwen-inference:8000",
            "chatglm": "http://chatglm-inference:8000",
        }
    
    async def route(self, request):
        model = request.json()["model"]
        
        # 根据模型选择后端
        backend = self.models.get(model)
        if not backend:
            raise ValueError(f"Unknown model: {model}")
        
        # 健康检查 + 负载选择
        target = await self.select_backend(backend)
        
        return await self.forward(request, target)
    
    async def select_backend(self, backend_url):
        # 简单的健康检查 + 负载选择
        # 实际可用服务发现(Consul/K8s)
        pass

3. 推理服务

使用 vLLM 部署:

# 启动多个推理实例
docker run -d --name llama-inference \
    -p 8001:8000 \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    vllm/vllm-openai:latest \
    --model meta-llama/Llama-2-7b-hf \
    --tensor-parallel-size 1

docker run -d --name qwen-inference \
    -p 8002:8000 \
    vllm/vllm-openai:latest \
    --model Qwen/Qwen-7B-Chat \
    --tensor-parallel-size 1

缓存策略

1. KV Cache 复用

相同前缀的请求共享 KV Cache:

# vLLM 内置前缀缓存
# SGLang RadixAttention 自动处理

2. 响应缓存

对相同请求缓存响应:

import redis
from hashlib import sha256

cache = redis.Redis(host='redis', port=6379)

async def chat(request):
    # 生成缓存 key
    cache_key = sha256(json.dumps(request.json())).hexdigest()
    
    # 尝试命中缓存
    cached = cache.get(cache_key)
    if cached:
        return json.loads(cached)
    
    # 推理
    result = await inference(request)
    
    # 写入缓存(TTL=1小时)
    cache.setex(cache_key, 3600, json.dumps(result))
    
    return result

高可用设计

1. 健康检查

# Kubernetes deployment
livenessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 10
  periodSeconds: 5

2. 自动扩缩容

# HPA (Horizontal Pod Autoscaler)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

3. 多地域部署

┌─────────────────────────────────────────────────┐
│                   Global LB                     │
│                   (Cloudflare)                  │
└───────────┬─────────────────┬───────────────────┘
            │                 │
    ┌───────▼───────┐   ┌───────▼───────┐
    │  Asia Region  │   │  US Region    │
    │  - 3AZ        │   │  - 3AZ        │
    └───────────────┘   └───────────────┘

成本优化

1. 模型选择

场景推荐模型成本
简单问答7B
中等复杂度13B
复杂推理70B

2. 量化部署

# INT4 量化,显存减少 70%
lmdeploy lite quantize model --w-bit 4 --q-bit 4

3. 夜间缩容

# 根据时段调整实例数
import croniter

def adjust_replicas():
    hour = datetime.now().hour
    
    # 夜间低峰缩减
    if 0 <= hour < 8:
        target_replicas = 1
    # 白天高峰扩容
    else:
        target_replicas = 5
    
    scale_deployment(target_replicas)

监控指标

关键指标

指标说明告警阈值
QPS每秒请求数>1000
P99 Latency99分位延迟>5s
Error Rate错误率>1%
GPU UtilGPU 利用率<30%
Memory显存使用>90%

监控面板

# Prometheus + Grafana 配置
- job_name: 'vllm'
  static_configs:
    - targets: ['inference:8000']
      labels:
        service: 'llama-inference'

总结

生产级推理服务关键点:

  1. Gateway 层:认证、限流、路由
  2. 推理层:多模型、高可用、自动扩缩
  3. 缓存层:KV 复用、响应缓存
  4. 基础设施:K8s、多 AZ、监控告警

合理的架构设计可以让你以最低的成本支撑最大的流量!


下期预告:GPU 显存优化与 KV Cache 管理