[Diffusion] Make DLO host weight cache opt-in

Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
This commit is contained in:
Hongsheng Liu committed 2026-08-19 11:23:36 +08:00
1 parent 75af33a76f
commit 16642dc2e8
12 files changed
+85 -20

No files matched your search

@@ -44,10 +44,12 @@ DLO weight collective.
Host storage is selected separately from the transfer protocol. The loader can
produce a direct-checkpoint mmap plan for a proven-compatible runtime layout;
otherwise it uses the ordinary loader. In no-AllGather mode, the Phase B host
weight cache automatically normalizes supported final ordinary-loader DiT
tensors into an immutable node-local mmap entry. Consequently, replicas can
share either proven-compatible checkpoint pages or equivalent final runtime
layouts. An opt-in host-registration budget can make the complete final mapping
weight cache can explicitly normalize supported final ordinary-loader DiT
tensors into an immutable node-local mmap entry. Ordinary pinned weights remain
the default after checkpoint mmap fallback because bounded cache staging can
reduce throughput. Replicas can share either proven-compatible checkpoint pages
or, when selected, equivalent final runtime layouts. An opt-in
host-registration budget can make the complete final mapping
directly H2D-copyable when the platform provides a backend, avoiding the
recurrent host packing otherwise required by mmap. CUDA is the first
implementation.
@@ -130,9 +132,12 @@ flowchart TB
The configuration fields are routed to the component that can enforce their
contract. The cache root and lock timeout are consumed by the loader.
`dlo_use_host_weight_cache` explicitly selects final-layout cache publication
after direct-checkpoint mmap fallback. It defaults to false so the ordinary
pinned-loader path remains available without requiring an opt-out.
`dlo_host_weight_cache_pin_limit_gib` is also visible while loading because a
positive value deliberately selects the transform-complete host weight cache;
the backend later consumes the same budget for registration.
positive value also deliberately selects the transform-complete host weight
cache; the backend later consumes the same budget for registration.
`dlo_use_allgather` controls loader plan routing because the host weight cache
is no-AllGather-only, and it selects the backend transfer protocol. This is
coordination through typed configuration and `HostWeightPlan`, not through
@@ -425,8 +430,10 @@ or failed registration retains the bounded staging behavior.
When direct mmap preflight fails, the regular model loader remains responsible
for preparing each rank's weights, including TP-local tensors or HSDP-managed
parameters. Supported CPU layouts then enter the host weight cache
automatically. Unsupported layouts keep one private runtime copy per process.
parameters. Those ordinary pinned tensors remain the default. When the host
weight cache or a positive registration budget is explicitly selected,
supported CPU layouts enter the cache; unsupported layouts keep one private
runtime copy per process.
This mode means:
@@ -447,7 +454,8 @@ The Phase B cache preserves the same ownership boundary. DLO neither derives
cache keys nor interprets model loaders. No-AllGather DLO first attempts a
compatible direct-checkpoint mmap plan. When that plan is unavailable, every
rank completes the ordinary loader, custom callbacks, post-load processing,
strict validation, and calibration. The loader then automatically:
strict validation, and calibration. When cache use or registration is
explicitly selected, the loader:
1. discovers final CPU DiT parameters and persistent buffers;
2. rejects unsupported non-contiguous, aliased, quantized, distributed, or
@@ -38,6 +38,12 @@ vllm serve /path/to/model --omni \
--enable-distributed-layerwise-offload \
--dlo-no-use-allgather
# Share final host weights with bounded pinned staging
vllm serve /path/to/model --omni \
--enable-distributed-layerwise-offload \
--dlo-no-use-allgather \
--dlo-use-host-weight-cache
# Share final host weights and register up to 80 GiB per worker for direct H2D
vllm serve /path/to/model --omni \
--enable-distributed-layerwise-offload \
@@ -52,12 +58,15 @@ vllm serve /path/to/model --omni \
| --- | --- | --- |
| `--enable-distributed-layerwise-offload` | Enable DLO | `false` |
| `--dlo-no-use-allgather` | Stream complete rank-local blocks independently | `false` |
| `--dlo-host-weight-cache-pin-limit-gib GIB` | Per-worker registration budget; zero uses bounded host staging | `0` |
| `--dlo-use-host-weight-cache` | Use the final-layout cache after checkpoint mmap fallback | `false` |
| `--dlo-host-weight-cache-pin-limit-gib GIB` | Per-worker registration budget; positive values also select the cache | `0` |
| `--dlo-resident-layers N` | Keep eligible leading DiT blocks resident in HBM | `0` |
No-AllGather DLO automatically uses a compatible checkpoint mmap plan, or
builds/joins the final-layout host weight cache after ordinary loading when a
checkpoint plan is unavailable. The cache uses
No-AllGather DLO automatically uses a compatible checkpoint mmap plan. When
checkpoint mmap is unavailable, it preserves ordinary pinned loader weights by
default. `--dlo-use-host-weight-cache` explicitly selects the final-layout
cache with bounded staging; a positive registration budget also selects the
cache and attempts direct H2D. The cache uses
`~/.cache/vllm-omni/dlo-host-weights`. Programmatic configuration may override
`dlo_host_weight_cache_dir` and the writer lock timeout; these advanced storage
controls are intentionally not separate CLI flags.
@@ -68,6 +77,10 @@ controls are intentionally not separate CLI flags.
directory. Do not use tmpfs or a cross-node filesystem for this version.
- Cache entries are immutable and validated before use. A cache or registration
failure keeps the ordinary loader weights or falls back to bounded staging.
- The bounded-staging cache is a memory-first mode: recurrent pageable-mmap to
pinned-slot copies can reduce throughput, especially across concurrent TP
engines. Keep ordinary pinned weights unless the host-memory saving is worth
that tradeoff, or use a validated registered path.
- A positive registration budget must cover the complete page-aligned mapping
reported in the worker log. Registration is all-or-nothing.
- CUDA is the first registration backend. Platforms without an equivalent
+14 -2
View File
@@ -912,12 +912,24 @@ def test_structured_diffusion_config_rejects_invalid_compile_granularity():
("enable_dlo", "use_allgather"),
[(False, False), (True, True)],
)
def test_structured_diffusion_config_restricts_host_weight_registration_to_no_allgather_dlo(enable_dlo, use_allgather):
@pytest.mark.parametrize(
("field_name", "field_value"),
[
("dlo_use_host_weight_cache", True),
("dlo_host_weight_cache_pin_limit_gib", 1.0),
],
)
def test_structured_diffusion_config_restricts_host_weight_cache_to_no_allgather_dlo(
enable_dlo,
use_allgather,
field_name,
field_value,
):
with pytest.raises(ValueError, match="requires no-AllGather distributed layerwise offload"):
omni_config_module._DiffusionConfigProjection(
enable_distributed_layerwise_offload=enable_dlo,
dlo_use_allgather=use_allgather,
dlo_host_weight_cache_pin_limit_gib=1.0,
**{field_name: field_value},
)
@@ -375,7 +375,7 @@ def test_dlo_plan_loads_component_sources_outside_planned_dit(monkeypatch):
assert loader.take_host_weight_plan() is plan
def test_dlo_plan_fallback_runs_ordinary_loader_then_cache(monkeypatch):
def test_dlo_plan_fallback_retains_ordinary_loader_weights_by_default(monkeypatch):
import vllm_omni.diffusion.model_loader.diffusers_loader as loader_mod
import vllm_omni.diffusion.model_loader.host_weight_cache as cache_mod
@@ -402,14 +402,13 @@ def test_dlo_plan_fallback_runs_ordinary_loader_then_cache(monkeypatch):
lambda *_args, **_kwargs: HostWeightPlanResult(None, "not direct-compatible"),
)
def build_cache(_pipeline, **_kwargs):
calls.append("cache")
return HostWeightPlanResult(None, "unsupported test layout", "unsupported_layout")
def build_cache(*_args, **_kwargs):
pytest.fail("host weight cache must require explicit selection")
monkeypatch.setattr(cache_mod, "build_host_weight_cache_plan", build_cache)
assert loader.load_model(load_device="cpu") is model
assert calls == ["load", "process", "cache"]
assert calls == ["load", "process"]
assert loader.take_host_weight_plan() is None
@@ -434,6 +433,7 @@ def test_dlo_host_weight_cache_is_built_after_final_post_load_mutation(monkeypat
quantization_config=None,
enable_distributed_layerwise_offload=True,
dlo_use_allgather=False,
dlo_use_host_weight_cache=True,
dlo_host_weight_cache_dir=str(tmp_path),
dlo_host_weight_cache_lock_timeout=1.0,
model="unused",
@@ -567,6 +567,7 @@ def test_dlo_host_weight_cache_failure_retains_ordinary_weights(monkeypatch, tmp
quantization_config=None,
enable_distributed_layerwise_offload=True,
dlo_use_allgather=False,
dlo_use_host_weight_cache=True,
dlo_host_weight_cache_dir=str(tmp_path),
model="unused",
)
@@ -328,6 +328,7 @@ def test_serve_cli_forwards_distributed_offload_residency():
"--omni",
"--enable-distributed-layerwise-offload",
"--dlo-no-use-allgather",
"--dlo-use-host-weight-cache",
"--dlo-host-weight-cache-pin-limit-gib",
"80",
"--dlo-resident-layers",
@@ -341,10 +342,12 @@ def test_serve_cli_forwards_distributed_offload_residency():
assert args.enable_distributed_layerwise_offload is True
assert args.dlo_use_allgather is False
assert args.dlo_use_host_weight_cache is True
assert args.dlo_host_weight_cache_pin_limit_gib == 80
assert args.dlo_resident_layers == 20
assert engine_args["enable_distributed_layerwise_offload"] is True
assert engine_args["dlo_use_allgather"] is False
assert engine_args["dlo_use_host_weight_cache"] is True
assert engine_args["dlo_host_weight_cache_dir"] is None
assert engine_args["dlo_host_weight_cache_lock_timeout"] == 600.0
assert engine_args["dlo_host_weight_cache_pin_limit_gib"] == 80
+3
View File
@@ -688,6 +688,7 @@ class _DiffusionConfigProjection:
enable_layerwise_offload: bool = False
enable_distributed_layerwise_offload: bool = False
dlo_use_allgather: bool = True
dlo_use_host_weight_cache: bool = False
dlo_host_weight_cache_dir: str | None = None
dlo_host_weight_cache_lock_timeout: float = Field(default=600.0, gt=0)
dlo_host_weight_cache_pin_limit_gib: float = Field(default=0.0, ge=0)
@@ -762,6 +763,8 @@ class _DiffusionConfigProjection:
not self.enable_distributed_layerwise_offload or self.dlo_use_allgather
):
raise ValueError("dlo_host_weight_cache_pin_limit_gib requires no-AllGather distributed layerwise offload")
if self.dlo_use_host_weight_cache and (not self.enable_distributed_layerwise_offload or self.dlo_use_allgather):
raise ValueError("dlo_use_host_weight_cache requires no-AllGather distributed layerwise offload")
if self.tf_model_config is None:
self.tf_model_config = TransformerConfig()
+1
View File
@@ -382,6 +382,7 @@ class StageDeployConfig:
enable_distributed_layerwise_offload: bool | None = None
dlo_use_allgather: bool | None = None
dlo_use_host_weight_cache: bool | None = None
dlo_host_weight_cache_dir: str | None = None
dlo_host_weight_cache_lock_timeout: float | None = None
dlo_host_weight_cache_pin_limit_gib: float | None = None
+6
View File
@@ -708,6 +708,10 @@ class OmniDiffusionConfig:
# This avoids AllGather synchronization, while host memory follows the
# loader's existing rank-local layout instead of adding a second DP shard.
dlo_use_allgather: bool = True
# Opt into publishing/joining the final-layout host weight cache when a
# compatible direct-checkpoint mmap plan is unavailable. A positive pin
# limit also selects the cache because registration requires its layout.
dlo_use_host_weight_cache: bool = False
# Shared local-disk root. None selects ~/.cache/vllm-omni/dlo-host-weights.
dlo_host_weight_cache_dir: str | None = None
# Maximum wait for the per-layout POSIX writer lock.
@@ -951,6 +955,8 @@ class OmniDiffusionConfig:
not self.enable_distributed_layerwise_offload or self.dlo_use_allgather
):
raise ValueError("dlo_host_weight_cache_pin_limit_gib requires no-AllGather distributed layerwise offload")
if self.dlo_use_host_weight_cache and (not self.enable_distributed_layerwise_offload or self.dlo_use_allgather):
raise ValueError("dlo_use_host_weight_cache requires no-AllGather distributed layerwise offload")
if self.diffusion_compile_granularity not in {"regional", "full"}:
raise ValueError(
"diffusion_compile_granularity must be 'regional' or 'full', "
@@ -550,6 +550,14 @@ class DiffusersPipelineLoader:
return
if getattr(self.od_config, "dlo_use_allgather", True):
return
if not (
getattr(self.od_config, "dlo_use_host_weight_cache", False)
or float(getattr(self.od_config, "dlo_host_weight_cache_pin_limit_gib", 0.0)) > 0
):
logger.info(
"DLO host weight cache not selected; retaining ordinary host tensors after checkpoint mmap fallback"
)
return
parallel_config = self.parallel_config
tp_size = int(getattr(parallel_config, "tensor_parallel_size", 1))
+1
View File
@@ -545,6 +545,7 @@ class OrchestratorArgs:
enable_layerwise_offload: bool = False
enable_distributed_layerwise_offload: bool = False
dlo_use_allgather: bool = True
dlo_use_host_weight_cache: bool = False
dlo_host_weight_cache_dir: str | None = None
dlo_host_weight_cache_lock_timeout: float = 600.0
dlo_host_weight_cache_pin_limit_gib: float = 0.0
+1
View File
@@ -1040,6 +1040,7 @@ class AsyncOmniEngine:
"enable_layerwise_offload": kwargs.get("enable_layerwise_offload", False),
"enable_distributed_layerwise_offload": kwargs.get("enable_distributed_layerwise_offload", False),
"dlo_use_allgather": kwargs.get("dlo_use_allgather", True),
"dlo_use_host_weight_cache": kwargs.get("dlo_use_host_weight_cache", False),
"dlo_host_weight_cache_dir": kwargs.get("dlo_host_weight_cache_dir", None),
"dlo_host_weight_cache_lock_timeout": kwargs.get("dlo_host_weight_cache_lock_timeout", 600.0),
"dlo_host_weight_cache_pin_limit_gib": kwargs.get("dlo_host_weight_cache_pin_limit_gib", 0.0),
+8
View File
@@ -722,6 +722,14 @@ class OmniServeCommand(CLISubcommand):
"independently (including existing TP shards)."
),
)
omni_config_group.add_argument(
"--dlo-use-host-weight-cache",
action="store_true",
help=(
"Use the node-local final-layout host weight cache when direct checkpoint mmap is unavailable. "
"This trades recurrent host staging work for shared host pages unless direct registration succeeds."
),
)
omni_config_group.add_argument(
"--dlo-host-weight-cache-pin-limit-gib",
type=float,