Diffusers documentation

Google TPU

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Google TPU

Les Tensor Processing Units (TPUs) sont les accélérateurs d’apprentissage automatique de Google, disponibles sous forme de Cloud TPUs (v6e, v7x). Diffusers s’exécute dessus via TorchTPU, le backend PyTorch pour les TPUs, avec des modifications de code minimales.

Trois modes d'exécution sont disponibles :

ModeConstantComment activerNotes
Strict eager (par défaut)EagerMode.DEFER_NEVERpipe.to("tpu")Opérations expédiées une à la fois, asynchrones
Eager optimiséEagerMode.DEFER_AND_FUSETORCH_TPU_DEFER_AND_FUSE=1Opérations différées et fusionnées en graphes plus larges ; plus rapide que l'exécution stricte en mode eager, compilation plus longue
Compiler—torch.compile(module, backend="tpu")Compilation AOT avec TpuBackend

Suivez le guide d’installation de TorchTPU. Une fois installé, import torch le charge automatiquement et enregistre le périphérique "tpu", de sorte que pipe.to("tpu") est la seule modification nécessaire. Ajoutez import torch_tpu uniquement si vous avez désactivé le chargement automatique du backend avec TORCH_DEVICE_BACKEND_AUTOLOAD=0.

Mode Eager

FLUX.1-schnell ne tient pas entièrement sur une seule puce v6e, utilisez donc enable_model_cpu_offload() pour déplacer chaque modèle sur le TPU uniquement pendant son exécution. Il détecte automatiquement le périphérique "tpu".

import torch

from diffusers import FluxPipeline

pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-schnell", dtype=torch.bfloat16)
pipe.enable_model_cpu_offload()

image = pipe(
    prompt="a golden retriever surfing a wave, photorealistic",
    height=1024,
    width=1024,
    num_inference_steps=4,
    guidance_scale=0.0,
).images[0]

image.save("output.png")

Si un modèle est trop volumineux pour une puce unique, ou si vous disposez de plusieurs puces et souhaitez réduire la latence, répartissez les modèles sur plusieurs puces. Consultez la section Parallélisme de tenseurs.

Mode compilé

TorchTPU enregistre "tpu" comme nom de backend pour torch.compile (TpuBackend en interne), de sorte que les composants sont compilés comme tout autre objectif torch.compile. Le premier appel (phase de préchauffage) est lent car il effectue la compilation ; les appels ultérieurs avec les mêmes formes réutilisent le graphe compilé.

TorchTPU exige des formes statiques, il faut donc passer dynamic=False. Une nouvelle height ou width déclenche une nouvelle compilation pour cette forme, une seule fois ; les formes déjà vues sont réutilisées. Modifier num_inference_steps ne provoque pas de re-compilation.

Lorsque le pipeline complet tient sur une seule puce, déplacez-le sur le TPU et compilez le transformer complet. Stable Diffusion 3.5 Medium (~15GB en bf16) tient sur une seule puce v6e.

import torch

from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_pretrained("stabilityai/stable-diffusion-3.5-medium", dtype=torch.bfloat16)
pipe.to("tpu")
pipe.transformer.compile(backend="tpu", fullgraph=True, dynamic=False)

# Warmup — triggers static graph compilation.
pipe(prompt="warmup", height=1024, width=1024, num_inference_steps=40, guidance_scale=4.5)

# Later calls with the same shapes reuse the compiled graph.
image = pipe(
    prompt="a golden retriever surfing a wave, photorealistic",
    height=1024,
    width=1024,
    num_inference_steps=40,
    guidance_scale=4.5,
).images[0]

image.save("output.png")

Si le pipeline ne tient pas sur une seule puce :

  • Avec plusieurs puces, utilisez plutôt le parallélisme de tenseurs pour le sharding. Tout reste sur le TPU, et pipe.transformer.compile(...) fonctionne de la même manière sur le transformer sharded.
  • Avec enable_model_cpu_offload(), les hooks de déchargement ne peuvent pas être tracés par torch.compile. Compilez uniquement les blocs répétés du transformeur, avec pipe.transformer.compile_repeated_blocks(backend="tpu", fullgraph=True, dynamic=False).

Parallélisme de tenseurs

Répartissez les modèles trop volumineux pour une seule puce sur plusieurs. L’encodeur de texte (~48 Go) et le transformeur (~64 Go) de FLUX.2-dev dépassent chacun la capacité d’une puce unique, l’exemple ci-dessous répartit donc les deux :

Sur TPU, initialisez le groupe de processus avec backend="tpu_dist" et construisez le maillage avec DeviceMesh("tpu", ...).

import torch
import torch.distributed as dist
from torch.distributed.device_mesh import DeviceMesh
from transformers import DistributedConfig, Mistral3ForConditionalGeneration

from diffusers import Flux2Pipeline, Flux2Transformer2DModel, TensorParallelConfig

dist.init_process_group(backend="tpu_dist")
mesh = DeviceMesh("tpu", list(range(dist.get_world_size())))

repo_id = "black-forest-labs/FLUX.2-dev"
text_encoder = Mistral3ForConditionalGeneration.from_pretrained(
    repo_id,
    subfolder="text_encoder",
    dtype=torch.bfloat16,
    distributed_config=DistributedConfig(tp_plan="auto"),
    device_mesh=mesh,
)
transformer = Flux2Transformer2DModel.from_pretrained(
    repo_id, subfolder="transformer", dtype=torch.bfloat16, parallel_config=TensorParallelConfig(mesh=mesh)
)
pipe = Flux2Pipeline.from_pretrained(
    repo_id, text_encoder=text_encoder, transformer=transformer, dtype=torch.bfloat16
)
pipe.vae.to("tpu")

image = pipe(
    prompt="a golden retriever surfing a wave, photorealistic",
    num_inference_steps=28,
    generator=torch.Generator("cpu").manual_seed(0),
).images[0]
if dist.get_rank() == 0:
    image.save("output.png")

Lancez un processus par puce. Définissez --nproc_per_node pour utiliser le nombre total de puces TPU sur votre hôte.

eval $(python -m torch_tpu._internal.distributed.launchers.singlehost_wrapper | sed 's/^/export /')
torchrun --nproc_per_node=8 flux2_tp.py

La commande de lancement ci-dessus utilise un module interne de TorchTPU (torch_tpu._internal), et non une API stable, et est susceptible d'évoluer dans une future version de TorchTPU. Consultez le dépôt TorchTPU pour connaître la méthode actuelle de lancement des tâches multi-puces.

Update on GitHub