Skip to content

[Doc] Document EPD (encoder-prefill disaggregation) - #381

Closed
DiegoCao wants to merge 1 commit into
vllm-project:mainfrom
DiegoCao:docs/epd-disaggregation
Closed

DiegoCao wants to merge 1 commit into
vllm-project:mainfrom
DiegoCao:docs/epd-disaggregation

Conversation

@DiegoCao

Copy link
Copy Markdown

Summary

EPD landed in #370, but it has no user-facing documentation: grep -rn encoder docs/ currently returns nothing, and worker_type: encoder is missing from every config reference table. This PR documents it.

Docs only — no behavior change.

docs/{en,zh}/advanced/vllm-config.md

New usage-pattern section "EPD Disaggregation (Vision Encoder Split)", covering:

  • The two supported layouts: encoder + prefill + decode (full EPD), and encoder + regular (vision split without PD)

  • The auto-derived role matrix, so users never hand-write ec_transfer_config:

    Worker type ec_role kv_role (with PD)
    encoder ec_producer
    prefill ec_consumer kv_producer
    regular ec_consumer
    decode kv_consumer
  • Why encoder groups start first and synchronously (their URLs are injected into the language engines' server args before those engines launch)

  • prime_encoder — automatic on the built-in rollout paths, required in custom rollout functions — plus the args.vllm_model_encoder_endpoints shape

  • How to swap the encoder-cache connector, and the caveat that a group-level ec_transfer_config replaces rather than deep-merges the generated one, so it must be set on every participating group with a matching shared_storage_path

  • Limitations: ECExampleConnector is file-backed and the default /dev/shm path is node-local, so producer and consumer must co-locate unless shared_storage_path points at a shared mount; and EPD is currently exercised in CI with update_weights: false, so weight sync into a split encoder/language-only deployment is not yet covered

Also updated the config-format comment, both worker_type reference tables, the Worker Types table, the intro paragraph, and the FAQ — the existing "can I mix PD and regular groups in the same model?" answer needed an encoder exception, since encoder composes with either layout. Added a FAQ entry noting encoder GPUs count toward --rollout-num-gpus.

docs/{en,zh}/advanced/pd-disaggregation.md

New "EPD: Splitting the Vision Encoder" section framing the vision tower as a third workload profile and showing PD ∘ EPD composition, linking through to the config guide for detail. Updated the operational note that forbids mixing regular with prefill/decode to record the encoder exception.

docs/{en,zh}/advanced/external-rollout-engines.md

Inserting EPD as section 3 renumbers the following usage patterns to 4–8, so the two links to vllm-config.md#3-multi-model-serving become #4-multi-model-serving. These are required by the renumbering, not drive-by edits.

Test plan

  • pre-commit run --files <the six .md files> passes (all Python hooks skip; no markdown hooks configured)
  • Verified every in-repo .md#anchor link across docs/**/*.md still resolves, including the renumbered ones and the two new EPD anchors. One pre-existing broken link in docs/zh/advanced/pd-disaggregation.md (an English slug used on the Chinese page) is left untouched, as it is unrelated to this change
  • Every documented claim checked against the implementation in vime/ray/rollout.py, vime/backends/vllm_utils/vllm_engine.py, vime/rollout/vllm_rollout.py, and the assertions in tests/test_qwen2.5_vl_3B_ep_disaggregation.py

No code paths touched, so no CI suite is affected.

Related: #11 (roadmap), #370 (the EPD implementation).

AI assistance disclosure

This PR was drafted with Claude Code. I reviewed every changed line and verified each documented claim against the implementation and the EPD test.

EPD landed in vllm-project#370 but had no user-facing documentation — `grep -rn
encoder docs/` returned nothing, and `worker_type: encoder` was absent
from every config reference table.

Add an EPD section to the vLLM config guide (en + zh) covering the two
supported layouts (encoder+prefill+decode, and encoder+regular), the
auto-derived ec_role/kv_role matrix, encoder-first startup ordering, the
prime_encoder requirement for custom rollout functions, how to swap the
encoder-cache connector, and current limitations. Add a shorter EPD
section to the PD guide framing the two as orthogonal, composable axes.

Update the worker_type reference tables, config-format comment, intro
paragraphs, and FAQ (the "can I mix PD and regular groups" answer needed
an encoder exception; added one on encoder GPU accounting).

Inserting EPD as section 3 renumbers the following usage patterns to
4-8, so the two external-rollout-engines.md links to
`vllm-config.md#3-multi-model-serving` are updated to `vllm-project#4-`.

Docs only; no behavior change.

Co-authored-by: Claude
Signed-off-by: Hangrui Cao <hangrui.cao@zoom.us>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces documentation for Encoder-Prefill-Decode (EPD) disaggregation, which allows splitting the vision encoder onto dedicated engines for vision-language models. The updates are applied to both English and Chinese versions of the advanced configuration guides, detailing the configuration, roles, startup ordering, and limitations of EPD. The reviewer suggested replacing absolute GitHub URLs with relative links in both English and Chinese documentation files to improve portability.

shared_storage_path: /mnt/shared/ec-cache
```

> **Limitations.** `ECExampleConnector` is upstream's reference implementation and is file-backed: the default `/dev/shm` path is node-local, so encoder and consumer engines must land on the same node unless you override `shared_storage_path` with a shared mount. EPD is also currently exercised in CI with `update_weights: false` (see [tests/test_qwen2.5_vl_3B_ep_disaggregation.py](https://github.com/vllm-project/vime/blob/main/tests/test_qwen2.5_vl_3B_ep_disaggregation.py)); weight sync into a split encoder/language-only deployment is not yet covered.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using absolute GitHub URLs pointing to the main branch makes the documentation less portable (e.g., when viewed on forks, offline, or other branches). It is better to use a relative link, which is also consistent with other links in this repository.

Suggested change
> **Limitations.** `ECExampleConnector` is upstream's reference implementation and is file-backed: the default `/dev/shm` path is node-local, so encoder and consumer engines must land on the same node unless you override `shared_storage_path` with a shared mount. EPD is also currently exercised in CI with `update_weights: false` (see [tests/test_qwen2.5_vl_3B_ep_disaggregation.py](https://github.com/vllm-project/vime/blob/main/tests/test_qwen2.5_vl_3B_ep_disaggregation.py)); weight sync into a split encoder/language-only deployment is not yet covered.
> **Limitations.** `ECExampleConnector` is upstream's reference implementation and is file-backed: the default `/dev/shm` path is node-local, so encoder and consumer engines must land on the same node unless you override `shared_storage_path` with a shared mount. EPD is also currently exercised in CI with `update_weights: false` (see [tests/test_qwen2.5_vl_3B_ep_disaggregation.py](../../../tests/test_qwen2.5_vl_3B_ep_disaggregation.py)); weight sync into a split encoder/language-only deployment is not yet covered.

shared_storage_path: /mnt/shared/ec-cache
```

> **限制。** `ECExampleConnector` 是上游的参考实现,基于文件存储:默认的 `/dev/shm` 路径是节点本地的,因此除非用共享挂载覆盖 `shared_storage_path`,encoder 与 consumer 引擎必须落在同一个节点上。此外,目前 CI 中的 EPD 用例使用 `update_weights: false`(见 [tests/test_qwen2.5_vl_3B_ep_disaggregation.py](https://github.com/vllm-project/vime/blob/main/tests/test_qwen2.5_vl_3B_ep_disaggregation.py));向 encoder / language-only 拆分部署做权重同步尚未覆盖。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using absolute GitHub URLs pointing to the main branch makes the documentation less portable (e.g., when viewed on forks, offline, or other branches). It is better to use a relative link, which is also consistent with other links in this repository.

Suggested change
> **限制。** `ECExampleConnector` 是上游的参考实现,基于文件存储:默认的 `/dev/shm` 路径是节点本地的,因此除非用共享挂载覆盖 `shared_storage_path`,encoder 与 consumer 引擎必须落在同一个节点上。此外,目前 CI 中的 EPD 用例使用 `update_weights: false`(见 [tests/test_qwen2.5_vl_3B_ep_disaggregation.py](https://github.com/vllm-project/vime/blob/main/tests/test_qwen2.5_vl_3B_ep_disaggregation.py));向 encoder / language-only 拆分部署做权重同步尚未覆盖。
> **限制。** `ECExampleConnector` 是上游的参考实现,基于文件存储:默认的 `/dev/shm` 路径是节点本地的,因此除非用共享挂载覆盖 `shared_storage_path`,encoder 与 consumer 引擎必须落在同一个节点上。此外,目前 CI 中的 EPD 用例使用 `update_weights: false`(见 [tests/test_qwen2.5_vl_3B_ep_disaggregation.py](../../../tests/test_qwen2.5_vl_3B_ep_disaggregation.py));向 encoder / language-only 拆分部署做权重同步尚未覆盖。

@read-the-docs-community

Copy link
Copy Markdown

@DiegoCao DiegoCao closed this Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants