Diffusers documentation

ControlNet

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

ControlNet

ControlNet, metin komutunu korurken, yapısal bir kontrol görseli (kenarlar, derinlik veya poz) ile önceden eğitilmiş bir difüzyon modelini yönlendirir. Temel modeli dondurur ve kalanları (residuals) ile gürültü gidericiyi (denoiser) yönlendiren paralel bir ağ ekler; böylece ince ayar yapmadan yerleşim kontrolü elde edersiniz.

İhtiyacınız olan kontrolü (örneğin canny) yükleyen bir ControlNet yükleyin, ardından bunu from_pretrained() fonksiyonuna controlnet= olarak iletin. Kontrolün üretimi ne kadar güçlü yönlendireceğini belirlemek için controlnet_conditioning_scale parametresini kullanın.

ControlNet'ler Flux, Hunyuan-DiT, Stable Diffusion 3 gibi birçok modelde kullanılabilir. Bu kılavuzdaki örnekler Flux ve Stable Diffusion XL kullanır. Eski Stable Diffusion ailesi checkpoint'lerinde T2I-Adapter için Eski nesil adaptörler bölümüne bakın. Yeni kontrol edilebilir üretim işleri için ControlNet tercih edin.

Aşağıdaki sekmeler, metinden görüntüye, görüntüden görüntüye ve inpainting için ControlNet'i gösterir.

metinden görüntüye
görselden görseli
inpainting

opencv-python ile bir canny görüntüsü oluşturun.

import cv2
import numpy as np
from PIL import Image
from diffusers.utils import load_image

original_image = load_image(
    "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png"
)

image = np.array(original_image)

low_threshold = 100
high_threshold = 200

image = cv2.Canny(image, low_threshold, high_threshold)
image = image[:, :, None]
image = np.concatenate([image, image, image], axis=2)
canny_image = Image.fromarray(image)

Canny görüntüsünü pipeline'a iletin. Kontrolün ne kadar ağırlık taşıyacağını belirlemek için controlnet_conditioning_scale parametresini kullanın.

import torch
from diffusers.utils import load_image
from diffusers import FluxControlNetPipeline, FluxControlNetModel

controlnet = FluxControlNetModel.from_pretrained(
    "InstantX/FLUX.1-dev-Controlnet-Canny", dtype=torch.bfloat16
)
pipeline = FluxControlNetPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev", controlnet=controlnet, dtype=torch.bfloat16
).to("cuda")  # or "mps", "xpu", "cpu"

prompt = """
A photorealistic overhead image of a cat reclining sideways in a flamingo pool floatie holding a margarita. 
The cat is floating leisurely in the pool and completely relaxed and happy.
"""

pipeline(
    prompt, 
    control_image=canny_image,
    controlnet_conditioning_scale=0.5,
    num_inference_steps=50, 
    guidance_scale=3.5,
).images[0]
Generated image (prompt only)
orijinal görüntü
Control image (Canny edges)
canny görüntü
Generated image (ControlNet + prompt)
oluşturulan görsel

Çoklu-ControlNet

Birden fazla ControlNet'i (örneğin canny + depth) bir liste olarak geçirerek birleştirin. Mümkünse üst üste binen bölgeleri maskeleyin ve her bir controlnet_conditioning_scale değerini ayarlayın. canny_image'i OpenCV Canny ile (metinden görüntüye üretimde olduğu gibi) ve depth_image'yi DPT ile (görüntüden görüntüye üretimde olduğu gibi) oluşturun. Pipeline'ı çağırmadan önce tüm kontrol görüntülerini pipeline boyutuna yeniden boyutlandırın.

import cv2
import torch
import numpy as np
from PIL import Image
from transformers import DPTImageProcessor, DPTForDepthEstimation
from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel, AutoencoderKL
from diffusers.utils import load_image

original_image = load_image(
    "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png"
)
image = np.array(original_image)
canny_image = Image.fromarray(
    np.concatenate([cv2.Canny(image, 100, 200)[:, :, None]] * 3, axis=2)
)

device = "cuda"  # or "mps", "xpu", "cpu"
depth_estimator = DPTForDepthEstimation.from_pretrained("Intel/dpt-hybrid-midas").to(device)
feature_extractor = DPTImageProcessor.from_pretrained("Intel/dpt-hybrid-midas")

def get_depth_map(image):
    image = feature_extractor(images=image, return_tensors="pt").pixel_values.to(device)
    with torch.no_grad(), torch.autocast(device):
        depth_map = depth_estimator(image).predicted_depth

    depth_map = torch.nn.functional.interpolate(
        depth_map.unsqueeze(1),
        size=(1024, 1024),
        mode="bicubic",
        align_corners=False,
    )
    depth_min = torch.amin(depth_map, dim=[1, 2, 3], keepdim=True)
    depth_max = torch.amax(depth_map, dim=[1, 2, 3], keepdim=True)
    depth_map = (depth_map - depth_min) / (depth_max - depth_min)
    image = torch.cat([depth_map] * 3, dim=1)
    image = image.permute(0, 2, 3, 1).cpu().numpy()[0]
    image = Image.fromarray((image * 255.0).clip(0, 255).astype(np.uint8))
    return image

depth_image = get_depth_map(original_image.resize((1024, 1024)))

controlnets = [
    ControlNetModel.from_pretrained(
        "diffusers/controlnet-canny-sdxl-1.0", dtype=torch.float16
    ),
    ControlNetModel.from_pretrained(
        "diffusers/controlnet-depth-sdxl-1.0-small", dtype=torch.float16
    ),
]

vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", dtype=torch.float16)
pipeline = StableDiffusionXLControlNetPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", controlnet=controlnets, vae=vae, dtype=torch.float16
).to(device)

prompt = """
a relaxed rabbit sitting on a striped towel next to a pool with a tropical drink nearby, 
bright sunny day, vacation scene, 35mm photograph, film, professional, 4k, highly detailed
"""
negative_prompt = "lowres, bad anatomy, worst quality, low quality, deformed, ugly"

images = [canny_image.resize((1024, 1024)), depth_image.resize((1024, 1024))]

pipeline(
    prompt,
    negative_prompt=negative_prompt,
    image=images,
    num_inference_steps=100,
    controlnet_conditioning_scale=[0.5, 0.5],
).images[0]
Canny image
canny görüntü
Depth map
derinlik haritası
Generated image (ControlNet + prompt)
oluşturulan görsel

Tahmin modu

Tahmin modu, metin komutu olmadığında (veya istemediğinizde) yalnızca bir kontrol girdisinden görüntü üretir. ControlNet artıklarını blok derinliğine göre ölçekler; erken alt bloklarda yaklaşık 0.1’den orta blokta 1.0’a kadar. Bu, erken katmanların aşırı kısıtlama yapmasını önlerken daha derin blokların yapıyı taşımasını sağlar.

import torch
from diffusers.utils import load_image
from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel

controlnet = ControlNetModel.from_pretrained(
  "diffusers/controlnet-canny-sdxl-1.0", dtype=torch.float16
)
pipeline = StableDiffusionXLControlNetPipeline.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  controlnet=controlnet,
  dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"

canny_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat.png")
pipeline(
  "",
  image=canny_image,
  guess_mode=True
).images[0]
Canny image
canny görüntü
Generated image (Guess mode)
oluşturulan görsel
Update on GitHub