Diffusers documentation
Phân chia các thành phần của mô hình trên các GPU bằng device_map
Phân chia các thành phần của mô hình trên các GPU bằng device_map
Tham số device_map đặt các thành phần của mô hình trên các GPU riêng biệt. Hãy sử dụng nó khi một mô hình không vừa trên một GPU và các GPU của bạn không có kết nối nhanh. Tham khảo Suy luận phân tán để so sánh nó với các chiến lược khác, và Đặt thiết bị để biết thêm các tùy chọn device_map.
Ví dụ dưới đây chỉ nạp mỗi thành phần cho giai đoạn cần đến nó, và sử dụng device_map để phân bổ các thành phần lớn sang hai GPU.
Mã hóa prompt
Đặt device_map="balanced" để đặt các text encoder trên các GPU riêng biệt. Sử dụng max_memory để giới hạn lượng bộ nhớ mà mỗi GPU sử dụng. Đặt transformer và vae thành None để chỉ tải các text encoder.
from diffusers import FluxPipeline
import torch
prompt = """
cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California
highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain
"""
pipeline = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
transformer=None,
vae=None,
device_map="balanced",
max_memory={0: "16GB", 1: "16GB"},
dtype=torch.bfloat16
)
with torch.no_grad():
print("Encoding prompts.")
prompt_embeds, pooled_prompt_embeds, text_ids = pipeline.encode_prompt(
prompt=prompt, prompt_2=None, max_sequence_length=512
)Sau khi có được các vector nhúng văn bản, hãy gỡ các bộ mã hóa văn bản khỏi GPU để nhường chỗ cho transformer.
import gc
def flush():
gc.collect()
torch.cuda.empty_cache()
torch.cuda.reset_max_memory_allocated()
torch.cuda.reset_peak_memory_stats()
del pipeline.text_encoder
del pipeline.text_encoder_2
del pipeline.tokenizer
del pipeline.tokenizer_2
del pipeline
flush()Loại bỏ nhiễu bằng transformer phân mảnh
Đặt device_map="auto" để Accelerate tự động bố trí transformer. Nó sẽ lấp đầy GPU đầu tiên trước khi chuyển sang GPU tiếp theo, và chỉ sử dụng CPU hoặc đĩa khi các GPU hết bộ nhớ. Trên hai GPU nhỏ hơn, transformer sẽ được chia đều trên cả hai. Trọng số nằm trên CPU hoặc đĩa sẽ làm chậm suy luận.
from diffusers import AutoModel
import torch
transformer = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
device_map="auto",
dtype=torch.bfloat16
)Kiểm tra
transformer.hf_device_mapđể xem transformer được phân phối trên các thiết bị như thế nào. Một pipeline được nạp vớidevice_mapcũng có thuộc tínhhf_device_mapcho biết mỗi thành phần được đặt ở đâu.
Tải một pipeline chỉ với transformer, và đặt output_type="latent" để nó trả về latents thay vì hình ảnh.
pipeline = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
text_encoder=None,
text_encoder_2=None,
tokenizer=None,
tokenizer_2=None,
vae=None,
transformer=transformer,
dtype=torch.bfloat16
)
print("Running denoising.")
height, width = 768, 1360
latents = pipeline(
prompt_embeds=prompt_embeds,
pooled_prompt_embeds=pooled_prompt_embeds,
num_inference_steps=50,
guidance_scale=3.5,
height=height,
width=width,
output_type="latent",
).imagesGiải mã các biến tiềm ẩn
Gỡ pipeline và transformer khỏi bộ nhớ và nạp VAE để giải mã các latents. VAE đủ nhỏ để chạy trên một GPU.
import torch
from diffusers import AutoencoderKL
from diffusers.image_processor import VaeImageProcessor
del pipeline.transformer
del pipeline
del transformer
flush()
vae = AutoencoderKL.from_pretrained(
"black-forest-labs/FLUX.1-dev", subfolder="vae", dtype=torch.bfloat16
).to("cuda") # or "mps", "xpu", "cpu"
vae_scale_factor = 2 ** (len(vae.config.block_out_channels) - 1)
image_processor = VaeImageProcessor(vae_scale_factor=vae_scale_factor)
with torch.no_grad():
print("Running decoding.")
latents = FluxPipeline._unpack_latents(latents, height, width, vae_scale_factor)
latents = (latents / vae.config.scaling_factor) + vae.config.shift_factor
image = vae.decode(latents, return_dict=False)[0]
image = image_processor.postprocess(image, output_type="pil")
image[0].save("split_transformer.png")Bằng cách tải và gỡ tải có chọn lọc các mô hình bạn cần ở một giai đoạn nhất định và chia nhỏ các mô hình lớn nhất trên nhiều GPU, bạn có thể chạy suy luận với các mô hình lớn trên GPU tiêu dùng.
Update on GitHub