[diffusion] fix: fix local-path detection for MiniMax-H3 and other non-diffusers models (#33365)

Co-authored-by: Mick <mickjagger19@icloud.com>
This commit is contained in:
TobyMint
2026-08-04 14:03:35 +08:00
committed by GitHub
co-authored by Mick
parent 4494fb96b2
commit 101bb2327c
4 changed files with 60 additions and 50 deletions
+12 -15
View File
@@ -9,7 +9,6 @@ from huggingface_hub import HfApi
from sglang.srt.environ import envs
from sglang.utils import (
has_diffusion_overlay_registry_match,
is_known_non_diffusers_diffusion_model,
load_diffusion_overlay_registry_from_env,
)
@@ -25,14 +24,14 @@ def _is_overlay_diffusion_model(model_path: str) -> bool:
return has_diffusion_overlay_registry_match(model_path, _load_overlay_registry())
def _is_registered_diffusion_model(model_path: str) -> bool:
def _is_diffusion_model_from_registry(model_path: str) -> bool:
try:
from sglang.multimodal_gen.registry import has_registered_diffusion_model_path
from sglang.multimodal_gen.registry import is_registered_diffusion_model_path
except ImportError:
# if diffusion dependencies are not installed
return False
return has_registered_diffusion_model_path(model_path)
return is_registered_diffusion_model_path(model_path)
def _is_diffusers_model_dir(model_dir: str) -> bool:
@@ -59,8 +58,9 @@ def _is_gated_diffusion_repo(repo_id: str) -> bool:
def get_is_diffusion_model(model_path: str) -> bool:
"""Detect whether model_path points to a diffusion model.
For local directories, checks the filesystem directly.
For HF/ModelScope model IDs, attempts to fetch only model_index.json.
For registered models, consults the diffusion registry first.
For other local directories, checks the filesystem directly.
For other HF/ModelScope model IDs, attempts to fetch only model_index.json.
For gated repos where file download fails, falls back to HF model card
metadata (library_name == "diffusers").
Returns False on any failure (network error, 404, offline mode, etc.)
@@ -70,16 +70,13 @@ def get_is_diffusion_model(model_path: str) -> bool:
# short-circuit, if applicable for the overlay mechanism (diffusion-only)
return True
# the diffusion registry is authoritative for native models, including
# local directories without a top-level model_index.json
if _is_diffusion_model_from_registry(model_path):
return True
if os.path.isdir(model_path):
if _is_diffusers_model_dir(model_path):
return True
return is_known_non_diffusers_diffusion_model(model_path)
if is_known_non_diffusers_diffusion_model(model_path):
return True
if _is_registered_diffusion_model(model_path):
return True
return _is_diffusers_model_dir(model_path)
try:
if envs.SGLANG_USE_MODELSCOPE.get():
+34 -8
View File
@@ -182,7 +182,6 @@ from sglang.multimodal_gen.runtime.utils.hf_diffusers_utils import (
maybe_download_model_index,
)
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.utils import KNOWN_NON_DIFFUSERS_DIFFUSION_MODEL_PATTERNS
logger = init_logger(__name__)
@@ -289,6 +288,22 @@ _MODEL_HF_PATH_TO_NAME: Dict[str, str] = {}
# Detectors to identify model families from paths or class names
_MODEL_NAME_DETECTORS: List[Tuple[str, Callable[[str], bool]]] = []
# native pipelines do not have a diffusers model_index.json. Keep their path
# aliases next to the resolver that consumes them so CLI detection and
# pipeline selection cannot drift apart
KNOWN_NON_DIFFUSERS_DIFFUSION_MODEL_PATTERNS: Dict[str, str] = {
"minimaxai/minimax-h3": "MiniMaxH3Pipeline",
"minimax/minimax-h3": "MiniMaxH3Pipeline",
"lerobot/pi05": "Pi05Pipeline",
"pi05": "Pi05Pipeline",
"pi0.5": "Pi05Pipeline",
"hunyuan3d": "Hunyuan3D2Pipeline",
"flux.2-dev-nvfp4": "Flux2NvfpPipeline",
"fal/ideogram-v4-fast": "Ideogram4FastPipeline",
"fal/ideogram-v4-instant": "Ideogram4InstantPipeline",
"comfy-org/ideogram-4": "Ideogram4Nvfp4Pipeline",
}
def register_configs(
sampling_param_cls: Any,
@@ -1163,17 +1178,28 @@ _register_configs()
def is_known_non_diffusers_multimodal_model(model_path: str) -> bool:
model_path_lower = model_path.lower()
return any(
pattern in model_path_lower
for pattern in KNOWN_NON_DIFFUSERS_DIFFUSION_MODEL_PATTERNS
)
return get_non_diffusers_pipeline_name(model_path) is not None
def get_non_diffusers_pipeline_name(model_path: str) -> Optional[str]:
"""Get the pipeline name for a known non-diffusers model."""
model_path_lower = model_path.lower()
normalized_model_path = _normalize_hf_cache_path(model_path)
model_short_name = get_model_short_name(normalized_model_path)
for pattern, pipeline_name in KNOWN_NON_DIFFUSERS_DIFFUSION_MODEL_PATTERNS.items():
if pattern in model_path_lower:
pattern = pattern.lower()
if "/" not in pattern and pattern in normalized_model_path:
return pipeline_name
if "/" in pattern and (
normalized_model_path == pattern
or model_short_name == get_model_short_name(pattern)
or f"models--{pattern.replace('/', '--')}" in normalized_model_path
):
return pipeline_name
return None
def is_registered_diffusion_model_path(model_path: str) -> bool:
"""Return whether the diffusion registry recognizes a model path."""
return has_registered_diffusion_model_path(model_path) or (
get_non_diffusers_pipeline_name(model_path) is not None
)
@@ -6,6 +6,7 @@ import unittest
from contextlib import contextmanager
from unittest.mock import patch
from sglang.cli.utils import get_is_diffusion_model
from sglang.multimodal_gen.configs.models.fsdp import (
is_module_list_entry,
is_module_list_entry_in,
@@ -697,7 +698,16 @@ class TestWarmupImageIsModelValid(unittest.TestCase):
self.assertGreaterEqual(height, 64)
class TestDiffusionModelDetection(unittest.TestCase):
def test_registered_local_model_path_is_detected_as_diffusion(self):
with tempfile.TemporaryDirectory() as root:
model_path = os.path.join(root, "Z-Image-Turbo")
os.mkdir(model_path)
self.assertTrue(get_is_diffusion_model(model_path))
class TestMiniMaxH3Routing(unittest.TestCase):
def test_semantic_variants_map_to_checkpoint_partitions(self):
self.assertEqual(
MiniMaxH3Pipeline.model_subfolder_for_variant("fl2va"), "FL2VA"
@@ -718,6 +728,10 @@ class TestMiniMaxH3Routing(unittest.TestCase):
get_non_diffusers_pipeline_name("MiniMax/MiniMax-H3"),
"MiniMaxH3Pipeline",
)
self.assertEqual(
get_non_diffusers_pipeline_name("/models/MiniMax-H3"),
"MiniMaxH3Pipeline",
)
class TestOffloadDefaults(unittest.TestCase):
-27
View File
@@ -31,25 +31,6 @@ from sglang.srt.environ import envs
logger = logging.getLogger(__name__)
KNOWN_NON_DIFFUSERS_DIFFUSION_MODEL_PATTERNS: dict[str, str] = {
"minimaxai/minimax-h3": "MiniMaxH3Pipeline",
"minimaxai--minimax-h3": "MiniMaxH3Pipeline",
"minimax/minimax-h3": "MiniMaxH3Pipeline",
"minimax--minimax-h3": "MiniMaxH3Pipeline",
"lerobot/pi05": "Pi05Pipeline",
"lerobot--pi05": "Pi05Pipeline",
"pi05": "Pi05Pipeline",
"pi0.5": "Pi05Pipeline",
"hunyuan3d": "Hunyuan3D2Pipeline",
"flux.2-dev-nvfp4": "Flux2NvfpPipeline",
"fal/ideogram-v4-fast": "Ideogram4FastPipeline",
"fal--ideogram-v4-fast": "Ideogram4FastPipeline",
"fal/ideogram-v4-instant": "Ideogram4InstantPipeline",
"fal--ideogram-v4-instant": "Ideogram4InstantPipeline",
"comfy-org/ideogram-4": "Ideogram4Nvfp4Pipeline",
"comfy-org--ideogram-4": "Ideogram4Nvfp4Pipeline",
}
def load_diffusion_overlay_registry_from_env() -> dict[str, dict[str, Any]]:
raw_value = os.getenv("SGLANG_DIFFUSION_MODEL_OVERLAY_REGISTRY", "").strip()
@@ -88,14 +69,6 @@ def has_diffusion_overlay_registry_match(
return any(base_name == key.rsplit("/", 1)[-1] for key in registry)
def is_known_non_diffusers_diffusion_model(model_path: str) -> bool:
model_path_lower = model_path.lower()
return any(
pattern in model_path_lower
for pattern in KNOWN_NON_DIFFUSERS_DIFFUSION_MODEL_PATTERNS
)
def execute_once(func):
has_run = None