> This page is for version v1.4.1.
> For other versions, use one of these documentation indexes:
> - Latest (v1.5.1) (default): https://docs.nvidia.com/dynamo/latest/llms.txt
> - dev: https://docs.nvidia.com/dynamo/dev/llms.txt
> - v1.5.1: https://docs.nvidia.com/dynamo/v1.5.1/llms.txt
> - v1.5.0: https://docs.nvidia.com/dynamo/v1.5.0/llms.txt
> - v1.4.2: https://docs.nvidia.com/dynamo/v1.4.2/llms.txt
> - v1.4.1: https://docs.nvidia.com/dynamo/v1.4.1/llms.txt
> - v1.4.0: https://docs.nvidia.com/dynamo/v1.4.0/llms.txt
> - v1.3.0: https://docs.nvidia.com/dynamo/v1.3.0/llms.txt
> - v1.2.1: https://docs.nvidia.com/dynamo/v1.2.1/llms.txt
> - v1.2.0: https://docs.nvidia.com/dynamo/v1.2.0/llms.txt
> - v1.1.1: https://docs.nvidia.com/dynamo/v1.1.1/llms.txt
> - v1.1.0: https://docs.nvidia.com/dynamo/v1.1.0/llms.txt
> - v1.0.2: https://docs.nvidia.com/dynamo/v1.0.2/llms.txt
> - v1.0.1: https://docs.nvidia.com/dynamo/v1.0.1/llms.txt
> - v1.0.0: https://docs.nvidia.com/dynamo/v1.0.0/llms.txt
> - v0.9.1: https://docs.nvidia.com/dynamo/v-0-9-1/llms.txt
> - v0.9.0: https://docs.nvidia.com/dynamo/v-0-9-0/llms.txt
> - v0.8.1: https://docs.nvidia.com/dynamo/v-0-8-1/llms.txt
> - v0.8.0: https://docs.nvidia.com/dynamo/v-0-8-0/llms.txt
> - v0.7.1: https://docs.nvidia.com/dynamo/v-0-7-1/llms.txt
> - v0.7.0: https://docs.nvidia.com/dynamo/v-0-7-0/llms.txt

> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/dynamo/llms-full.txt.

# Encoder Disaggregation

## Overview

Encoder disaggregation separates the vision encoder from the prefill/decode pipeline into its own worker. Instead of running image encoding inline, a dedicated encode worker handles media processing and transfers the resulting embeddings to downstream workers via NIXL (RDMA).

This enables:

- Independent scaling of encode workers based on vision workload
- Reduced GPU memory pressure on prefill/decode workers
- Better GPU utilization by matching worker counts to actual bottlenecks

## When to Use

Use encoder disaggregation when:

- Vision encoding is a bottleneck and you need to scale encoders independently of LLM workers
- You want to run the vision encoder on different hardware (e.g., smaller GPUs for encoding, larger GPUs for LLM inference)
- Your deployment handles high volumes of multimodal requests and encoding throughput is limiting

For simple deployments or development/testing, the aggregated (EPD) pattern is easier to set up.

## Deployment Patterns

<CardGroup cols={2}>
  <Card title="E/PD">
    **Separate encoder, combined prefill and decode**

    <Badge intent="info" minimal>Frontend</Badge> → <Badge intent="info" minimal>Processor</Badge> → <Badge intent="info" minimal>Encode Worker</Badge> → <Badge intent="info" minimal>PD Worker</Badge> → <Badge intent="info" minimal>Response</Badge>

    The encode worker runs the vision model and transfers embeddings over NIXL to the combined prefill and decode worker.
  </Card>
  <Card title="E/P/D">
    **Separate encoder, prefill, and decode**

    <Badge intent="info" minimal>Frontend</Badge> → <Badge intent="info" minimal>Processor</Badge> → <Badge intent="info" minimal>Encode Worker</Badge> → <Badge intent="info" minimal>Prefill Worker</Badge> → <Badge intent="info" minimal>Decode Worker</Badge> → <Badge intent="info" minimal>Response</Badge>

    The encode worker transfers embeddings over NIXL to the prefill worker. The prefill worker then transfers the KV cache to the decode worker.
  </Card>
</CardGroup>

## Launching

<Tabs>
  <Tab title="vLLM" language="vllm">
    ```bash
    cd $DYNAMO_HOME/examples/backends/vllm

    # E/PD
    bash launch/disagg_multimodal_e_pd.sh --model "Qwen/Qwen3-VL-30B-A3B-Instruct-FP8"

    # E/P/D
    bash launch/disagg_multimodal_epd.sh --model "Qwen/Qwen3-VL-30B-A3B-Instruct-FP8"
    ```
  </Tab>
  <Tab title="SGLang" language="sglang">
    ```bash
    cd $DYNAMO_HOME/examples/backends/sglang

    # E/PD
    ./launch/multimodal_epd.sh

    # E/P/D
    ./launch/multimodal_disagg.sh
    ```
  </Tab>
  <Tab title="TensorRT-LLM" language="trtllm">
    ```bash
    cd $DYNAMO_HOME/examples/backends/trtllm

    # E/PD
    bash launch/disagg_e_pd.sh

    # E/P/D
    ./launch/epd_multimodal_image_and_embeddings.sh
    ```
  </Tab>
</Tabs>

See the backend-specific documentation ([vLLM](/dynamo/v1.4.1/knowledge-base/modular-components/backends/v-llm/vllm-multimodal), [TRT-LLM](/dynamo/v1.4.1/knowledge-base/modular-components/backends/tensor-rt-llm/tensorrt-llm-multimodal), [SGLang](/dynamo/v1.4.1/knowledge-base/modular-components/backends/sg-lang/sglang-multimodal)) for full configuration details and component flags.

## Support Matrix

| Backend | E/PD | E/P/D | Notes |
|---------|------|-------|-------|
| **vLLM** | <Badge intent="success" minimal>Yes</Badge> | <Badge intent="success" minimal>Yes</Badge> | Separate encode worker currently handles `image_url` inputs; `video_url` inputs stay on the prefill/PD path |
| **TensorRT-LLM** | — | <Badge intent="success" minimal>Yes</Badge> | Supports image URLs (via `MultimodalEncoder`) and pre-computed embeddings (via NIXL) |
| **SGLang** | <Badge intent="success" minimal>Yes</Badge> | <Badge intent="success" minimal>Yes</Badge> | NIXL for embeddings; bootstrap mechanism for P/D KV transfer |