Scheduler-Managed Paged KV Cache¶
Scheduler-managed paged KV cache stores diffusion DiT key/value tensors in Worker-owned pages. It is useful when a denoising request should keep its stable prompt/reference prefix in device memory while rewriting only the changing image span on later steps. The current HunyuanImage-3.0 integration is request-level only; it does not silently change an unsupported request to dense attention.
Paging changes KV storage and scheduling ownership; it does not change the model's causal/full attention semantics.
Choose a mode¶
| Need | Mode |
|---|---|
| Broadest compatibility or step execution | dense_legacy (default) |
| HunyuanImage-3.0 request-mode serving with Scheduler-managed KV pages | paged_scheduler |
Use dense_legacy when the model, attention backend, or offload combination has not been validated for paged KV. HunyuanImage-3.0 paged KV currently accepts request-level execution only; set step_execution: false.
Supported scope¶
| Model | Platform | Execution | Backend | Status |
|---|---|---|---|---|
| HunyuanImage-3.0 | NVIDIA CUDA | Request-level | FLASH_ATTN (native FlashAttention/FA3) | Implemented and validated |
| HunyuanImage-3.0 | Ascend NPU | Request-level | FLASH_ATTN (Ascend FIA) | Implemented and validated |
| Other diffusion models | Any | N/A | Any | Not integrated or tested |
Only the logical FLASH_ATTN backend currently advertises paged-KV support. TORCH_SDPA, CUDNN_ATTN, FLASHINFER_ATTN, SAGE, Hub, and other diffusion backends do not transparently fall back to dense execution for a paged request.
Strict Ulysses SP and two-branch CFG parallel are supported in HunyuanImage-3.0 request mode when the selected device topology has been validated. Ring SP, AllGather-KV SP, Hunyuan paged step execution, and independent public-request batching are not supported by this path. DreamZero and LingBot-World use the separate ar_diffusion_kv imported-AR-KV contract.
Configure¶
The diffusion KV fields are stage settings. The two diffusion_kv_* fields are diffusion-specific engine fields and are forwarded through engine_extras; kv_cache_memory_bytes is a standard stage field and is placed directly under the stage.
Set pipeline: hunyuan_image3_dit to select the standalone DiT pipeline, where stage 0 is the diffusion stage.
pipeline: hunyuan_image3_dit
stages:
- stage_id: 0
max_num_seqs: 1
enforce_eager: true
diffusion_attention_backend: FLASH_ATTN
step_execution: false
kv_cache_memory_bytes: 536870912 # 512 MiB per Worker/rank
engine_extras:
diffusion_kv_mode: paged_scheduler
diffusion_kv_max_rows_per_request: 2
| Field | Required | Meaning |
|---|---|---|
diffusion_kv_mode | Yes | paged_scheduler enables Scheduler-managed pages; dense_legacy is the default |
diffusion_kv_max_rows_per_request | Yes for paged | Positive Worker row limit, including all internal CFG branches; use 1 without CFG and 2 for standard CFG |
kv_cache_memory_bytes | Optional | Explicit physical KV-pool budget per Worker/rank; omit it to use automatic sizing |
gpu_memory_utilization | Optional | Automatic pool-sizing fraction when no explicit byte budget is set |
max_num_seqs | Recommended 1 | Public request capacity; it is separate from the internal CFG row limit |
step_execution | Must be false | Hunyuan paged KV is request-level only |
diffusion_attention_backend | FLASH_ATTN | Required logical backend for the current paged implementation |
kv_cache_memory_bytes describes pool capacity, not live payload. Reserved memory can therefore exceed the memory currently used by active requests. The Scheduler allocates all rows belonging to one request together: a request with CFG disabled has one row, while standard two-branch CFG has two rows. CFG rows are internal branches, not independent public requests.
Paged KV is currently unquantized BF16. diffusion_kv_cache_dtype does not enable quantized paged KV, and model weight quantization has not been validated in combination with this mode. CPU offload, layerwise offload, and distributed layerwise offload (DLO) are currently untested with paged KV. Leave these options disabled for paged KV; use dense_legacy when offload is required.
Hunyuan request-mode example¶
Create a small deploy overlay (for example, hunyuan_image3_paged.yaml) with the stage settings above, then start the validated Hunyuan request-mode path:
vllm serve tencent/HunyuanImage-3.0-Instruct \
--omni \
--trust-remote-code \
--port 8091 \
--deploy-config /path/to/hunyuan_image3_paged.yaml
The base Hunyuan DiT deploy file can be reused and overridden from the command line when a separate overlay is inconvenient:
vllm serve tencent/HunyuanImage-3.0-Instruct \
--omni \
--trust-remote-code \
--deploy-config vllm_omni/deploy/hunyuan_image3_dit.yaml \
--stage-overrides \
'{"0":{"diffusion_kv_mode":"paged_scheduler","diffusion_kv_max_rows_per_request":2,"kv_cache_memory_bytes":536870912,"step_execution":false,"diffusion_attention_backend":"FLASH_ATTN"}}'
After the server is ready, send the normal Hunyuan image-generation request:
curl -s http://localhost:8091/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"modalities": ["image"],
"messages": [{"role": "user", "content": "A red ceramic vase on a wooden table"}],
"extra_body": {
"height": 1024,
"width": 1024,
"num_inference_steps": 20,
"guidance_scale": 5.0,
"seed": 1234
}
}' | jq -r '.choices[0].message.content[0].image_url.url' \
| cut -d',' -f2- | base64 -d > hunyuan_image3_paged.png
The same configuration is shown in the HunyuanImage-3.0 recipe.
Confirm from startup and worker logs that the resolved backend is FLASH_ATTN and that the paged native path is active. A paged request must fail explicitly if its Worker metadata or native backend is unavailable; it must not silently switch to dense attention.
Parallelism¶
Hunyuan request-mode paged KV can be combined with tensor parallelism, strict Ulysses SP, or two-way CFG parallel when the selected topology has been validated. Configure the topology in the stage's existing parallel_config:
| Setting | User-visible effect | Paged-KV requirement |
|---|---|---|
tensor_parallel_size | Shards model weights across ranks | Device count must match the stage topology |
sequence_parallel_size + strict Ulysses | Shards the sequence across ranks | Ring and AllGather-KV modes are not supported |
cfg_parallel_size: 2 | Places the positive and negative branches on separate ranks | Set diffusion_kv_max_rows_per_request to at least 2 |
max_num_seqs controls public request concurrency and is independent of the internal CFG row limit. Keep max_num_seqs: 1 for the current Hunyuan paged path; increasing it does not enable independent request batching.
Troubleshooting¶
paged_scheduler requires diffusion_kv_max_rows_per_request: add a positive stage value and include all CFG rows.- Unsupported backend error: select
FLASH_ATTN; the other attention backends currently do not implement the paged-KV capability. - Step-mode rejection: remove
step_execution: trueand use request-level execution, or selectdense_legacyfor step execution. - Imported AR-KV rejection:
paged_schedulerdoes not consume thear_diffusion_kvcontract used by DreamZero or LingBot-World. - Missing image output: include
"modalities": ["image"]when using the chat completions endpoint, and decode the returned data URI as shown above.
For the ownership and lifecycle contract, see the Scheduler-managed paged KV design.