mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
c48fd9c083
Refine concept of "parameter" nodes to "primitives": - integer - float - string - boolean - image - latents - conditioning - color Each primitive has: - A field definition, if it is not already python primitive value. The field is how this primitive value is passed between nodes. Collections are lists of the field in node definitions. ex: `ImageField` & `list[ImageField]` - A single output class. ex: `ImageOutput` - A collection output class. ex: `ImageCollectionOutput` - A node, which functions to load or pass on the primitive value. ex: `ImageInvocation` (in this case, `ImageInvocation` replaces `LoadImage`) Plus a number of related changes: - Reorganize these into `primitives.py` - Update all nodes and logic to use primitives - Consolidate "prompt" outputs into "string" & "mask" into "image" (there's no reason for these to be different, the function identically) - Update default graphs & tests - Regen frontend types & minor frontend tidy related to changes
194 lines
6.6 KiB
Python
194 lines
6.6 KiB
Python
from typing import Literal
|
|
|
|
from ...backend.model_management import ModelType, SubModelType
|
|
from .baseinvocation import (
|
|
BaseInvocation,
|
|
BaseInvocationOutput,
|
|
FieldDescriptions,
|
|
Input,
|
|
InputField,
|
|
InvocationContext,
|
|
OutputField,
|
|
UITypeHint,
|
|
tags,
|
|
title,
|
|
)
|
|
from .model import ClipField, MainModelField, ModelInfo, UNetField, VaeField
|
|
|
|
|
|
class SDXLModelLoaderOutput(BaseInvocationOutput):
|
|
"""SDXL base model loader output"""
|
|
|
|
type: Literal["sdxl_model_loader_output"] = "sdxl_model_loader_output"
|
|
|
|
unet: UNetField = OutputField(description=FieldDescriptions.unet, title="UNet")
|
|
clip: ClipField = OutputField(description=FieldDescriptions.clip, title="CLIP 1")
|
|
clip2: ClipField = OutputField(description=FieldDescriptions.clip, title="CLIP 2")
|
|
vae: VaeField = OutputField(description=FieldDescriptions.vae, title="VAE")
|
|
|
|
|
|
class SDXLRefinerModelLoaderOutput(BaseInvocationOutput):
|
|
"""SDXL refiner model loader output"""
|
|
|
|
type: Literal["sdxl_refiner_model_loader_output"] = "sdxl_refiner_model_loader_output"
|
|
|
|
unet: UNetField = OutputField(description=FieldDescriptions.unet, title="UNet")
|
|
clip2: ClipField = OutputField(description=FieldDescriptions.clip, title="CLIP 2")
|
|
vae: VaeField = OutputField(description=FieldDescriptions.vae, title="VAE")
|
|
|
|
|
|
@title("SDXL Main Model Loader")
|
|
@tags("model", "sdxl")
|
|
class SDXLModelLoaderInvocation(BaseInvocation):
|
|
"""Loads an sdxl base model, outputting its submodels."""
|
|
|
|
type: Literal["sdxl_model_loader"] = "sdxl_model_loader"
|
|
|
|
# Inputs
|
|
model: MainModelField = InputField(
|
|
description=FieldDescriptions.sdxl_main_model, input=Input.Direct, ui_type_hint=UITypeHint.SDXLMainModel
|
|
)
|
|
# TODO: precision?
|
|
|
|
def invoke(self, context: InvocationContext) -> SDXLModelLoaderOutput:
|
|
base_model = self.model.base_model
|
|
model_name = self.model.model_name
|
|
model_type = ModelType.Main
|
|
|
|
# TODO: not found exceptions
|
|
if not context.services.model_manager.model_exists(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
):
|
|
raise Exception(f"Unknown {base_model} {model_type} model: {model_name}")
|
|
|
|
return SDXLModelLoaderOutput(
|
|
unet=UNetField(
|
|
unet=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.UNet,
|
|
),
|
|
scheduler=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Scheduler,
|
|
),
|
|
loras=[],
|
|
),
|
|
clip=ClipField(
|
|
tokenizer=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Tokenizer,
|
|
),
|
|
text_encoder=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.TextEncoder,
|
|
),
|
|
loras=[],
|
|
skipped_layers=0,
|
|
),
|
|
clip2=ClipField(
|
|
tokenizer=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Tokenizer2,
|
|
),
|
|
text_encoder=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.TextEncoder2,
|
|
),
|
|
loras=[],
|
|
skipped_layers=0,
|
|
),
|
|
vae=VaeField(
|
|
vae=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Vae,
|
|
),
|
|
),
|
|
)
|
|
|
|
|
|
@title("SDXL Refiner Model Loader")
|
|
@tags("model", "sdxl", "refiner")
|
|
class SDXLRefinerModelLoaderInvocation(BaseInvocation):
|
|
"""Loads an sdxl refiner model, outputting its submodels."""
|
|
|
|
type: Literal["sdxl_refiner_model_loader"] = "sdxl_refiner_model_loader"
|
|
|
|
# Inputs
|
|
model: MainModelField = InputField(
|
|
description=FieldDescriptions.sdxl_refiner_model,
|
|
input=Input.Direct,
|
|
ui_type_hint=UITypeHint.SDXLRefinerModel,
|
|
)
|
|
# TODO: precision?
|
|
|
|
def invoke(self, context: InvocationContext) -> SDXLRefinerModelLoaderOutput:
|
|
base_model = self.model.base_model
|
|
model_name = self.model.model_name
|
|
model_type = ModelType.Main
|
|
|
|
# TODO: not found exceptions
|
|
if not context.services.model_manager.model_exists(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
):
|
|
raise Exception(f"Unknown {base_model} {model_type} model: {model_name}")
|
|
|
|
return SDXLRefinerModelLoaderOutput(
|
|
unet=UNetField(
|
|
unet=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.UNet,
|
|
),
|
|
scheduler=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Scheduler,
|
|
),
|
|
loras=[],
|
|
),
|
|
clip2=ClipField(
|
|
tokenizer=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Tokenizer2,
|
|
),
|
|
text_encoder=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.TextEncoder2,
|
|
),
|
|
loras=[],
|
|
skipped_layers=0,
|
|
),
|
|
vae=VaeField(
|
|
vae=ModelInfo(
|
|
model_name=model_name,
|
|
base_model=base_model,
|
|
model_type=model_type,
|
|
submodel=SubModelType.Vae,
|
|
),
|
|
),
|
|
)
|