unslothai/unsloth · error · ValueError

Refusing to train from untrusted base model '{base_model}'.

Error message

Refusing to train from untrusted base model '{base_model}'. Use a local path or a trusted repo (an unsloth/* repo or an official base).

What it means

The training base is gated exactly like the inference backend's non-GGUF loads: it must be a local path or a trusted repo (unsloth/* or an allowlisted official base, plus _TRAIN_EXTRA_TRUSTED_REPOS). The check runs BEFORE from_pretrained so an untrusted remote repo — which could ship pickle-encoded weights — is never fetched or deserialized. A local path additionally must contain a pipeline index (or modular_model_index.json when allow_modular).

Source

Thrown at studio/backend/core/training/diffusion_train_common.py:1804


def _assert_trusted_base_model(base_model: str, *, allow_modular: bool = False) -> None:
    """Gate the training base model the same way the inference backend gates non-GGUF loads:
    a local path or a trusted repo (``unsloth/*`` or an allowlisted official base). This runs
    BEFORE ``from_pretrained`` so an untrusted remote repo (which could ship pickle weights)
    is never fetched or deserialised.

    ``allow_modular`` is for a trainer whose loader is ``ModularPipeline.from_pretrained``: a
    local MiniMax-H3 pipeline carries ``modular_model_index.json`` and no ``model_index.json``,
    so the conventional shape check rejected the one local layout that family HAS."""
    from core.inference.diffusion import _assert_local_base_is_pipeline, _is_trusted_diffusion_repo

    trusted = (
        _is_trusted_diffusion_repo(base_model)
        or str(base_model or "").strip().lower() in _TRAIN_EXTRA_TRUSTED_REPOS
    )
    if not trusted:
        raise ValueError(
            f"Refusing to train from untrusted base model '{base_model}'. Use a local path or "
            f"a trusted repo (an unsloth/* repo or an official base)."
        )
    # An existing LOCAL base is loaded as a full pipeline, which needs an index; reject a non-pipeline local dir before /diffusion/start frees the GPU models.
    _assert_local_base_is_pipeline(base_model, allow_modular = allow_modular)


# ── resume checkpoints ────────────────────────────────────────────────────────
# One writer and one reader for BOTH trainers, so an SDXL and a DiT run resume from the same
# bundle shape. The family-specific part (the deployable adapter export) stays in the trainers.
def trainable_state_dict(model: Any) -> dict[str, Any]:
    """The trainable (LoRA) parameters of ``model``, keyed by parameter name.

    Deliberately NOT the peft/diffusers export format: this is the checkpoint's private
    copy of exactly the tensors the optimizer holds moments for, so restoring it and the
    optimizer state together reproduces the run bit-for-bit. Parameter names are stable
    across a re-attach and across regional torch.compile (which compiles submodules in
    place without renaming), which is the same assumption ``LoRAEMA`` already makes."""

View on GitHub (pinned to 203007d190)

Solutions

  1. Use an official base repo for the family or an unsloth/* mirror.
  2. Or point at a local path containing a complete diffusers pipeline (model_index.json plus component subfolders).
  3. If the repo is genuinely trustworthy and you own the deployment, add it to the trust allowlist in code/config after reviewing what it ships — never as a blanket bypass.

Example fix

# before
cfg = DiffusionLoraConfig(base_model='randomuser/flux-finetune')
# after
cfg = DiffusionLoraConfig(base_model='black-forest-labs/FLUX.1-dev')
# local path must contain model_index.json + component dirs
Defensive patterns

Strategy: validation

Validate before calling

from core.inference.diffusion import _is_trusted_diffusion_repo
def assert_trainable_base(base_model):
    if not (_is_trusted_diffusion_repo(base_model) or Path(base_model).expanduser().is_dir()):
        raise ValueError(f'untrusted base model: {base_model}')

Prevention

When it happens

Trigger: base_model set to an arbitrary Hub repo outside the trust allowlist (e.g. a random user's 'someone/my-flux-remix'), or a local directory that is not a full pipeline layout.

Common situations: Pointing the trainer at a community fine-tune repo with custom weights; a typo'd repo id; a local directory holding only safetensors shards without model_index.json.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/8564d0d9f055d740. Report an issue: GitHub.