- Diffusionsmodelle (Diffusion Models) haben 2021 erstmals GANs bei der FID-Metrik umfassend uebertroffen[7] und wurden zum neuen Standard der Bildgenerierung -- die Open-Source-Veroeffentlichung von Stable Diffusion loeste eine industrielle Revolution der generativen KI aus[8]
- Das Kernprinzip ist aeusserst elegant: Der Vorwaertsprozess fuegt schrittweise Rauschen hinzu und verwandelt ein Bild in reines Rauschen, der Umkehrprozess lernt das Entrauschen -- das Trainingsziel ist lediglich die Vorhersage des Rauschens, dennoch entstehen hochwertige Bilder[1]
- Das Diffusionsframework beschraenkt sich nicht auf Bilder -- diskrete Diffusionsmodelle (D3PM)[14] und Diffusion-LM[15] haben dieses Paradigma auf die Textgenerierung ausgeweitet und ermoeglichen kontrollierbare Sprachgenerierung
- Dieser Artikel enthaelt zwei Google Colab Implementierungen: Diskrete Diffusion x BERT Textgenerierung (CPU) und Stable Diffusion x Text-zu-Bild-Generierung mit Visualisierung des Entrauschungsprozesses (GPU)
1. Warum Diffusionsmodelle die Spielregeln der generativen KI veraendert haben
Vor 2020 war der unbestrittene Koenig der Bildgenerierung das GAN (Generative Adversarial Networks). GANs konnten erstaunlich realistische Bilder erzeugen, hatten jedoch drei schwerwiegende Maengel: aeusserst instabiles Training (Mode Collapse), mangelnde Diversitaet (das Modell lernt oft nur wenige Muster) und die Unmoeglichkeit, eine exakte Log-Likelihood zu berechnen.
2020 veroeffentlichten Ho et al. auf der NeurIPS DDPM (Denoising Diffusion Probabilistic Models)[1], das das von Sohl-Dickstein et al. 2015 vorgeschlagene, von der Nichtgleichgewichtsthermodynamik inspirierte Framework[2] zu einem eleganten und effektiven Trainingsverfahren umgestaltete. Das Ergebnis ueberraschte die gesamte Forschungsgemeinschaft: Diffusionsmodelle erreichten in der Bildqualitaet nahezu GAN-Niveau und boten gleichzeitig einen stabilen Trainingsprozess sowie ein vollstaendiges Log-Likelihood-Framework.
Ein Jahr spaeter bewiesen Dhariwal und Nichol[7] experimentell, dass Diffusionsmodelle GANs bei der FID-Metrik umfassend uebertreffen -- auf ImageNet 256x256 erreichten sie einen FID von 3,94, waehrend das damals beste BigGAN-deep bei 6,95 lag. Der Titel dieser Arbeit verkuendete direkt den Epochenwechsel: "Diffusion Models Beat GANs on Image Synthesis".
Danach explodierte die Entwicklung von Diffusionsmodellen: 2022 veroeffentlichte Stability AI Stable Diffusion[8] als Open Source, sodass jeder auf Consumer-GPUs hochwertige Bilder generieren konnte; OpenAI brachte DALL·E 2[10] heraus, Google veroeffentlichte Imagen[11]; 2023 trieb SDXL[12] Aufloesung und aesthetische Qualitaet auf neue Hoehen; und DiT[13] (Diffusion Transformer) wies den Weg der architektonischen Evolution, U-Net durch Transformer zu ersetzen, und brachte eine neue Generation von Modellen wie Sora und FLUX hervor.
Doch der Einfluss von Diffusionsmodellen geht weit ueber Bilder hinaus. Diskrete Diffusionsmodelle[14] haben dieses Framework in die Bereiche Textgenerierung, Proteindesign, Molekuelgenerierung und andere diskrete Datenbereiche gebracht. Die Prinzipien der Diffusionsmodelle zu verstehen, bedeutet den Schluessel zur gesamten Welt der generativen KI in der Hand zu halten.
2. Mathematische Intuition: Vorwaerts-Verrauschung und Rueckwaerts-Entrauschung
Die Kernidee von Diffusionsmodellen laesst sich in einem Satz zusammenfassen: Zu lernen, wie man Daten aus Rauschen wiederherstellt, ist gleichbedeutend damit, zu lernen, wie man Daten generiert.
2.1 Vorwaertsprozess (Forward Process)
Gegeben ein reales Bild x_0, fuegt der Vorwaertsprozess in T Zeitschritten schrittweise gausssches Rauschen hinzu:
q(x_t | x_{t-1}) = N(x_t; sqrt(1-beta_t) * x_{t-1}, beta_t I)
Dabei ist beta_t der Rauschplan (Noise Schedule), der typischerweise von einem sehr kleinen Wert (z.B. beta_1 = 0,0001) linear oder kosinusfoermig auf einen groesseren Wert (z.B. beta_T = 0,02) anwaechst. Wenn T gross genug ist (ueblicherweise T = 1000), ist das endgueltige x_T nahezu reines gausssches Rauschen.
Ein Schluesseltrick von DDPM ist: Es ist nicht noetig, schrittweise Rauschen hinzuzufuegen -- man kann direkt von x_0 zu einer verrauschten Version bei beliebigem Zeitschritt t springen:
q(x_t | x_0) = N(x_t; sqrt(alpha_bar_t) * x_0, (1-alpha_bar_t)I)
Dabei ist alpha_bar_t = Produkt_{i=1}^{t} (1-beta_i). Dies ermoeglicht waehrend des Trainings die zufaellige Auswahl beliebiger Zeitschritte und steigert die Effizienz erheblich.
2.2 Umkehrprozess (Reverse Process)
Der Umkehrprozess versucht, die Verrauschung rueckgaengig zu machen -- von x_T (reines Rauschen) schrittweise zurueck zu x_0 (klares Bild). Dieser Prozess wird durch ein neuronales Netz epsilon_theta parametrisiert:
p_theta(x_{t-1} | x_t) = N(x_{t-1}; mu_theta(x_t, t), sigma_t^2 I)
Der Mittelwert mu_theta wird dabei aus dem vom Modell vorhergesagten Rauschen epsilon_theta(x_t, t) berechnet.
2.3 Trainingsziel: Rauschvorhersage
Der Schluesselcbeitrag von Ho et al.[1] war der Beweis, dass ein erstaunlich einfaches Trainingsziel ausreicht:
L_simple = E[||epsilon - epsilon_theta(x_t, t)||^2]
In einfachen Worten: Ein zufaelliges Bild waehlen, ein zufaelliges Mass an Rauschen hinzufuegen und das Modell vorhersagen lassen, wie viel Rauschen hinzugefuegt wurde -- das ist alles. Diese vereinfachte Version laesst die Gewichtungsterme aus der ELBO-Herleitung weg, liefert in der Praxis jedoch sogar bessere Generierungsqualitaet.
Song et al.[4] vereinheitlichten spaeter auf der ICLR 2021 DDPM und Score-Based Modelle[3] in einem SDE-Framework (Stochastische Differentialgleichungen) und bewiesen, dass beide lediglich unterschiedliche Diskretisierungen desselben kontinuierlichen Prozesses darstellen. Diese einheitliche Perspektive legte die theoretische Grundlage fuer nachfolgende Methoden zur Beschleunigung der Abtastung.
3. Meilensteine der Entwicklung: Von DDPM ueber Stable Diffusion zu DiT
| Jahr | Meilenstein | Kernbeitrag | Auswirkung |
|---|---|---|---|
| 2015 | Sohl-Dickstein et al.[2] | Von Nichtgleichgewichtsthermodynamik inspiriertes Diffusionsframework | Theoretische Grundlage |
| 2019 | Score Matching[3] | Score-Based Generative Modelle | Alternative theoretische Perspektive |
| 2020 | DDPM[1] | Einfaches Rauschvorhersage-Trainingsziel | Der "GPT-Moment" der Diffusionsmodelle |
| 2021 | DDIM[5] | Nicht-markovsche Abtastung, 1000 Schritte -> 50 Schritte | Erste praxistaugliche Beschleunigung |
| 2021 | Improved DDPM[6] | Kosinus-Rauschplan, lernbare Varianz | Verbesserung von Qualitaet und Log-Likelihood |
| 2021 | Diffusion Beats GANs[7] | Classifier Guidance + Architekturoptimierung | FID erstmals besser als GAN |
| 2021 | Score SDE[4] | Vereinheitlichung von DDPM und Score-Based Modellen | Theoretische Rahmenvereinheitlichung |
| 2022 | LDM / Stable Diffusion[8] | Diffusion im Latent Space, Effizienzsteigerung um Dutzende Male | Open Source loest industrielle Revolution aus |
| 2022 | DALL·E 2[10] | CLIP-Steuerung + kaskadierende Diffusion | Kommerzialisierung von Text-zu-Bild |
| 2022 | Imagen[11] | T5-XXL Textencoder + kaskadierende Super-Resolution | Nachweis der Bedeutung des Sprachverstaendnisses |
| 2022 | CFG[17] | Klassifikatorfreie Steuerung, Vereinheitlichung bedingter/unbedingter Generierung | Standardmethode fuer bedingte Generierung |
| 2023 | SDXL[12] | Groesseres U-Net + dualer Textencoder | Sprung in aesthetischer Qualitaet |
| 2023 | DiT[13] | Transformer ersetzt U-Net | Beginn der Sora / FLUX Aera |
| 2023 | LCM[16] | Konsistenzdestillation, Generierung in 2-4 Schritten | Durchbruch bei der Inferenzeffizienz |
4. Kernarchitektur bildbasierter Diffusionsmodelle
4.1 U-Net: Vom Pixelraum zum Latent Space
Die urspruengliche Architektur von DDPM operiert direkt im Pixelraum -- bei einem 256x256-Bild muss jeder Entrauschungsschritt 256x256x3 = 196.608 Dimensionen verarbeiten. Dies macht sowohl Training als auch Inferenz aeusserst kostspielig.
Rombach et al.[8] loesten dieses Problem mit dem Latent Diffusion Model (LDM): Zunaechst wird das Bild mit einem vortrainierten VAE in einen niedrigdimensionalen Latent Space komprimiert, dann wird die Diffusion im Latent Space durchgefuehrt. Ein 512x512-Bild wird zu einer 64x64x4-Latent-Darstellung komprimiert -- eine Dimensionsreduktion um den Faktor 48. Das Diffusionsmodell muss nur in diesem komprimierten Raum entrauschen, wodurch Rechenaufwand und Speicherbedarf drastisch sinken.
Stable Diffusion ist die Open-Source-Implementierung von LDM und besteht aus drei Kernkomponenten:
- VAE-Encoder/Decoder: Komprimiert Bilder in den Latent Space / rekonstruiert Bilder aus dem Latent Space
- U-Net: Fuehrt die Entrauschung im Latent Space durch, einschliesslich Residualbloecken, Self-Attention-Schichten und Cross-Attention-Schichten
- Textencoder (CLIP / T5): Wandelt Textprompts in Konditionierungsvektoren um und injiziert sie ueber Cross-Attention in das U-Net
4.2 Classifier-Free Guidance: Steuerung der Generierungsqualitaet
Die von Ho und Salimans[17] vorgeschlagene Classifier-Free Guidance (CFG) ist die Standardmethode fuer bedingte Generierung mit Diffusionsmodellen. Die Kernidee: Gleichzeitiges Training von bedingter und unbedingter Generierung (zufaelliges Weglassen der Textbedingung), wobei bei der Inferenz die Differenz beider genutzt wird, um den Einfluss der Textbedingung zu "verstaerken":
epsilon_tilde = epsilon_unconditional + w * (epsilon_conditional - epsilon_unconditional)
Die Steuerungsskala w (Guidance Scale) kontrolliert die Staerke des Texteinflusses auf das Bild: w = 1 entspricht keiner Steuerung, w = 7-12 ist der gaengige Bereich, je groesser w, desto staerker entspricht das Bild der Textbeschreibung, aber die Diversitaet nimmt ab.
4.3 DiT: Transformer uebernehmen Diffusionsmodelle
DiT (Diffusion Transformer) von Peebles und Xie[13] ersetzt das U-Net durch einen Standard Vision Transformer als Entrauschungsnetzwerk. Sie serialisieren die Patches des Latent Space, verarbeiten sie mit einem Transformer und injizieren Zeitschritt- und Konditionierungsinformationen ueber adaLN-Zero (Adaptive Layer Normalization).
Die Bedeutung von DiT liegt darin, dass das Scaling Law von Transformern klarer ist als das von U-Net -- groessere Modelle, laengeres Training, bessere Qualitaet. Diese Erkenntnis fuehrte direkt zu OpenAIs Sora (Videogenerierung) und Black Forest Labs' FLUX sowie anderen Diffusionsmodellen der naechsten Generation im grossen Massstab.
5. Der Schnittpunkt von Text und Diffusion: Von CLIP-Steuerung zu diskreter Textdiffusion
Die Beziehung zwischen Diffusionsmodellen und Text-KI hat zwei Dimensionen: erstens Text als Bedingung zur Steuerung der Bildgenerierung; zweitens die direkte Anwendung der Diffusion auf Text selbst.
5.1 Textbedingung: Wie CLIP Diffusionsmodelle zum "Verstehen" von Sprache befaehigt
Stable Diffusion verwendet CLIP[9] (Contrastive Language-Image Pretraining) als Textencoder. CLIP wurde auf 400 Millionen Text-Bild-Paaren mittels kontrastivem Lernen trainiert und hat gelernt, Text und Bilder in einen gemeinsamen Repraesentationsraum abzubilden -- semantisch aehnliche Texte und Bilder liegen in diesem Raum nahe beieinander.
In Stable Diffusion wandelt der Textencoder von CLIP den Prompt in eine Reihe von Token-Vektoren um, die ueber die Cross-Attention-Schichten des U-Net in den Entrauschungsprozess injiziert werden. Jede Attention-Schicht des U-Net "befragt" die Textbedingung: "Was sollte an dieser Stelle gezeichnet werden?" -- die Textvektoren liefern die Antwort.
Googles Imagen[11] waaehlte einen anderen Ansatz: die Verwendung eines eingefrorenen T5-XXL (eines reinen Text-Sprachmodells) als Textencoder. Die Ergebnisse von Imagen lieferten eine wichtige Erkenntnis: Die Sprachverstaendnisfaehigkeit des Textencoders ist wichtiger als die Groesse des Diffusionsmodells selbst. Ein groesserer und leistungsfaehigerer Textencoder bringt weitaus mehr Qualitaetsverbesserung als die Vergroesserung des U-Net.
5.2 Diskrete Diffusion: Das Diffusionsparadigma in die Textgenerierung bringen
Standard-Diffusionsmodelle arbeiten im kontinuierlichen Raum (Pixelwerte sind kontinuierlich), doch Text ist diskret (bestehend aus Token-IDs). Austin et al.[14] haben mit D3PM (Discrete Denoising Diffusion Probabilistic Models) das Diffusionsframework auf diskrete Zustandsraeume verallgemeinert.
Der Vorwaertsprozess von D3PM fuegt kein gausssches Rauschen hinzu, sondern "korrumpiert" schrittweise die Token -- Token werden zufaellig durch [MASK] oder andere Token ersetzt. Die intuitivste Variante ist die absorbierende Zustandsdiffusion (Absorbing State Diffusion): In jedem Zeitschritt wird ein Token mit einer bestimmten Wahrscheinlichkeit zu [MASK], bis schliesslich alle Token maskiert sind. Der Umkehrprozess startet von einer vollstaendig maskierten Sequenz und stellt schrittweise die korrekten Token wieder her.
Li et al.[15] gingen mit Diffusion-LM einen anderen Weg: Diffusion im kontinuierlichen Token-Embedding-Raum, gefolgt von einem Rounding-Schritt, der die kontinuierlichen Vektoren zurueck auf diskrete Token abbildet. Der einzigartige Vorteil von Diffusion-LM ist die Kontrollierbarkeit -- durch Gradientensteuerung kann der generierte Text bestimmte Einschraenkungen erfuellen (wie syntaktische Strukturen, semantische Eigenschaften), was fuer autoregressive Sprachmodelle schwer zu erreichen ist.
Bemerkenswert ist, dass BERTs Masked Language Modeling im Wesentlichen ein Einschritt-Entrauscher fuer diskrete Diffusion ist -- gegeben eine teilweise maskierte Sequenz, werden die Token an den maskierten Positionen vorhergesagt. Wenn man BERT in ein iteratives Diffusionsabtastframework einbettet, erhaelt man ein praktisches diskretes Textdiffusionssystem.
6. Hands-on Lab 1: Diskrete Diffusion x BERT Textgenerierung (Google Colab)
Dieses Lab zeigt, wie BERT als Entrauscher verwendet wird, um diskrete Diffusions-Textgenerierung zu implementieren -- von einer vollstaendig maskierten Sequenz ausgehend, wird schrittweise kohaerenter Text "entrauscht". Dies ist eine vereinfachte Implementierung der absorbierenden Zustandsdiffusion von D3PM[14].
Google Colab oeffnen (CPU genuegt), ein neues Notebook erstellen und folgenden Code der Reihe nach einfuegen:
6.1 Umgebungsinstallation
# ★ Erforderliche Pakete installieren ★
!pip install transformers torch -q
6.2 BERT laden und diskrete Diffusion verstehen
import torch
import torch.nn.functional as F
from transformers import BertTokenizer, BertForMaskedLM
import numpy as np
# ★ Vortrainiertes BERT laden (Masked Language Model = Einschritt-Entrauscher fuer diskrete Diffusion) ★
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForMaskedLM.from_pretrained('bert-base-uncased').eval()
MASK_ID = tokenizer.mask_token_id
CLS_ID = tokenizer.cls_token_id
SEP_ID = tokenizer.sep_token_id
print(f"BERT vocab size: {tokenizer.vocab_size}")
print(f"[MASK] token ID: {MASK_ID}")
print(f"Model parameters: {sum(p.numel() for p in model.parameters())/1e6:.0f}M")
6.3 Vorwaertsprozess: Schrittweise Textkorrumpierung
# ★ Vorwaerts-Diffusionsprozess: Schrittweiser Ersatz von Token durch [MASK] ★
def forward_diffusion(text, num_steps=10):
"""
Simulation des Vorwaertsprozesses der absorbierenden diskreten Diffusion.
In jedem Schritt werden Token mit steigender Wahrscheinlichkeit durch [MASK] ersetzt.
"""
tokens = tokenizer.encode(text, return_tensors='pt')[0] # [seq_len]
seq_len = len(tokens) - 2 # Ohne [CLS] und [SEP]
content_tokens = tokens[1:-1].clone()
print(f"Originaltext: {text}")
print(f"Tokenanzahl: {seq_len}")
print("-" * 60)
for step in range(num_steps + 1):
mask_prob = step / num_steps
mask = torch.rand(seq_len) < mask_prob
noisy = content_tokens.clone()
noisy[mask] = MASK_ID
decoded = tokenizer.decode(noisy)
n_masked = mask.sum().item()
print(f"t={step:2d} (mask {mask_prob:.0%}, {n_masked:2d}/{seq_len} masked): {decoded}")
return tokens
# ★ Vorwaertsprozess demonstrieren ★
print("【Vorwaerts-Diffusionsprozess: Text -> Rauschen】")
print("=" * 60)
forward_diffusion("The quick brown fox jumps over the lazy dog", num_steps=8)
6.4 Umkehrprozess: Text aus Rauschen generieren
# ★ Rueckwaerts-Diffusionsabtastung: Schrittweises Entrauschen von vollstaendigem [MASK] zu Text ★
@torch.no_grad()
def reverse_diffusion_step(token_ids, temperature=1.0):
"""
Ein Schritt der Rueckwaertsdiffusion: BERT sagt alle [MASK]-Positionen vorher,
die Position mit der hoechsten Konfidenz wird demaskiert.
"""
outputs = model(token_ids.unsqueeze(0))
logits = outputs.logits[0] # [seq_len, vocab_size]
# Alle [MASK]-Positionen finden
mask_positions = (token_ids == MASK_ID).nonzero(as_tuple=True)[0]
if len(mask_positions) == 0:
return token_ids, 0
# Vorhersagekonfidenz fuer jede [MASK]-Position berechnen
probs = F.softmax(logits[mask_positions] / temperature, dim=-1)
max_probs, predictions = probs.max(dim=-1)
return token_ids, mask_positions, max_probs, predictions
def generate_text(seq_length=12, num_steps=15, temperature=1.0, top_k=0):
"""
Vollstaendige diskrete Diffusionsabtastung: Schrittweises Entrauschen einer vollstaendig maskierten Sequenz.
In jedem Schritt werden die Positionen mit der hoechsten Konfidenz demaskiert.
"""
# Anfangszustand: [CLS] + vollstaendig [MASK] + [SEP]
ids = torch.full((seq_length + 2,), MASK_ID, dtype=torch.long)
ids[0] = CLS_ID
ids[-1] = SEP_ID
print(f"\n【Rueckwaerts-Diffusionsprozess: Rauschen -> Text】(length={seq_length}, steps={num_steps})")
print("=" * 60)
for step in range(num_steps):
# Vorhersage fuer jede [MASK]-Position
with torch.no_grad():
logits = model(ids.unsqueeze(0)).logits[0]
mask_positions = (ids == MASK_ID).nonzero(as_tuple=True)[0]
# [CLS] und [SEP] ausschliessen
mask_positions = mask_positions[(mask_positions > 0) & (mask_positions < len(ids)-1)]
if len(mask_positions) == 0:
break
# Jede Maskenposition vorhersagen
probs = F.softmax(logits[mask_positions] / temperature, dim=-1)
if top_k > 0:
# Top-k Abtastung
topk_probs, topk_indices = probs.topk(top_k, dim=-1)
topk_probs = topk_probs / topk_probs.sum(dim=-1, keepdim=True)
sampled = torch.multinomial(topk_probs, 1).squeeze(-1)
predictions = topk_indices.gather(1, sampled.unsqueeze(-1)).squeeze(-1)
confidence = topk_probs.gather(1, sampled.unsqueeze(-1)).squeeze(-1)
else:
# Greedy-Auswahl (maximale Wahrscheinlichkeit)
confidence, predictions = probs.max(dim=-1)
# Anzahl der Demaskierungen pro Schritt: linear abnehmend
total_masks = len(mask_positions)
n_unmask = max(1, int(total_masks * (1.0 / (num_steps - step))))
# Positionen mit hoechster Konfidenz demaskieren
_, top_indices = confidence.topk(min(n_unmask, len(mask_positions)))
chosen_positions = mask_positions[top_indices]
chosen_tokens = predictions[top_indices]
ids[chosen_positions] = chosen_tokens
# Aktuellen Zustand anzeigen
text = tokenizer.decode(ids[1:-1])
remaining = (ids == MASK_ID).sum().item()
print(f"Step {step+1:2d} ({remaining:2d} masks left): {text}")
final_text = tokenizer.decode(ids[1:-1])
print(f"\n✓ Final: {final_text}")
return final_text
# ★ Greedy-Generierung (deterministisch) ★
generate_text(seq_length=10, num_steps=12, temperature=1.0)
6.5 Top-k Abtastung und Temperatursteuerung
# ★ Top-k Abtastung (erhoehte Diversitaet) ★
print("\n" + "=" * 60)
print("Top-k Abtastung (k=5, temperature=1.2) — Mehrfachgenerierung mit unterschiedlichen Ergebnissen")
print("=" * 60)
for i in range(4):
result = generate_text(seq_length=10, num_steps=12, temperature=1.2, top_k=5)
print()
# ★ Wichtige Beobachtungen ★
# 1. Der Greedy-Modus liefert jedes Mal dasselbe Ergebnis, Top-k Abtastung variiert
# 2. Hoehere Temperatur = mehr Diversitaet, aber moeglicherweise weniger Kohaerenz
# 3. Beachten Sie, dass BERT dazu neigt, gaengige Phrasenmuster zu generieren
6.6 Bedingte Generierung: Lueckenfuellung und Textvervollstaendigung
# ★ Bedingte Generierung: Teiltext vorgeben, Diffusion fuellt den Rest ★
def conditional_generate(template, num_steps=12, temperature=1.0, top_k=0):
"""
Bedingte diskrete Diffusion: Bekannte Token beibehalten, nur [MASK]-Positionen entrauschen.
Aehnlich der Infilling-Faehigkeit von Diffusion-LM.
"""
ids = tokenizer.encode(template, return_tensors='pt')[0]
print(f"\n【Bedingte Generierung】Vorlage: {template}")
print("=" * 60)
for step in range(num_steps):
with torch.no_grad():
logits = model(ids.unsqueeze(0)).logits[0]
mask_positions = (ids == MASK_ID).nonzero(as_tuple=True)[0]
if len(mask_positions) == 0:
break
probs = F.softmax(logits[mask_positions] / temperature, dim=-1)
if top_k > 0:
topk_probs, topk_indices = probs.topk(top_k, dim=-1)
topk_probs = topk_probs / topk_probs.sum(dim=-1, keepdim=True)
sampled = torch.multinomial(topk_probs, 1).squeeze(-1)
predictions = topk_indices.gather(1, sampled.unsqueeze(-1)).squeeze(-1)
confidence = topk_probs.gather(1, sampled.unsqueeze(-1)).squeeze(-1)
else:
confidence, predictions = probs.max(dim=-1)
total_masks = len(mask_positions)
n_unmask = max(1, int(total_masks / max(1, num_steps - step)))
_, top_idx = confidence.topk(min(n_unmask, len(mask_positions)))
ids[mask_positions[top_idx]] = predictions[top_idx]
text = tokenizer.decode(ids[1:-1])
remaining = (ids == MASK_ID).sum().item()
print(f"Step {step+1:2d} ({remaining:2d} masks): {text}")
final = tokenizer.decode(ids[1:-1])
print(f"✓ Result: {final}")
return final
# ★ Beispiel 1: Satzlueckenfuellung ★
conditional_generate(
"The [MASK] [MASK] [MASK] is the most [MASK] [MASK] in the world.",
num_steps=8
)
# ★ Beispiel 2: Themengesteuert ★
conditional_generate(
"In machine learning, [MASK] [MASK] [MASK] [MASK] are used to [MASK] [MASK] [MASK].",
num_steps=8
)
# ★ Beispiel 3: Stimmungsgesteuert ★
conditional_generate(
"I absolutely love [MASK] [MASK] [MASK] because [MASK] [MASK] [MASK] [MASK].",
num_steps=8, temperature=1.1, top_k=5
)
# ★ Zentrale Beobachtungen ★
# Diskrete Diffusion vs. autoregressive Modelle (GPT):
# - Autoregressive: Token-fuer-Token von links nach rechts, keine Korrektur moeglich
# - Diskrete Diffusion: Globale gleichzeitige Beruecksichtigung aller Positionen, hohe Konfidenz zuerst
# - Vorteil der Diffusion: Natuerliche Unterstuetzung fuer Infilling, kontrollierbare Generierung, globale Konsistenz
7. Hands-on Lab 2: Stable Diffusion x Text-zu-Bild-Generierung (Google Colab)
Dieses Lab verwendet HuggingFace Diffusers zum Laden von Stable Diffusion und demonstriert Text-zu-Bild-Generierung, Steuerung der Guidance Scale sowie die schrittweise Visualisierung des Diffusions-Entrauschungsprozesses.
Google Colab oeffnen, stellen Sie sicher, dass auf GPU-Laufzeitumgebung umgeschaltet wurde (Runtime -> Change runtime type -> T4 GPU), ein neues Notebook erstellen und folgenden Code der Reihe nach einfuegen:
7.1 Umgebungsinstallation
# ★ Diffusers-Oekosystem installieren ★
!pip install diffusers transformers accelerate safetensors -q
7.2 Stable Diffusion Pipeline laden
import torch
from diffusers import StableDiffusionPipeline
import matplotlib.pyplot as plt
import numpy as np
# ★ Stable Diffusion 1.5 laden (float16, ca. 3,5 GB VRAM) ★
pipe = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype=torch.float16,
safety_checker=None # Zur Beschleunigung; fuer den Produktiveinsatz bitte aktivieren
).to("cuda")
# Speicheroptimierung aktivieren
pipe.enable_attention_slicing()
print(f"Pipeline loaded on: {pipe.device}")
print(f"U-Net parameters: {sum(p.numel() for p in pipe.unet.parameters())/1e6:.0f}M")
print(f"Text encoder: {sum(p.numel() for p in pipe.text_encoder.parameters())/1e6:.0f}M")
print(f"VAE: {sum(p.numel() for p in pipe.vae.parameters())/1e6:.0f}M")
7.3 Grundlegende Text-zu-Bild-Generierung
# ★ Text-zu-Bild-Generierung ★
prompt = "A serene Japanese garden with cherry blossoms, koi pond, wooden bridge, soft morning light, photorealistic"
negative_prompt = "blurry, low quality, distorted, deformed"
image = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
num_inference_steps=30,
guidance_scale=7.5,
width=512,
height=512,
generator=torch.Generator("cuda").manual_seed(42)
).images[0]
plt.figure(figsize=(8, 8))
plt.imshow(image)
plt.title("Stable Diffusion 1.5 — Text-to-Image", fontsize=14)
plt.axis("off")
plt.show()
7.4 Vergleich der Guidance Scale Effekte
# ★ Einfluss der Classifier-Free Guidance Scale ★
# w=1 (keine Steuerung) -> w=7.5 (Standard) -> w=15 (starke Steuerung) -> w=25 (uebermaessige Steuerung)
guidance_scales = [1.0, 5.0, 7.5, 15.0]
prompt = "A futuristic cyberpunk city at night, neon lights, rain reflections"
seed = 123
fig, axes = plt.subplots(1, 4, figsize=(24, 6))
for i, scale in enumerate(guidance_scales):
img = pipe(
prompt=prompt,
num_inference_steps=25,
guidance_scale=scale,
width=512, height=512,
generator=torch.Generator("cuda").manual_seed(seed)
).images[0]
axes[i].imshow(img)
axes[i].set_title(f"guidance_scale = {scale}", fontsize=13)
axes[i].axis("off")
plt.suptitle("Vergleich der Classifier-Free Guidance Scale Effekte", fontsize=16)
plt.tight_layout()
plt.show()
# ★ Wichtige Beobachtungen ★
# w=1.0: Text wird fast ignoriert, Bild ist zufaellig und unscharf
# w=5-7.5: Optimale Balance zwischen Textsteuerung und Diversitaet
# w=15+: Starke Textbefolgung, aber uebersaettigte Farben und Detailverzerrungen
7.5 Schrittweise Visualisierung des Entrauschungsprozesses
# ★ Visualisierung des umgekehrten Entrauschungsprozesses der Diffusion ★
# Zwischenzustaende werden per Callback alle paar Schritte erfasst
from diffusers import DDIMScheduler
# Zu DDIM Scheduler wechseln (unterstuetzt weniger Schritte und ist deterministisch)
pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
intermediates = []
def callback_fn(pipe, step, timestep, callback_kwargs):
"""Latent-Variablen bei jedem Schritt aufzeichnen und als visualisierbare Bilder decodieren"""
latents = callback_kwargs["latents"]
# Latent-Variablen zu Bildern decodieren
with torch.no_grad():
decoded = pipe.vae.decode(latents / pipe.vae.config.scaling_factor)
img = decoded.sample[0].cpu().float()
img = (img / 2 + 0.5).clamp(0, 1).permute(1, 2, 0).numpy()
intermediates.append((step, timestep.item(), img))
return callback_kwargs
# Generieren und Zwischenschritte erfassen
intermediates.clear()
prompt = "A majestic mountain landscape with aurora borealis, oil painting style"
final_image = pipe(
prompt=prompt,
num_inference_steps=20,
guidance_scale=7.5,
width=512, height=512,
generator=torch.Generator("cuda").manual_seed(77),
callback_on_step_end=callback_fn
).images[0]
# ★ Entrauschungsprozess visualisieren ★
n_show = min(8, len(intermediates))
indices = np.linspace(0, len(intermediates)-1, n_show, dtype=int)
fig, axes = plt.subplots(1, n_show, figsize=(n_show * 3.5, 3.5))
for i, idx in enumerate(indices):
step, timestep, img = intermediates[idx]
axes[i].imshow(img)
axes[i].set_title(f"Step {step}\nt={timestep}", fontsize=10)
axes[i].axis("off")
plt.suptitle("Diffusion Denoising Process — Vom Rauschen zum Bild", fontsize=14)
plt.tight_layout()
plt.show()
print(f"\nInsgesamt {len(intermediates)} Entrauschungsschritte")
print("Beobachtung: Fruehphase formt die grobe Komposition -> Mittelphase etabliert Farben und Strukturen -> Spaetphase verfeinert Details und Texturen")
7.6 Image-to-Image: Stiltransfer
from diffusers import StableDiffusionImg2ImgPipeline
from PIL import Image
# ★ img2img Pipeline laden (gemeinsame Modellgewichte) ★
pipe_img2img = StableDiffusionImg2ImgPipeline(**pipe.components).to("cuda")
# Das oben generierte Bild als Eingabe verwenden
init_image = final_image.resize((512, 512))
# ★ Stiltransfer mit unterschiedlichen Strength-Werten ★
strengths = [0.3, 0.5, 0.7, 0.9]
style_prompt = "A majestic mountain landscape, watercolor painting, artistic brush strokes, vibrant colors"
fig, axes = plt.subplots(1, 5, figsize=(30, 6))
# Originalbild
axes[0].imshow(init_image)
axes[0].set_title("Original", fontsize=13)
axes[0].axis("off")
for i, strength in enumerate(strengths):
styled = pipe_img2img(
prompt=style_prompt,
image=init_image,
strength=strength,
num_inference_steps=25,
guidance_scale=7.5,
generator=torch.Generator("cuda").manual_seed(42)
).images[0]
axes[i+1].imshow(styled)
axes[i+1].set_title(f"strength = {strength}", fontsize=13)
axes[i+1].axis("off")
plt.suptitle("Image-to-Image Stiltransfer — strength steuert den 'Veraenderungsgrad'", fontsize=15)
plt.tight_layout()
plt.show()
# ★ Wichtige Beobachtungen ★
# strength=0.3: Nur leichte Farb- und Stilanpassung, Originalkomposition bleibt erhalten
# strength=0.5: Deutliche Stilisierung, Hauptstruktur bleibt jedoch unveraendert
# strength=0.7: Weitgehende Neuerstellung, nur die grobe Anordnung bleibt
# strength=0.9: Fast vollstaendige Neugeneration, nur von der Vorlage "inspiriert"
7.7 Text-Embedding-Exploration
# ★ Untersuchen, wie CLIP Text-Embeddings die Generierung beeinflussen ★
from transformers import CLIPTextModel, CLIPTokenizer
clip_tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14")
clip_model = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14").to("cuda")
def get_text_embedding(text):
tokens = clip_tokenizer(text, return_tensors="pt", padding=True, truncation=True).to("cuda")
with torch.no_grad():
emb = clip_model(**tokens).last_hidden_state
return emb
# ★ Aehnlichkeit zwischen verschiedenen Prompts berechnen ★
prompts = [
"A beautiful sunset over the ocean",
"A gorgeous sunrise by the sea",
"A cat sitting on a windowsill",
"Neural network architecture diagram",
]
embeddings = [get_text_embedding(p) for p in prompts]
# Embedding des [CLS]-Tokens fuer Aehnlichkeitsberechnung verwenden
cls_embs = torch.stack([e[0, 0] for e in embeddings])
cls_embs = F.normalize(cls_embs, dim=-1)
sim_matrix = (cls_embs @ cls_embs.T).cpu().numpy()
fig, ax = plt.subplots(figsize=(7, 6))
im = ax.imshow(sim_matrix, cmap='RdYlBu_r', vmin=0.5, vmax=1.0)
ax.set_xticks(range(len(prompts)))
ax.set_yticks(range(len(prompts)))
short_labels = [p[:25] + "..." if len(p) > 25 else p for p in prompts]
ax.set_xticklabels(short_labels, rotation=45, ha='right', fontsize=9)
ax.set_yticklabels(short_labels, fontsize=9)
for i in range(len(prompts)):
for j in range(len(prompts)):
ax.text(j, i, f"{sim_matrix[i,j]:.2f}", ha='center', va='center', fontsize=11)
plt.colorbar(im)
plt.title("CLIP Text Embedding Cosine Similarity", fontsize=13)
plt.tight_layout()
plt.show()
# ★ Beobachtungen ★
# sunset/sunrise: Hohe Aehnlichkeit -> CLIP versteht semantische Naehe
# cat vs. neural network: Geringe Aehnlichkeit -> Grosse semantische Distanz
# Dies erklaert, warum aehnliche Prompts Bilder in aehnlichem Stil erzeugen
8. Beschleunigungs- und Optimierungstechniken fuer Diffusionsmodelle
Der groesste praktische Engpass von Diffusionsmodellen ist die Inferenzgeschwindigkeit -- das originale DDPM benoetigt 1000 iterative Abtastschritte, und selbst auf einer GPU dauert die Generierung eines einzelnen Bildes mehrere Minuten. Im Folgenden werden mehrstufige Beschleunigungsansaetze von der Mathematik bis zur Technik vorgestellt:
| Beschleunigungsmethode | Prinzip | Effekt | Referenzarbeit |
|---|---|---|---|
| Schnellere Sampler | Nicht-markovsche Abtastung, ODE-Loeser | 1000 Schritte -> 20-50 Schritte | DDIM[5], DPM-Solver |
| Konsistenzdestillation | Mehrstufige Entrauschung zu wenigen Schritten destilliert | 50 Schritte -> 1-4 Schritte | LCM[16], SDXL-Turbo |
| Latent-Space-Diffusion | Operationen im komprimierten Latent Space | Rechenaufwand um ~48x reduziert | LDM / Stable Diffusion[8] |
| Modellkompression | Pruning + Quantisierung + Destillation | Modellgroesse um 30-70% reduziert | BK-SDM, SVDQuant |
| Token-Zusammenfuehrung | Zusammenfuehrung redundanter visueller Token | Zusaetzliche 1,5-2x Beschleunigung | ToMe for SD |
| Feature-Caching | Caching hochstufiger Features zur Vermeidung redundanter Berechnungen | Zusaetzliche 2-2,5x Beschleunigung | DeepCache |
| Architekturevolution | Transformer ersetzt U-Net | Bessere Skalierung | DiT[13], FLUX |
Diese Beschleunigungsmethoden lassen sich kombinieren. Wie wir im Artikel Die ultimative Integration fuenf zentraler Technologien ausfuehrlich zeigen: Die Kombination von BK-SDM (Pruning + Destillation) + LCM-LoRA (Konsistenzdestillation) + ToMe (Token-Zusammenfuehrung) erreicht auf einer kostenlosen Colab T4 eine End-to-End-Beschleunigung um den Faktor 10 und mehr.
9. Unternehmensanwendungen und strategischer Wert
Die industrielle Anwendung von Diffusionsmodellen entwickelt sich von der reinen Technologiedemonstration zur echten Wertschoepfung:
- E-Commerce und Einzelhandel: Virtuelle Anprobe (Virtual Try-On), Hintergrundaustausch fuer Produktbilder, Massengenerierung von Marketingmaterialien. Die Kontrollierbarkeit von Diffusionsmodellen ermoeglicht es Marken, Hintergrund und Stil zu aendern und gleichzeitig die praezise Darstellung des Produkts beizubehalten
- Gaming und Film: Schnelle Iteration von Konzeptkunst, Szenengenerierung, Charakterdesign. Stable Diffusion + ControlNet ermoeglicht es Kuenstlern, die Generierung direkt mit Skizzen zu steuern und den Produktionszyklus erheblich zu verkuerzen
- Medizinische Bildgebung: Synthetische Trainingsdaten (Loesung des Problems knapper medizinischer Bilddaten), Super-Resolution-Verbesserung, modaluebergreifende Konvertierung (CT -> MRI). Bedingte Diffusionsmodelle erweitern Datensaetze bei gleichzeitiger Wahrung der medizinischen Praezision
- Architektur und Design: Generierung von Architekturvisualisierungen, Inneneinrichtungskonzepten und Industrieproduktdesigns aus Textbeschreibungen oder Skizzen. Die img2img-Funktion ermoeglicht Designern die schnelle Erkundung des Designraums
- Materialwissenschaft und Medikamentendesign: 3D-Molekuelstrukturgenerierung, Kristallstrukturvorhersage. Die Flexibilitaet von Diffusionsmodellen in gemischten diskreten und kontinuierlichen Raeumen macht sie zu einem neuen Werkzeug fuer wissenschaftliche Entdeckungen
Aus strategischer Sicht sollten Unternehmen drei zentrale Trends im Auge behalten:
- Dramatisch sinkende Feinabstimmungskosten: LoRA + Quantisierung ermoeglichen es Unternehmen, mit einigen hundert domenenspezifischen Bildern ein massgeschneidertes Stilmodell zu trainieren, wobei die Kosten von Zehntausenden auf wenige Hundert Euro sinken
- Stetig steigende Kontrollierbarkeit: Technologien wie ControlNet, IP-Adapter und T2I-Adapter machen Generierungsergebnisse praeziser kontrollierbar -- von "Gluecksspiel" hin zu "praeziser Anleitung"
- Inferenzeffizienz ueberschreitet kritische Schwelle: LCM + Quantisierung + Cache-Optimierung bringen hochwertige Bildgenerierung vom Sekundenbereich in den Millisekundenbereich und oeffnen die Tuer fuer interaktive Echtzeitanwendungen
10. Fazit und Ausblick
Diffusionsmodelle haben in nur fuenf Jahren den Sprung vom theoretischen Framework zur industriellen Infrastruktur geschafft. Ihr Erfolg ist kein Zufall -- sie basieren auf dem Schnittpunkt von Physik (Nichtgleichgewichtsthermodynamik), Statistik (Score Matching) und Deep Learning und bieten die theoretische Vollstaendigkeit und Trainingsstabilitaet, die GANs fehlt.
Einige bemerkenswerte Forschungsrichtungen an vorderster Front:
- Skalierung der Videogenerierung: Sora hat das Potenzial der DiT-Architektur fuer zeitlich-raeumlich konsistente Videogenerierung demonstriert. Die Erweiterung von Diffusionsmodellen von 2D auf den 3D-Raum-Zeit-Bereich ist derzeit die aktivste Forschungsrichtung
- 3D-Inhaltsgenerierung: Direkte Generierung von 3D-Objekten und -Szenen aus Text (DreamFusion, Zero-1-to-3), Ausdehnung des Erfolgs von Diffusionsmodellen von 2D auf 3D
- Vereinheitlichung der diskreten Diffusion: Vereinigung von kontinuierlicher und diskreter Diffusion in einem einzigen Framework, sodass ein Modell gleichzeitig Text, Bilder, Code, Musik und andere multimodale Daten verarbeiten kann
- Flow Matching: Als Alternative zu Diffusionsmodellen lernt es direkt den optimalen Transportpfad von Rauschen zu Daten und zeigt sowohl theoretische als auch praktische Vorteile
- Die Grenzen der Inferenzeffizienz: Die Reise von 1000 Schritten auf 1 Schritt geht weiter -- Consistency Models und Rectified Flow erkunden die Qualitaetsobergrenze der "Ein-Schritt-Generierung"
Die Kernerkenntnis der Diffusionsmodelle -- die Zerlegung komplexer Generierungsprobleme in eine Reihe einfacher Entrauschungsschritte -- hat nicht nur die Bildgenerierung veraendert, sondern gestaltet auch unser konzeptionelles Verstaendnis von generativer KI neu. Dieses Framework zu beherrschen bedeutet, die Kernsprache der KI-Innovation des naechsten Jahrzehnts zu beherrschen.
Wenn Ihr Team Anwendungsszenarien fuer Diffusionsmodelle im Unternehmen evaluiert oder eine vollstaendige Pipeline von der Modellauswahl ueber die Feinabstimmung bis zur Deployment-Optimierung aufbauen moechte, laden wir Sie herzlich zu einem vertieften technischen Gespraech ein. Das Forschungsteam von Meta Intelligence kann Ihnen dabei helfen, das technische Potenzial von Diffusionsmodellen in messbaren Geschaeftswert umzuwandeln.



