Diffusers documentation
배치 추론
배치 추론
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에 분산하세요.