第17章 §03 · 服务与批处理 · 讲解稿¶
承接: Ch17 §02 架构 → §03 服务部署 篇幅: ~4000 字
一 · 一句话总览¶
LLM 服务 = 把模型变成可靠 API。vLLM / SGLang / TensorRT-LLM / TGI 4 大引擎, PagedAttention + 连续批处理 让吞吐量提升 10-24×。
二 · 服务引擎 4 大家族¶
2.1 vLLM (UC Berkeley)¶
核心: PagedAttention (类 OS 虚拟内存)
from vllm import LLM, SamplingParams
llm = LLM(
model="meta-llama/Llama-3-70B-Instruct",
tensor_parallel_size=4,
gpu_memory_utilization=0.9,
quantization="awq",
max_model_len=8192,
)
prompts = ["Hello, my name is", "The future of AI is"]
outputs = llm.generate(prompts, SamplingParams(temperature=0.7, max_tokens=100))
特性: - PagedAttention: KV 分块, 解决碎片 - 连续批处理: 每步加入新请求 - CUDA Graph: 减少 kernel launch 开销
2.2 SGLang (Stanford)¶
核心: RadixAttention + DSL (前端语言)
import sglang as sgl
@sgl.function
def multi_turn(s, user_q):
s += sgl.system("You are a helpful assistant.")
s += sgl.user(user_q)
s += sgl.assistant(sgl.gen("answer", max_tokens=100))
runtime = sgl.Runtime(model="meta-llama/Llama-3-8B")
state = multi_turn.run(user_q="What is AI?", runtime=runtime)
print(state["answer"])
优势: 前端 DSL 让复杂 prompt 编程简单, RadixAttention 让 prefix 共享。
2.3 TensorRT-LLM (NVIDIA)¶
特性: - 极致性能: NVIDIA 官方, 完整 GPU 利用 - In-flight batching / Continuous batching - FP8 / INT4 量化
from tensorrt_llm import LLM
llm = LLM(model="meta-llama/Llama-3-8B")
outputs = llm.generate(["Hello"])
2.4 TGI (HuggingFace)¶
特性: 易部署, Rust 写, 支持多模型。
2.5 LMDeploy (上海AI Lab)¶
特性: 中文 LLM 优化, 高吞吐。
三 · 连续批处理 (Continuous Batching)¶
3.1 传统批处理¶
3.2 连续批处理¶
3.3 性能对比¶
| 引擎 | 静态批处理 | 连续批处理 |
|---|---|---|
| vLLM | 1× | 24× |
| SGLang | 1× | 20× |
| TGI | 1× | 15× |
| TensorRT-LLM | 1× | 20× |
四 · Speculative Decoding¶
4.1 核心思想¶
小模型草拟 + 大模型并行验证
草拟: [t1, t2, t3, t4, t5] (小模型, 1 ms)
验证: 1 次 forward 算 5 个位置概率 (大模型, 2 ms)
接受率 70%: 平均接受 3.5 个, 节省 60% 时间
4.2 主流方案¶
| 方案 | 草拟模型 | 适用 |
|---|---|---|
| Self-Speculative | 模型本身 (退出层) | 通用 |
| Draft Model | 独立小模型 | 7B/70B 配 1B |
| Medusa | 多头并行预测 | Llama 专属 |
| EAGLE | 特征层预测 | SOTA 2024 |
4.3 Medusa 示例¶
from medusa import MedusaModel
model = MedusaModel.from_pretrained(
"FasterDecoding/medusa-1.0-vicuna-7b-v1.5",
base_model="lmsys/vicuna-7b-v1.5",
)
output = model.generate("Hello", max_tokens=100)
五 · Prompt Caching¶
5.1 原理¶
缓存相同前缀的 KV: - System prompt 10K+ token 时, 节省 80% 成本 - Anthropic / OpenAI 均支持
5.2 Anthropic Prompt Caching¶
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system=[
{
"type": "text",
"text": "你是专业的代码助手...",
"cache_control": {"type": "ephemeral"} # 缓存标记
}
],
messages=[{"role": "user", "content": "写一个 Hello World"}]
)
5.3 5 大缓存策略¶
- Prefix cache: 相同前缀复用
- Semantic cache: 相似 query 复用
- KV cache: 完整 KV 存储
- CDN: 模型 + 响应全局缓存
- Browser cache: 客户端 (WebLLM)
六 · 调度策略¶
6.1 FCFS vs Priority¶
- FCFS: 简单, 不公平 (长 prompt 拖慢)
- Priority: 用户分等级 (付费 > 免费)
- Fair: 保证 SLA
6.2 Prefill vs Decode 分离¶
- Prefill: 长 prompt 一次性 forward (慢, 大 batch 友好)
- Decode: 逐 token 生成 (latency-bound)
DistServe (NSDI 2024): 分离 Prefill + Decode 到不同 GPU, 互不干扰。
6.3 SLO-aware 调度¶
- P99 latency 目标
- 动态 batching + priority queue
- Kubernetes + 自定义调度器
七 · 监控与可观测性¶
7.1 关键指标¶
| 指标 | 含义 | 目标 |
|---|---|---|
| TTFT | Time To First Token | < 500 ms |
| TPOT | Time Per Output Token | < 50 ms |
| Throughput | tokens/s/GPU | 越高越好 |
| GPU Util | GPU 利用率 | > 70% |
| Queue Length | 等待请求数 | < 100 |
7.2 工具¶
- Prometheus + Grafana: 通用
- vLLM metrics: 内置
- Langfuse: LLM 专属 (含 trace)
- Phoenix (Arize): Eval + Trace
- Helicone: API 网关层
八 · 一句话总结¶
LLM 服务 = 引擎 + 批处理 + Speculative + Cache + 调度 + 监控。vLLM / SGLang 是工业首选, 连续批处理 + Speculative Decoding + Prompt Caching 三件套让 LLM 服务吞吐 + 延迟双优。