invoke-ai/InvokeAI · warning · NotAMatchError

folder is SDNQ-quantized; use Qwen3Encoder_SDNQ_Folder_Confi

Error message

folder is SDNQ-quantized; use Qwen3Encoder_SDNQ_Folder_Config

What it means

NotAMatchError raised by Qwen3Encoder_Qwen3Encoder_Config._reject_if_sdnq_quantized (qwen3_encoder.py:358). A quantization_config.json with quant_method="sdnq" was found at the model root or in text_encoder/. The folder is an SDNQ-quantized Qwen3 encoder and must be matched by Qwen3Encoder_SDNQ_Folder_Config; the unquantized config rejects it so the two configs stay mutually exclusive and the correct (SDNQ) loader handles the packed weights.

Source

Thrown at invokeai/backend/model_manager/configs/qwen3_encoder.py:358

        return cls(variant=variant, **override_fields)

    @classmethod
    def _reject_if_sdnq_quantized(cls, mod: ModelOnDisk) -> None:
        # Primary signal: quantization_config.json with quant_method="sdnq" (at root or in
        # text_encoder/). Fallback: SDNQ-style weight+scale key pairs in the state dict. This mirrors
        # the detection in Qwen3Encoder_SDNQ_Folder_Config so the two stay mutually exclusive.
        for folder in (mod.path, mod.path / "text_encoder"):
            quant_config_path = folder / "quantization_config.json"
            if not quant_config_path.exists():
                continue
            try:
                with open(quant_config_path, "r", encoding="utf-8") as f:
                    quant_config = json.load(f)
            except (json.JSONDecodeError, OSError):
                continue
            if quant_config.get("quant_method") == "sdnq":
                raise NotAMatchError("folder is SDNQ-quantized; use Qwen3Encoder_SDNQ_Folder_Config")

        if _has_sdnq_keys(mod.load_state_dict()):
            raise NotAMatchError("state dict looks SDNQ-quantized; use Qwen3Encoder_SDNQ_Folder_Config")

    @classmethod
    def _get_variant_from_config(cls, config_path) -> Qwen3VariantType:
        """Get variant from config.json based on hidden_size, or raise NotAMatch if unknown."""
        QWEN3_06B_HIDDEN_SIZE = 1024
        QWEN3_4B_HIDDEN_SIZE = 2560
        QWEN3_8B_HIDDEN_SIZE = 4096

        try:
            with open(config_path, "r", encoding="utf-8") as f:
                config = json.load(f)
        except (json.JSONDecodeError, OSError) as e:
            raise NotAMatchError(f"unable to read Qwen3 config.json: {e}") from e

        hidden_size = config.get("hidden_size")

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Allow the scan to continue — Qwen3Encoder_SDNQ_Folder_Config should match the folder instead.
  2. If it stays unidentified, explicitly register the model with the SDNQ Qwen3 encoder config/type.
  3. To use the unquantized loader, download the non-SDNQ revision of the model.
  4. If quantization_config.json is a stray leftover, remove it and rescan (only if weights truly are not SDNQ-quantized).

Example fix

// before
invokeai-install models/qwen3-encoder/  // contains quantization_config.json (quant_method: sdnq)
// after
register models/qwen3-encoder/ with Qwen3Encoder_SDNQ_Folder_Config (or download the unquantized revision)
Defensive patterns

Strategy: validation

Validate before calling

import json
def is_sdnq_folder(path) -> bool:
    for folder in (path, path / 'text_encoder'):
        q = folder / 'quantization_config.json'
        if q.exists():
            try:
                if json.loads(q.read_text()).get('quant_method') == 'sdnq':
                    return True
            except (json.JSONDecodeError, OSError):
                pass
    return False  # if True, register with Qwen3Encoder_SDNQ_Folder_Config

Type guard

def needs_sdnq_config(path) -> bool:
    import json
    q = path / 'quantization_config.json'
    alt = path / 'text_encoder' / 'quantization_config.json'
    for f in (q, alt):
        if f.exists() and json.loads(f.read_text()).get('quant_method') == 'sdnq':
            return True
    return False

Try / catch

if is_sdnq_folder(model_dir):
    register_model(model_dir, config='Qwen3Encoder_SDNQ_Folder_Config')
else:
    try:
        register_model(model_dir, model_type='Qwen3Encoder')
    except NotAMatchError as e:
        logger.warning('Rejected: %s', e)

Prevention

When it happens

Trigger: from_model_on_disk on a folder where quantization_config.json (root or text_encoder/) parses with quant_method == 'sdnq' while the unquantized Qwen3Encoder config probes it.

Common situations: Installing an SDNQ-quantized download of a Qwen3/Z-Image text encoder while expecting the standard (unquantized) Qwen3Encoder loader to run; upgrading a model to an SDNQ re-release without changing its registered config.

Related errors


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