EPD 解耦#

什么是 EPD 解耦,为什么要进行 EPD 解耦?#

在现代多模态模型(VLM)推理中,请求执行自然地分解为三个不同阶段:编码器(Encoder)、预填充(Prefill)和解码(Decode)。编码器阶段执行视觉预处理和基于 ViT 的图像编码,这属于计算密集型任务,但仅在请求初始化期间需要。预填充阶段处理完整的多模态输入序列以初始化语言模型的键值(KV)缓存,而解码阶段则受内存带宽和 KV 缓存访问限制,进行自回归 Token 生成。

现有的部署通常将这些阶段并置在统一的执行引擎中,或者至多应用预填充-解码(PD)解耦。然而,这类设计仍然将视觉编码与语言预填充紧密耦合,导致资源利用效率低下、图像密集型工作负载的可扩展性受限,以及负载下的调度优化不足。

为了应对这些挑战,我们在 SGLang 中引入了编码器-预填充-解码(EPD)解耦。EPD 进一步将视觉编码与语言处理分离,使编码器服务器能够独立进行水平扩展,改善了多模态请求的负载均衡,并能与现有的 PD 解耦无缝集成,从而形成完全解耦的三层推理架构。

用法#

您可以使用 --language-only 启动纯语言模型,或者使用 --encoder-only 启动纯编码器模型。在启动纯语言模型时,您必须额外通过 --encoder-urls 指定编码器服务的端点。

我们支持多种编码器传输后端,包括 zmq_to_scheduler、zmq_to_tokenizer 和 mooncake(默认值为 zmq_to_scheduler)。可以使用 --encoder-transfer-backend 选择后端。

Qwen VL#

  • EP 解耦

# encoder 0
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --encoder-only \
  --encoder-transfer-backend zmq_to_scheduler \
  --port 30000
# encoder 1
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --encoder-only \
  --encoder-transfer-backend zmq_to_scheduler \
  --port 30001
# language-only server
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --language-only \
  --encoder-urls http://127.0.0.1:30000 http://127.0.0.1:30001 \
  --encoder-transfer-backend zmq_to_scheduler \
  --port 30002
  • EPD 分离 (EPD Disaggregation)

# encoder 0
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --encoder-only \
  --encoder-transfer-backend zmq_to_scheduler \
  --port 30000
# encoder 1
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --encoder-only \
  --encoder-transfer-backend zmq_to_scheduler \
  --port 30001
# prefill 0
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --disaggregation-mode prefill \
  --language-only \
  --encoder-urls http://127.0.0.1:30000 http://127.0.0.1:30001 \
  --encoder-transfer-backend zmq_to_scheduler \
  --port 30002
# decode 0
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-VL-8B-Instruct \
  --disaggregation-mode decode \
  --port 30003
# router
python -m sglang_router.launch_router \
  --pd-disaggregation \
  --prefill http://$PREFILL_HOST:30002 \
  --decode http://$DECODE_HOST:30003 \
  --port 8000