Merge branch 'main' into refactor/rename-performance-options

This commit is contained in:
Lincoln Stein
2023-08-21 22:29:34 -04:00
committed by GitHub
267 changed files with 3650 additions and 2675 deletions

View File

@ -122,6 +122,7 @@ def custom_openapi():
output_schemas = schema(output_types, ref_prefix="#/components/schemas/")
for schema_key, output_schema in output_schemas["definitions"].items():
output_schema["class"] = "output"
openapi_schema["components"]["schemas"][schema_key] = output_schema
# TODO: note that we assume the schema_key here is the TYPE.__name__
@ -130,8 +131,8 @@ def custom_openapi():
# Add Node Editor UI helper schemas
ui_config_schemas = schema([UIConfigBase, _InputField, _OutputField], ref_prefix="#/components/schemas/")
for schema_key, output_schema in ui_config_schemas["definitions"].items():
openapi_schema["components"]["schemas"][schema_key] = output_schema
for schema_key, ui_config_schema in ui_config_schemas["definitions"].items():
openapi_schema["components"]["schemas"][schema_key] = ui_config_schema
# Add a reference to the output type to additionalProperties of the invoker schema
for invoker in all_invocations:
@ -140,8 +141,8 @@ def custom_openapi():
output_type_title = output_type_titles[output_type.__name__]
invoker_schema = openapi_schema["components"]["schemas"][invoker_name]
outputs_ref = {"$ref": f"#/components/schemas/{output_type_title}"}
invoker_schema["output"] = outputs_ref
invoker_schema["class"] = "invocation"
from invokeai.backend.model_management.models import get_model_config_enums

View File

@ -143,6 +143,7 @@ class UIType(str, Enum):
# region Misc
FilePath = "FilePath"
Enum = "enum"
Scheduler = "Scheduler"
# endregion
@ -392,6 +393,13 @@ class BaseInvocationOutput(BaseModel):
toprocess.extend(next_subclasses)
return tuple(subclasses)
class Config:
@staticmethod
def schema_extra(schema: dict[str, Any], model_class: Type[BaseModel]) -> None:
if "required" not in schema or not isinstance(schema["required"], list):
schema["required"] = list()
schema["required"].extend(["type"])
class RequiredConnectionException(Exception):
"""Raised when an field which requires a connection did not receive a value."""
@ -452,6 +460,9 @@ class BaseInvocation(ABC, BaseModel):
schema["title"] = uiconfig.title
if uiconfig and hasattr(uiconfig, "tags"):
schema["tags"] = uiconfig.tags
if "required" not in schema or not isinstance(schema["required"], list):
schema["required"] = list()
schema["required"].extend(["type", "id"])
@abstractmethod
def invoke(self, context: InvocationContext) -> BaseInvocationOutput:

View File

@ -115,12 +115,14 @@ class DenoiseLatentsInvocation(BaseInvocation):
noise: Optional[LatentsField] = InputField(description=FieldDescriptions.noise, input=Input.Connection)
steps: int = InputField(default=10, gt=0, description=FieldDescriptions.steps)
cfg_scale: Union[float, List[float]] = InputField(
default=7.5, ge=1, description=FieldDescriptions.cfg_scale, ui_type=UIType.Float
default=7.5, ge=1, description=FieldDescriptions.cfg_scale, ui_type=UIType.Float, title="CFG Scale"
)
denoising_start: float = InputField(default=0.0, ge=0, le=1, description=FieldDescriptions.denoising_start)
denoising_end: float = InputField(default=1.0, ge=0, le=1, description=FieldDescriptions.denoising_end)
scheduler: SAMPLER_NAME_VALUES = InputField(default="euler", description=FieldDescriptions.scheduler)
unet: UNetField = InputField(description=FieldDescriptions.unet, input=Input.Connection)
scheduler: SAMPLER_NAME_VALUES = InputField(
default="euler", description=FieldDescriptions.scheduler, ui_type=UIType.Scheduler
)
unet: UNetField = InputField(description=FieldDescriptions.unet, input=Input.Connection, title="UNet")
control: Union[ControlField, list[ControlField]] = InputField(
default=None, description=FieldDescriptions.control, input=Input.Connection
)
@ -454,7 +456,7 @@ class DenoiseLatentsInvocation(BaseInvocation):
@title("Latents to Image")
@tags("latents", "image", "vae")
@tags("latents", "image", "vae", "l2i")
class LatentsToImageInvocation(BaseInvocation):
"""Generates an image from latents."""
@ -642,7 +644,7 @@ class ScaleLatentsInvocation(BaseInvocation):
@title("Image to Latents")
@tags("latents", "image", "vae")
@tags("latents", "image", "vae", "i2l")
class ImageToLatentsInvocation(BaseInvocation):
"""Encodes an image into latents."""

View File

@ -21,7 +21,7 @@ class AddInvocation(BaseInvocation):
b: int = InputField(default=0, description=FieldDescriptions.num_2)
def invoke(self, context: InvocationContext) -> IntegerOutput:
return IntegerOutput(a=self.a + self.b)
return IntegerOutput(value=self.a + self.b)
@title("Subtract Integers")
@ -36,7 +36,7 @@ class SubtractInvocation(BaseInvocation):
b: int = InputField(default=0, description=FieldDescriptions.num_2)
def invoke(self, context: InvocationContext) -> IntegerOutput:
return IntegerOutput(a=self.a - self.b)
return IntegerOutput(value=self.a - self.b)
@title("Multiply Integers")
@ -51,7 +51,7 @@ class MultiplyInvocation(BaseInvocation):
b: int = InputField(default=0, description=FieldDescriptions.num_2)
def invoke(self, context: InvocationContext) -> IntegerOutput:
return IntegerOutput(a=self.a * self.b)
return IntegerOutput(value=self.a * self.b)
@title("Divide Integers")
@ -66,7 +66,7 @@ class DivideInvocation(BaseInvocation):
b: int = InputField(default=0, description=FieldDescriptions.num_2)
def invoke(self, context: InvocationContext) -> IntegerOutput:
return IntegerOutput(a=int(self.a / self.b))
return IntegerOutput(value=int(self.a / self.b))
@title("Random Integer")
@ -81,4 +81,4 @@ class RandomIntInvocation(BaseInvocation):
high: int = InputField(default=np.iinfo(np.int32).max, description="The exclusive high value")
def invoke(self, context: InvocationContext) -> IntegerOutput:
return IntegerOutput(a=np.random.randint(self.low, self.high))
return IntegerOutput(value=np.random.randint(self.low, self.high))

View File

@ -72,7 +72,7 @@ class LoRAModelField(BaseModel):
base_model: BaseModelType = Field(description="Base model")
@title("Main Model Loader")
@title("Main Model")
@tags("model")
class MainModelLoaderInvocation(BaseInvocation):
"""Loads a main model, outputting its submodels."""
@ -179,7 +179,7 @@ class LoraLoaderOutput(BaseInvocationOutput):
# fmt: on
@title("LoRA Loader")
@title("LoRA")
@tags("lora", "model")
class LoraLoaderInvocation(BaseInvocation):
"""Apply selected lora to unet and text_encoder."""
@ -257,7 +257,7 @@ class SDXLLoraLoaderOutput(BaseInvocationOutput):
# fmt: on
@title("SDXL LoRA Loader")
@title("SDXL LoRA")
@tags("sdxl", "lora", "model")
class SDXLLoraLoaderInvocation(BaseInvocation):
"""Apply selected lora to unet and text_encoder."""
@ -356,7 +356,7 @@ class VaeLoaderOutput(BaseInvocationOutput):
vae: VaeField = OutputField(description=FieldDescriptions.vae, title="VAE")
@title("VAE Loader")
@title("VAE")
@tags("vae", "model")
class VaeLoaderInvocation(BaseInvocation):
"""Loads a VAE model, outputting a VaeLoaderOutput"""

View File

@ -169,7 +169,7 @@ class ONNXTextToLatentsInvocation(BaseInvocation):
ui_type=UIType.Float,
)
scheduler: SAMPLER_NAME_VALUES = InputField(
default="euler", description=FieldDescriptions.scheduler, input=Input.Direct
default="euler", description=FieldDescriptions.scheduler, input=Input.Direct, ui_type=UIType.Scheduler
)
precision: PRECISION_VALUES = InputField(default="tensor(float16)", description=FieldDescriptions.precision)
unet: UNetField = InputField(
@ -406,7 +406,7 @@ class OnnxModelField(BaseModel):
model_type: ModelType = Field(description="Model Type")
@title("ONNX Model Loader")
@title("ONNX Main Model")
@tags("onnx", "model")
class OnnxModelLoaderInvocation(BaseInvocation):
"""Loads a main model, outputting its submodels."""

View File

@ -2,8 +2,8 @@
from typing import Literal, Optional, Tuple
from pydantic import BaseModel, Field
import torch
from pydantic import BaseModel, Field
from .baseinvocation import (
BaseInvocation,
@ -33,7 +33,7 @@ class BooleanOutput(BaseInvocationOutput):
"""Base class for nodes that output a single boolean"""
type: Literal["boolean_output"] = "boolean_output"
a: bool = OutputField(description="The output boolean")
value: bool = OutputField(description="The output boolean")
class BooleanCollectionOutput(BaseInvocationOutput):
@ -42,9 +42,7 @@ class BooleanCollectionOutput(BaseInvocationOutput):
type: Literal["boolean_collection_output"] = "boolean_collection_output"
# Outputs
collection: list[bool] = OutputField(
default_factory=list, description="The output boolean collection", ui_type=UIType.BooleanCollection
)
collection: list[bool] = OutputField(description="The output boolean collection", ui_type=UIType.BooleanCollection)
@title("Boolean Primitive")
@ -55,10 +53,10 @@ class BooleanInvocation(BaseInvocation):
type: Literal["boolean"] = "boolean"
# Inputs
a: bool = InputField(default=False, description="The boolean value")
value: bool = InputField(default=False, description="The boolean value")
def invoke(self, context: InvocationContext) -> BooleanOutput:
return BooleanOutput(a=self.a)
return BooleanOutput(value=self.value)
@title("Boolean Primitive Collection")
@ -70,7 +68,7 @@ class BooleanCollectionInvocation(BaseInvocation):
# Inputs
collection: list[bool] = InputField(
default=False, description="The collection of boolean values", ui_type=UIType.BooleanCollection
default_factory=list, description="The collection of boolean values", ui_type=UIType.BooleanCollection
)
def invoke(self, context: InvocationContext) -> BooleanCollectionOutput:
@ -86,7 +84,7 @@ class IntegerOutput(BaseInvocationOutput):
"""Base class for nodes that output a single integer"""
type: Literal["integer_output"] = "integer_output"
a: int = OutputField(description="The output integer")
value: int = OutputField(description="The output integer")
class IntegerCollectionOutput(BaseInvocationOutput):
@ -95,9 +93,7 @@ class IntegerCollectionOutput(BaseInvocationOutput):
type: Literal["integer_collection_output"] = "integer_collection_output"
# Outputs
collection: list[int] = OutputField(
default_factory=list, description="The int collection", ui_type=UIType.IntegerCollection
)
collection: list[int] = OutputField(description="The int collection", ui_type=UIType.IntegerCollection)
@title("Integer Primitive")
@ -108,10 +104,10 @@ class IntegerInvocation(BaseInvocation):
type: Literal["integer"] = "integer"
# Inputs
a: int = InputField(default=0, description="The integer value")
value: int = InputField(default=0, description="The integer value")
def invoke(self, context: InvocationContext) -> IntegerOutput:
return IntegerOutput(a=self.a)
return IntegerOutput(value=self.value)
@title("Integer Primitive Collection")
@ -139,7 +135,7 @@ class FloatOutput(BaseInvocationOutput):
"""Base class for nodes that output a single float"""
type: Literal["float_output"] = "float_output"
a: float = OutputField(description="The output float")
value: float = OutputField(description="The output float")
class FloatCollectionOutput(BaseInvocationOutput):
@ -148,9 +144,7 @@ class FloatCollectionOutput(BaseInvocationOutput):
type: Literal["float_collection_output"] = "float_collection_output"
# Outputs
collection: list[float] = OutputField(
default_factory=list, description="The float collection", ui_type=UIType.FloatCollection
)
collection: list[float] = OutputField(description="The float collection", ui_type=UIType.FloatCollection)
@title("Float Primitive")
@ -161,10 +155,10 @@ class FloatInvocation(BaseInvocation):
type: Literal["float"] = "float"
# Inputs
param: float = InputField(default=0.0, description="The float value")
value: float = InputField(default=0.0, description="The float value")
def invoke(self, context: InvocationContext) -> FloatOutput:
return FloatOutput(a=self.param)
return FloatOutput(value=self.value)
@title("Float Primitive Collection")
@ -176,7 +170,7 @@ class FloatCollectionInvocation(BaseInvocation):
# Inputs
collection: list[float] = InputField(
default=0, description="The collection of float values", ui_type=UIType.FloatCollection
default_factory=list, description="The collection of float values", ui_type=UIType.FloatCollection
)
def invoke(self, context: InvocationContext) -> FloatCollectionOutput:
@ -192,7 +186,7 @@ class StringOutput(BaseInvocationOutput):
"""Base class for nodes that output a single string"""
type: Literal["string_output"] = "string_output"
text: str = OutputField(description="The output string")
value: str = OutputField(description="The output string")
class StringCollectionOutput(BaseInvocationOutput):
@ -201,9 +195,7 @@ class StringCollectionOutput(BaseInvocationOutput):
type: Literal["string_collection_output"] = "string_collection_output"
# Outputs
collection: list[str] = OutputField(
default_factory=list, description="The output strings", ui_type=UIType.StringCollection
)
collection: list[str] = OutputField(description="The output strings", ui_type=UIType.StringCollection)
@title("String Primitive")
@ -214,10 +206,10 @@ class StringInvocation(BaseInvocation):
type: Literal["string"] = "string"
# Inputs
text: str = InputField(default="", description="The string value", ui_component=UIComponent.Textarea)
value: str = InputField(default="", description="The string value", ui_component=UIComponent.Textarea)
def invoke(self, context: InvocationContext) -> StringOutput:
return StringOutput(text=self.text)
return StringOutput(value=self.value)
@title("String Primitive Collection")
@ -229,7 +221,7 @@ class StringCollectionInvocation(BaseInvocation):
# Inputs
collection: list[str] = InputField(
default=0, description="The collection of string values", ui_type=UIType.StringCollection
default_factory=list, description="The collection of string values", ui_type=UIType.StringCollection
)
def invoke(self, context: InvocationContext) -> StringCollectionOutput:
@ -262,9 +254,7 @@ class ImageCollectionOutput(BaseInvocationOutput):
type: Literal["image_collection_output"] = "image_collection_output"
# Outputs
collection: list[ImageField] = OutputField(
default_factory=list, description="The output images", ui_type=UIType.ImageCollection
)
collection: list[ImageField] = OutputField(description="The output images", ui_type=UIType.ImageCollection)
@title("Image Primitive")
@ -334,7 +324,6 @@ class LatentsCollectionOutput(BaseInvocationOutput):
type: Literal["latents_collection_output"] = "latents_collection_output"
collection: list[LatentsField] = OutputField(
default_factory=list,
description=FieldDescriptions.latents,
ui_type=UIType.LatentsCollection,
)
@ -365,7 +354,7 @@ class LatentsCollectionInvocation(BaseInvocation):
# Inputs
collection: list[LatentsField] = InputField(
default=0, description="The collection of latents tensors", ui_type=UIType.LatentsCollection
description="The collection of latents tensors", ui_type=UIType.LatentsCollection
)
def invoke(self, context: InvocationContext) -> LatentsCollectionOutput:
@ -410,9 +399,7 @@ class ColorCollectionOutput(BaseInvocationOutput):
type: Literal["color_collection_output"] = "color_collection_output"
# Outputs
collection: list[ColorField] = OutputField(
default_factory=list, description="The output colors", ui_type=UIType.ColorCollection
)
collection: list[ColorField] = OutputField(description="The output colors", ui_type=UIType.ColorCollection)
@title("Color Primitive")
@ -455,7 +442,6 @@ class ConditioningCollectionOutput(BaseInvocationOutput):
# Outputs
collection: list[ConditioningField] = OutputField(
default_factory=list,
description="The output conditioning tensors",
ui_type=UIType.ConditioningCollection,
)

View File

@ -37,7 +37,7 @@ class SDXLRefinerModelLoaderOutput(BaseInvocationOutput):
vae: VaeField = OutputField(description=FieldDescriptions.vae, title="VAE")
@title("SDXL Main Model Loader")
@title("SDXL Main Model")
@tags("model", "sdxl")
class SDXLModelLoaderInvocation(BaseInvocation):
"""Loads an sdxl base model, outputting its submodels."""
@ -122,7 +122,7 @@ class SDXLModelLoaderInvocation(BaseInvocation):
)
@title("SDXL Refiner Model Loader")
@title("SDXL Refiner Model")
@tags("model", "sdxl", "refiner")
class SDXLRefinerModelLoaderInvocation(BaseInvocation):
"""Loads an sdxl refiner model, outputting its submodels."""

View File

@ -17,9 +17,9 @@ def create_text_to_image() -> LibraryGraph:
description="Converts text to an image",
graph=Graph(
nodes={
"width": IntegerInvocation(id="width", a=512),
"height": IntegerInvocation(id="height", a=512),
"seed": IntegerInvocation(id="seed", a=-1),
"width": IntegerInvocation(id="width", value=512),
"height": IntegerInvocation(id="height", value=512),
"seed": IntegerInvocation(id="seed", value=-1),
"3": NoiseInvocation(id="3"),
"4": CompelInvocation(id="4"),
"5": CompelInvocation(id="5"),
@ -29,15 +29,15 @@ def create_text_to_image() -> LibraryGraph:
},
edges=[
Edge(
source=EdgeConnection(node_id="width", field="a"),
source=EdgeConnection(node_id="width", field="value"),
destination=EdgeConnection(node_id="3", field="width"),
),
Edge(
source=EdgeConnection(node_id="height", field="a"),
source=EdgeConnection(node_id="height", field="value"),
destination=EdgeConnection(node_id="3", field="height"),
),
Edge(
source=EdgeConnection(node_id="seed", field="a"),
source=EdgeConnection(node_id="seed", field="value"),
destination=EdgeConnection(node_id="3", field="seed"),
),
Edge(
@ -65,9 +65,9 @@ def create_text_to_image() -> LibraryGraph:
exposed_inputs=[
ExposedNodeInput(node_path="4", field="prompt", alias="positive_prompt"),
ExposedNodeInput(node_path="5", field="prompt", alias="negative_prompt"),
ExposedNodeInput(node_path="width", field="a", alias="width"),
ExposedNodeInput(node_path="height", field="a", alias="height"),
ExposedNodeInput(node_path="seed", field="a", alias="seed"),
ExposedNodeInput(node_path="width", field="value", alias="width"),
ExposedNodeInput(node_path="height", field="value", alias="height"),
ExposedNodeInput(node_path="seed", field="value", alias="seed"),
],
exposed_outputs=[ExposedNodeOutput(node_path="8", field="image", alias="image")],
)