cddb07a176
docs / deploy (push) Has been cancelled
docs / changes (push) Has been cancelled
docs / check-and-build (push) Has been cancelled
build container image / cpu (push) Has been cancelled
build container image / cuda (push) Has been cancelled
build container image / rocm (push) Has been cancelled
frontend checks / frontend-checks (push) Has been cancelled
frontend tests / frontend-tests (push) Has been cancelled
lfs checks / lfs-check (push) Has been cancelled
python checks / python-checks (push) Has been cancelled
python tests / py3.12: macos-default (push) Has been cancelled
python tests / py3.11: windows-cpu (push) Has been cancelled
python tests / py3.12: windows-cpu (push) Has been cancelled
python tests / py3.11: linux-cpu (push) Has been cancelled
typegen checks / typegen-checks (push) Has been cancelled
uv lock checks / uv-lock-checks (push) Has been cancelled
openapi checks / openapi-checks (push) Has been cancelled
python tests / py3.11: macos-default (push) Has been cancelled
python tests / py3.12: linux-cpu (push) Has been cancelled
55 lines
2.2 KiB
Python
55 lines
2.2 KiB
Python
from typing import (
|
|
Literal,
|
|
Self,
|
|
)
|
|
|
|
from pydantic import Field
|
|
from typing_extensions import Any
|
|
|
|
from invokeai.backend.model_manager.configs.base import Config_Base
|
|
from invokeai.backend.model_manager.configs.identification_utils import (
|
|
NotAMatchError,
|
|
raise_for_override_fields,
|
|
raise_if_not_file,
|
|
)
|
|
from invokeai.backend.model_manager.model_on_disk import ModelOnDisk
|
|
from invokeai.backend.model_manager.taxonomy import (
|
|
BaseModelType,
|
|
ModelFormat,
|
|
ModelType,
|
|
)
|
|
from invokeai.backend.spandrel_image_to_image_model import SpandrelImageToImageModel
|
|
|
|
|
|
class Spandrel_Checkpoint_Config(Config_Base):
|
|
"""Model config for Spandrel Image to Image models."""
|
|
|
|
base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)
|
|
type: Literal[ModelType.SpandrelImageToImage] = Field(default=ModelType.SpandrelImageToImage)
|
|
format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)
|
|
|
|
@classmethod
|
|
def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:
|
|
raise_if_not_file(mod)
|
|
|
|
raise_for_override_fields(cls, override_fields)
|
|
|
|
cls._validate_spandrel_loads_model(mod)
|
|
|
|
return cls(**override_fields)
|
|
|
|
@classmethod
|
|
def _validate_spandrel_loads_model(cls, mod: ModelOnDisk) -> None:
|
|
try:
|
|
# It would be nice to avoid having to load the Spandrel model from disk here. A couple of options were
|
|
# explored to avoid this:
|
|
# 1. Call `SpandrelImageToImageModel.load_from_state_dict(ckpt)`, where `ckpt` is a state_dict on the meta
|
|
# device. Unfortunately, some Spandrel models perform operations during initialization that are not
|
|
# supported on meta tensors.
|
|
# 2. Spandrel has internal logic to determine a model's type from its state_dict before loading the model.
|
|
# This logic is not exposed in spandrel's public API. We could copy the logic here, but then we have to
|
|
# maintain it, and the risk of false positive detections is higher.
|
|
SpandrelImageToImageModel.load_from_file(mod.path)
|
|
except Exception as e:
|
|
raise NotAMatchError("model does not match SpandrelImageToImage heuristics") from e
|