Diffusers documentation
Suy luận theo lô
Suy luận theo lô
Suy luận theo lô (batch inference) xử lý nhiều prompt cùng lúc để tăng thông lượng. Một lô dữ liệu giúp GPU hoạt động liên tục, trong khi một prompt đơn lẻ khiến GPU bị khai thác chưa hết công suất.
Nhược điểm là độ trễ cao hơn, vì bạn phải chờ toàn bộ lô (batch) hoàn thành. Các lô lớn cũng cần nhiều bộ nhớ GPU hơn.
Gom nhiều prompt thành một lô
Truyền một danh sách các prompt vào pipeline để tạo một hình ảnh cho mỗi 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"
)
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()
Tạo nhiều hình ảnh cho mỗi prompt
Để tạo nhiều biến thể của một prompt, hãy sử dụng đối số 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()
Tạo một vài hình ảnh cho một vài prompt
Kết hợp cả hai cách tiếp cận để tạo ra các biến thể khác nhau của các prompt khác nhau. Ví dụ này tái sử dụng pipeline và prompts từ các ví dụ ở trên.
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()
Tạo các lô dữ liệu có thể tái lập
Để một lô (batch) có thể tái lập được, hãy truyền cho pipeline một danh sách các đối tượng Generator, mỗi đối tượng tương ứng với một hình ảnh, mỗi đối tượng có một seed riêng.
Tham khảo tài liệu Reproducibility để tìm hiểu thêm về các thuật toán tất định và đối tượng
Generator.
Tạo một Generator cho mỗi hình ảnh bằng list comprehension. Nhân một list ([generator] * 3) sẽ cho bạn ba tham chiếu đến cùng một Generator, do đó các hình ảnh không nhận được các seed độc lập.
# don't do this
generator = [torch.Generator(device="cuda").manual_seed(0)] * 3 # or "mps", "xpu", "cpu"Số lượng generator phải khớp với số lượng ảnh trong batch. Truyền generator vào 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"
)
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()Mỗi hình ảnh được gắn với một seed, vì vậy bạn có thể chọn một hình ảnh mà bạn thích và tạo lại nó với cùng một seed trong khi bạn tinh chỉnh prompt của nó.
Xử lý các yêu cầu đồng thời
Máy chủ cũng tăng thông lượng bằng cách xử lý các yêu cầu từ nhiều người dùng cùng lúc. Nạp pipeline một lần và chia sẻ nó giữa các yêu cầu để các mô hình chỉ nằm trong bộ nhớ GPU một lần. Scheduler không an toàn cho đa luồng, vì vậy hãy cấp cho mỗi yêu cầu một scheduler riêng bằng from_pipe(). Chia sẻ một scheduler duy nhất giữa các luồng sẽ gây ra các lỗi như 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)
Đối với các máy chủ hoàn chỉnh được xây dựng bằng FastAPI, hãy xem ví dụ server và ví dụ server-async. Ví dụ server-async cũng sao chép trạng thái của bộ tạo số ngẫu nhiên cho mỗi yêu cầu và đảm bảo các tokenizer an toàn khi chia sẻ giữa các luồng.
Các bước tiếp theo
- Khi một batch không vừa trên một GPU, hoặc bạn có nhiều prompt hơn số lượng mà một GPU có thể xử lý, hãy phân tán các prompt trên nhiều GPU bằng Data parallelism.