Skip to content

ModularPipeline: loading from a local directory still resolves components against the hub id stored in modular_model_index.json (MiniMax-H3 re-downloads 134 GB) #14640

Description

@4suino

Describe the bug

ModularPipeline.from_pretrained(local_dir) / blocks.init_pipeline(local_dir) followed by load_components() does not load the components from local_dir when the directory contains a modular_model_index.json whose specs carry a hub repo id. The specs are taken verbatim from the file, so every component is resolved against the hub instead of the directory that already holds it. For a converted checkpoint like MiniMaxAI/MiniMax-H3 — whose index files ship nine "pretrained_model_name_or_path": "MiniMaxAI/MiniMax-H3" entries — a user who downloaded the snapshot to a local directory (e.g. hf download MiniMaxAI/MiniMax-H3 --local-dir models/minimax-h3) gets a second, full 134 GB download into the hub cache on first load_components(). Offline, the components simply fail to load and stay None.

The asymmetry is in modular_pipeline.py (v0.40.0):

  • with modular_model_index.json present (line 1749), each spec is rebuilt from the file as-is (line 1755) — the hub id wins over the local directory;
  • without it, the model_index.json fallback builds the spec as "repo": pretrained_model_name_or_path (line 1768) — i.e. the local directory, which is the expected behaviour.

So a local snapshot works only if the user hand-edits both index files to point at the local path (which is what we do).

Reproduction

No download needed — an empty cache plus offline mode makes the hub lookup fail loudly instead of pulling 134 GB. snapshot/ is a local copy of MiniMaxAI/MiniMax-H3 with its original index files.

import os
os.environ["HF_HOME"] = "/tmp/empty_hf_home"   # fresh, empty cache
os.environ["HF_HUB_OFFLINE"] = "1"

from diffusers.modular_pipelines.minimax_h3 import MiniMaxH3Blocks

pipe = MiniMaxH3Blocks().init_pipeline("snapshot")   # contains scheduler/scheduler_config.json
pipe.load_components(names=["scheduler"])            # smallest component, 4 KB on disk
print(pipe.scheduler)                                # -> None

Rewriting the nine pretrained_model_name_or_path entries in snapshot/modular_model_index.json (and model_index.json) to the local path, and running the same script, loads MiniMaxH3Scheduler from disk.

Logs

ValueError: Unable to load scheduler using load method: MiniMaxAI/MiniMax-H3 does not appear to have a file named scheduler_config.json.


(logged by `load_components`; the component is left as `None`. With the network on, the same call downloads the whole repo into the cache.)

### Expected behavior / proposed fix

When `pretrained_model_name_or_path` is a local directory, specs read from its `modular_model_index.json` should resolve against that directory whenever `<local_dir>/<subfolder>` exists — the same thing the `model_index.json` fallback already does — with the hub id kept only as a fallback for pruned snapshots that intentionally omit components. Alternatively, `save_pretrained` could write local/relative references so a downloaded snapshot is self-contained. Happy to open a PR for the first option if that shape is acceptable.

System Info

  • 🤗 Diffusers version: 0.40.0 (lines above from the v0.40.0 tag; same on main)
  • Platform: macOS-26.6.2-arm64-arm-64bit-Mach-O
  • Python version: 3.14.5
  • PyTorch version (GPU?): 2.14.0.dev20260808 (MPS)
  • Huggingface_hub version: 1.27.0
  • Transformers version: 5.14.1
  • Accelerate version: 1.14.0
  • Accelerator: Apple M5 Max, 128 GB unified memory
  • Using GPU in script?: no (loading only)
  • Using distributed or parallel set-up in script?: no

Who can help?

@apolinario (MiniMax-H3 integration, #14355) — and whoever owns Modular Diffusers loading

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions