跳转至

Diffusion Model 分离部署指南

本页目录

对于大规模生成模型(如 Wan、Qwen Image 等),Text Encoder、Image Encoder 以及 VAE 编解码器往往常驻显存,极大挤压核心 DiT 模型的可用空间,在高分辨率、长时生成场景下容易导致 OOM。

LightX2V 提供了原生的 Disaggregation Mode(分离部署模式),通过高性能 Mooncake 传输引擎,将推理流水线拆分为 Encoder、Transformer、Decoder 三段,分别部署在不同显卡或节点上,支持 RDMA / TCP 通信。Wan 与 Qwen Image 均已支持完整三段式部署(含 VAE Decoder 独立节点)。分离部署模式支持各段并发处理不同请求,从而提升多请求吞吐。


方案对比

特性 Baseline(常规单机部署) Disagg Mode(分离微服务部署)
部署架构 所有模型聚合在同一进程中 三段式:Encoder 节点 → Transformer 节点 → Decoder 节点(VAE 解码独立)
显存占用 极高 按需分配(各节点只加载自身所需部分,Decoder 仅 VAE Decoder)
通信底层 进程内原生 Tensor 共享 Mooncake 引擎(Phase1: Encoder→Transformer;Phase2: Transformer→Decoder)
适用场景 显存充裕的单机环境、快速验证 显存受限、长帧视频、多机分布式高并发生产环境

Quick Start

以下是单机三段式示例,每次选择一种模型运行。两个终端均使用已安装 LightX2V 的环境,并进入仓库根目录。

公共准备

在终端一安装 Mooncake,设置仓库路径和 GPU:

pip install mooncake-transfer-engine
export LIGHTX2V_PATH="$PWD"
export GPU_ENCODER=0 GPU_TRANSFORMER=1 GPU_DECODER=0

示例将 Encoder 和 Decoder 放在 GPU 0、Transformer 放在 GPU 1;按实际显卡编号和可用显存调整。模型目录需包含相应的 DiT、编码器和 VAE 权重。

各阶段配置位于 configs/disagg/wan/ 或 configs/disagg/qwen/。安装其中指定的后端:Wan 示例使用 sage_attn2;Qwen Encoder 使用 lightllm_kernel 和 flash_attn3,Transformer 的 T2I/I2I 示例分别使用 flash_attn2/flash_attn3。如需替换后端,同步修改配置并确认模型和 GPU 支持。

启动脚本会保持运行。等待三个服务均就绪后,在终端二发送请求;在终端一按 Ctrl+C 会停止整组服务。

Wan2.1-T2V-14B(50 步、480×832、81 帧)

终端一:替换模型绝对路径并启动。

WAN_T2V_MODEL_PATH="/absolute/path/to/Wan2.1-T2V-14B" \
  bash scripts/server/disagg/wan/start_wan_t2v_disagg.sh

终端二:

python scripts/server/disagg/wan/post_wan_t2v.py

Wan2.1-I2V-14B-480P(40 步、480×832、81 帧)

终端一:

WAN_I2V_MODEL_PATH="/absolute/path/to/Wan2.1-I2V-14B-480P" \
  bash scripts/server/disagg/wan/start_wan_i2v_disagg.sh

终端二:先将请求脚本中的 IMAGE_PATH 改为本地图片路径,再运行。

python scripts/server/disagg/wan/post_wan_i2v.py

Qwen Image(T2I)

先编辑 configs/disagg/qwen/qwen_image_t2i_disagg_transformer.json,将 dit_original_ckpt 替换为与模型和推理配置匹配的 DiT 权重文件。该字段优先于模型目录,只修改 QWEN_IMAGE_MODEL_PATH 不会覆盖它。

终端一:

QWEN_IMAGE_MODEL_PATH="/absolute/path/to/qwen-model" \
  bash scripts/server/disagg/qwen/start_qwen_t2i_disagg.sh

终端二:

python scripts/server/disagg/qwen/post_qwen_t2i.py

Qwen Image Edit 2511(I2I)

终端一:

QWEN_IMAGE_MODEL_PATH="/absolute/path/to/Qwen-Image-Edit-2511" \
  bash scripts/server/disagg/qwen/start_qwen_i2i_disagg.sh

终端二:先将请求脚本中的 IMAGE_PATH 改为本地图片路径,再运行。

python scripts/server/disagg/qwen/post_qwen_i2i.py

地址与端口

示例 API 端口(Encoder / Transformer / Decoder) 指标端口
Wan T2V 8002 / 8003 / 8006 18002 / 18003 / 18006
Wan I2V 8004 / 8005 / 8007 18004 / 18005 / 18007
Qwen T2I 8002 / 8003 / 8008 18002 / 18003 / 18008
Qwen I2I 8012 / 8013 / 8014 18012 / 18013 / 18014

修改 API 地址或端口时,同步修改请求脚本中的 ENCODER_URL、TRANSFORMER_URL、DECODER_URL。同时运行多组服务时,API 和指标端口都必须避免冲突。

性能实测 Benchmark

测试环境:sage_attn2,BF16,PROFILING_DEBUG_LEVEL=2,Mooncake RDMA 协议。 Baseline 使用单张 GPU 加载全部模型;Disagg Mode 可将 Encoder、Transformer、Decoder 分别部署在不同 GPU 上。

RTX 4090 24GB(显存/PCIe 受限场景)

该组数据用于说明 显存受限显卡(例如 4090 24GB)上,Baseline 往往必须依赖 cpu_offload=block 才能跑通;而 Disagg 将 Encoder/DiT/VAE Decoder 拆分到不同进程/显卡后,可以显著降低单卡常驻显存压力,从而降低 offload 总体latency并改善延迟与吞吐。

Wan2.1-I2V-14B(BF16,40 steps)

指标 Baseline(1×4090,block offload) Disagg(2×4090,block offload) 备注
峰值显存 480P:9GB;720P:14GB — Baseline 依赖 offload 才能跑通
DiT 单步 480P:24.24 s/step;720P:90.71 s/step 480P:19.02 s/step;720P:62.80 s/step 4090 上 DiT 更容易被显存/PCIe 限制
Image Encoder 480P:0.57s;720P:0.52s 480P:0.28s;720P:0.20s Disagg 资源解耦后 Encoder 更稳定
VAE Encoder 480P:3.02s;720P:6.83s 480P:3.22s;720P:7.36s 受分辨率影响显著
Text Encoder 480P:2.14s;720P:1.90s 480P:0.20s;720P:0.20s 4090 上 Baseline 受 offload/调度影响更大
Encoder 总计 480P:6.09s;720P:9.78s 480P:4.08s;720P:8.32s

Wan2.1-I2V-14B(INT8)

指标 Baseline(block offload) Disagg(no offload) Disagg(block offload)
说明 use_offload=false 会 OOM — —
DiT 单步 12.94 s/step 12.55 s/step 12.91 s/step
Image Encoder 0.79s 0.19s 0.19s
VAE Encoder 3.11s 2.93s 2.93s
Text Encoder 1.67s 0.20s 0.20s
Encoder 总计 5.90s 3.69s 3.70s

4090 并发压测(BF16 + block offload,Wan2.1 480P 4 steps Distill端到端压测)

该组并发数据用于观察在多请求排队/资源争用下,Disagg 是否更容易提升 QPS 与尾延迟。

N(concurrency) mode ok/total QPS P50(s) P95(s) P99(s) note
1 baseline 1 0.0091 109.45 109.45 109.45 wan2.1 480P 4step
2 baseline 2 0.0092 162.52 211.01 215.32 wan2.1 480P 4step
4 baseline 4 0.0093 269.85 414.94 427.83 wan2.1 480P 4step
8 baseline 8 0.0093 485.82 824.24 854.32 wan2.1 480P 4step
1 disagg 1 0.0117 85.38 85.38 85.38 wan2.1 480P 4step
2 disagg 2 0.0122 125.83 160.18 163.23 wan2.1 480P 4step
4 disagg 4 0.0126 201.85 305.73 314.94 wan2.1 480P 4step
8 disagg 8 0.0129 358.20 595.12 616.48 wan2.1 480P 4step

4090 并发压测(Qwen Image 2512,T2I,5 steps Distill端到端压测)

N(concurrency) mode ok/total QPS P50(s) P95(s) P99(s) note
1 baseline 1 0.0207 48.30 48.30 48.30 qwen-image-2512 5step
2 baseline 2 0.0207 72.57 94.31 94.24 qwen-image-2512 5step
4 baseline 4 0.0212 118.77 181.44 187.33 qwen-image-2512 5step
8 baseline 8 0.0216 208.64 354.94 367.90 qwen-image-2512 5step
1 disagg 1 0.0452 22.11 22.11 22.11 qwen-image-2512 5step
2 disagg 2 0.0510 29.68 38.25 39.02 qwen-image-2512 5step
4 disagg 4 0.0528 48.52 73.00 75.17 qwen-image-2512 5step
8 disagg 8 0.0534 85.78 143.37 148.62 qwen-image-2512 5step

NVIDIA H100 SXM5 80 GB

Wan2.1-T2V-1.3B(小模型参考)

测试条件:Baseline 混合部署在 cuda:0;Disagg 模式将 Transformer 部署于 cuda:0,Encoder 挂载于 cuda:1。

测试指标(T2V 50 Steps) Baseline(单卡) Disagg Mode(双卡) 备注
峰值显存 ~16.4 GB (16823 MiB) Enc: ~11.3 GB / Trans: ~9.2 GB Transformer 显存压缩至 9.2 GB
Text Encoder 耗时 ~0.282 s ~0.294 s 通过 RDMA 几乎无损
DiT 单步延迟 0.945 s/step 0.882 s/step 独占 VRAM 带宽,加速 ~6.6%
VAE Decoder 耗时 2.360 s 2.434 s 基本不受网络影响
端到端总耗时 52.46 s 49.27 s Disagg 缩减约 3 s

Wan2.1-14B(H100 单卡 Baseline vs 双卡 Disagg 对比)

Wan2.1-T2V-14B(50 Steps, 480×832, 81 帧)

阶段 Baseline(单卡) Disagg Encoder Disagg Transformer
Encoder Pipeline 总耗时 0.84 s 0.89 s —
DiT 推理(50 steps) 252.7 s(~4.95 s/step) — 252.8 s(~4.95 s/step)
VAE Decoder 2.25 s — 2.38 s
端到端 Pipeline 总耗时 253.2 s — 253.5 s

分析:两种模式的端到端延迟几乎持平。Disagg 能支持 Encoder 与 Transformer 并发处理不同请求,提升多请求吞吐。

Wan2.1-I2V-14B-480P(40 Steps, 480×832, 81 帧)

阶段 Baseline(单卡) Disagg Encoder Disagg Transformer
Image Encoder(CLIP ViT-H/14) 0.68 s 0.29 s ↓ 57% —
VAE Encoder 1.90 s 1.35 s ↓ 29% —
Text Encoder(T5) 0.17 s 0.18 s —
Encoder Pipeline 总耗时 4.75 s 3.17 s ↓ 33% —
DiT 推理(40 steps) 208.2 s(~5.06 s/step) — 207.7 s(~5.06 s/step)
VAE Decoder 2.03 s — 2.22 s
端到端 Pipeline 总耗时 211.6 s — 210.9 s

分析:I2V Disagg 模式下 端到端延迟两者持平。

显存占用对比

模型 部署模式 所需 GPU 数 各卡显存峰值
Wan2.1-T2V-14B Baseline 1× ~39 GB
Wan2.1-T2V-14B Disagg 2× Encoder: ~11 GB / Transformer: ~28 GB
Wan2.1-I2V-14B-480P Baseline 1× ~48 GB
Wan2.1-I2V-14B-480P Disagg 2× Encoder: ~13 GB / Transformer: ~32 GB

qwen-image-edit-release-251130

Qwen Image 在 H100 上对 T2I/I2I 任务的测试,Disagg 模式 Text Encoder 使用 lightllm_kernel 加速。

任务 部署模式 Text Encoder (s) VAE Encoder (s) DiT Total (s) 端到端 (s)
T2I Baseline 0.430 N/A 23.24 (50 steps) 25.50
T2I Disagg (Kernel) 0.300 N/A 22.04 25.05
I2I Baseline 0.924 0.844 33.81 (40 steps) 38.83
I2I Disagg (Kernel) 0.746 0.137 31.39 33.90

核心发现:

  1. Text Encoder 加速:lightllm_kernel 使 T2I Text Encoder 耗时从 0.43s 降至 0.30s(加速 ~30%),I2I 从 0.92s 降至 0.75s(加速 ~19%)。
  2. VAE Encoder 差异:Disagg 模式下 VAE Encoder 表现出显著加速,源于 GPU 资源独占带来的调度优化。
  3. 计算资源解耦:Text Encoder/VAE 与 DiT 分离至不同 GPU,端到端延迟显著降低(I2I 降低约 5 秒)。

1. Disagg 分离架构解析

通过配置参数 disagg_mode,推理 Pipeline 被物理拆分为 三段式 独立服务,数据流经 Phase1(Encoder → Transformer) 与 Phase2(Transformer → Decoder) 两次 Mooncake 传输:

  • Encoder 角色(disagg_mode="encoder"):
  • 仅加载 Text Encoder、Image Encoder(I2V / I2I 时)以及 VAE Encoder,跳过 DiT 与 VAE Decoder。
  • 执行特征提取,将 context、clip_encoder_out、vae_encoder_out、latent_shape 等通过 Mooncake Phase1 投递给 Transformer 节点。
  • Transformer 角色(disagg_mode="transformer"):
  • 仅加载 DiT 模型,跳过 Encoder 与 VAE Decoder(三段式下由 Decoder 节点承担解码)。
  • 启动后等待 Phase1 数据,收到后执行哈希校验、拼装输入并完成去噪;若配置了 decoder_engine_rank,将去噪后的潜空间通过 Mooncake Phase2 发送给 Decoder 节点,不本地做 VAE 解码。
  • Decoder 角色(disagg_mode="decode"):
  • 仅加载 VAE Decoder,跳过 Text/Image Encoder 与 DiT。
  • 启动后进入 Phase2 接收等待状态,收到 Transformer 发来的潜空间后执行 VAE 解码并保存输出视频/图像,任务完成状态与结果文件均落在 Decoder 节点。

2. 配置方法

路由和队列参数写在 disagg_config 中。Mooncake 读取 MOONCAKE_CONFIG_PATH 指定的文件(脚本使用 configs/mooncake_config.json),对应的 MOONCAKE_* 环境变量优先。

2.1 T2V 配置示例

Encoder 端(configs/disagg/wan/wan_t2v_disagg_encoder.json):

{
    "infer_steps": 50,
    "num_frames": 81,
    "size": [480, 832],
    "self_attn_1_type": "sage_attn2",
    "cross_attn_1_type": "sage_attn2",
    "sample_guide_scale": 5,
    "sample_shift": 5,
    "enable_cfg": true,
    "cpu_offload": false,
    "fps": 16,
    "disagg_mode": "encoder",
    "disagg_config": {
        "bootstrap_addr": "127.0.0.1",
        "bootstrap_room": 0,
        "sender_engine_rank": 0,
        "receiver_engine_rank": 1
    }
}

Transformer 端(configs/disagg/wan/wan_t2v_disagg_transformer.json):将 disagg_mode 改为 "transformer",并增加 Phase2 相关配置,用于向 Decoder 发送潜空间:

{
    "disagg_mode": "transformer",
    "disagg_config": {
        "bootstrap_addr": "127.0.0.1",
        "bootstrap_room": 0,
        "sender_engine_rank": 0,
        "receiver_engine_rank": 1,
        "decoder_engine_rank": 2,
        "decoder_bootstrap_room": 1
    }
}

Decoder 端(configs/disagg/wan/wan_t2v_disagg_decode.json):仅加载 VAE Decoder,Phase2 接收端;bootstrap_room 需与 Transformer 的 decoder_bootstrap_room 一致:

{
    "disagg_mode": "decode",
    "disagg_config": {
        "bootstrap_addr": "127.0.0.1",
        "bootstrap_room": 1,
        "sender_engine_rank": 1,
        "receiver_engine_rank": 2
    }
}

2.2 I2V 配置示例

I2V 使用 ViT-H/14 CLIP 图像编码器,其完整序列特征包含 257 × 1280 = 328960 个元素。clip_embed_dim 用于预留 CLIP 传输缓冲区容量,必须覆盖实际输出大小;现有示例配置使用 329216。

Encoder 端(configs/disagg/wan/wan_i2v_disagg_encoder.json):

{
    "infer_steps": 40,
    "num_frames": 81,
    "size": [480, 832],
    "self_attn_1_type": "sage_attn2",
    "sample_guide_scale": 5,
    "sample_shift": 3,
    "enable_cfg": true,
    "cpu_offload": false,
    "fps": 16,
    "clip_embed_dim": 329216,
    "disagg_mode": "encoder",
    "disagg_config": {
        "bootstrap_addr": "127.0.0.1",
        "bootstrap_room": 2,
        "sender_engine_rank": 0,
        "receiver_engine_rank": 1
    }
}

329216 是示例配置的缓冲区容量,大于上述输出所需的 328960 个元素。T2V 无 CLIP 编码器,无需此字段;I2V 应显式配置足够的容量,避免缓冲区复制失败。

Transformer 端同样需要 clip_embed_dim: 329216,与 Encoder 端保持一致。

2.3 Decoder 配置示例(三段式)

Wan T2V Decoder 见上文;Qwen Image I2I Decoder 示例(configs/disagg/qwen/qwen_image_i2i_disagg_decode.json):

{
    "task": "i2i",
    "disagg_mode": "decode",
    "infer_steps": 40,
    "vae_z_dim": 16,
    "vae_stride": [1, 8, 8],
    "num_frames": 1,
    "size": [1664, 1664],
    "disagg_config": {
        "bootstrap_addr": "127.0.0.1",
        "bootstrap_room": 2,
        "sender_engine_rank": 1,
        "receiver_engine_rank": 2
    }
}

Decoder 的 bootstrap_room 必须与 Transformer 配置中的 decoder_bootstrap_room 相同;sender_engine_rank / receiver_engine_rank 对应 Phase2 的 Transformer(发送方)与 Decoder(接收方)引擎 rank。

2.4 关键参数说明

参数 说明
disagg_mode 分离部署服务角色:"encoder"、"transformer" 或 "decode"
bootstrap_addr 对端节点 IP(Encoder 连 Transformer;Decoder 连 Transformer)
bootstrap_room Phase1/Phase2 房间号,收发端必须一致;多组服务需不同 room
sender_engine_rank Phase1 中 Encoder 的 rank;Phase2 中 Transformer 的 rank
receiver_engine_rank Phase1 中 Transformer 的 rank;Phase2 中 Decoder 的 rank
decoder_engine_rank 仅 Transformer 配置:Phase2 中 Decoder 的 rank,用于建立 Phase2 发送
decoder_bootstrap_room 仅 Transformer 配置:Phase2 房间号,需与 Decoder 的 bootstrap_room 一致
clip_embed_dim CLIP 传输缓冲区预留的元素容量(仅 I2V 需要,现有示例配置使用 329216)

3. 启动服务与请求流程

LightX2V 使用 lightx2v.server 启动 HTTP API 服务。三段式分离部署的通用原则如下:

启动顺序(建议):

  1. 先启动 Decoder 服务(进入 Phase2 接收等待)。
  2. 再启动 Transformer 服务(等待 Phase1 数据,并准备向 Decoder 发送 Phase2)。
  3. 最后启动 Encoder 服务。

请求与轮询顺序:

  1. 先向 Decoder 发请求,拿到 decoder_task_id(Decoder 开始等待 Phase2 数据)。
  2. 再向 Transformer 发相同 payload 的请求(Transformer 等待 Phase1,收到后跑 DiT,再通过 Phase2 发给 Decoder)。
  3. 再向 Encoder 发相同 payload 的请求(Encoder 编码并通过 Phase1 发给 Transformer)。
  4. 向 Decoder 轮询任务状态:结果文件与 completed 状态均在 Decoder 节点,使用 Decoder 的 task_id 与 Decoder 的 URL 轮询。

原因:Transformer 收到请求后才开始等待 Phase1;Encoder 发送后触发 Transformer 的 DiT;Transformer 完成后通过 Phase2 把潜空间发给已等待的 Decoder;Decoder 完成 VAE 解码并落盘,故任务完成与结果路径以 Decoder 为准。

3.1 Wan2.1 T2V 启动示例(三段式)

参考脚本:scripts/server/disagg/wan/。配置使用带 decoder_engine_rank 的 transformer 与 decode 配置(见 2.1、2.3)。

启动顺序: Decoder → Transformer → Encoder(三端可绑定不同 CUDA_VISIBLE_DEVICES 与端口)。

先启动 Decoder(例如 port 8004):

python -m lightx2v.server \
    --model_cls wan2.1 \
    --task t2v \
    --model_path $model_path \
    --config_json ${lightx2v_path}/configs/disagg/wan/wan_t2v_disagg_decode.json \
    --host 0.0.0.0 \
    --port 8004 \
    --metric_port 18004

再启动 Transformer(例如 --port 8003 --metric_port 18003)、最后启动 Encoder(例如 --port 8002 --metric_port 18002)。各阶段是独立服务,API 与默认启动的指标服务均需使用互不冲突的端口。

发起请求时,Wan 的 T2V / I2V 走视频任务接口 /v1/tasks/video/。三段式请求顺序:先 POST Decoder → 再 POST Transformer → 再 POST Encoder → 轮询 Decoder 状态:

import requests
import time

DECODER_URL = "http://localhost:8004"
TRANSFORMER_URL = "http://localhost:8003"
ENCODER_URL = "http://localhost:8002"
PAYLOAD = {
    "prompt": "Two anthropomorphic cats in boxing gear fight on a spotlighted stage.",
    "negative_prompt": "色调艳丽,过曝,静态",
    "seed": 42,
    "save_result_path": "/path/to/output.mp4",
}

# 1. Decoder 先收请求,进入 Phase2 等待
resp_d = requests.post(f"{DECODER_URL}/v1/tasks/video/", json=PAYLOAD)
decoder_task_id = resp_d.json()["task_id"]

# 2. Transformer 收请求,等待 Phase1 并跑 DiT,再发 Phase2
requests.post(f"{TRANSFORMER_URL}/v1/tasks/video/", json=PAYLOAD)

# 3. Encoder 编码并发送 Phase1
requests.post(f"{ENCODER_URL}/v1/tasks/video/", json=PAYLOAD)

# 4. 轮询 Decoder 获取完成状态与结果路径
while True:
    status = requests.get(f"{DECODER_URL}/v1/tasks/{decoder_task_id}/status").json()
    if status["status"] == "completed":
        print(f"Done: {status['save_result_path']}")
        break
    if status["status"] == "failed":
        raise RuntimeError(status.get("error"))
    time.sleep(5)

3.2 Qwen Image T2I / I2I 启动示例(三段式)

参考脚本:scripts/server/disagg/qwen。Qwen Image 的 T2I / I2I 均支持 Encoder + Transformer + Decoder 三段式,走图片任务接口 /v1/tasks/image/(与 Wan 的 /v1/tasks/video/ 不同)。

启动顺序: 先 Decoder → 再 Transformer → 再 Encoder。T2I 脚本的 API 端口为 Encoder 8002、Transformer 8003、Decoder 8008;I2I 脚本为 Encoder 8012、Transformer 8013、Decoder 8014。

Qwen T2I 三段式

先按 Qwen Image T2I 快速开始 配置模型目录、JSON 中的 DiT 权重路径和 GPU 编号,再依次启动 Decoder、Transformer、Encoder(使用 qwen_image_t2i_disagg_decode.json、qwen_image_t2i_disagg_transformer.json、qwen_image_t2i_disagg_encoder.json)。请求顺序:先 POST Decoder 拿 task_id → 再 POST Transformer → 再 POST Encoder → 轮询 Decoder 的 task_id 状态,结果图在 Decoder 节点保存。

# 启动三端后再执行(脚本内已配置 ENCODER_URL / TRANSFORMER_URL / DECODER_URL 与 ENDPOINT)
python scripts/server/disagg/qwen/post_qwen_t2i.py

Qwen I2I 三段式

同样先启动 Decoder、Transformer、Encoder(使用 qwen_image_i2i_disagg_decode.json、qwen_image_i2i_disagg_transformer.json、qwen_image_i2i_disagg_encoder.json)。可直接使用提供的 3-way 请求脚本:

# 启动三端后再执行(脚本内已配置 ENCODER_URL / TRANSFORMER_URL / DECODER_URL 与 ENDPOINT)
python scripts/server/disagg/qwen/post_qwen_i2i.py

脚本逻辑:先向 Decoder 发请求 → 再向 Transformer 发请求 → 再向 Encoder 发请求 → 轮询 Decoder 完成;结果图默认保存为 save_results/qwen_i2i_disagg_3way.png(在 Decoder 节点)。执行前请在脚本中确认 IMAGE_PATH 指向有效输入图。

3.3 接口约定总结

模型 任务 请求接口 结果与状态轮询
Wan2.1 T2V / I2V /v1/tasks/video/ Decoder 节点
Qwen Image T2I / I2I /v1/tasks/image/ Decoder 节点

启动成功后日志一般会出现:

INFO:     Application startup complete.

4. 去中心化队列:现有实现与入口

当前保留 RDMA 队列、Controller 的 ring 服务、Runner 的队列通信接口和 Qwen 配置,但缺少 Qwen 独立 pull-worker 模块,因此 Qwen 队列模式暂不能完整启动。

4.1 组件与数据流

队列设计将请求派发与推理分离:Encoder 将任务元数据写入 Phase1 ring,Transformer 消费任务并将下一阶段元数据写入 Phase2 ring,Decoder 消费后完成解码。Controller 维护 ring 和握手服务。

Encoder → Phase1 RDMA ring → Transformer → Phase2 RDMA ring → Decoder
                   ↑                              ↑
                   └──── Controller ring 服务 ────┘
组件 当前实现与作用
RDMA ring RDMABuffer 提供元数据缓冲区
Controller ControllerService 的 serve_rdma_dispatch_only() 提供 request、Phase1、Phase2 ring 服务
Runner 通信 DisaggMixin 实现队列连接、请求快照及 Transformer/Decoder 的 dispatch 准备

DisaggMixin 的源码还注明多消费者排序限制:当前 FAA 实现不是跨进程的真正远端原子操作。多 worker 并发的正确性需要单独验证,不能仅依据 rank 配置推断。

4.2 配置参考

以下配置仍位于当前仓库,模型路径和后端需按实际环境调整:

角色 配置文件
Controller qwen_image_t2i_disagg_controller.json
Encoder qwen_image_t2i_disagg_encoder_decentralized.json
Transformer qwen_image_t2i_disagg_transformer_decentralized.json
Decoder qwen_image_t2i_disagg_decode_decentralized.json

Encoder、Transformer、Decoder 的 disagg_config 使用 decentralized_queue: true 选择队列通信;Controller 配置定义 ring 服务。主要字段如下:

字段 含义
rdma_request_handshake_port Controller request ring 握手端口,示例为 5566
rdma_phase1_handshake_port Phase1 ring 握手端口,相关组件需保持一致,示例为 5567
rdma_phase2_handshake_port Phase2 ring 握手端口,相关组件需保持一致,示例为 5568
rdma_phase1_host / rdma_phase2_host 对应 ring 的握手主机地址
rdma_buffer_slots / rdma_buffer_slot_size 元数据 ring 的槽数和每槽字节数,示例为 128 和 4096
receiver_engine_rank / transformer_engine_rank Transformer 的接收与执行 rank,按角色保持一致;不同 worker 使用不同 rank
decoder_engine_rank Decoder 的 rank,相关组件使用相同值

4.3 当前可选入口

使用场景 现有入口与适用范围
Qwen Image 三阶段 HTTP 服务 使用 T2I 快速开始中的启动和请求脚本,先配置模型目录、DiT 权重、GPU 和依赖
Wan 动态分离调度 参阅 Disagg 使用说明和 run_dynamic.sh,按拓扑配置路径、设备与网络;启动脚本会清理旧服务
单独启动 Wan 服务角色 run_service.py 接收 --service encoder/transformer/decoder/controller;当前服务实现加载 Wan 组件

run_service.py 仅适用于 Wan,不能替代 Qwen 的 pull-worker。

4.4 请求与分发字段的边界

DisaggMixin 的内部请求快照使用 data_bootstrap_room 标识传输 room,并可携带 disagg_phase1_receiver_engine_rank 选择 Transformer rank;save_result_path 表示输出路径。这些是内部配置/分发字段,不能直接视为 HTTP 请求字段。

当前 HTTP schema 禁止额外字段,ImageTaskRequest 未声明上述 room 和 rank 字段。HTTP 使用第 3 节的现有请求脚本;队列模式的任务完成回传、轮询端点和 Decoder 结果交付仍需随完整 worker 实现验证。

5. RDMA vs TCP 协议选择

特性 RDMA TCP
传输机制 网卡直接内存访问(Zero-Copy),完全绕过 OS 内核 走 Kernel 网络协议栈
CPU 开销 极低 较高
延迟 微秒级 毫秒级
硬件要求 需 InfiniBand / RoCE 网卡 任意网络
推荐场景 生产多机部署 单机验证、无 RDMA 硬件环境

启动前设置 export MOONCAKE_PROTOCOL=tcp 可让 Mooncake 使用 TCP;去中心化队列仍需 RDMA 硬件。