invoke-ai/InvokeAI · error · ValueError

No safetensors files found in {model_path}

Error message

No safetensors files found in {model_path}

What it means

sdnq_sd_loader expects either a directory containing *.safetensors shard(s) or a single .safetensors file. When given a directory with no safetensors files, it raises ValueError because there are no weights to load.

Source

Thrown at invokeai/backend/quantization/sdnq/loaders.py:217

    SDNQ stores quantized weights with associated scale, zero_point (optional),
    and SVD correction matrices (optional). This loader creates SDNQTensor
    wrappers that provide on-the-fly dequantization.

    Args:
        model_path: Path to safetensors file or directory containing model files.
        compute_dtype: Dtype for dequantized computation (default: bfloat16).

    Returns:
        State dict with SDNQTensor wrappers for quantized weights and
        regular tensors for non-quantized weights.
    """
    # Determine which safetensors file(s) hold the weights. For larger models (FLUX.2 Klein 9B,
    # FLUX.2 dev, ...) the transformer is sharded across multiple ``*-NNNNN-of-MMMMM.safetensors``
    # files; we merge all of them into one state_dict before grouping.
    if model_path.is_dir():
        safetensors_files = sorted(model_path.glob("*.safetensors"))
        if not safetensors_files:
            raise ValueError(f"No safetensors files found in {model_path}")
        config_path = model_path / "quantization_config.json"
    else:
        safetensors_files = [model_path]
        config_path = model_path.parent / "quantization_config.json"

    # Load quantization config if available
    quant_config = _parse_quantization_config(config_path)

    # Get group_size from config (default: 128 for SDNQ)
    # Note: group_size=0 in config means per-tensor quantization or it needs to be inferred
    config_group_size = quant_config.get("group_size", 128)

    # Build a reverse map for dynamic-mixed-precision models. SDNQ stores
    # ``modules_dtype_dict`` as ``{dtype_name: [list of layer keys]}``; we flip it to
    # ``{layer_key: dtype_name}`` for O(1) lookup during the per-tensor type inference.
    per_tensor_dtype_map: dict[str, str] = {}
    modules_dtype_dict = quant_config.get("modules_dtype_dict") or {}
    if isinstance(modules_dtype_dict, dict):

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Point model_path at the folder containing the .safetensors weight file(s) or at the file itself
  2. Re-download with git lfs / proper download tool so *.safetensors files actually exist
  3. Verify the path with ls: it must contain at least one *.safetensors file

Example fix

// before
loader = sdnq_sd_loader(Path("models/flux2-transformer/config-only-dir"))
// after
loader = sdnq_sd_loader(Path("models/flux2-transformer"))  # contains *.safetensors shards
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
path = Path(model_path)
if path.is_dir() and not list(path.glob("*.safetensors")):
    raise FileNotFoundError(f"{path} has no *.safetensors weights")
model = load_sdnq(path)

Type guard

def has_safetensors(p: Path) -> bool:
    return p.is_file() and p.suffix == ".safetensors" or (p.is_dir() and any(p.glob("*.safetensors")))

Try / catch

try:
    model = _load_sdnq_transformer(path)
except ValueError as e:
    if "No safetensors" in str(e):
        re_download_weights(path)
    raise

Prevention

When it happens

Trigger: Passing model_path as a directory that contains only config/JSON files (no *.safetensors), e.g. a diffusers-style folder of .bin weights, an empty folder, or a wrong path.

Common situations: Downloading a repo without the safetensors weights (LFS not fetched, so pointer text files only); pointing at a config-only directory; path typo selecting the wrong subfolder.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/241290a7b08771b0. Report an issue: GitHub.