| <!--Copyright 2025 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. | |
| --> | |
| # Batch inference | |
| Batch inference processes multiple prompts at a time to increase throughput. It is more efficient because processing multiple prompts at once maximizes GPU usage versus processing a single prompt and underutilizing the GPU. | |
| The downside is increased latency because you must wait for the entire batch to complete, and more GPU memory is required for large batches. | |
| <hfoptions id="usage"> | |
| <hfoption id="text-to-image"> | |
| For text-to-image, pass a list of prompts to the pipeline. | |
| ```py | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| torch_dtype=torch.float16 | |
| ).to("cuda") | |
| prompts = [ | |
| "cinematic photo of A beautiful sunset over mountains, 35mm photograph, film, professional, 4k, highly detailed", | |
| "cinematic film still of a cat basking in the sun on a roof in Turkey, highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain", | |
| "pixel-art a cozy coffee shop interior, low-res, blocky, pixel art style, 8-bit graphics" | |
| ] | |
| images = pipeline( | |
| prompt=prompts, | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| To generate multiple variations of one prompt, use the `num_images_per_prompt` argument. | |
| ```py | |
| import torch | |
| import matplotlib.pyplot as plt | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| torch_dtype=torch.float16 | |
| ).to("cuda") | |
| images = pipeline( | |
| prompt="pixel-art a cozy coffee shop interior, low-res, blocky, pixel art style, 8-bit graphics", | |
| num_images_per_prompt=4 | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| Combine both approaches to generate different variations of different prompts. | |
| ```py | |
| images = pipeline( | |
| prompt=prompts, | |
| num_images_per_prompt=2, | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| </hfoption> | |
| <hfoption id="image-to-image"> | |
| For image-to-image, pass a list of input images and prompts to the pipeline. | |
| ```py | |
| import torch | |
| from diffusers.utils import load_image | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| torch_dtype=torch.float16 | |
| ).to("cuda") | |
| input_images = [ | |
| load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png"), | |
| load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png"), | |
| load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/detail-prompt.png") | |
| ] | |
| prompts = [ | |
| "cinematic photo of a beautiful sunset over mountains, 35mm photograph, film, professional, 4k, highly detailed", | |
| "cinematic film still of a cat basking in the sun on a roof in Turkey, highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain", | |
| "pixel-art a cozy coffee shop interior, low-res, blocky, pixel art style, 8-bit graphics" | |
| ] | |
| images = pipeline( | |
| prompt=prompts, | |
| image=input_images, | |
| guidance_scale=8.0, | |
| strength=0.5 | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| To generate multiple variations of one prompt, use the `num_images_per_prompt` argument. | |
| ```py | |
| import torch | |
| import matplotlib.pyplot as plt | |
| from diffusers.utils import load_image | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| torch_dtype=torch.float16 | |
| ).to("cuda") | |
| input_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/detail-prompt.png") | |
| images = pipeline( | |
| prompt="pixel-art a cozy coffee shop interior, low-res, blocky, pixel art style, 8-bit graphics", | |
| image=input_image, | |
| num_images_per_prompt=4 | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| Combine both approaches to generate different variations of different prompts. | |
| ```py | |
| input_images = [ | |
| load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png"), | |
| load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/detail-prompt.png") | |
| ] | |
| prompts = [ | |
| "cinematic film still of a cat basking in the sun on a roof in Turkey, highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain", | |
| "pixel-art a cozy coffee shop interior, low-res, blocky, pixel art style, 8-bit graphics" | |
| ] | |
| images = pipeline( | |
| prompt=prompts, | |
| image=input_images, | |
| num_images_per_prompt=2, | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| </hfoption> | |
| </hfoptions> | |
| ## Deterministic generation | |
| Enable reproducible batch generation by passing a list of [Generator’s](https://pytorch.org/docs/stable/generated/torch.Generator.html) to the pipeline and tie each `Generator` to a seed to reuse it. | |
| Use a list comprehension to iterate over the batch size specified in `range()` to create a unique `Generator` object for each image in the batch. | |
| Don't multiply the `Generator` by the batch size because that only creates one `Generator` object that is used sequentially for each image in the batch. | |
| ```py | |
| generator = [torch.Generator(device="cuda").manual_seed(0)] * 3 | |
| ``` | |
| Pass the `generator` to the pipeline. | |
| ```py | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| torch_dtype=torch.float16 | |
| ).to("cuda") | |
| generator = [torch.Generator(device="cuda").manual_seed(i) for i in range(3)] | |
| prompts = [ | |
| "cinematic photo of A beautiful sunset over mountains, 35mm photograph, film, professional, 4k, highly detailed", | |
| "cinematic film still of a cat basking in the sun on a roof in Turkey, highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain", | |
| "pixel-art a cozy coffee shop interior, low-res, blocky, pixel art style, 8-bit graphics" | |
| ] | |
| images = pipeline( | |
| prompt=prompts, | |
| generator=generator | |
| ).images | |
| fig, axes = plt.subplots(2, 2, figsize=(12, 12)) | |
| axes = axes.flatten() | |
| for i, image in enumerate(images): | |
| axes[i].imshow(image) | |
| axes[i].set_title(f"Image {i+1}") | |
| axes[i].axis('off') | |
| plt.tight_layout() | |
| plt.show() | |
| ``` | |
| You can use this to iteratively select an image associated with a seed and then improve on it by crafting a more detailed prompt. |