Spaces:
Runtime error
Runtime error
| <!--Copyright 2024 The HuggingFace Team. All rights reserved. | |
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | |
| the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | |
| an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
| specific language governing permissions and limitations under the License. | |
| --> | |
| # T2I-Adapter | |
| [T2I-Adapter](https://hf.co/papers/2302.08453) is a lightweight adapter for controlling and providing more accurate | |
| structure guidance for text-to-image models. It works by learning an alignment between the internal knowledge of the | |
| text-to-image model and an external control signal, such as edge detection or depth estimation. | |
| The T2I-Adapter design is simple, the condition is passed to four feature extraction blocks and three downsample | |
| blocks. This makes it fast and easy to train different adapters for different conditions which can be plugged into the | |
| text-to-image model. T2I-Adapter is similar to [ControlNet](controlnet) except it is smaller (~77M parameters) and | |
| faster because it only runs once during the diffusion process. The downside is that performance may be slightly worse | |
| than ControlNet. | |
| This guide will show you how to use T2I-Adapter with different Stable Diffusion models and how you can compose multiple | |
| T2I-Adapters to impose more than one condition. | |
| > [!TIP] | |
| > There are several T2I-Adapters available for different conditions, such as color palette, depth, sketch, pose, and | |
| > segmentation. Check out the [TencentARC](https://hf.co/TencentARC) repository to try them out! | |
| Before you begin, make sure you have the following libraries installed. | |
| ```py | |
| # uncomment to install the necessary libraries in Colab | |
| #!pip install -q diffusers accelerate controlnet-aux==0.0.7 | |
| ``` | |
| ## Text-to-image | |
| Text-to-image models rely on a prompt to generate an image, but sometimes, text alone may not be enough to provide more | |
| accurate structural guidance. T2I-Adapter allows you to provide an additional control image to guide the generation | |
| process. For example, you can provide a canny image (a white outline of an image on a black background) to guide the | |
| model to generate an image with a similar structure. | |
| <hfoptions id="stablediffusion"> | |
| <hfoption id="Stable Diffusion 1.5"> | |
| Create a canny image with the [opencv-library](https://github.com/opencv/opencv-python). | |
| ```py | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| from diffusers.utils import load_image | |
| image = load_image("https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/hf-logo.png") | |
| image = np.array(image) | |
| low_threshold = 100 | |
| high_threshold = 200 | |
| image = cv2.Canny(image, low_threshold, high_threshold) | |
| image = Image.fromarray(image) | |
| ``` | |
| Now load a T2I-Adapter conditioned on [canny images](https://hf.co/TencentARC/t2iadapter_canny_sd15v2) and pass it to | |
| the [`StableDiffusionAdapterPipeline`]. | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionAdapterPipeline, T2IAdapter | |
| adapter = T2IAdapter.from_pretrained("TencentARC/t2iadapter_canny_sd15v2", torch_dtype=torch.float16) | |
| pipeline = StableDiffusionAdapterPipeline.from_pretrained( | |
| "stable-diffusion-v1-5/stable-diffusion-v1-5", | |
| adapter=adapter, | |
| torch_dtype=torch.float16, | |
| ) | |
| pipeline.to("cuda") | |
| ``` | |
| Finally, pass your prompt and control image to the pipeline. | |
| ```py | |
| generator = torch.Generator("cuda").manual_seed(0) | |
| image = pipeline( | |
| prompt="cinematic photo of a plush and soft midcentury style rug on a wooden floor, 35mm photograph, film, professional, 4k, highly detailed", | |
| image=image, | |
| generator=generator, | |
| ).images[0] | |
| image | |
| ``` | |
| <div class="flex justify-center"> | |
| <img class="rounded-xl" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/t2i-sd1.5.png"/> | |
| </div> | |
| </hfoption> | |
| <hfoption id="Stable Diffusion XL"> | |
| Create a canny image with the [controlnet-aux](https://github.com/huggingface/controlnet_aux) library. | |
| ```py | |
| from controlnet_aux.canny import CannyDetector | |
| from diffusers.utils import load_image | |
| canny_detector = CannyDetector() | |
| image = load_image("https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/hf-logo.png") | |
| image = canny_detector(image, detect_resolution=384, image_resolution=1024) | |
| ``` | |
| Now load a T2I-Adapter conditioned on [canny images](https://hf.co/TencentARC/t2i-adapter-canny-sdxl-1.0) and pass it | |
| to the [`StableDiffusionXLAdapterPipeline`]. | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionXLAdapterPipeline, T2IAdapter, EulerAncestralDiscreteScheduler, AutoencoderKL | |
| scheduler = EulerAncestralDiscreteScheduler.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", subfolder="scheduler") | |
| vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16) | |
| adapter = T2IAdapter.from_pretrained("TencentARC/t2i-adapter-canny-sdxl-1.0", torch_dtype=torch.float16) | |
| pipeline = StableDiffusionXLAdapterPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| adapter=adapter, | |
| vae=vae, | |
| scheduler=scheduler, | |
| torch_dtype=torch.float16, | |
| variant="fp16", | |
| ) | |
| pipeline.to("cuda") | |
| ``` | |
| Finally, pass your prompt and control image to the pipeline. | |
| ```py | |
| generator = torch.Generator("cuda").manual_seed(0) | |
| image = pipeline( | |
| prompt="cinematic photo of a plush and soft midcentury style rug on a wooden floor, 35mm photograph, film, professional, 4k, highly detailed", | |
| image=image, | |
| generator=generator, | |
| ).images[0] | |
| image | |
| ``` | |
| <div class="flex justify-center"> | |
| <img class="rounded-xl" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/t2i-sdxl.png"/> | |
| </div> | |
| </hfoption> | |
| </hfoptions> | |
| ## MultiAdapter | |
| T2I-Adapters are also composable, allowing you to use more than one adapter to impose multiple control conditions on an | |
| image. For example, you can use a pose map to provide structural control and a depth map for depth control. This is | |
| enabled by the [`MultiAdapter`] class. | |
| Let's condition a text-to-image model with a pose and depth adapter. Create and place your depth and pose image and in a list. | |
| ```py | |
| from diffusers.utils import load_image | |
| pose_image = load_image( | |
| "https://huggingface.co/datasets/diffusers/docs-images/resolve/main/t2i-adapter/keypose_sample_input.png" | |
| ) | |
| depth_image = load_image( | |
| "https://huggingface.co/datasets/diffusers/docs-images/resolve/main/t2i-adapter/depth_sample_input.png" | |
| ) | |
| cond = [pose_image, depth_image] | |
| prompt = ["Santa Claus walking into an office room with a beautiful city view"] | |
| ``` | |
| <div class="flex gap-4"> | |
| <div> | |
| <img class="rounded-xl" src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/t2i-adapter/depth_sample_input.png"/> | |
| <figcaption class="mt-2 text-center text-sm text-gray-500">depth image</figcaption> | |
| </div> | |
| <div> | |
| <img class="rounded-xl" src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/t2i-adapter/keypose_sample_input.png"/> | |
| <figcaption class="mt-2 text-center text-sm text-gray-500">pose image</figcaption> | |
| </div> | |
| </div> | |
| Load the corresponding pose and depth adapters as a list in the [`MultiAdapter`] class. | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionAdapterPipeline, MultiAdapter, T2IAdapter | |
| adapters = MultiAdapter( | |
| [ | |
| T2IAdapter.from_pretrained("TencentARC/t2iadapter_keypose_sd14v1"), | |
| T2IAdapter.from_pretrained("TencentARC/t2iadapter_depth_sd14v1"), | |
| ] | |
| ) | |
| adapters = adapters.to(torch.float16) | |
| ``` | |
| Finally, load a [`StableDiffusionAdapterPipeline`] with the adapters, and pass your prompt and conditioned images to | |
| it. Use the [`adapter_conditioning_scale`] to adjust the weight of each adapter on the image. | |
| ```py | |
| pipeline = StableDiffusionAdapterPipeline.from_pretrained( | |
| "CompVis/stable-diffusion-v1-4", | |
| torch_dtype=torch.float16, | |
| adapter=adapters, | |
| ).to("cuda") | |
| image = pipeline(prompt, cond, adapter_conditioning_scale=[0.7, 0.7]).images[0] | |
| image | |
| ``` | |
| <div class="flex justify-center"> | |
| <img class="rounded-xl" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/t2i-multi.png"/> | |
| </div> |