{"record":{"id":"37c404ed6dd2fc16","repo":"invoke-ai/InvokeAI","slug":"gemma2-hidden-size-hidden-size-is-incompatible-w","errorCode":null,"errorMessage":"Gemma2 hidden_size {hidden_size} is incompatible with PiD, which requires {_PID_GEMMA_HIDDEN_SIZE} (Gemma-2-2b); 9B/27B variants are not supported.","messagePattern":"Gemma2 hidden_size (.+?) is incompatible with PiD, which requires (.+?) \\(Gemma-2-2b\\); 9B/27B variants are not supported\\.","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/gemma2_encoder.py","lineNumber":77,"sourceCode":"        raise_for_override_fields(cls, override_fields)\n\n        config_path = mod.path / \"config.json\"\n        if not config_path.exists():\n            raise NotAMatchError(f\"missing config.json at {config_path}\")\n\n        # Reject full diffusers pipelines (they have model_index.json at root).\n        if (mod.path / \"model_index.json\").exists():\n            raise NotAMatchError(\"directory looks like a full diffusers pipeline, not a standalone Gemma2 encoder\")\n\n        # Architecture marker is the canonical signal.\n        raise_for_class_name(config_path, {\"Gemma2ForCausalLM\"})\n\n        # Only Gemma-2-2b (2304-dim hidden state) is compatible with PiD's fixed caption projection.\n        # Reject 9B/27B variants here so they are not offered as compatible encoders and then fail with\n        # a matrix-shape error deep inside PiD inference.\n        hidden_size = get_config_dict_or_raise(config_path).get(\"hidden_size\")\n        if hidden_size != _PID_GEMMA_HIDDEN_SIZE:\n            raise NotAMatchError(\n                f\"Gemma2 hidden_size {hidden_size} is incompatible with PiD, which requires \"\n                f\"{_PID_GEMMA_HIDDEN_SIZE} (Gemma-2-2b); 9B/27B variants are not supported.\"\n            )\n\n        # Sanity check that tokenizer files live alongside the model (PiD calls\n        # AutoTokenizer.from_pretrained on the same directory).\n        if not any((mod.path / f).exists() for f in (\"tokenizer.json\", \"tokenizer.model\")):\n            raise NotAMatchError(\"directory does not contain Gemma2 tokenizer files (tokenizer.json/tokenizer.model)\")\n\n        return cls(**override_fields)\n\n\ndef _read_gguf_arch_and_hidden_size(path: Path) -> tuple[str, int | None]:\n    \"\"\"Read (general.architecture, <arch>.embedding_length) from a GGUF file's metadata.\n\n    Raises NotAMatchError if the file is not a readable GGUF or is missing the architecture marker.\n    \"\"\"\n    import gguf","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/gemma2_encoder.py#L59-L95","documentation":"NotAMatchError raised by Gemma2Encoder_Gemma2Encoder_Config.from_model_on_disk when a Gemma2 directory's config.json reports a hidden_size other than 2304. PiD's caption projection is hard-wired to Gemma-2-2b's 2304-dim hidden state, so 9B (3584) and 27B (4608) variants are rejected early instead of failing with a matrix-shape error deep inside PiD inference. During model scanning this exception is normally caught per candidate config class and just means 'not my kind of model'.","triggerScenarios":"Calling ModelConfigFactory.from_model_on_disk (directly or via model scan/import) on a directory whose config.json has architectures=[\"Gemma2ForCausalLM\"] but hidden_size != 2304, e.g. any Gemma-2-9b-it or Gemma-2-27b-it checkpoint.","commonSituations":"User downloaded google/gemma-2-9b-it or gemma-2-27b-it instead of the 2b variant (e.g. Efficient-Large-Model/gemma-2-2b-it) and adds it as a PiD text encoder; also happens when a partial download of a sibling model directory is pointed at.","solutions":["Download/point at Gemma-2-2b (hidden_size 2304), e.g. Efficient-Large-Model/gemma-2-2b-it or google/gemma-2-2b-it","Check config.json hidden_size before importing: it must be 2304 for PiD use","If you only need a generic Gemma2 LM (not a PiD encoder), register it under a different model type instead"],"exampleFix":"// before (config.json of wrong variant)\n{ \"architectures\": [\"Gemma2ForCausalLM\"], \"hidden_size\": 3584 } // gemma-2-9b-it\n// after\n{ \"architectures\": [\"Gemma2ForCausalLM\"], \"hidden_size\": 2304 } // gemma-2-2b-it","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\ndef is_pid_compatible_gemma2_dir(model_dir: str | Path) -> bool:\n    cfg = Path(model_dir) / \"config.json\"\n    if not cfg.exists():\n        return False\n    try:\n        data = json.loads(cfg.read_text())\n    except (json.JSONDecodeError, OSError):\n        return False\n    return (\n        \"Gemma2ForCausalLM\" in (data.get(\"architectures\") or [])\n        and data.get(\"hidden_size\") == 2304\n    )","typeGuard":"def has_valid_gemma2_config(cfg: dict) -> bool:\n    return isinstance(cfg.get(\"hidden_size\"), int) and cfg.get(\"hidden_size\") == 2304","tryCatchPattern":"from invokeai.backend.model_manager.configs.identification_utils import NotAMatchError\n\ntry:\n    config = ModelConfigFactory.from_model_on_disk(mod, {})\nexcept NotAMatchError as e:\n    print(f\"Not a usable Gemma2 encoder for PiD: {e}\")  # suggest downloading gemma-2-2b-it","preventionTips":["Always download Efficient-Large-Model/gemma-2-2b-it (hidden_size 2304) for PiD encoders","Check config.json hidden_size == 2304 before importing any Gemma2 model","Never substitute 9b/27b variants 'just to try' — the projection shape is fixed at 2304"],"tags":["model-compatibility","gemma2","model-import"],"backgroundTag":"model-variant-incompatible","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}