性能与调优#
抢占#
由于transformer架构的自回归特性,有时KV缓存空间不足以处理所有批处理请求。vLLM可以抢占请求以释放KV缓存空间给其他请求。被抢占的请求在有足够的KV缓存空间时会重新计算。当这种情况发生时,会打印以下警告:
` WARNING 05-09 00:49:33 scheduler.py:1057] 序列组 0 被 PreemptionMode.SWAP 模式抢占,因为 KV 缓存空间不足。这可能会影响端到端性能。增加 gpu_memory_utilization 或 tensor_parallel_size 以提供更多 KV 缓存内存。total_cumulative_preemption_cnt=1 `
虽然这种机制确保了系统的健壮性,但抢占和重新计算可能会对端到端延迟产生不利影响。如果你经常遇到来自vLLM引擎的抢占,请考虑以下措施:
增加 gpu_memory_utilization。vLLM 通过使用 gpu_memory_utilization% 的内存来预分配 GPU 缓存。通过增加这个利用率,您可以提供更多的 KV 缓存空间。
减少 max_num_seqs 或 max_num_batched_tokens。这可以减少批次中的并发请求数量,从而需要更少的 KV 缓存空间。
增加 tensor_parallel_size。这种方法将模型权重分片,因此每个GPU都有更多的内存可用于KV缓存。
你还可以通过 vLLM 暴露的 Prometheus 指标来监控抢占请求的数量。此外,你可以通过设置 disable_log_stats=False 来记录抢占请求的累计数量。
分块预填充#
vLLM 支持一个实验性功能:分块预填充(chunked prefill)。分块预填充允许将大型预填充分成较小的块,并将它们与解码请求一起批处理。
您可以通过在命令行中指定 --enable-chunked-prefill
或在 LLM 构造函数中设置 enable_chunked_prefill=True
来启用该功能。
llm = LLM(model="meta-llama/Llama-2-7b-hf", enable_chunked_prefill=True)
# Set max_num_batched_tokens to tune performance.
# NOTE: 512 is the default max_num_batched_tokens for chunked prefill.
# llm = LLM(model="meta-llama/Llama-2-7b-hf", enable_chunked_prefill=True, max_num_batched_tokens=512)
默认情况下,vLLM 调度器优先处理预填充,并且不会将预填充和解码批处理到同一个批次中。这种策略优化了 TTFT(首次令牌时间),但会导致 ITL(令牌间延迟)较慢和 GPU 利用率低下。
一旦启用了分块预填充,策略将更改为优先处理解码请求。它将所有待处理的解码请求批处理到批处理之前,然后再安排任何预填充。当有可用的token_budget(max_num_batched_tokens
)时,它会安排待处理的预填充。如果最后一个待处理的预填充请求无法适应``max_num_batched_tokens``,则将其分块。
这项政策有两个好处:
它提高了ITL和生成解码,因为解码请求被优先处理。
它通过将计算受限(预填充)和内存受限(解码)的请求定位到同一个批次中,从而帮助实现更好的GPU利用率。
你可以通过更改 max_num_batched_tokens
来调整性能。默认情况下,它设置为 512,这在初始基准测试(llama 70B 和 mixtral 8x22B)中在 A100 上具有最佳的 ITL。较小的 max_num_batched_tokens
可以实现更好的 ITL,因为中断解码的预填充较少。较大的 max_num_batched_tokens
可以实现更好的 TTFT,因为你可以将更多的预填充放入批次中。
如果
max_num_batched_tokens
与max_model_len
相同,那几乎等同于默认调度策略(除了它仍然优先考虑解码)。请注意,
max_num_batched_tokens
的默认值(512)是为 ITL 优化的,它可能比默认调度器的吞吐量更低。
我们建议您设置 max_num_batched_tokens > 2048
以提高吞吐量。
更多详情请参阅相关论文 (https://arxiv.org/pdf/2401.08671 或 https://arxiv.org/pdf/2308.16369)。
请尝试此功能,并通过 GitHub 问题向我们提供反馈!