[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:
+12
-15
@@ -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():
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user