ControlNet
ControlNet ergänzt Text-zu-Bild-Diffusionsmodellen eine räumliche Steuerung. Damit lässt sich das Layout anhand von Kantenkarten, Tiefenkarten oder Posenskeletten lenken. Hier erfährst du, wie es funktioniert – mit Code.
ControlNet ist eine Neuronales-Netzwerk-Architektur, die einem vortrainierten Text-zu-Bild-Diffusionsmodell wie Stable Diffusion räumliche Steuerung hinzufügt. Zusätzlich zum Textprompt nimmt das Modell ein Bedingungsbild entgegen, zum Beispiel eine Kantenkarte, eine Tiefenkarte, ein menschliches Posenskelett oder eine Segmentierungsmaske. Das generierte Bild folgt dieser Struktur, während der Prompt Inhalt und Stil bestimmt. Ein Prompt wie „ein Ritter in silberner Rüstung“ ergibt in Kombination mit einem Posenskelett einen Ritter genau in dieser Pose. Lvmin Zhang, Anyi Rao und Maneesh Agrawala von der Stanford University stellten ControlNet 2023 in Adding Conditional Control to Text-to-Image Diffusion Models vor. Die Arbeit erhielt bei der ICCV 2023 gemeinsam den Marr-Preis für die beste Arbeit. Die Gewichte des Basismodells bleiben eingefroren, sodass ControlNet die Steuerung ergänzt, ohne das vorhandene Wissen des Modells zu beeinträchtigen.
So funktioniert ControlNet#
Stable Diffusion erzeugt ein Bild, indem es ein latentes Abbild wiederholt entrauscht und dabei ein U-Net verwendet. ControlNet fixiert dieses U-Net und erstellt eine trainierbare Kopie seines Encoders mit den 12 Codierungsblöcken und dem mittleren Block. Ein kleines Faltungsnetz wandelt zunächst das 512×512-Bedingungsbild in eine 64×64-Merkmalskarte um, die zum latenten Abbild passt. Die trainierbare Kopie verarbeitet das latente Abbild zusammen mit diesen Bedingungsmerkmalen. Ihre Ausgaben werden zu den 12 Skip-Verbindungen des fixierten U-Net und zu dessen mittlerem Block addiert, sodass der fixierte Decoder das Steuersignal erhält:
Die Kopie ist nur über Nullfaltungen mit dem fixierten Modell verbunden: 1×1-Faltungen, deren Gewichte und Bias-Werte anfangs null sind. Beim ersten Trainingsschritt geben sie daher null aus. Das kombinierte Modell verhält sich exakt wie das Original, und die vortrainierten Schichten erhalten kein zufälliges Rauschen. Die Ausgabe-Nullfaltung erhält dennoch einen von null verschiedenen Gewichtsgradienten, da ihre Eingabe nicht null ist. Daher entfernt das erste Update sie vom Nullwert, und das Steuersignal wächst von dort aus. Dieser PyTorch-Code zeigt einen Block:
import copy
import torch
from torch import nn
# A frozen block from the pretrained model and a trainable copy of it
torch.manual_seed(0)
locked = nn.Conv2d(64, 64, 3, padding=1).requires_grad_(False)
trainable = copy.deepcopy(locked).requires_grad_(True)
# Zero convolutions: 1x1 convolutions whose weights and biases start at zero
zero_in, zero_out = nn.Conv2d(64, 64, 1), nn.Conv2d(64, 64, 1)
for conv in (zero_in, zero_out):
nn.init.zeros_(conv.weight)
nn.init.zeros_(conv.bias)
x = torch.randn(1, 64, 32, 32) # features entering the block
condition = torch.randn(1, 64, 32, 32) # encoded edge, depth, or pose map
y = locked(x) + zero_out(trainable(x + zero_in(condition)))
# At step 0 the output equals the frozen block's, and only the outer zero conv gets a gradient
print(torch.equal(y, locked(x)))
y.sum().backward()
print(f"zero_in grad: {zero_in.weight.grad.norm():.1f}, zero_out grad: {zero_out.weight.grad.norm():.1f}")Die Ausgabe lautet True und zero_in grad: 0.0, zero_out grad: 2040.6. Die Ausgabe des Blocks ist identisch mit der des eingefrorenen Modells. Die äußere Nullfaltung erhält einen Gradienten, da ihre Eingabe nicht null ist, und die innere beginnt zu lernen, sobald sich die äußere vom Nullwert entfernt hat.
Arten von Bedingungen#
Die ursprüngliche Arbeit trainierte getrennte ControlNets für Canny-Kanten, Tiefenkarten, Karten der Oberflächennormalen, gerade M-LSD-Linien, weiche HED-Kanten, ADE20K-Segmentierungskarten, menschliche Posen von OpenPose und Skizzen von Nutzern. Jedes Konditionierungsbild wird mit einem bereits verfügbaren Modell aus einem Referenzfoto extrahiert, beispielsweise mit dem in OpenCV enthaltenen Canny-Kantendetektor oder einem Netz zur Tiefenschätzung; mehrere ControlNets lassen sich gleichzeitig anwenden, jeweils mit eigener Stärke. Ultralytics YOLO26-Modelle zur Posenschätzung extrahieren Posenbedingungen dieser Art und sagen für jede Person 17 COCO-Schlüsselpunkte voraus, die auf einer leeren Leinwand als Skelette eingezeichnet werden können:
import cv2
import numpy as np
from ultralytics import YOLO
# Lade ein YOLO26-Posenmodell, das 17 Schlüsselpunkte pro Person vorhersagt
model = YOLO("yolo26n-pose.pt")
results = model("https://ultralytics.com/images/bus.jpg")
result = results[0]
# Zeichne nur die Skelette auf eine schwarze Fläche in der Größe des Fotos
skeletons = result.plot(img=np.zeros_like(result.orig_img), boxes=False)
cv2.imwrite("pose_condition.png", skeletons)Das gespeicherte Bild zeigt die Gliedmaßen jeder Person als farbige Linien auf schwarzem Hintergrund; Farben, Texturen und Hintergrund des Fotos sind entfernt.
ControlNet und verwandte Methoden#
- LoRA: Passt eine kleine Anzahl hinzugefügter Gewichte an, um einem Modell einen neuen Stil, eine neue Figur oder ein neues Objekt beizubringen. LoRA verändert, was das Modell zeichnet, während ControlNet festlegt, wo Dinge erscheinen. Beide Verfahren werden häufig kombiniert.
- T2I-Adapter: Eine ressourcenschonendere Alternative mit etwa 77 Millionen Parametern. Sie fügt Bedingungsmerkmale zu den Encodermerkmalen des eingefrorenen U-Net hinzu, statt eine vollständige Encoderkopie auszuführen. Adapter für verschiedene Bedingungen lassen sich bei der Generierung kombinieren.
- Bild-zu-Bild-Generierung: Beginnt mit dem Entrauschen einer verrauschten Kopie eines Eingabefotos, sodass die Ausgabe dessen Farben und grobe Anordnung übernimmt. ControlNet schränkt nur die extrahierte Struktur ein, etwa Kanten, und überlässt Farben und Texturen dem Prompt.
- Bild-Inpainting: Generiert einen maskierten Bildbereich neu, sodass er zum Rest des Bildes passt. Dabei wird festgelegt, welcher Bereich sich ändert, während ControlNet die Struktur des generierten Inhalts steuert.
Anwendungen in der Praxis#
- Architektur und Inneneinrichtung: Skizzen, CAD-Linienzeichnungen oder M-LSD-Linienkarten eines Raums werden mit derselben Geometrie in fotorealistische Darstellungen mit verschiedenen Materialien und Stilen umgewandelt.
- Figurenkunst und Animation: Posenskelette halten die Körperhaltung einer Figur bei Stilvariationen konstant. Aus Referenzvideos extrahierte Posen pro Einzelbild steuern konsistente animierte Sequenzen.
- Produkt- und Marketingbilder: Tiefen- oder Kantenkarten eines Produktfotos bewahren dessen Form und Position, während der Prompt Umgebung, Beleuchtung und Hintergrund verändert.
- Synthetische Daten: Die Generierung von Bildern anhand von Segmentierungskarten oder Posen erzeugt neue Trainingsbilder mit im Voraus bekannten Beschriftungen, da die Anordnung vor der Generierung festgelegt wurde.
Ein ControlNet trainieren#
Für das Training werden Bildpaare und die dazugehörigen Bedingungskarten benötigt. Diese werden automatisch erstellt, indem der Bedingungsextraktor auf einen beschrifteten Bilddatensatz angewendet wird. Da die fixierten Gewichte keine Gradientenaktualisierungen benötigen, beansprucht jeder Trainingsdurchlauf nur etwa 23 % mehr GPU-Speicher und 34 % mehr Zeit als die Optimierung von Stable Diffusion ohne ControlNet. Die Arbeit berichtet von robustem Training mit Datensätzen von weniger als 50.000 bis zu über einer Million Bildern. Beim Training zeigt sich außerdem eine „plötzliche Konvergenz“: Das Modell ignoriert die Bedingung über Tausende von Schritten und beginnt dann abrupt, ihr zu folgen – gewöhnlich innerhalb von 10.000 Optimierungsschritten, im Beispiel der Arbeit bei Schritt 6.133.










