模型服务

返回工程实践

将训练好的模型部署为可调用的 API 服务,是 MLOps 的核心环节。服务化需要考虑延迟、吞吐、成本、可用性和版本管理的综合权衡。


服务架构模式

同步推理(Request-Response)

客户端 → HTTP POST /predict → 模型服务 → 返回结果
  • 适合:实时查询、低延迟需求(<500ms)
  • 问题:高并发时容易成为瓶颈

异步推理(队列模式)

客户端 → 发布到消息队列 → Worker 消费 → 结果写回 → 客户端轮询/回调
  • 适合:批量处理、允许延迟的场景
  • 优势:解耦生产者/消费者,Worker 可弹性扩缩

批推理(Batch Inference)

调度器 → 触发批任务 → 模型读取数据集 → 批量预测 → 结果写入存储
  • 适合:离线分析、定期评分
  • 工具:Spark、Ray、SageMaker Batch Transform

主流推理框架

框架特点适用场景
vLLMPagedAttention,高吞吐,LLM 专用开源 LLM 生产部署
TGI(Text Generation Inference)HuggingFace 出品,支持流式HF 模型快速部署
Triton Inference ServerNVIDIA,多框架,GPU 优化企业级,多模型管理
TorchServePyTorch 官方,灵活PyTorch 模型
ONNX Runtime跨框架,CPU 友好边缘/CPU 部署
Ollama本地运行 LLM,开箱即用开发调试

vLLM 部署示例

# 启动 vLLM 服务
# python -m vllm.entrypoints.openai.api_server \
#     --model meta-llama/Llama-3-8B-Instruct \
#     --tensor-parallel-size 2 \
#     --max-model-len 8192 \
#     --gpu-memory-utilization 0.9
 
# 调用(兼容 OpenAI SDK)
from openai import OpenAI
 
client = OpenAI(base_url="http://localhost:8000/v1", api_key="ignored")
response = client.chat.completions.create(
    model="meta-llama/Llama-3-8B-Instruct",
    messages=[{"role": "user", "content": "你好"}],
    stream=True,
)
for chunk in response:
    print(chunk.choices[0].delta.content or "", end="")

性能优化技术

技术原理收益
连续批处理(Continuous Batching)动态将多个请求合并推理吞吐提升 3-10x
KV Cache缓存注意力的 K/V 矩阵,避免重算减少重复计算
PagedAttention非连续内存管理 KV Cache,减少碎片显存利用率 +40%
投机采样(Speculative Decoding)小模型起草 + 大模型验证延迟降低 2-3x
量化推理INT4/INT8 权重显存减半,速度提升
张量并行大模型切分到多 GPU支持超过单卡显存的模型

接口设计

from fastapi import FastAPI
from pydantic import BaseModel
 
app = FastAPI()
 
class PredictRequest(BaseModel):
    text: str
    model_version: str = "v1"
    temperature: float = 0.7
 
class PredictResponse(BaseModel):
    prediction: str
    confidence: float
    latency_ms: float
    model_version: str
 
@app.post("/predict", response_model=PredictResponse)
async def predict(req: PredictRequest):
    start = time.time()
    result = model.inference(req.text, temperature=req.temperature)
    return PredictResponse(
        prediction=result.text,
        confidence=result.score,
        latency_ms=(time.time() - start) * 1000,
        model_version=req.model_version,
    )
 
@app.get("/health")
async def health():
    return {"status": "ok", "model_loaded": model is not None}

容器化与 K8s 部署

# k8s Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: model-serving
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: inference
        image: myrepo/model-server:v1.2
        resources:
          limits:
            nvidia.com/gpu: 1
            memory: "16Gi"
          requests:
            cpu: "4"
            memory: "8Gi"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 60
        readinessProbe:
          httpGet:
            path: /health
            port: 8080

SLA 与监控关键指标

指标目标值(参考)说明
P50 延迟< 200ms中位响应时间
P99 延迟< 1s99% 请求响应时间
首 Token 延迟(TTFT)< 500msLLM 流式关键指标
吞吐(RPS/TPS)按业务定每秒请求/token 数
错误率< 0.1%5xx 比例
GPU 利用率> 70%低于此值说明资源浪费

相关文档