推理评估
推理机制
- 推理方式:语言模型生成文本时(Decode 阶段),是逐个 token 生成的,无法并行。
- 生成过程建模:一般采用 KV Cache。
- 瓶颈分析:需要对每个 key 执行一次乘加运算,对每个 value 执行一次乘加运算。而 ALU 的速度要比访问内存快得多。
推理时延
总数据量
以 Mistral-7B 为例,约 7111M 参数,32 层,GQA(32 头分为 8 组,每头维度 128)。采用 FP16 精度,每生成一个 token 需加载的数据量为 14.2GB。
虽然计算下一个 token 时的参数可以复用,但硬件缓存通常只有几十 MB,参数无法放入缓存,因此生成过程的速度不会快于显存带宽。
Attention 计算需要读取当前 token 及所有前文 token 对应的 KV Cache,读取量取决于:
- 系统提示词(通常对用户隐藏)
- 用户提示词
- 前面的模型输出
- 长聊天会话中多个用户的提示词
KV Cache 数据量
对于 Mistral-7B,每层的每个 key 存储 8 个 128 元素向量,每个 value 同理。每个 token 对应
推理时延估算
以 NVIDIA RTX 4090(1008 GB/s)为例,14.2GB 的参数需要约 14.1ms 读取。这是理论下限,代表生成每个 token 的最小可能时间。
分析理论下限的意义:
- 若实际时延与理论时延差异较大,需检查代码和硬件配置。
- 推理过程未充分利用 ALU 算力,可通过数据并行、异步通信与计算重叠等方式优化。
- 带宽与权重量化的 bit 数成正比,低延迟场景可考虑更激进的量化。
压测
大模型压测是对 LLM 及其服务系统进行的压力测试,核心目的是评估系统在接近或超过设计负载极限时的性能、稳定性和资源利用情况。
为什么要做压测:
- 确保服务质量:模拟高并发请求,监控响应时间、吞吐量和错误率,避免线上故障。
- 发现性能瓶颈:精准定位延迟、资源耗尽等"最弱一环"。
- 容量规划:确定系统最大承载能力,制定 SLA 和预案。
- 成本优化:基于真实负载数据选择合理的实例类型和伸缩策略。
- 验证优化效果:对比架构调整前后的指标变化。
关键指标
| 类别 | 指标 | 说明 |
|---|---|---|
| 性能 | 平均延迟 | 从请求到响应的平均时间 |
| 性能 | P90/P95/P99 延迟 | 尾部延迟,评估极端情况 |
| 性能 | QPS/TPS | 单位时间处理的请求数 |
| 稳定性 | 错误率 | 超时、异常或错误码比例 |
| 稳定性 | 长时间稳定性 | 持续高压下观察性能漂移 |
| 资源 | CPU/GPU 使用率 | 计算资源占用率 |
| 资源 | 内存/显存使用率 | 防止 OOM,辅助动态批处理 |
| 扩展性 | 水平扩展性能 | 增加实例后吞吐量提升比例 |
性能指标详细解释
延迟指标
平均延迟(Average Latency):所有请求的端到端响应时间的算术平均值。
其中
P90/P95/P99 延迟(Percentile Latency):表示 90%/95%/99% 的请求延迟低于该值。
尾部延迟比平均延迟更能反映用户体验,因为少量高延迟请求会影响大量用户。
吞吐量指标
QPS(Queries Per Second):每秒处理的请求数。
TPS(Tokens Per Second):每秒生成的 token 数。
TTFT(Time to First Token):从请求发送到收到第一个 token 的时间,反映首 token 延迟。
TPOT(Time per Output Token):生成每个 token 的平均时间,反映生成速度。
稳定性指标
错误率:失败请求占总请求的比例。
长时间稳定性:在持续高压下观察性能指标的变化趋势,如延迟是否逐渐增加、吞吐量是否下降等。
资源指标
GPU 使用率:GPU 核心的活跃时间占比。
显存使用率:已使用显存占总显存的比例。
显存带宽利用率:实际显存带宽占理论最大带宽的比例。
性能瓶颈分析方法
分析框架
性能瓶颈分析应遵循以下步骤:
- 识别症状:确定是延迟高、吞吐量低,还是两者兼有
- 定位阶段:判断瓶颈发生在 Prefill 阶段还是 Decode 阶段
- 分析资源:检查是计算资源、内存资源,还是带宽资源不足
- 确定根因:根据资源分析确定根本原因
- 制定方案:针对性地制定优化方案
Prefill 阶段瓶颈
症状:TTFT 高,TPOT 正常。
可能原因:
- 自注意力计算复杂度过高(
) - GPU 计算资源不足
- 批次大小过大导致排队
分析方法:
- 监控 GPU 利用率,如果接近 100%,说明是计算瓶颈
- 检查输入序列长度,长序列会显著增加 Prefill 时间
- 分析批次组成,混合长短序列会影响整体性能
优化方案:
- 启用 FlashAttention 优化计算
- 使用张量并行跨多个 GPU
- 采用 Chunked Prefill 分块处理长序列
- 优化调度策略,避免长序列阻塞短序列
Decode 阶段瓶颈
症状:TPOT 高,TTFT 正常。
可能原因:
- 显存带宽不足
- KV Cache 访问效率低
- 批次大小过大导致显存压力
分析方法:
- 监控显存带宽利用率,如果接近理论值,说明是带宽瓶颈
- 检查 KV Cache 大小,长序列或大批次会增加访问量
- 分析批次组成,不同请求的输出长度差异会影响性能
优化方案:
- 使用 GQA 减少 KV Cache 大小
- 启用 PagedAttention 优化内存管理
- 使用量化降低参数读取量
- 采用投机解码加速生成
显存不足(OOM)
症状:请求失败,返回 OOM 错误。
可能原因:
- 模型参数占用显存过大
- KV Cache 显存不足
- 批次大小超过显存容量
分析方法:
- 检查模型参数大小和显存占用
- 监控 KV Cache 的使用情况
- 分析批次大小和序列长度分布
优化方案:
- 使用量化减小模型参数大小
- 增大
gpu-memory-utilization参数 - 降低
max-num-batched-tokens和max-num-seqs - 启用 KV Cache 压缩技术
并发不足
症状:吞吐量低,但单请求延迟正常。
可能原因:
- 批次大小设置过小
- 调度策略不够激进
- 资源碎片化导致无法充分利用
分析方法:
- 监控批次大小变化,如果经常远低于上限,说明调度不够激进
- 检查显存碎片化情况
- 分析请求队列长度和等待时间
优化方案:
- 增大
max-num-batched-tokens和max-num-seqs - 启用 Continuous Batching 动态调整批次
- 使用 PagedAttention 减少显存碎片
- 优化调度策略,提升资源利用率
优化建议
架构优化
选择合适的模型架构:
- 使用 GQA 模型减少 KV Cache 显存
- 选择合适的模型大小,平衡精度和性能
- 考虑使用 MoE 架构提升计算效率
优化推理框架:
- 使用 vLLM 等高效推理框架
- 启用 PagedAttention 优化内存管理
- 启用 Continuous Batching 提升吞吐量
硬件选型:
- 根据场景选择合适的 GPU 类型
- 考虑显存带宽而非仅算力
- 多卡部署时优化通信拓扑
参数调优
批次大小:
- 增大
max-num-batched-tokens提升吞吐量 - 增大
max-num-seqs提升并发数 - 根据显存和延迟要求动态调整
- 增大
序列长度:
- 限制最大输入长度避免长序列阻塞
- 根据业务需求设置合理的输出长度上限
- 启用前缀缓存复用公共前缀
量化配置:
- 根据精度要求选择合适的量化格式
- 测试量化后的精度损失
- 考虑混合精度策略
监控告警
关键指标监控:
- 延迟指标:TTFT、TPOT、P90/P99 延迟
- 吞吐量指标:QPS、TPS
- 资源指标:GPU 利用率、显存使用率、显存带宽利用率
告警阈值设置:
- 延迟告警:TTFT > 阈值,TPOT > 阈值
- 资源告警:显存使用率 > 90%,GPU 利用率 > 95%
- 错误告警:错误率 > 1%
容量规划:
- 根据监控数据预测资源需求
- 提前扩容避免服务降级
- 优化资源配置降低成本
压测工具
以 EvalScope 为例,使用 vLLM 在 A100 上压测 Qwen2.5-0.5B-Instruct(输入/输出各 1024 token):
pip install evalscope[perf] -Ufrom evalscope.perf.main import run_perf_benchmark
from evalscope.perf.arguments import Arguments
task_cfg = Arguments(
parallel=[1, 10, 50, 100, 200],
number=[10, 20, 100, 200, 400],
model='Qwen2.5-0.5B-Instruct',
url='http://127.0.0.1:8801/v1/chat/completions',
api='openai',
dataset='openqa',
)
results = run_perf_benchmark(task_cfg)压测流程
环境准备:
- 确保 vLLM 服务正常运行
- 检查 GPU 资源和网络连接
- 准备测试数据集
基准测试:
- 单请求延迟测试,建立性能基线
- 逐步增加并发数,观察性能变化
- 记录不同并发下的性能指标
压力测试:
- 达到设计负载上限
- 持续运行一段时间观察稳定性
- 监控资源使用和错误率
结果分析:
- 分析性能指标变化趋势
- 识别性能瓶颈和优化点
- 制定优化方案
压测结果解读
| 并发数 | QPS | 平均延迟(ms) | P99延迟(ms) | GPU使用率 | 显存使用率 |
|---|---|---|---|---|---|
| 1 | 10 | 100 | 120 | 30% | 40% |
| 10 | 95 | 105 | 150 | 85% | 70% |
| 50 | 400 | 125 | 200 | 95% | 85% |
| 100 | 450 | 222 | 350 | 98% | 92% |
| 200 | 420 | 476 | 800 | 99% | 95% |
解读:
- 并发 1-50:性能随并发数线性增长,资源利用率逐步提升
- 并发 50-100:吞吐量增长放缓,延迟明显增加,接近系统极限
- 并发 100-200:吞吐量下降,延迟急剧增加,系统过载
结论:系统最佳并发数为 50-100,超过 100 后性能下降,建议设置并发上限为 100。