173 lines
7.8 KiB
Markdown
173 lines
7.8 KiB
Markdown
# 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.
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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](https://github.com/vllm-project/vllm-omni/blob/main/recipes/Tencent/HunyuanImage-3.0-Instruct.md).
|
|
|
|
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: true` and use request-level
|
|
execution, or select `dense_legacy` for step execution.
|
|
- Imported AR-KV rejection: `paged_scheduler` does not consume the
|
|
`ar_diffusion_kv` contract 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](../../design/feature/diffusion_paged_kv_cache.md).
|