[Bugfix][MiniMax-Music3] Resolve stage subdirs against a real snapshot (#6640)

Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
This commit is contained in:
Yueqian Lin authored and GitHub committed 2026-08-30 06:51:24 +00:00
1 parent 8be601ed7f
commit a6b559cf54
7 files changed
+1172 -27

No files matched your search

@@ -4,6 +4,7 @@
import concurrent.futures
import contextlib
import importlib
import json
import os
import time
import types
@@ -1093,6 +1094,8 @@ def test_build_engine_args_cli_tokenizer_overrides_inferred_base_tokenizer(tmp_p
default_sampling_params={},
)
(tmp_path / "llm").mkdir()
engine_args = build_engine_args_dict(
stage_cfg,
str(tmp_path),
@@ -1154,6 +1157,9 @@ def test_build_engine_args_keeps_stage_owned_tokenizer_subdir(tmp_path):
default_sampling_params={},
)
(tmp_path / "llm").mkdir()
(tmp_path / "tokenizer").mkdir()
engine_args = build_engine_args_dict(
stage_cfg,
str(tmp_path),
@@ -1164,6 +1170,430 @@ def test_build_engine_args_keeps_stage_owned_tokenizer_subdir(tmp_path):
assert engine_args["tokenizer"] == os.path.join(str(tmp_path), "tokenizer")
def test_build_engine_args_rejects_missing_subdir_in_local_model_dir(tmp_path):
"""A local model directory without the stage subfolder must fail closed.
Forwarding the joined path as ``EngineArgs.model`` sends a non-directory
string to HuggingFace, which reports it as a malformed repo id.
"""
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
(tmp_path / "tokenizer").mkdir()
with pytest.raises(RuntimeError, match="language_model"):
build_engine_args_dict(stage_cfg, str(tmp_path))
# A real snapshot subfolder always carries artifacts; empty directories would
# assert the broken exists-means-complete predicate this suite regresses.
_SUBDIR_ARTIFACT = {"language_model": "model.safetensors", "tokenizer": "tokenizer.json"}
def _make_snapshot(root, subdirs):
for subdir in subdirs:
folder = root / subdir
folder.mkdir(parents=True, exist_ok=True)
(folder / _SUBDIR_ARTIFACT.get(subdir, "data.bin")).write_text("x")
return str(root)
def test_build_engine_args_pulls_stage_subdirs_missing_from_cached_snapshot(monkeypatch, tmp_path):
"""Regression for issue #6638.
``snapshot_download(local_files_only=True)`` hands back a snapshot root as
soon as the repo is partly cached, even when this stage's subfolders were
never materialized. Stage init must fetch exactly those subfolders instead
of joining onto a path that exists nowhere.
"""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
_make_snapshot(snapshot, ["tokenizer"])
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if kwargs.get("local_files_only"):
return str(snapshot)
_make_snapshot(snapshot, ["language_model"])
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert engine_args["model"] == os.path.join(str(snapshot), "language_model")
assert engine_args["tokenizer"] == os.path.join(str(snapshot), "tokenizer")
assert os.path.isdir(engine_args["model"])
# Only the stage's own subfolders are pulled, not the whole repo.
assert calls[-1]["allow_patterns"] == ["language_model/*", "tokenizer/*"]
def test_build_engine_args_skips_hub_call_when_cached_snapshot_is_complete(monkeypatch, tmp_path):
"""A warm cache stays offline-friendly: no outgoing Hub request."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
_make_snapshot(snapshot, ["language_model", "tokenizer"])
def fake_snapshot_download(self, repo_id, **kwargs):
assert kwargs.get("local_files_only"), "warm cache must not reach the Hub"
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert engine_args["model"] == os.path.join(str(snapshot), "language_model")
def test_build_engine_args_redownloads_a_partial_subdir(monkeypatch, tmp_path):
"""A subfolder holding only config.json is an interrupted download.
The warm-cache early return must not accept it: converting the Hub ID into
that local path leaves vLLM's loader without any fallback for the missing
weights.
"""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
partial = snapshot / "language_model"
partial.mkdir(parents=True)
(partial / "config.json").write_text("{}")
_make_snapshot(snapshot, ["tokenizer"])
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if kwargs.get("local_files_only"):
return str(snapshot)
_make_snapshot(snapshot, ["language_model"])
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert any(not call.get("local_files_only") for call in calls), "a partial subdir must fall through to the Hub"
assert engine_args["model"] == os.path.join(str(snapshot), "language_model")
def test_build_engine_args_redownloads_when_index_lists_missing_shards(monkeypatch, tmp_path):
"""An index plus a subset of its shards is an interrupted download.
The index downloads early; accepting it as proof of weights converts the
Hub ID into a local path vLLM cannot fetch the remaining shards for.
"""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
partial = snapshot / "language_model"
partial.mkdir(parents=True)
(partial / "model.safetensors.index.json").write_text(
json.dumps(
{
"weight_map": {
"a.weight": "model-00001-of-00002.safetensors",
"b.weight": "model-00002-of-00002.safetensors",
}
}
)
)
(partial / "model-00001-of-00002.safetensors").write_text("x")
_make_snapshot(snapshot, ["tokenizer"])
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if not kwargs.get("local_files_only"):
(partial / "model-00002-of-00002.safetensors").write_text("x")
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert any(not call.get("local_files_only") for call in calls), "missing shards must fall through to the Hub"
assert engine_args["model"] == os.path.join(str(snapshot), "language_model")
def test_build_engine_args_redownloads_shards_without_their_index(monkeypatch, tmp_path):
"""Shard-named weights always ship an index; one without it is partial."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
partial = snapshot / "language_model"
partial.mkdir(parents=True)
(partial / "model-00001-of-00004.safetensors").write_text("x")
_make_snapshot(snapshot, ["tokenizer"])
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if not kwargs.get("local_files_only"):
shards = {f"w{i}.weight": f"model-0000{i}-of-00004.safetensors" for i in range(1, 5)}
(partial / "model.safetensors.index.json").write_text(json.dumps({"weight_map": shards}))
for shard in shards.values():
(partial / shard).write_text("x")
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert any(not call.get("local_files_only") for call in calls)
def test_build_engine_args_redownloads_a_tokenizer_folder_without_vocabulary(monkeypatch, tmp_path):
"""Templates and configs download first; alone they are not a tokenizer."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
_make_snapshot(snapshot, ["language_model"])
partial = snapshot / "tokenizer"
partial.mkdir(parents=True)
(partial / "chat_template.jinja").write_text("{{ messages }}")
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if not kwargs.get("local_files_only"):
_make_snapshot(snapshot, ["tokenizer"])
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert any(not call.get("local_files_only") for call in calls)
assert engine_args["tokenizer"] == os.path.join(str(snapshot), "tokenizer")
def test_build_engine_args_forwards_revision_and_download_dir(monkeypatch, tmp_path):
"""revision/download_dir must shape snapshot selection (they cannot be
corrected downstream once the repo ID is a local path)."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "pinned"
_make_snapshot(snapshot, ["language_model", "tokenizer"])
seen = []
def fake_snapshot_download(self, repo_id, **kwargs):
seen.append(kwargs)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={
"model_subdir": "language_model",
"tokenizer_subdir": "tokenizer",
"revision": "v2.0",
"download_dir": str(tmp_path / "cache"),
},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert engine_args["model"] == os.path.join(str(snapshot), "language_model")
assert seen, "snapshot resolution must have been consulted"
for call in seen:
assert call.get("revision") == "v2.0"
assert call.get("cache_dir") == str(tmp_path / "cache")
def test_build_engine_args_resolves_tokenizer_revision_separately(monkeypatch, tmp_path):
"""A tokenizer pinned to a different revision resolves against its own snapshot."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
model_snapshot = tmp_path / "snapshots" / "model-rev"
_make_snapshot(model_snapshot, ["language_model"])
tokenizer_snapshot = tmp_path / "snapshots" / "tok-rev"
_make_snapshot(tokenizer_snapshot, ["tokenizer"])
def fake_snapshot_download(self, repo_id, **kwargs):
if kwargs.get("revision") == "tok-rev":
return str(tokenizer_snapshot)
return str(model_snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={
"model_subdir": "language_model",
"tokenizer_subdir": "tokenizer",
"revision": "model-rev",
"tokenizer_revision": "tok-rev",
},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert engine_args["model"] == os.path.join(str(model_snapshot), "language_model")
assert engine_args["tokenizer"] == os.path.join(str(tokenizer_snapshot), "tokenizer")
def test_build_engine_args_resolves_root_tokenizer_revision_separately(monkeypatch, tmp_path):
"""An empty tokenizer_subdir targets the snapshot root and still honors
its own revision."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
model_snapshot = tmp_path / "snapshots" / "model-rev"
_make_snapshot(model_snapshot, ["language_model"])
# An empty tokenizer_subdir means the tokenizer IS the snapshot root, so
# the vocabulary artifact must sit at the root. Building it under
# ``tokenizer/`` returned a root that holds no loadable tokenizer, which
# the root-tokenizer validation now correctly rejects.
tokenizer_snapshot = tmp_path / "snapshots" / "tok-rev"
tokenizer_snapshot.mkdir(parents=True, exist_ok=True)
(tokenizer_snapshot / _SUBDIR_ARTIFACT["tokenizer"]).write_text("x")
def fake_snapshot_download(self, repo_id, **kwargs):
if kwargs.get("revision") == "tok-rev":
return str(tokenizer_snapshot)
return str(model_snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={
"model_subdir": "language_model",
"tokenizer_subdir": "",
"revision": "model-rev",
"tokenizer_revision": "tok-rev",
},
default_sampling_params={},
)
engine_args = build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
assert engine_args["model"] == os.path.join(str(model_snapshot), "language_model")
assert engine_args["tokenizer"] == str(tokenizer_snapshot)
def test_build_engine_args_fails_closed_when_subdir_cannot_be_downloaded(monkeypatch, tmp_path):
"""An undownloadable subfolder raises here instead of reaching HuggingFace."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
snapshot = tmp_path / "snapshots" / "deadbeef"
_make_snapshot(snapshot, ["tokenizer"])
def fake_snapshot_download(self, repo_id, **kwargs):
if kwargs.get("local_files_only"):
return str(snapshot)
raise OSError("offline")
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
with pytest.raises(RuntimeError, match="language_model"):
build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
def test_build_engine_args_fails_closed_on_cold_cache_instead_of_joining_repo_id(monkeypatch):
"""With nothing cached, the stage must not join a subdir onto the repo id."""
from huggingface_hub import HfApi
from vllm_omni.engine.stage_init_utils import build_engine_args_dict
def fake_snapshot_download(self, repo_id, **kwargs):
raise OSError("offline")
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
stage_cfg = types.SimpleNamespace(
stage_id=0,
stage_type="llm",
engine_args={"model_subdir": "language_model", "tokenizer_subdir": "tokenizer"},
default_sampling_params={},
)
with pytest.raises(RuntimeError, match="nothing is cached locally"):
build_engine_args_dict(stage_cfg, "MiniMaxAI/MiniMax-Music3")
def test_model_path_resolver_is_generic_and_model_owned(tmp_path):
from vllm_omni.engine.stage_init_utils import _resolve_model_path
+21 -4
View File
@@ -630,8 +630,24 @@ def test_typed_ming_image_engine_args_defer_diffusion_batch_default():
assert OmniDiffusionConfig(**typed_backend_args).max_num_seqs == 1
def _fake_model_root(pipeline, tmp_path):
"""A model directory carrying every subfolder the pipeline's stages declare.
Stage init fails closed when a declared ``model_subdir``/``tokenizer_subdir``
is not a real directory, because the joined path would otherwise reach
HuggingFace as a malformed repo id (issue #6638).
"""
root = tmp_path / "model"
root.mkdir(exist_ok=True)
for stage in pipeline.stages:
for subdir in (stage.model_subdir, stage.tokenizer_subdir):
if subdir:
(root / subdir).mkdir(parents=True, exist_ok=True)
return str(root)
@pytest.mark.parametrize("model_type", sorted(OMNI_PIPELINES))
def test_typed_engine_args_match_current_registry_backend_semantics(model_type):
def test_typed_engine_args_match_current_registry_backend_semantics(model_type, tmp_path):
pipeline = resolve_pipeline_config(model_type)
if pipeline is None:
pytest.skip(f"Pipeline {model_type!r} requires an HF config to resolve")
@@ -641,18 +657,19 @@ def test_typed_engine_args_match_current_registry_backend_semantics(model_type):
if pipeline.default_deploy_config_name is not None
else DeployConfig()
)
model = _fake_model_root(pipeline, tmp_path)
legacy_stages, omni_config = _legacy_and_typed_stages(
pipeline,
deploy,
model="/tmp",
model=model,
)
for legacy_stage in legacy_stages:
stage_id = legacy_stage.stage_id
legacy_args = build_legacy_engine_args_dict(legacy_stage, model="/tmp")
legacy_args = build_legacy_engine_args_dict(legacy_stage, model=model)
typed_args = build_engine_args_dict_from_omni_stage_config(
omni_config.stage_by_id(stage_id),
model="/tmp",
model=model,
)
if legacy_stage.stage_type == StageType.DIFFUSION:
backend_fields = _DIFFUSION_BACKEND_FIELDS
@@ -0,0 +1,339 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Repository-root resolution for MiniMax Music 3's multi-component checkpoint.
The acoustic stage declares no ``model_subdir`` because it reads the repo root
itself, so on a hub-id deployment its model path is ``MiniMaxAI/MiniMax-Music3``
rather than a directory. Resolving that as a relative path silently points at
the server's working directory (issue #6638).
"""
from __future__ import annotations
import pytest
from vllm_omni.model_executor.models.minimax_music3.weights import (
_COMPONENT_WEIGHT_NAME,
_REQUIRED_COMPONENTS,
_ROOT_MARKERS,
resolve_repo_root,
)
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
def _make_root(path):
# A real snapshot carries weights for every component a stage loads, not
# just the folders that identify the root. Building only ``_ROOT_MARKERS``
# here would let a snapshot missing ``condition_encoder`` pass as complete,
# which is the gap this suite regresses.
for component in _REQUIRED_COMPONENTS:
folder = path / component
folder.mkdir(parents=True, exist_ok=True)
(folder / _COMPONENT_WEIGHT_NAME).write_bytes(b"x")
return path
def test_resolve_repo_root_accepts_the_root_itself(tmp_path):
root = _make_root(tmp_path / "snapshot")
assert resolve_repo_root(str(root)) == root
def test_resolve_repo_root_walks_up_from_a_model_subdir(tmp_path):
root = _make_root(tmp_path / "snapshot")
(root / "language_model").mkdir()
assert resolve_repo_root(str(root / "language_model")) == root
def test_resolve_repo_root_resolves_a_hub_id_to_a_local_snapshot(monkeypatch, tmp_path):
"""A hub id must resolve through the cache, not against the working directory."""
from huggingface_hub import HfApi
root = _make_root(tmp_path / "snapshots" / "deadbeef")
seen = []
def fake_snapshot_download(self, repo_id, **kwargs):
seen.append(kwargs)
return str(root)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root("MiniMaxAI/MiniMax-Music3") == root
# Cache-first, and only the component folders.
assert seen[0]["local_files_only"] is True
assert "transformer/*" in seen[0]["allow_patterns"]
assert "qwen_7B/*" not in seen[0]["allow_patterns"]
def test_resolve_repo_root_falls_back_to_the_hub_when_the_cache_is_incomplete(monkeypatch, tmp_path):
from huggingface_hub import HfApi
root = _make_root(tmp_path / "snapshots" / "deadbeef")
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if kwargs.get("local_files_only"):
raise OSError("incomplete snapshot")
return str(root)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root("MiniMaxAI/MiniMax-Music3") == root
assert len(calls) == 2
def test_resolve_repo_root_retries_online_when_the_local_lookup_returns_a_partial_root(monkeypatch, tmp_path):
"""Hub clients differ on partial caches: some raise, some return the root.
A returned partial root must fall through to the online call all the same,
or startup fails without ever consulting the Hub.
"""
from huggingface_hub import HfApi
snapshot = tmp_path / "models--MiniMaxAI--MiniMax-Music3" / "snapshots" / "deadbeef"
(snapshot / "language_model").mkdir(parents=True)
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if not kwargs.get("local_files_only"):
_make_root(snapshot)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root("MiniMaxAI/MiniMax-Music3") == snapshot
assert [bool(call.get("local_files_only")) for call in calls] == [True, False]
def test_resolve_repo_root_redownloads_weightless_marker_dirs(monkeypatch, tmp_path):
"""Marker folders without their component weights are an interrupted download."""
from huggingface_hub import HfApi
snapshot = tmp_path / "models--MiniMaxAI--MiniMax-Music3" / "snapshots" / "deadbeef"
for marker in _ROOT_MARKERS:
(snapshot / marker).mkdir(parents=True)
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
if not kwargs.get("local_files_only"):
_make_root(snapshot)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root("MiniMaxAI/MiniMax-Music3") == snapshot
assert any(not call.get("local_files_only") for call in calls)
def test_resolve_repo_root_reports_the_original_reference_when_unresolvable(monkeypatch):
from huggingface_hub import HfApi
def fake_snapshot_download(self, repo_id, **kwargs):
raise OSError("offline")
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
with pytest.raises(FileNotFoundError, match="MiniMaxAI/MiniMax-Music3"):
resolve_repo_root("MiniMaxAI/MiniMax-Music3")
def test_resolve_repo_root_downloads_components_for_a_cold_cache_model_subdir(monkeypatch, tmp_path):
"""Cold-cache stage 0: the talker gets an EXISTING ``language_model`` dir.
Stage init pre-downloads only ``language_model/`` and ``tokenizer/``, so
the marker walk fails although the repo id is recoverable from the cache
layout and one snapshot_download away from working.
"""
from huggingface_hub import HfApi
snapshot = tmp_path / "models--MiniMaxAI--MiniMax-Music3" / "snapshots" / "deadbeef"
(snapshot / "language_model").mkdir(parents=True)
(snapshot / "tokenizer").mkdir()
seen = []
def fake_snapshot_download(self, repo_id, **kwargs):
seen.append(repo_id)
_make_root(snapshot)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root(str(snapshot / "language_model")) == snapshot
assert seen == ["MiniMaxAI/MiniMax-Music3"]
def test_resolve_repo_root_does_not_guess_a_repo_id_for_plain_directories(monkeypatch, tmp_path):
"""A directory outside the HF cache has no recoverable repo id."""
from huggingface_hub import HfApi
def fake_snapshot_download(self, repo_id, **kwargs):
raise AssertionError("must not reach the Hub for a plain directory")
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
plain = tmp_path / "language_model"
plain.mkdir()
with pytest.raises(FileNotFoundError, match="expected sibling folders"):
resolve_repo_root(str(plain))
def test_resolve_repo_root_rejects_a_snapshot_missing_condition_encoder(monkeypatch, tmp_path):
"""``condition_encoder`` is loaded by the acoustic stage but is not a root marker.
A cache holding only the marker folders satisfies the name probe while the
acoustic stage would still fail, so completeness must cover every required
component rather than the identification markers alone.
"""
from huggingface_hub import HfApi
snapshot = tmp_path / "models--MiniMaxAI--MiniMax-Music3" / "snapshots" / "deadbeef"
for marker in _ROOT_MARKERS:
folder = snapshot / marker
folder.mkdir(parents=True)
(folder / _COMPONENT_WEIGHT_NAME).write_bytes(b"x")
repaired = []
def fake_snapshot_download(self, repo_id, **kwargs):
if not kwargs.get("local_files_only"):
repaired.append(repo_id)
_make_root(snapshot)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root(str(snapshot)) == snapshot
assert repaired == ["MiniMaxAI/MiniMax-Music3"]
def test_resolve_repo_root_rejects_a_partial_shard_run(monkeypatch, tmp_path):
"""One shard of a multi-shard component satisfies a bare glob but cannot load."""
from huggingface_hub import HfApi
stem = _COMPONENT_WEIGHT_NAME.removesuffix(".safetensors")
snapshot = tmp_path / "models--MiniMaxAI--MiniMax-Music3" / "snapshots" / "deadbeef"
for component in _REQUIRED_COMPONENTS:
(snapshot / component).mkdir(parents=True)
(snapshot / component / _COMPONENT_WEIGHT_NAME).write_bytes(b"x")
# Replace one component with an interrupted 1-of-3 shard run.
partial = snapshot / _ROOT_MARKERS[0]
(partial / _COMPONENT_WEIGHT_NAME).unlink()
(partial / f"{stem}-00001-of-00003.safetensors").write_bytes(b"x")
repaired = []
def fake_snapshot_download(self, repo_id, **kwargs):
if not kwargs.get("local_files_only"):
repaired.append(repo_id)
for index in (2, 3):
(partial / f"{stem}-0000{index}-of-00003.safetensors").write_bytes(b"x")
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root(str(snapshot)) == snapshot
assert repaired == ["MiniMaxAI/MiniMax-Music3"]
def test_resolve_repo_root_threads_revision_and_download_dir(monkeypatch, tmp_path):
"""A pinned revision must not be dropped when fetching the components.
Resolving components against the default branch while the AR backbone is
pinned elsewhere would combine weights from two different commits.
"""
from huggingface_hub import HfApi
snapshot = tmp_path / "snapshot"
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
_make_root(snapshot)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root("MiniMaxAI/MiniMax-Music3", revision="abc123", download_dir="/tmp/hub-cache") == snapshot
assert calls
assert all(call.get("revision") == "abc123" for call in calls)
assert all(call.get("cache_dir") == "/tmp/hub-cache" for call in calls)
def test_resolve_repo_root_reuses_the_snapshot_revision_from_the_cache_path(monkeypatch, tmp_path):
"""The commit is recoverable from ``snapshots/<sha>`` and must be reused.
Re-resolving the repo id alone would fetch the default branch rather than
the snapshot the caller is already sitting in.
"""
from huggingface_hub import HfApi
snapshot = tmp_path / "models--MiniMaxAI--MiniMax-Music3" / "snapshots" / "cafebabe"
(snapshot / "language_model").mkdir(parents=True)
calls = []
def fake_snapshot_download(self, repo_id, **kwargs):
calls.append(kwargs)
_make_root(snapshot)
return str(snapshot)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root(str(snapshot / "language_model")) == snapshot
assert calls
assert all(call.get("revision") == "cafebabe" for call in calls)
def test_resolve_repo_root_accepts_shard_names_the_loader_can_read(monkeypatch, tmp_path):
"""The completeness predicate must not be stricter than ``load_component_state``.
The loader globs ``<stem>-*.safetensors`` and reads whatever it finds, so a
component whose weights do not use the ``-<index>-of-<total>`` naming is
loadable. Judging it incomplete would force a needless re-download and, with
no network, fail on weights that are present and readable.
"""
from huggingface_hub import HfApi
stem = _COMPONENT_WEIGHT_NAME.removesuffix(".safetensors")
root = tmp_path / "snapshot"
for component in _REQUIRED_COMPONENTS:
(root / component).mkdir(parents=True)
(root / component / _COMPONENT_WEIGHT_NAME).write_bytes(b"x")
unsharded = root / _ROOT_MARKERS[0]
(unsharded / _COMPONENT_WEIGHT_NAME).unlink()
(unsharded / f"{stem}-fp16.safetensors").write_bytes(b"x")
def fake_snapshot_download(self, repo_id, **kwargs):
raise AssertionError("must not reach the Hub for readable weights")
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
assert resolve_repo_root(str(root)) == root
def test_resolve_repo_root_still_rejects_a_partial_run_beside_an_extra_file(monkeypatch, tmp_path):
"""An unparsable extra must not mask a genuinely short ``-of-`` run."""
from huggingface_hub import HfApi
stem = _COMPONENT_WEIGHT_NAME.removesuffix(".safetensors")
root = tmp_path / "snapshot"
for component in _REQUIRED_COMPONENTS:
(root / component).mkdir(parents=True)
(root / component / _COMPONENT_WEIGHT_NAME).write_bytes(b"x")
partial = root / _ROOT_MARKERS[0]
(partial / _COMPONENT_WEIGHT_NAME).unlink()
(partial / f"{stem}-00001-of-00003.safetensors").write_bytes(b"x")
(partial / f"{stem}-extra.safetensors").write_bytes(b"x")
repaired = []
def fake_snapshot_download(self, repo_id, **kwargs):
repaired.append(repo_id)
for index in (2, 3):
(partial / f"{stem}-0000{index}-of-00003.safetensors").write_bytes(b"x")
return str(root)
monkeypatch.setattr(HfApi, "snapshot_download", fake_snapshot_download)
with pytest.raises(FileNotFoundError, match="components are incomplete"):
resolve_repo_root(str(root))
assert repaired == []