Diffusers documentation

배치 추론

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

배치 추론

Batch inference는 여러 프롬프트를 한 번에 처리하여 처리량을 높입니다. 배치(batch)는 GPU를 지속적으로 활용하게 하지만, 단일 프롬프트만 처리하면 GPU가 충분히 활용되지 않습니다.

단점은 배치 전체가 완료될 때까지 기다려야 하므로 지연 시간이 길어질 수 있다는 점입니다. 또한 배치 크기가 크면 더 많은 GPU 메모리가 필요합니다.

여러 프롬프트를 배치

pipeline에 프롬프트 목록을 전달하여 각 프롬프트에 대해 이미지를 하나씩 생성합니다.

import torch
import matplotlib.pyplot as plt
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    device_map="cuda"  # or "mps", "xpu", "cpu"
)

prompts = [
    "Cinematic shot of a cozy coffee shop interior, warm pastel light streaming through a window where a cat rests. Shallow depth of field, glowing cups in soft focus, dreamy lofi-inspired mood, nostalgic tones, framed like a quiet film scene.",
    "Polaroid-style photograph of a cozy coffee shop interior, bathed in warm pastel light. A cat sits on the windowsill near steaming mugs. Soft, slightly faded tones and dreamy blur evoke nostalgia, a lofi mood, and the intimate, imperfect charm of instant film.",
    "Soft watercolor illustration of a cozy coffee shop interior, pastel washes of color filling the space. A cat rests peacefully on the windowsill as warm light glows through. Gentle brushstrokes create a dreamy, lofi-inspired atmosphere with whimsical textures and nostalgic calm.",
    "Isometric pixel-art illustration of a cozy coffee shop interior in detailed 8-bit style. Warm pastel light fills the space as a cat rests on the windowsill. Blocky furniture and tiny mugs add charm, low-res retro graphics enhance the nostalgic, lofi-inspired game aesthetic."
]

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()

프롬프트당 여러 이미지 생성

하나의 프롬프트에 대해 여러 가지 변형을 생성하려면 num_images_per_prompt 인수를 사용합니다.

import torch
import matplotlib.pyplot as plt
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    device_map="cuda"  # or "mps", "xpu", "cpu"
)

prompt="""
Isometric pixel-art illustration of a cozy coffee shop interior in detailed 8-bit style. Warm pastel light fills the
space as a cat rests on the windowsill. Blocky furniture and tiny mugs add charm, low-res retro graphics enhance the
nostalgic, lofi-inspired game aesthetic.
"""

images = pipeline(
    prompt=prompt,
    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()

여러 프롬프트에 대해 여러 이미지를 생성

두 가지 접근법을 결합하여 서로 다른 프롬프트의 다양한 변형을 생성합니다. 이 예제는 위의 예제에서 pipeline과 prompts를 재사용합니다.

images = pipeline(
    prompt=prompts,
    num_images_per_prompt=2,
).images

fig, axes = plt.subplots(2, 4, 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()

재현 가능한 배치 생성

배치를 재현 가능하게 하려면, 각 이미지에 해당하는 Generator 객체를 각각 고유한 시드로 설정하여 리스트로 파이프라인에 전달하세요.

결정적 알고리즘 및 Generator 객체에 대해 자세히 알아보려면 Reproducibility 문서를 참조하세요.

리스트 내포(list comprehension)를 사용하여 이미지마다 Generator 하나를 생성합니다. 리스트를 곱하면([generator] * 3) 동일한 Generator에 대한 세 개의 참조가 반환되므로, 이미지마다 독립적인 시드가 부여되지 않습니다.

# don't do this
generator = [torch.Generator(device="cuda").manual_seed(0)] * 3  # or "mps", "xpu", "cpu"

생성기의 수는 배치 내 이미지 수와 일치해야 합니다. generator를 파이프라인에 전달하세요.

import torch
import matplotlib.pyplot as plt
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    device_map="cuda"
)

prompts = [
    "Cinematic shot of a cozy coffee shop interior, warm pastel light streaming through a window where a cat rests. Shallow depth of field, glowing cups in soft focus, dreamy lofi-inspired mood, nostalgic tones, framed like a quiet film scene.",
    "Polaroid-style photograph of a cozy coffee shop interior, bathed in warm pastel light. A cat sits on the windowsill near steaming mugs. Soft, slightly faded tones and dreamy blur evoke nostalgia, a lofi mood, and the intimate, imperfect charm of instant film.",
    "Soft watercolor illustration of a cozy coffee shop interior, pastel washes of color filling the space. A cat rests peacefully on the windowsill as warm light glows through. Gentle brushstrokes create a dreamy, lofi-inspired atmosphere with whimsical textures and nostalgic calm.",
    "Isometric pixel-art illustration of a cozy coffee shop interior in detailed 8-bit style. Warm pastel light fills the space as a cat rests on the windowsill. Blocky furniture and tiny mugs add charm, low-res retro graphics enhance the nostalgic, lofi-inspired game aesthetic."
]
generator = [torch.Generator(device="cuda").manual_seed(i) for i in range(len(prompts))]  # or "mps", "xpu", "cpu"

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()

각 이미지는 시드(seed)와 연결되어 있으므로, 마음에 드는 이미지를 선택한 후 프롬프트를 다듬는 동안 동일한 시드로 이미지를 재생성할 수 있습니다.

동시 요청 처리

서버는 여러 사용자의 요청을 동시에 처리하여 처리량을 높입니다. 파이프라인을 한 번만 로드하고 요청 간에 공유하면 모델이 GPU 메모리에 한 번만 유지됩니다. 스케줄러는 스레드 안전하지 않으므로, 각 요청에 대해 from_pipe()을 사용하여 개별 스케줄러를 제공해야 합니다. 여러 스레드에서 하나의 스케줄러를 공유하면 IndexError: index 21 is out of bounds for dimension 0 with size 21과 같은 오류가 발생합니다.

scheduler = shared_pipeline.scheduler.from_config(shared_pipeline.scheduler.config)
pipeline = StableDiffusion3Pipeline.from_pipe(shared_pipeline, scheduler=scheduler)

FastAPI로 구축된 완전한 서버에 대해서는 server 예제와 server-async 예제를 참고하세요. server-async 예제는 각 요청마다 난수 생성기 상태를 복제하고, 토크나이저가 스레드 간에 안전하게 공유되도록 합니다.

다음 단계

  • 배치가 하나의 GPU에 맞지 않거나, 하나의 GPU가 처리할 수 있는 것보다 프롬프트가 더 많다면, 데이터 병렬성을 사용하여 프롬프트를 여러 GPU에 분산하세요.
Update on GitHub