{"record":{"id":"d618259877a5b16e","repo":"invoke-ai/InvokeAI","slug":"directory-looks-like-a-full-diffusers-pipeline-no","errorCode":null,"errorMessage":"directory looks like a full diffusers pipeline, not a standalone Gemma2 encoder","messagePattern":"directory looks like a full diffusers pipeline, not a standalone Gemma2 encoder","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/gemma2_encoder.py","lineNumber":67,"sourceCode":"    \"\"\"\n\n    base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)\n    type: Literal[ModelType.Gemma2Encoder] = Field(default=ModelType.Gemma2Encoder)\n    format: Literal[ModelFormat.Gemma2Encoder] = Field(default=ModelFormat.Gemma2Encoder)\n    cpu_only: bool | None = Field(default=None, description=\"Whether this model should run on CPU only\")\n\n    @classmethod\n    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:\n        raise_if_not_dir(mod)\n        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)\")","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/gemma2_encoder.py#L49-L85","documentation":"After config.json exists, the prober rejects directories that also contain model_index.json at the root, since that marks a full diffusers pipeline (UNet+VAE+encoders together) rather than the standalone Gemma2 encoder InvokeAI requires for PiD caption projection. Probing such a pipeline raises NotAMatchError.","triggerScenarios":"from_model_on_disk pointed at a downloaded diffusers repo root (e.g. a full pipeline snapshot with model_index.json) instead of the text_encoder subfolder; or copying the whole HF snapshot into the models directory.","commonSituations":"Downloading gemma-2-2b-it as a full pipeline snapshot and importing the whole folder; pointing InvokeAI at the repo root rather than the encoder component directory.","solutions":["Import only the text_encoder/ subdirectory of the pipeline, not the repo root","Remove model_index.json only if you truly isolated the encoder files into their own directory (otherwise keep the pipeline elsewhere)","Download the standalone Gemma2 model and import its top-level folder directly","Keep full pipelines outside InvokeAI's models directory to avoid component mis-probing"],"exampleFix":"// before\ninstall_model(\"/models/gemma-2-2b-it\")            # full pipeline: has model_index.json\n// after\ninstall_model(\"/models/gemma-2-2b-it/text_encoder\")  # standalone encoder dir","handlingStrategy":"validation","validationCode":"import pathlib\n\ndef is_full_diffusers_pipeline(path: str) -> bool:\n    p = pathlib.Path(path)\n    return (p / \"model_index.json\").exists()\n\ndef encoder_import_path(path: str) -> str:\n    p = pathlib.Path(path)\n    return str(p / \"text_encoder\") if is_full_diffusers_pipeline(str(p)) else str(p)","typeGuard":null,"tryCatchPattern":"try:\n    config = probe(mod)\nexcept NotAMatchError as e:\n    if \"full diffusers pipeline\" in str(e):\n        encoder = pathlib.Path(mod.path) / \"text_encoder\"\n        config = probe(encoder)\n    else:\n        raise","preventionTips":["Never import full pipeline snapshots as single models","Point at the text_encoder subdirectory of pipelines","Keep full pipelines outside the InvokeAI models directory","Check for model_index.json before import to detect pipelines"],"tags":["python","gemma2","diffusers","model-probing"],"backgroundTag":"model-format-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}