[Diffusion] Make auto residency decisions component-scoped (#34615)

This commit is contained in:
Xiaoyu Zhang
2026-08-13 23:20:55 +08:00
committed by GitHub
parent 07821e9d56
commit 82f7afb881
2 changed files with 109 additions and 8 deletions
@@ -11,10 +11,12 @@ from sglang.multimodal_gen.configs.pipeline_configs.model_deployment_config impo
ModelDeploymentConfig, ModelDeploymentConfig,
) )
from sglang.multimodal_gen.runtime.managers.memory_managers.layerwise_offload_components import ( from sglang.multimodal_gen.runtime.managers.memory_managers.layerwise_offload_components import (
LAYERWISE_OFFLOAD_ALL_COMPONENTS,
LAYERWISE_OFFLOAD_DIT_GROUP, LAYERWISE_OFFLOAD_DIT_GROUP,
LAYERWISE_OFFLOAD_IMAGE_ENCODER_GROUP, LAYERWISE_OFFLOAD_IMAGE_ENCODER_GROUP,
LAYERWISE_OFFLOAD_TEXT_ENCODER_GROUP, LAYERWISE_OFFLOAD_TEXT_ENCODER_GROUP,
LAYERWISE_OFFLOAD_VAE_GROUP, LAYERWISE_OFFLOAD_VAE_GROUP,
normalize_layerwise_offload_components,
) )
from sglang.multimodal_gen.runtime.platforms import current_platform from sglang.multimodal_gen.runtime.platforms import current_platform
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
@@ -122,13 +124,31 @@ class ServerArgsAutoTuner:
def maybe_adjust_auto_component_residency_after_offload(self) -> None: def maybe_adjust_auto_component_residency_after_offload(self) -> None:
args = self.server_args args = self.server_args
if ( if args.performance_mode != "auto" or current_platform.is_cpu():
args.performance_mode != "auto"
or self._explicit_memory_policy
or current_platform.is_cpu()
):
return return
# Explicitness is component-scoped below. For example, explicitly
# disabling DiT layerwise offload must not freeze an unrelated,
# implicit ``dit_cpu_offload=True`` default on a high-memory GPU.
# Each mutation below already preserves its own explicit CLI flag.
explicit_cpu_components = args.is_arg_explicitly_set("cpu_offload_components")
explicit_layerwise_components = (
normalize_layerwise_offload_components(args.layerwise_offload_components)
if args.is_arg_explicitly_set("layerwise_offload_components")
else None
)
explicit_dit_layerwise = bool(
args.is_arg_explicitly_set("dit_layerwise_offload")
and args.dit_layerwise_offload
) or bool(
explicit_layerwise_components
and (
LAYERWISE_OFFLOAD_DIT_GROUP in explicit_layerwise_components
or LAYERWISE_OFFLOAD_ALL_COMPONENTS in explicit_layerwise_components
)
)
min_available_gb = self._get_min_available_device_memory_gb() min_available_gb = self._get_min_available_device_memory_gb()
deployment_config = self._deployment_config() deployment_config = self._deployment_config()
disable_threshold_gb = self._resolve_keep_resident_min_available_gb( disable_threshold_gb = self._resolve_keep_resident_min_available_gb(
@@ -161,6 +181,8 @@ class ServerArgsAutoTuner:
args.dit_cpu_offload args.dit_cpu_offload
and "dit" in components and "dit" in components
and not args.is_arg_explicitly_set("dit_cpu_offload") and not args.is_arg_explicitly_set("dit_cpu_offload")
and not explicit_cpu_components
and not explicit_dit_layerwise
): ):
args.dit_cpu_offload = False args.dit_cpu_offload = False
changed.append("dit_cpu_offload=False") changed.append("dit_cpu_offload=False")
@@ -168,6 +190,7 @@ class ServerArgsAutoTuner:
args.text_encoder_cpu_offload args.text_encoder_cpu_offload
and LAYERWISE_OFFLOAD_TEXT_ENCODER_GROUP in components and LAYERWISE_OFFLOAD_TEXT_ENCODER_GROUP in components
and not args.is_arg_explicitly_set("text_encoder_cpu_offload") and not args.is_arg_explicitly_set("text_encoder_cpu_offload")
and not explicit_cpu_components
): ):
args.text_encoder_cpu_offload = False args.text_encoder_cpu_offload = False
changed.append("text_encoder_cpu_offload=False") changed.append("text_encoder_cpu_offload=False")
@@ -175,6 +198,7 @@ class ServerArgsAutoTuner:
args.image_encoder_cpu_offload args.image_encoder_cpu_offload
and LAYERWISE_OFFLOAD_IMAGE_ENCODER_GROUP in components and LAYERWISE_OFFLOAD_IMAGE_ENCODER_GROUP in components
and not args.is_arg_explicitly_set("image_encoder_cpu_offload") and not args.is_arg_explicitly_set("image_encoder_cpu_offload")
and not explicit_cpu_components
): ):
args.image_encoder_cpu_offload = False args.image_encoder_cpu_offload = False
changed.append("image_encoder_cpu_offload=False") changed.append("image_encoder_cpu_offload=False")
@@ -182,6 +206,7 @@ class ServerArgsAutoTuner:
args.vae_cpu_offload args.vae_cpu_offload
and LAYERWISE_OFFLOAD_VAE_GROUP in components and LAYERWISE_OFFLOAD_VAE_GROUP in components
and not args.is_arg_explicitly_set("vae_cpu_offload") and not args.is_arg_explicitly_set("vae_cpu_offload")
and not explicit_cpu_components
): ):
args.vae_cpu_offload = False args.vae_cpu_offload = False
changed.append("vae_cpu_offload=False") changed.append("vae_cpu_offload=False")
@@ -998,6 +998,80 @@ class TestOffloadDefaults(unittest.TestCase):
self.assertTrue(args.dit_layerwise_offload) self.assertTrue(args.dit_layerwise_offload)
self.assertEqual(args.layerwise_offload_components, ["dit"]) self.assertEqual(args.layerwise_offload_components, ["dit"])
def test_explicit_layerwise_false_keeps_independent_auto_residency(self):
args = self._from_dict_with_pipeline_config(
QwenImagePipelineConfig(),
kwargs={
"performance_mode": "auto",
"dit_layerwise_offload": False,
},
)
self.assertFalse(args.dit_layerwise_offload)
self.assertFalse(args.dit_cpu_offload)
def test_explicit_dit_cpu_offload_is_preserved_by_auto_residency(self):
args = self._from_dict_with_pipeline_config(
QwenImagePipelineConfig(),
kwargs={
"performance_mode": "auto",
"dit_layerwise_offload": False,
"dit_cpu_offload": True,
},
)
self.assertFalse(args.dit_layerwise_offload)
self.assertTrue(args.dit_cpu_offload)
def test_explicit_layerwise_true_preserves_initial_dit_residency(self):
args = self._from_dict_with_pipeline_config(
QwenImagePipelineConfig(),
kwargs={
"performance_mode": "auto",
"dit_layerwise_offload": True,
},
)
self.assertTrue(args.dit_layerwise_offload)
self.assertTrue(args.dit_cpu_offload)
def test_explicit_vae_cpu_offload_is_preserved_by_auto_residency(self):
args = self._from_dict_with_pipeline_config(
QwenImagePipelineConfig(),
kwargs={
"performance_mode": "auto",
"dit_layerwise_offload": False,
"vae_cpu_offload": True,
},
)
self.assertFalse(args.dit_cpu_offload)
self.assertTrue(args.vae_cpu_offload)
def test_explicit_cpu_offload_components_are_preserved_by_auto_residency(self):
args = self._from_dict_with_pipeline_config(
QwenImagePipelineConfig(),
kwargs={
"performance_mode": "auto",
"cpu_offload_components": ["dit", "vae"],
},
)
self.assertTrue(args.dit_cpu_offload)
self.assertTrue(args.vae_cpu_offload)
def test_explicit_dit_layerwise_component_preserves_initial_residency(self):
args = self._from_dict_with_pipeline_config(
QwenImagePipelineConfig(),
kwargs={
"performance_mode": "auto",
"layerwise_offload_components": ["dit"],
},
)
self.assertTrue(args.dit_cpu_offload)
self.assertEqual(args.layerwise_offload_components, ["dit"])
def test_pipeline_configs_declare_auto_tune_hints(self): def test_pipeline_configs_declare_auto_tune_hints(self):
qwen_deployment = QwenImagePipelineConfig().get_model_deployment_config() qwen_deployment = QwenImagePipelineConfig().get_model_deployment_config()
wan_deployment = WanT2V480PConfig().get_model_deployment_config() wan_deployment = WanT2V480PConfig().get_model_deployment_config()
@@ -1724,10 +1798,12 @@ class TestOffloadDefaults(unittest.TestCase):
self.assertFalse(args.use_fsdp_inference) self.assertFalse(args.use_fsdp_inference)
self.assertTrue(args.enable_cfg_parallel) self.assertTrue(args.enable_cfg_parallel)
self.assertTrue(args.dit_cpu_offload) # Explicit FSDP selection must not freeze unrelated, implicit DiT
# residency decisions on a high-memory GPU.
self.assertFalse(args.dit_cpu_offload)
self.assertFalse(args.vae_cpu_offload) self.assertFalse(args.vae_cpu_offload)
# explicit use_fsdp_inference skips the residency pass, but the layerwise # The layerwise filter still drops VAE (kept resident); encoders stay
# filter still drops vae (kept resident); encoders stay offloaded # offloaded.
self.assertEqual( self.assertEqual(
args.layerwise_offload_components, args.layerwise_offload_components,
["text_encoder", "image_encoder"], ["text_encoder", "image_encoder"],