Erste Schritte mit Hugging Face Diffusers
Richten Sie Hugging Face Diffusers mit SDXL ein, erzeugen Sie Bilder, passen Sie Einstellungen an, sparen Sie GPU-Speicher und stellen Sie einen FastAPI-Endpunkt für JavaScript bereit.
Hugging Face Diffusers ist eine Python-Bibliothek, mit der Sie Diffusionsmodelle für Bilder, Videos und Audio auf Ihrer eigenen Hardware ausführen. Sie bündelt Text-Encoder, Scheduler, Denoising-Netzwerk und VAE in einem einzigen Pipeline-Objekt, das Sie mit einem Prompt aufrufen.
Gehostete Bild-APIs sind ein bequemer Einstieg. Dann kommen die Rechnungen pro Bild, Rate Limits bremsen Ihren Prototyp aus, und Sie möchten verstehen, was das Modell eigentlich tut. Das Modell lokal auszuführen löst alle drei Probleme, doch die meisten Tutorials setzen PyTorch-Kenntnisse voraus.
Dieser Leitfaden richtet sich an JavaScript-Entwickler. Er führt Sie von der Installation bis zum ersten Bild, erklärt die wirklich relevanten Einstellungen, zeigt, wie das Modell auch auf kleineren GPUs läuft, und endet mit einem FastAPI-Endpunkt, den Ihr Frontend per fetch() aufruft. Die Beispiele beziehen sich auf Diffusers v0.42.1.
Das Wichtigste in Kürze
- Laden Sie
stabilityai/stable-diffusion-xl-base-1.0mitDiffusionPipeline.from_pretrained(..., dtype=torch.float16)und verschieben Sie es auf NVIDIA-GPUs nach"cuda"bzw. auf Apple Silicon nach"mps". - SDXL base 1.0 steht unter der CreativeML Open RAIL++-M License. Lesen Sie sie, bevor Sie generierte Bilder ausliefern.
- Ein mit einem Seed initialisierter
torch.Generatormacht Ergebnisse reproduzierbar, sodass Sie jeweils eine Einstellung ändern und deren Wirkung beobachten können. - Passt das Modell nicht in den GPU-Speicher, rufen Sie zuerst
enable_model_cpu_offload()auf. Die Diffusers-Dokumentation bezeichnet sequenzielles CPU-Offloading als extrem langsam. - Laden Sie die Pipeline einmal beim Serverstart und verwenden Sie sie für jede Anfrage wieder. Laden Sie sie niemals innerhalb eines Request-Handlers.
Was ist Hugging Face Diffusers?
Diffusers ist die Bibliothek von Hugging Face für Diffusionsmodelle. Ihre zentrale Abstraktion ist DiffusionPipeline, die alle Komponenten bündelt, die ein Modell benötigt:
- einen oder mehrere Text-Encoder, die den Prompt in Embeddings umwandeln
- einen Scheduler, der den Denoising-Algorithmus steuert
- ein UNet oder einen Diffusion Transformer, der in jedem Schritt das Rauschen vorhersagt
- ein VAE, das das Ergebnis in Pixel decodiert
Wenn Ihnen der Hub, Inference Providers oder Spaces noch neu sind, lesen Sie zunächst A Quick Guide to Hugging Face for Developers. Wenn Sie Inferenz ganz ohne Python-Backend möchten: Transformers.js führt Modelle direkt im Browser aus, deckt allerdings ein anderes Modellspektrum ab.
Welche Hardware benötigt Diffusers?
Diffusers läuft auf drei Arten von Systemen. Eine NVIDIA-GPU ist mit großem Abstand am schnellsten, ein Mac mit Apple Silicon funktioniert über das "mps"-Backend von PyTorch, und eine reine CPU funktioniert ebenfalls, ist aber sehr langsam.
| Hardware | Device-String | dtype | Was Sie erwarten können |
|---|---|---|---|
| NVIDIA-GPU | "cuda" | torch.float16 | Schnell |
| Mac mit Apple Silicon | "mps" | torch.float16 | Funktioniert, langsamer als eine dedizierte NVIDIA-GPU |
| Nur CPU | "cpu" | torch.float32 | Funktioniert, sehr langsam |
Der Quickstart nennt "cuda", "mps", "xpu" und "cpu" als Zielgeräte. Für Apple Silicon gibt es außerdem einen eigenen Leitfaden zu Apple Silicon (MPS). Dieses Hilfs-Snippet wählt das passende Gerät und den passenden dtype für das aktuelle System:
import torch
if torch.cuda.is_available():
device, dtype = "cuda", torch.float16
elif torch.backends.mps.is_available():
device, dtype = "mps", torch.float16
else:
device, dtype = "cpu", torch.float32
Diffusers installieren und ein erstes Bild generieren
Ein erstes Bild mit Hugging Face Diffusers erzeugen Sie in drei Schritten: Diffusers zusammen mit PyTorch installieren, SDXL laden und anschließend die Pipeline mit einem Prompt aufrufen und .images[0] speichern.
Seit v0.42.0 setzt Diffusers Python 3.11 oder neuer voraus und wird mit PyTorch 2.6 oder neuer getestet. Richten Sie gemäß der Installationsanleitung eine virtuelle Umgebung ein und installieren Sie dann die Pakete. Die Text-Encoder von SDXL sind CLIP-Modelle aus Transformers, daher installieren Sie diese Bibliothek ebenfalls:
uv pip install "diffusers[torch]>=0.42.1" transformers
# or: pip install "diffusers[torch]>=0.42.1" transformers
Generieren Sie nun mit device und dtype aus dem obigen Hilfs-Snippet ein Bild:
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=dtype,
).to(device)
prompt = "isometric pixel-art coffee shop at dusk, warm window light, rain on the street"
image = pipeline(prompt).images[0]
image.save("first.png")
image ist ein PIL-Bild, daher schreibt .save() eine PNG-Datei auf die Festplatte. Die Modell-ID ist der vollständige Hub-Name des Checkpoints einschließlich des Organisationspräfixes stabilityai/.
Lizenz: SDXL base 1.0 steht unter der CreativeML Open RAIL++-M License. Lesen Sie sie, bevor Sie generierte Bilder in einem Produkt verwenden, und prüfen Sie die Lizenz jedes anderen Modells, das Sie stattdessen einsetzen.
Welche SDXL-Einstellungen sind am wichtigsten?
Vier Argumente der SDXL-Pipeline bestimmen den Großteil dessen, was Sie im Ergebnis sehen: num_inference_steps, guidance_scale, generator sowie height / width. Legen Sie zuerst den Seed fest und ändern Sie dann jeweils nur ein Argument.
generator = torch.Generator().manual_seed(42)
image = pipeline(
prompt,
num_inference_steps=30,
guidance_scale=7.0,
height=1024,
width=1024,
generator=generator,
).images[0]
num_inference_stepslegt fest, wie viele Denoising-Durchläufe ausgeführt werden. Mehr Schritte dauern länger und liefern meist mehr Details, bis sich der Zugewinn abflacht.guidance_scalebestimmt, wie genau sich das Modell an den Prompt hält. Höhere Werte bleiben näher am Text, zu hohe Werte können jedoch übersteuert wirken.generatorfixiert das Ausgangsrauschen. Bei gleichem Modell, gleichen Einstellungen und gleicher Hardware liefert ein Generator mit festem Seed erneut dasselbe Bild.height/widthlegen die Ausgabegröße in Pixeln fest. Größere Bilder benötigen mehr Speicher und mehr Zeit.
Die Referenz zur SDXL-Pipeline führt alle Argumente samt Standardwerten auf.
Den Scheduler austauschen
Der Scheduler entscheidet, wie in jedem Schritt Rauschen entfernt wird, und verschiedene Scheduler wägen Geschwindigkeit und Qualität unterschiedlich ab. Ersetzen Sie ihn in einer geladenen Pipeline mit from_config() und übergeben Sie dabei die bestehende Konfiguration, damit die zum Checkpoint passenden Einstellungen erhalten bleiben:
from diffusers import DPMSolverMultistepScheduler
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)
generator = torch.Generator().manual_seed(42)
image = pipeline(prompt, num_inference_steps=20, generator=generator).images[0]
Der Schedulers-Leitfaden verwendet genau dieses Muster mit SDXL. Laut der Referenz zu DPMSolverMultistepScheduler erzeugt er in rund 20 Schritten hochwertige Ergebnisse. Behalten Sie beim Vergleich von Schedulern den Seed bei, damit sich zwischen den beiden Bildern ausschließlich der Scheduler unterscheidet.
Wie bringen Sie SDXL auf kleineren GPUs zum Laufen?
Wenn SDXL Out-of-Memory-Fehler auslöst, probieren Sie diese vier Speicheroptimierungen von Diffusers der Reihe nach aus: Model CPU Offload, VAE Tiling, VAE Slicing und 4-Bit-Quantisierung. Jeder Schritt spart mehr Speicher und kostet mehr Geschwindigkeit.
- Model CPU Offload. Verzichten Sie auf
.to(device)und rufen Siepipeline.enable_model_cpu_offload()auf. Jedes Modell liegt dann nur während seiner Ausführung vollständig auf der GPU. - VAE Tiling.
pipeline.vae.enable_tiling()decodiert große Bilder in Kacheln. Der Speicher-Leitfaden weist darauf hin, dass dies zu leichten Farbtonabweichungen zwischen den Kacheln führen kann. - VAE Slicing.
pipeline.vae.enable_slicing()decodiert einen Batch Bild für Bild. Das hilft nur, wenn Sie mehrere Bilder in einem einzigen Aufruf generieren. - 4-Bit-Quantisierung. Installieren Sie
bitsandbytesund ergänzen Sie eine kurze Konfiguration:
from diffusers.quantizers import PipelineQuantizationConfig
quant_config = PipelineQuantizationConfig(
quant_backend="bitsandbytes_4bit",
quant_kwargs={"load_in_4bit": True, "bnb_4bit_quant_type": "nf4", "bnb_4bit_compute_dtype": torch.float16},
components_to_quantize=["unet"],
)
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16,
quantization_config=quant_config,
)
pipeline.enable_model_cpu_offload()
Die Quantisierungsübersicht dokumentiert PipelineQuantizationConfig und die verfügbaren Backends. Mit v0.39.0 hat Diffusers bitsandbytes-Quantisierung auf MPS eingeführt, sodass dieser Ansatz nicht auf CUDA beschränkt ist. Auf Apple Silicon benötigt bitsandbytes PyTorch 2.9 oder neuer – also mehr als die oben genannte Mindestversion PyTorch 2.6.
Vermeiden Sie enable_sequential_cpu_offload(), sofern nicht alles andere scheitert. Diese Methode spart zwar am meisten Speicher, der Speicher-Leitfaden bezeichnet sie jedoch als extrem langsam. Beachten Sie außerdem: Eine mit device_map geladene Pipeline muss reset_device_map() aufrufen, bevor Sie .to() oder eine der Offload-Methoden verwenden.
Hugging Face Diffusers aus einer Web-App aufrufen
Um Diffusers aus einem Frontend heraus zu nutzen, kapseln Sie die Pipeline in einem kleinen HTTP-Server. Der Server sollte das Modell einmal beim Start laden und PNG-Bytes zurückgeben. Installieren Sie fastapi und uvicorn und speichern Sie Folgendes als main.py:
import io, threading
from contextlib import asynccontextmanager
import torch
from diffusers import DiffusionPipeline
from fastapi import FastAPI, Response
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
state = {}
lock = threading.Lock()
@asynccontextmanager
async def lifespan(app: FastAPI):
state["pipe"] = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16
).to("cuda") # or "mps"
yield
state.clear()
app = FastAPI(lifespan=lifespan)
app.add_middleware(CORSMiddleware, allow_origins=["http://localhost:5173"],
allow_methods=["POST"], allow_headers=["*"])
class GenerateRequest(BaseModel):
prompt: str
seed: int | None = None
@app.post("/generate")
def generate(req: GenerateRequest):
gen = torch.Generator().manual_seed(req.seed) if req.seed is not None else None
with lock:
image = state["pipe"](req.prompt, generator=gen).images[0]
buf = io.BytesIO()
image.save(buf, format="PNG")
return Response(content=buf.getvalue(), media_type="image/png")
Starten Sie den Server mit uvicorn main:app. Der Code basiert auf drei FastAPI-Features:
- Der Lifespan-Handler lädt das Modell einmalig, bevor der Server Anfragen annimmt.
from_pretrained()ist viel zu langsam, um es pro Anfrage aufzurufen. - Da
generateeine normaledef-Funktion ist, führt FastAPI sie in einem Threadpool aus, statt den Event Loop zu blockieren. - Der Lock sorgt dafür, dass Anfragen die GPU nacheinander nutzen.
CORSMiddleware erlaubt dem Origin Ihres Entwicklungs-Frontends, den Endpunkt aufzurufen.
Im Frontend fordern Sie das Bild per fetch() an, lesen den Body als Blob ein und zeigen ihn mit URL.createObjectURL() an:
async function generate(prompt, seed, img) {
const res = await fetch("http://localhost:8000/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt, seed }),
});
if (!res.ok) throw new Error(`Generation failed: ${res.status}`);
if (img.src.startsWith("blob:")) URL.revokeObjectURL(img.src);
img.src = URL.createObjectURL(await res.blob());
}
Die Generierung dauert Sekunden, nicht Millisekunden. Zeigen Sie einen Ladezustand an, deaktivieren Sie den Absenden-Button, solange eine Anfrage läuft, und übergeben Sie ein AbortController-Signal, falls Nutzer abbrechen können sollen. Bevor Sie die generierten PNGs an echte Besucher ausliefern, verkleinern Sie sie mit dem OpenReplay Image Compressor.
Nächste Schritte
Sobald die Pipeline auf dem richtigen Gerät geladen ist, kommt Diffusers mit sehr wenig Code aus: eine Modell-ID, ein dtype, ein Prompt und ein Seed. Generieren Sie ein erstes Bild mit SDXL, legen Sie den Seed fest und passen Sie jeweils eine Einstellung an. Wird der Speicher knapp, arbeiten Sie die Offload- und Quantisierungsschritte der Reihe nach ab. Binden Sie anschließend den FastAPI-Endpunkt an Ihr Frontend an. Von dort aus behandeln der Speicher-Leitfaden und der Schedulers-Leitfaden die Abwägungen, die beim Feintuning für den Produktivbetrieb auftreten.
FAQs
Wo speichert Diffusers heruntergeladene Modellgewichte?
from_pretrained() legt Modelldateien im Hugging-Face-Hub-Cache ab und verwendet sie bei späteren Ausführungen wieder, sodass sie nicht erneut heruntergeladen werden. Standardmäßig liegt der Cache unter ~/.cache/huggingface/hub. Setzen Sie die Umgebungsvariable HF_HUB_CACHE, um nur den Modell-Cache zu verschieben. Setzen Sie HF_HOME, um sämtliche Hugging-Face-Daten zu verschieben; der Cache liegt dann unter HF_HOME/hub. Alternativ können Sie das Argument cache_dir übergeben, um den Speicherort für einen einzelnen Ladevorgang festzulegen.
Warum liefert derselbe Seed auf einem anderen Rechner ein anderes Bild?
Ein Seed reproduziert ein Bild nur auf derselben Hardware mit derselben PyTorch-Version vollständig. CUDA-GPUs verwenden einen anderen Zufallszahlengenerator als CPUs, und Matrixmultiplikationen auf der GPU sind weniger deterministisch. Der Reproduzierbarkeits-Leitfaden von Diffusers empfiehlt, einen CPU-Generator zu übergeben, wenn die Ergebnisse übereinstimmen müssen – genau das erzeugt torch.Generator() standardmäßig. Identische Ergebnisse über verschiedene GPU-Modelle oder PyTorch-Versionen hinweg sind aber auch damit nicht garantiert.
Funktioniert die 4-Bit-Quantisierung mit bitsandbytes auf einem Mac mit Apple Silicon?
Ja, mit aktuellen Versionen. Diffusers hat mit v0.39.0 die bitsandbytes-Quantisierung auf MPS eingeführt, und mit bitsandbytes 0.50.0 funktionieren sämtliche 4-Bit- und LLM.int8()-Konfigurationen auf MPS. Der MPS-Pfad von bitsandbytes benötigt PyTorch 2.9 oder neuer – also mehr als die Mindestversion PyTorch 2.6 für Diffusers. Unter macOS 26 und neuer aktiviert die Installation des Pakets kernels schnellere Metal-Kernel.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k