diff --git a/invokeai/app/invocations/ip_adapter.py b/invokeai/app/invocations/ip_adapter.py index cb686c906b..0fc9c90128 100644 --- a/invokeai/app/invocations/ip_adapter.py +++ b/invokeai/app/invocations/ip_adapter.py @@ -15,7 +15,7 @@ from invokeai.app.invocations.model import ModelIdentifierField from invokeai.app.invocations.primitives import ImageField from invokeai.app.invocations.util import validate_begin_end_step, validate_weights from invokeai.app.services.shared.invocation_context import InvocationContext -from invokeai.backend.model_manager.config import BaseModelType, IPAdapterConfig, ModelType +from invokeai.backend.model_manager.config import AnyModelConfig, BaseModelType, IPAdapterConfig, ModelType class IPAdapterField(BaseModel): @@ -89,17 +89,32 @@ class IPAdapterInvocation(BaseInvocation): assert isinstance(ip_adapter_info, IPAdapterConfig) image_encoder_model_id = ip_adapter_info.image_encoder_model_id image_encoder_model_name = image_encoder_model_id.split("/")[-1].strip() - image_encoder_models = context.models.search_by_attrs( - name=image_encoder_model_name, base=BaseModelType.Any, type=ModelType.CLIPVision - ) - assert len(image_encoder_models) == 1 + image_encoder_model = self._get_image_encoder(context, image_encoder_model_name) return IPAdapterOutput( ip_adapter=IPAdapterField( image=self.image, ip_adapter_model=self.ip_adapter_model, - image_encoder_model=ModelIdentifierField.from_config(image_encoder_models[0]), + image_encoder_model=ModelIdentifierField.from_config(image_encoder_model), weight=self.weight, begin_step_percent=self.begin_step_percent, end_step_percent=self.end_step_percent, ), ) + + def _get_image_encoder(self, context: InvocationContext, image_encoder_model_name: str) -> AnyModelConfig: + found = False + while not found: + image_encoder_models = context.models.search_by_attrs( + name=image_encoder_model_name, base=BaseModelType.Any, type=ModelType.CLIPVision + ) + found = len(image_encoder_models) > 0 + if not found: + context.logger.warning( + f"The image encoder required by this IP Adapter ({image_encoder_model_name}) is not installed." + ) + context.logger.warning("Downloading and installing now. This may take a while.") + installer = context._services.model_manager.install + job = installer.heuristic_import(f"InvokeAI/{image_encoder_model_name}") + installer.wait_for_job(job, timeout=600) # wait up to 10 minutes - then raise a TimeoutException + assert len(image_encoder_models) == 1 + return image_encoder_models[0]