LLM推理服务架构设计¶
面试频率:字节/阿里/百度AI Infra方向必考题 核心考点:高并发、低延迟、成本优化的LLM推理系统
1. LLM推理的特殊性¶
与传统模型推理(BERT/ResNet毫秒级)不同,LLM推理有独特挑战:
| 特性 | 传统模型推理 | LLM推理 |
|---|---|---|
| 延迟 | 1-50ms | 2-30s |
| 模式 | 单次前向传播 | 自回归逐Token生成 |
| 显存 | GB级 | 十GB到百GB |
| 输出 | 固定大小 | 变长(几个Token到几千Token) |
| 批处理 | 固定Batch | 动态Batch(请求到达时间/长度各异) |
2. 完整推理服务架构¶
Text Only
┌─────────────────── 接入层 ───────────────────┐
│ 客户端 → CDN(静态) → LB(Nginx/ALB) │
│ → API Gateway: │
│ - 认证/鉴权(API Key + Rate Limit) │
│ - 请求验证(Token长度/内容安全) │
│ - 路由策略(模型选择/区域) │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────── 调度层 ───────────────────┐
│ 请求队列(Redis Stream / Kafka): │
│ - 优先级队列(VIP用户/普通用户) │
│ - 长度分桶(短请求→快队列, 长请求→慢队列) │
│ - 背压控制(队列满时拒绝/降级) │
│ │
│ 智能路由器: │
│ - 简单Query → 7B模型(高并发池) │
│ - 复杂推理 → 70B模型(高质量池) │
│ - 代码生成 → 代码专用模型 │
│ - 多模态 → VLM模型池 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────── 推理层 ───────────────────┐
│ vLLM / TensorRT-LLM / SGLang 集群: │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 7B Pool │ │ 70B Pool │ │ VLM Pool │ │
│ │ 16×A10G │ │ 8×A100 │ │ 4×A100 │ │
│ │ INT4量化 │ │ FP8量化 │ │ FP16 │ │
│ │ 并发200+ │ │ 并发40 │ │ 并发20 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 关键优化: │
│ - PagedAttention(显存碎片化解决) │
│ - Continuous Batching(动态批处理) │
│ - Prefix Caching(系统Prompt缓存) │
│ - Speculative Decoding(投机解码加速) │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────── 输出层 ───────────────────┐
│ SSE流式响应 → 安全过滤 → Token计量 → 客户端 │
└──────────────────────────────────────────────┘
┌─────────────────── 运维层 ───────────────────┐
│ 监控: Prometheus(QPS/延迟/GPU利用率) + Grafana │
│ 扩缩: K8s HPA(基于GPU利用率+队列长度) │
│ 模型: 热加载/灰度发布/A/B测试 │
└──────────────────────────────────────────────┘
3. 核心优化技术(面试必考)¶
3.1 PagedAttention¶
传统KV Cache:为每个请求预分配最大长度的连续显存 → 严重浪费
Text Only
传统方案(预分配):
请求A(实际200 Token, 预分配2048): [████░░░░░░░░░░░░░░░░] 90%浪费
请求B(实际500 Token, 预分配2048): [██████████░░░░░░░░░░] 75%浪费
→ 显存利用率低,并发数受限
PagedAttention(按需分页):
请求A: [Page1][Page2][Page3]...(按需分配,用完释放)
请求B: [Page1][Page2][Page3][Page4][Page5]...
→ 显存利用率从30%→90%,并发提升2-4倍
3.2 Continuous Batching¶
传统Static Batching:一个Batch内所有请求等最长的完成才能释放
Text Only
Static Batching:
时间 → ────────────────────────────→
请求A: [████████████████████████████] (长请求)
请求B: [████████] (短请求,但等A完成才释放)
请求C: [████████████] (中请求,同上)
→ 短请求延迟被长请求拖累,GPU利用率低
Continuous Batching:
时间 → ────────────────────────────→
请求A: [████████████████████████████]
请求B: [████████]→释放→[请求D填入]
请求C: [████████████]→释放→[请求E填入]
→ 空出的位置立即被新请求填入,GPU始终满载
3.3 KV Cache量化与压缩¶
Text Only
KV Cache显存占用公式:
KV_size = 2 × num_layers × num_heads × head_dim × seq_len × batch_size × precision_bytes
7B模型, 32层, 32头, 128维, 4096 seq_len, batch=100:
FP16: 2 × 32 × 32 × 128 × 4096 × 100 × 2B ≈ 214GB ← 远超单卡显存!
优化:
1. KV Cache FP8量化: 显存减半,精度损失极小
2. GQA(Grouped Query Attention): KV头数远少于Q头数(如8 KV对32 Q)
3. 滑动窗口注意力: 限制KV长度(如4096),超出部分丢弃/汇总
4. Prefix Caching: 相同System Prompt的KV Cache复用
3.4 投机解码(Speculative Decoding)¶
Text Only
标准自回归: 大模型逐Token生成,每步都走完整前向传播
Token 1 → Token 2 → Token 3 → ... → Token N
延迟 = N × 大模型单步延迟
投机解码:
小模型(1B)快速草拟K个Token → 大模型(70B)并行验证K个Token
→ 接受正确的前j个 → 从第j+1个重新生成
加速原理: 大模型验证K个Token的成本 ≈ 生成1个Token(并行化)
平均加速: 2-3倍(取决于小模型与大模型的一致率)
适用: 大小模型能力差距大的场景(如70B做主模型, 1B做草稿模型)
4. 性能估算(面试必做)¶
题目:设计一个日调用1亿次的LLM推理服务,平均输入500 Token,输出200 Token。
Text Only
容量估算:
日调用量: 1亿
平均QPS: 1亿 / 86400 ≈ 1157 QPS
峰值QPS: 1157 × 3 ≈ 3500 QPS
延迟目标:
TTFT(首Token): < 1s (P99)
TPS(生成速度): > 30 Token/s
总延迟: TTFT + 200/30 ≈ 7.7s (P50)
GPU需求估算(以A100 80GB为例):
单卡7B模型(INT4): 吞吐约500 Token/s(批处理)
每请求200 Token输出 → 单卡约2.5 QPS(独占)
但Continuous Batching下, 单卡可并发50+请求 → 有效QPS约50-80
3500 QPS ÷ 60 QPS/卡 ≈ 60张A100
+ 冗余50%(故障/扩缩/排队) → 约90张A100
+ 如果用70B模型(单请求需4卡) → 需求量级更大
成本月估算:
90 × A100云实例 × ¥40/小时 × 720小时 ≈ ¥260万/月
优化:
- 70%请求路由到7B模型(INT4, 成本1/10) → 节省50%+
- Prefix Caching节省20% GPU时间
- 低峰期缩容 → 节省30%
→ 优化后约¥80万/月
5. 面试高频追问¶
Q: 如何实现LLM推理服务的灰度发布?
Text Only
方案: 流量分桶 + 影子模式
1. 影子模式(零风险验证):
新模型部署后,接收与生产相同的请求
但结果不返回给用户,只做日志对比
→ 对比新旧模型的质量/延迟/成本
2. 灰度分流:
5% → 10% → 30% → 100% 逐步放量
关键指标(回答质量/延迟/用户反馈)任何一项恶化则自动回滚
3. A/B测试:
用固定的用户分桶(哈希用户ID)保证同一用户体验一致
统计显著性达标后做决策
Q: 如何处理长尾请求(超长输入/输出)?
Q: GPU机器挂了怎么办?
Text Only
高可用设计:
1. 健康检查: 每30s探测GPU状态 + 推理延迟
2. 自动摘除: 异常实例从负载均衡器摘除
3. 请求重试: 失败请求自动路由到健康实例(幂等性保证)
4. K8s自愈: Pod失败自动重启/重新调度
5. 多AZ部署: GPU实例分布在多个可用区
Q: 如何降低推理成本?
Text Only
成本优化金字塔(从高到低效果):
1. 模型路由(节省50-70%): 简单→小模型, 复杂→大模型
2. 量化(节省50-75%): FP16→INT8→INT4, 质量损失评估
3. KV Cache优化(节省20-30%): PagedAttention + Prefix Caching
4. 批处理优化(节省20-40%): Continuous Batching最大化GPU利用率
5. 弹性扩缩(节省20-30%): 低峰缩容, Spot实例混合
6. Prompt压缩(节省10-20%): 压缩系统Prompt, 减少输入Token
最后更新:2026年2月