# 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](../training/distributed_inference) để so sánh nó với các chiến lược khác, và [Đặt thiết bị](./memory#device-placement) để 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.

```py
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.

```py
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.

```py
from diffusers import AutoModel
import torch

transformer = AutoModel.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    subfolder="transformer",
    device_map="auto",
    dtype=torch.bfloat16
)
```

> [!TIP]
> 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ới `device_map` cũng có thuộc tính `hf_device_map` cho 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.

```py
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",
).images
```

## Giả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.

```py
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.

