跳至内容

解耦预填充(实验性功能)

本页面向您介绍vLLM中的解耦预填充功能。

注意

此功能为实验性质,可能会发生变化。

为什么需要分离式预填充?

两个主要原因:

  • 分别优化首令牌时间(TTFT)和令牌间延迟(ITL)。解耦预填充技术将LLM推理的预填充和解码阶段放在不同的vLLM实例中执行。这使您能够灵活地为不同阶段分配并行策略(例如tppp),在不影响ITL的情况下优化TTFT,或在不影响TTFT的情况下优化ITL。
  • 控制尾部ITL。在没有解耦预填充的情况下,vLLM可能会在单个请求的解码过程中插入一些预填充任务,从而导致更高的尾部延迟。解耦预填充功能可帮助您解决此问题并控制尾部ITL。采用适当分块大小的分块预填充也能实现相同目标,但在实践中很难确定正确的分块大小值。因此,解耦预填充是控制尾部ITL更为可靠的方式。

注意

解耦预填充并不会提高吞吐量。

使用示例

请参考 examples/online_serving/disaggregated_prefill.sh查看解耦预填充的示例用法。

基准测试

请参考 benchmarks/disagg_benchmarks获取分解预填充基准测试数据。

开发

我们通过运行2个vLLM实例来实现解耦的预填充。一个用于预填充(我们称之为预填充实例),另一个用于解码(我们称之为解码实例),然后使用连接器将预填充的KV缓存和结果从预填充实例传输到解码实例。

所有解耦的预填充实现都在vllm/distributed/kv_transfer目录下。

解耦预填充的关键抽象概念:

  • 连接器: 连接器允许kv消费者kv生产者处获取一批请求的KV缓存。
  • LookupBuffer: LookupBuffer提供两个API接口:insert KV缓存和drop_select KV缓存。insertdrop_select的语义与SQL类似,其中insert将KV缓存插入缓冲区,而drop_select返回符合给定条件的KV缓存并将其从缓冲区中移除。
  • Pipe: 一个单向的FIFO管道,用于张量传输。它支持send_tensorrecv_tensor

注意

insert 是非阻塞操作,但 drop_select 是阻塞操作。

下图展示了上述3个抽象概念的组织方式:

Disaggregated prefilling abstractions

解耦预填充的工作流程如下:

Disaggregated prefilling workflow

buffer对应LookupBuffer中的insert API,而drop_select对应LookupBuffer中的drop_select API。

第三方贡献

解耦式预填充与基础设施高度相关,因此vLLM依赖第三方连接器来实现生产级解耦式预填充(vLLM团队将积极审核并合并第三方连接器的新PR)。

我们推荐三种实现方式:

  • 完全自定义的连接器: 实现你自己的Connector,并调用第三方库来发送和接收KV缓存,以及更多功能(比如编辑vLLM的模型输入以执行自定义预填充等)。这种方法给你最大的控制权,但存在与未来vLLM版本不兼容的风险。
  • 类数据库连接器: 实现你自己的 LookupBuffer 并支持类似SQL的 insertdrop_select API接口。
  • 分布式P2P连接器: 实现你自己的Pipe并支持send_tensorrecv_tensor API,就像torch.distributed一样。
优云智算