diff --git a/invokeai/app/services/images/images_default.py b/invokeai/app/services/images/images_default.py index 74aeeccca5..ff21731a50 100644 --- a/invokeai/app/services/images/images_default.py +++ b/invokeai/app/services/images/images_default.py @@ -154,7 +154,7 @@ class ImageService(ImageServiceABC): self.__invoker.services.logger.error("Image record not found") raise except Exception as e: - self.__invoker.services.logger.error("Problem getting image DTO") + self.__invoker.services.logger.error("Problem getting image metadata") raise e def get_workflow(self, image_name: str) -> Optional[WorkflowWithoutID]: diff --git a/invokeai/backend/model_management/seamless.py b/invokeai/backend/model_management/seamless.py index e145c6f481..fb9112b56d 100644 --- a/invokeai/backend/model_management/seamless.py +++ b/invokeai/backend/model_management/seamless.py @@ -30,6 +30,8 @@ def set_seamless(model: Union[UNet2DConditionModel, AutoencoderKL], seamless_axe # Callable: (input: Tensor, weight: Tensor, bias: Optional[Tensor]) -> Tensor to_restore: list[tuple[nn.Conv2d | nn.ConvTranspose2d, Callable]] = [] try: + # Hard coded to skip down block layers, allowing for seamless tiling at the expense of prompt adherence + skipped_layers = 1 for m_name, m in model.named_modules(): if not isinstance(m, (nn.Conv2d, nn.ConvTranspose2d)): continue @@ -40,8 +42,7 @@ def set_seamless(model: Union[UNet2DConditionModel, AutoencoderKL], seamless_axe block_num = int(block_num) resnet_num = int(resnet_num) - # Could be configurable to allow skipping arbitrary numbers of down blocks - if block_num >= len(model.down_blocks): + if block_num >= len(model.down_blocks) - skipped_layers: continue # Skip the second resnet (could be configurable) diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts index daa214364d..7413302fa5 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts @@ -23,6 +23,7 @@ import { NOISE, NOISE_HRF, RESIZE_HRF, + SEAMLESS, VAE_LOADER, } from './constants'; import { setMetadataReceivingNode, upsertMetadata } from './metadata'; @@ -30,7 +31,6 @@ import { setMetadataReceivingNode, upsertMetadata } from './metadata'; // Copy certain connections from previous DENOISE_LATENTS to new DENOISE_LATENTS_HRF. function copyConnectionsToDenoiseLatentsHrf(graph: NonNullableGraph): void { const destinationFields = [ - 'vae', 'control', 'ip_adapter', 'metadata', @@ -107,9 +107,10 @@ export const addHrfToGraph = (state: RootState, graph: NonNullableGraph): void = } const log = logger('txt2img'); - const { vae } = state.generation; + const { vae, seamlessXAxis, seamlessYAxis } = state.generation; const { hrfStrength, hrfEnabled, hrfMethod } = state.hrf; const isAutoVae = !vae; + const isSeamlessEnabled = seamlessXAxis || seamlessYAxis; const width = state.generation.width; const height = state.generation.height; const optimalDimension = selectOptimalDimension(state); @@ -158,7 +159,7 @@ export const addHrfToGraph = (state: RootState, graph: NonNullableGraph): void = }, { source: { - node_id: isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, field: 'vae', }, destination: { @@ -259,7 +260,7 @@ export const addHrfToGraph = (state: RootState, graph: NonNullableGraph): void = graph.edges.push( { source: { - node_id: isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, field: 'vae', }, destination: { @@ -322,7 +323,7 @@ export const addHrfToGraph = (state: RootState, graph: NonNullableGraph): void = graph.edges.push( { source: { - node_id: isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, field: 'vae', }, destination: { diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/addSeamlessToLinearGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/addSeamlessToLinearGraph.ts index 850b2a65bd..803437e968 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/addSeamlessToLinearGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/addSeamlessToLinearGraph.ts @@ -14,6 +14,7 @@ import { SDXL_IMAGE_TO_IMAGE_GRAPH, SDXL_TEXT_TO_IMAGE_GRAPH, SEAMLESS, + VAE_LOADER, } from './constants'; import { upsertMetadata } from './metadata'; @@ -23,7 +24,8 @@ export const addSeamlessToLinearGraph = ( modelLoaderNodeId: string ): void => { // Remove Existing UNet Connections - const { seamlessXAxis, seamlessYAxis } = state.generation; + const { seamlessXAxis, seamlessYAxis, vae } = state.generation; + const isAutoVae = !vae; graph.nodes[SEAMLESS] = { id: SEAMLESS, @@ -32,6 +34,15 @@ export const addSeamlessToLinearGraph = ( seamless_y: seamlessYAxis, } as SeamlessModeInvocation; + if (!isAutoVae) { + graph.nodes[VAE_LOADER] = { + type: 'vae_loader', + id: VAE_LOADER, + is_intermediate: true, + vae_model: vae, + }; + } + if (seamlessXAxis) { upsertMetadata(graph, { seamless_x: seamlessXAxis, @@ -75,7 +86,7 @@ export const addSeamlessToLinearGraph = ( }, { source: { - node_id: modelLoaderNodeId, + node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/addVAEToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/addVAEToGraph.ts index b886c9b7d5..95781d08e7 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/addVAEToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/addVAEToGraph.ts @@ -21,6 +21,7 @@ import { SDXL_IMAGE_TO_IMAGE_GRAPH, SDXL_REFINER_INPAINT_CREATE_MASK, SDXL_TEXT_TO_IMAGE_GRAPH, + SEAMLESS, TEXT_TO_IMAGE_GRAPH, VAE_LOADER, } from './constants'; @@ -31,15 +32,16 @@ export const addVAEToGraph = ( graph: NonNullableGraph, modelLoaderNodeId: string = MAIN_MODEL_LOADER ): void => { - const { vae, canvasCoherenceMode } = state.generation; + const { vae, canvasCoherenceMode, seamlessXAxis, seamlessYAxis } = state.generation; const { boundingBoxScaleMethod } = state.canvas; const { refinerModel } = state.sdxl; const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod); const isAutoVae = !vae; + const isSeamlessEnabled = seamlessXAxis || seamlessYAxis; - if (!isAutoVae) { + if (!isAutoVae && !isSeamlessEnabled) { graph.nodes[VAE_LOADER] = { type: 'vae_loader', id: VAE_LOADER, @@ -56,7 +58,7 @@ export const addVAEToGraph = ( ) { graph.edges.push({ source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -74,7 +76,7 @@ export const addVAEToGraph = ( ) { graph.edges.push({ source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -92,7 +94,7 @@ export const addVAEToGraph = ( ) { graph.edges.push({ source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -111,7 +113,7 @@ export const addVAEToGraph = ( graph.edges.push( { source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -121,7 +123,7 @@ export const addVAEToGraph = ( }, { source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -131,7 +133,7 @@ export const addVAEToGraph = ( }, { source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -145,7 +147,7 @@ export const addVAEToGraph = ( if (canvasCoherenceMode !== 'unmasked') { graph.edges.push({ source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: { @@ -160,7 +162,7 @@ export const addVAEToGraph = ( if (graph.id === SDXL_CANVAS_INPAINT_GRAPH || graph.id === SDXL_CANVAS_OUTPAINT_GRAPH) { graph.edges.push({ source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + node_id: isSeamlessEnabled ? SEAMLESS : isAutoVae ? modelLoaderNodeId : VAE_LOADER, field: 'vae', }, destination: {