Prefill/decode 分离#
通过分离 prefill 和 decode 阶段来部署 LLM,以提高资源利用率和成本优化。
警告
此功能需要 vLLM v1,这是默认引擎。对于使用 vLLM v0 的旧部署,请先升级到 v1。
Prefill/decode 分离将 prefill 阶段(处理输入提示)与 decode 阶段(生成 token)分开。这种分离提供了
独立优化:您可以独立地使用不同的配置优化 prefill 和 decode。
减少干扰:Prefill 操作会干扰 decode 操作,反之亦然,在不可预测的流量高峰期间会降低性能。分离消除了这种争用。
独立扩展:您可以根据需求独立扩展每个阶段。
成本优化:您可以为不同的工作负载使用不同的节点类型,从而利用异构集群。
vLLM 提供了几种用于分离服务的 KV 传输后端
NIXLConnector:基于网络的 KV 缓存传输,使用 NVIDIA Inference Xfer Library (NIXL),支持 UCX、libfabric 和 EFA 等各种后端。设置简单,配置最少。
LMCacheConnectorV1:高级缓存解决方案,支持各种存储后端,包括与 NIXL 集成。
何时使用 prefill/decode 分离#
当出现以下情况时,请考虑此模式
您的工作负载模式多变,prefill 和 decode 对资源的需求不同。
您希望通过为不同阶段使用不同的硬件来优化成本。
您的应用程序需要高吞吐量,这可以从解耦 prefill 和 decode 中受益。
使用 NIXLConnector 进行部署#
NIXLConnector 在 prefill 和 decode 服务器之间提供基于网络的 KV 缓存传输,配置最少。
先决条件#
如果您使用 ray-project/ray-llm Docker 镜像,NIXL 已经安装。否则,请安装它
uv pip install nixl
NIXL wheel 捆绑了其支持的后端(UCX、libfabric、EFA 等)。这些共享二进制文件可能不是您硬件和网络堆栈的最新版本。如果您需要最新版本,请针对目标后端库从源代码构建 NIXL。有关详细信息,请参阅 NIXL 安装指南。
基本部署#
以下示例显示了如何使用 NIXLConnector 进行部署
from ray.serve.llm import LLMConfig, build_pd_openai_app
import ray.serve as serve
# Configure prefill instance
prefill_config = LLMConfig(
model_loading_config={
"model_id": "meta-llama/Llama-3.1-8B-Instruct"
},
engine_kwargs={
"kv_transfer_config": {
"kv_connector": "NixlConnector",
"kv_role": "kv_both",
}
}
)
# Configure decode instance
decode_config = LLMConfig(
model_loading_config={
"model_id": "meta-llama/Llama-3.1-8B-Instruct"
},
engine_kwargs={
"kv_transfer_config": {
"kv_connector": "NixlConnector",
"kv_role": "kv_both",
}
}
)
pd_config = dict(
prefill_config=prefill_config,
decode_config=decode_config,
)
app = build_pd_openai_app(pd_config)
serve.run(app)
生产 YAML 配置#
对于生产部署,请使用 YAML 配置文件
# Example: Basic NIXLConnector configuration for prefill/decode disaggregation
# nixl_config.yaml
applications:
- args:
prefill_config:
model_loading_config:
model_id: meta-llama/Llama-3.1-8B-Instruct
engine_kwargs:
kv_transfer_config:
kv_connector: NixlConnector
kv_role: kv_producer
engine_id: engine1
deployment_config:
autoscaling_config:
min_replicas: 2
max_replicas: 4
decode_config:
model_loading_config:
model_id: meta-llama/Llama-3.1-8B-Instruct
engine_kwargs:
kv_transfer_config:
kv_connector: NixlConnector
kv_role: kv_consumer
engine_id: engine2
deployment_config:
autoscaling_config:
min_replicas: 6
max_replicas: 10
import_path: ray.serve.llm:build_pd_openai_app
name: pd-disaggregation-nixl
route_prefix: "/"
使用以下命令部署
serve deploy nixl_config.yaml
配置参数#
kv_connector:设置为"NixlConnector"以使用 NIXL。kv_role:设置为"kv_both",适用于 prefill 和 decode 实例。
使用 LMCacheConnectorV1 进行部署#
LMCacheConnectorV1 提供高级缓存,支持多种存储后端。
先决条件#
安装 LMCache
uv pip install lmcache
场景 1:LMCache 与 NIXL 后端#
此配置使用 LMCache 和基于 NIXL 的存储后端进行网络通信。
以下是 LMCache 与 NIXL 集成的 Ray Serve 配置示例
# Example: LMCacheConnectorV1 with NIXL backend configuration
applications:
- args:
prefill_config:
model_loading_config:
model_id: meta-llama/Llama-3.1-8B-Instruct
engine_kwargs:
kv_transfer_config:
kv_connector: LMCacheConnectorV1
kv_role: kv_producer
kv_connector_extra_config:
discard_partial_chunks: false
lmcache_rpc_port: producer1
deployment_config:
autoscaling_config:
min_replicas: 2
max_replicas: 2
runtime_env:
env_vars:
LMCACHE_CONFIG_FILE: lmcache_prefiller.yaml
LMCACHE_USE_EXPERIMENTAL: "True"
decode_config:
model_loading_config:
model_id: meta-llama/Llama-3.1-8B-Instruct
engine_kwargs:
kv_transfer_config:
kv_connector: LMCacheConnectorV1
kv_role: kv_consumer
kv_connector_extra_config:
discard_partial_chunks: false
lmcache_rpc_port: consumer1
deployment_config:
autoscaling_config:
min_replicas: 6
max_replicas: 6
runtime_env:
env_vars:
LMCACHE_CONFIG_FILE: lmcache_decoder.yaml
LMCACHE_USE_EXPERIMENTAL: "True"
import_path: ray.serve.llm:build_pd_openai_app
name: pd-disaggregation-lmcache-nixl
route_prefix: "/"
为 prefill 实例创建 LMCache 配置(lmcache_prefiller.yaml)
local_cpu: False
max_local_cpu_size: 0
max_local_disk_size: 0
remote_serde: NULL
enable_nixl: True
nixl_role: "sender"
nixl_receiver_host: "localhost"
nixl_receiver_port: 55555
nixl_buffer_size: 1073741824 # 1GB
nixl_buffer_device: "cuda"
nixl_enable_gc: True
为 decode 实例创建 LMCache 配置(lmcache_decoder.yaml)
local_cpu: False
max_local_cpu_size: 0
max_local_disk_size: 0
remote_serde: NULL
enable_nixl: True
nixl_role: "receiver"
nixl_receiver_host: "localhost"
nixl_receiver_port: 55555
nixl_buffer_size: 1073741824 # 1GB
nixl_buffer_device: "cuda"
nixl_enable_gc: True
注意
环境变量 LMCACHE_CONFIG_FILE 必须指向 Ray Serve 容器或工作程序环境中可访问的现有配置文件。确保这些配置文件已正确挂载或在您的部署环境中可用。
场景 2:LMCache 与 Mooncake 存储后端#
此配置使用 LMCache 和 Mooncake 存储,一个高性能的分布式存储系统。
以下是 LMCache 与 Mooncake 集成的 Ray Serve 配置示例
# Example: LMCacheConnectorV1 with Mooncake store configuration
applications:
- args:
prefill_config:
model_loading_config:
model_id: meta-llama/Llama-3.1-8B-Instruct
engine_kwargs:
kv_transfer_config: &kv_transfer_config
kv_connector: LMCacheConnectorV1
kv_role: kv_both
deployment_config:
autoscaling_config:
min_replicas: 2
max_replicas: 2
runtime_env: &runtime_env
env_vars:
LMCACHE_CONFIG_FILE: lmcache_mooncake.yaml
LMCACHE_USE_EXPERIMENTAL: "True"
decode_config:
model_loading_config:
model_id: meta-llama/Llama-3.1-8B-Instruct
engine_kwargs:
kv_transfer_config: *kv_transfer_config
deployment_config:
autoscaling_config:
min_replicas: 1
max_replicas: 1
runtime_env: *runtime_env
import_path: ray.serve.llm:build_pd_openai_app
name: pd-disaggregation-lmcache-mooncake
route_prefix: "/"
为 Mooncake 创建 LMCache 配置(lmcache_mooncake.yaml)
# LMCache configuration for Mooncake store backend
chunk_size: 256
local_device: "cpu"
remote_url: "mooncakestore://storage-server:49999/"
remote_serde: "naive"
pipelined_backend: false
local_cpu: false
max_local_cpu_size: 5
extra_config:
local_hostname: "compute-node-001"
metadata_server: "etcd://metadata-server:2379"
protocol: "rdma"
device_name: "rdma0"
master_server_address: "storage-server:49999"
global_segment_size: 3355443200 # 3.125 GB
local_buffer_size: 1073741824 # 1 GB
transfer_timeout: 1
警告
对于 Mooncake 部署
确保 etcd 元数据服务器正在运行,并且可以通过指定地址访问。
验证您是否已正确配置 RDMA 设备和存储服务器,并且它们是否可访问。
在容器化部署中,挂载具有适当读取权限的配置文件(例如,
chmod 644)。确保配置文件中引用的所有主机名和 IP 地址都可以从部署环境中解析。
配置参数#
kv_connector:设置为"LMCacheConnectorV1"。kv_role:对于 prefill 设置为"kv_producer",对于 decode 设置为"kv_consumer"。kv_buffer_size:KV 缓存缓冲区的大小。LMCACHE_CONFIG_FILE:指定配置文件路径的环境变量。
测试您的部署#
在使用 LMCacheConnectorV1 进行部署之前,请启动所需的服务
# Start etcd server if not already running
docker run -d --name etcd-server \
-p 2379:2379 -p 2380:2380 \
quay.io/coreos/etcd:latest \
etcd --listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls https://:2379
# For Mooncake backend, start the Mooncake master
# See https://docs.lmcache.ai/kv_cache/mooncake.html for details
mooncake_master --port 49999
使用聊天补全请求进行测试
curl -X POST "https://:8000/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"messages": [
{"role": "user", "content": "Explain the benefits of prefill/decode disaggregation"}
],
"max_tokens": 100,
"temperature": 0.7
}'
最佳实践#
选择合适的后端:对于更简单的部署,请使用 NIXLConnector。当您需要高级缓存或多个存储后端时,请使用 LMCacheConnectorV1。
监控 KV 传输开销:确保分离的好处大于网络传输成本。监控延迟和吞吐量。
独立扩展:通过单独监控每个阶段的资源利用率来利用独立扩展的优势。
使用实际工作负载进行测试:在生产部署之前,使用您的实际流量模式验证性能改进。
确保网络连接:对于 NIXLConnector,请验证 prefill 和 decode 实例是否可以通过网络进行通信。
保护 etcd 访问:对于 LMCacheConnectorV1,请确保您的 etcd 服务器得到妥善保护,并且仅供授权服务访问。
故障排除#
Prefill 和 decode 实例无法通信#
验证实例之间的网络连接,并确保有足够的带宽用于 KV 传输。
检查您的网络是否支持您正在使用的后端(例如,用于高性能部署的 RDMA)。
对于 NIXLConnector,请确保在所有节点上都正确安装了 NIXL。
验证防火墙规则和安全组是否允许 prefill 和 decode 实例之间的通信。
找不到 LMCache 配置#
验证
LMCACHE_CONFIG_FILE环境变量是否指向一个现有文件。确保 Ray Serve 工作程序环境可以访问该配置文件。
检查文件是否具有适当的读取权限。
另请参阅#
快速入门 - 基本 LLM 部署示例。