驾驭 vLLM 大模型推理:一次关于并发、长度与显存的探索之旅
最近在探索如何更高效地部署和使用大语言模型,我使用了这个 vLLM 这个以高性能著称的推理框架。在使用过程中,我遇到了一些关键的参数,比如 max-num-batched-tokens
、max-num-seqs
、max-model-len
和 gpu-memory-utilization
。今天就来和大家分享一下我对这些参数的理解和一些思考。
初识 vLLM:高性能推理的魅力
vLLM 标榜的高吞吐和低延迟让我非常期待。在着手部署我的 32B 模型时(运行在 A100-80G GPU 上,精度选择 bf16),我很快就接触到了这些核心配置参数。一开始,面对这些参数,我有些困惑,它们之间是什么关系?又该如何设置才能发挥出最佳性能呢?
max-num-seqs
:并发处理能力的基石
首先让我关注的是 max-num-seqs
。顾名思义,这个参数控制了 vLLM 能够同时处理的最大独立请求(序列)数量。每个用户发起的一次推理请求,都会被 vLLM 视为一个序列。
我的理解是,如果我将 max-num-seqs
设置为 4,那么 vLLM 在同一时刻最多只能并行处理 4 个不同的推理请求。如果有第 5 个请求到来,它就必须等待前面某个请求处理完毕,释放资源后才能被 vLLM 接纳。
这让我意识到,max-num-seqs
直接决定了系统的并发处理能力,也与吞吐量息息相关。更高的 max-num-seqs
理论上可以带来更高的吞吐量(前提是有足够的并发请求),但也意味着需要为更多的并发序列维护 KV-Cache 等状态,可能会增加显存压力。
max-num-batched-tokens
:优化 GPU 利用率的关键
接下来是 max-num-batched-tokens
。这个参数定义了 vLLM 在一个批次中能够处理的最大 Token 总数。为了更高效地利用 GPU 的并行计算能力,vLLM 会尝试将多个独立的请求(来自不同的 max-num-seqs
)合并成一个批次进行处理。
我的理解是,即使我设置了 max-num-seqs
为 4,vLLM 也不会立即处理这 4 个请求,而是会等待一定的时机,将它们(或者部分)组合成一个批次,这个批次的总 Token 数量不能超过 max-num-batched-tokens
。更大的 max-num-batched-tokens
可以让 GPU 更饱满地运行,但也可能增加延迟,因为需要等待更多的请求或者更长的序列片段才能组成一个足够大的批次。
max-model-len
:模型上下文的边界
max-model-len
对我来说并不陌生,它定义了模型能够处理的最大上下文长度(以 Token 为单位)。这包括了输入 Prompt 的 Token 数以及模型生成输出的 Token 数之和。
我的学习是,如果我将 max-model-len
设置为某个值(比如我部署的 QwQ 32B 模型支持的 131072),那么任何单个请求的输入和输出 Token 总长度都不能超过这个限制。一旦超过,vLLM 可能会截断输入或者提前停止生成,这可能导致回答不完整或者丢失关键信息。因此,选择合适的 max-model-len
需要根据模型的固有能力和我的应用场景中预期的输入输出长度来权衡。
gpu-memory-utilization
:显存管理的艺术
最后一个重要的参数是 gpu-memory-utilization
。它控制了 vLLM 可以使用的 GPU 显存的比例(0.0 到 1.0)。
我了解到,即使我的 A100-80G 拥有 80GB 的显存,我也不能让 vLLM 无限制地使用。通过设置 gpu-memory-utilization
,我可以为操作系统和其他进程预留一部分显存,避免 OOM(Out Of Memory)错误。例如,设置为 0.85 就意味着 vLLM 最多可以使用 80GB * 0.85 = 68GB 的显存。
我的体会是,更高的利用率可以提高吞吐量,因为 vLLM 可以更积极地分配显存来处理更多的并发请求或者更大的批次。但过高的利用率会增加 OOM 的风险。因此,根据我的模型大小(32B),预估的显存需求,以及我期望的并发水平,合理设置这个参数至关重要。
参数间的联动:牵一发而动全身
在学习过程中,我逐渐认识到这些参数并非孤立存在,而是相互影响的:
max-model-len
的增大 会直接增加每个序列的 KV-Cache 需求,从而限制了在有限的显存下能够支持的max-num-seqs
。- 更高的
max-num-seqs
意味着需要维护更多的 KV-Cache,可能会更快地达到gpu-memory-utilization
的上限,也可能影响每个批次的平均max-num-batched-tokens
。 max-num-batched-tokens
的增大 可能会提高单个批次的效率,但也可能因为需要等待更多请求而增加延迟,并且需要更多的临时显存。gpu-memory-utilization
是一个全局性的约束,它限制了以上所有参数可以使用的显存总量。
我的下一步:实践与调优
理论学习只是第一步,真正的理解还需要在实践中检验。我的下一步计划是:
- 基准测试: 使用不同的参数组合进行基准测试,记录吞吐量、延迟和显存占用等关键指标。
- 逐步调优: 从一个保守的配置开始(较低的
max-num-seqs
和gpu-memory-utilization
),逐步调整参数,观察性能变化。 - 监控: 在实际应用中持续监控 GPU 显存使用情况,避免 OOM 错误,并根据需求动态调整参数。
总结与分享
这次对 vLLM 关键参数的学习经历让我受益匪浅。理解 max-num-batched-tokens
、max-num-seqs
、max-model-len
和 gpu-memory-utilization
的作用以及它们之间的关系,对于高效部署大模型至关重要。没有一套万能的参数配置,只有根据你的具体模型、硬件环境和应用场景进行不断地实验和调优,才能找到最佳的平衡点。
希望我的分享能对正在探索 vLLM 的你有所帮助!如果你也有相关的经验或者见解,欢迎在评论区一起交流学习。
相关文章
本文首发于Xunberg's Tech Blog