← Назад к вопросам

Что такое ControlNet и LoRA?

3.0 Senior🔥 101 комментариев
#Глубокое обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ControlNet и LoRA: расширения для генеративных моделей

Контекст: почему нужны ControlNet и LoRA

Основные генеративные модели (Stable Diffusion, DALL-E) требуют дорогого обучения или fine-tuning на большом количестве видеокарт. ControlNet и LoRA позволяют адаптировать модели с минимальными ресурсами.

LoRA (Low-Rank Adaptation)

LoRA — это способ эффективного fine-tuning через добавление небольших параметризованных слоёв.

Как работает LoRA

Вместо обновления всех весов модели (огромное количество параметров), LoRA добавляет низкоранговую матрицу к каждому слою:

W' = W + ΔW
где ΔW = A × B^T
A: (d, r), B: (d, r), r << d

Вместо обновления d×d матрицы, обновляем 2×d×r параметров. Если d=10000, r=8, то экономия: 100M параметров → 160K параметров!

import torch
import torch.nn as nn

class LoRALinear(nn.Module):
    def __init__(self, in_features, out_features, rank=8):
        super().__init__()
        self.linear = nn.Linear(in_features, out_features)
        
        # LoRA матрицы
        self.lora_A = nn.Linear(in_features, rank, bias=False)
        self.lora_B = nn.Linear(rank, out_features, bias=False)
        self.scale = 1.0
        
        nn.init.kaiming_uniform_(self.lora_A.weight)
        nn.init.zeros_(self.lora_B.weight)
    
    def forward(self, x):
        base = self.linear(x)
        lora = self.lora_B(self.lora_A(x)) * self.scale
        return base + lora

# Использование
model = LoRALinear(10000, 10000, rank=8)
x = torch.randn(32, 10000)
output = model(x)

Применение LoRA в Stable Diffusion

from diffusers import StableDiffusionPipeline
import torch

# Загружаем базовую модель
pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16
).to("cuda")

# Загружаем LoRA адаптер
pipe.load_lora_weights("path/to/lora_weights", weight_name="model.safetensors")

# Генерируем изображение
prompt = "a photo of a cat wearing sunglasses"
image = pipe(prompt, num_inference_steps=50).images[0]

Преимущества LoRA

✓ Экономия памяти: 100x меньше параметров
✓ Быстрое обучение: может обучиться за часы на одной GPU
✓ Лёгкое переключение: один файл ~40-100 MB вместо 4 GB
✓ Комбинируется: несколько LoRA можно использовать одновременно
✓ Портативность: работает со многими моделями

Недостатки

✗ Меньше гибкости чем полный fine-tuning
✗ Требует выбора ранга r
✗ Может работать хуже на очень специфичных задачах

ControlNet

ControlNet — это техника для добавления spatial контроля к генеративным моделям.

Вместо простого текстового prompt, ControlNet позволяет добавить:

  • Sketch (силуэт)
  • Pose (поза человека)
  • Depth map (карта глубины)
  • Canny edges (контуры)
  • Optical flow и т.д.

Архитектура ControlNet

ControlNet добавляет extra U-Net, которая учит пространственные условия:

Text Prompt → CLIP → Token Embeddings
                        ↓
                    [U-Net]
                    ↙  ↓  ↘
              ControlNet (скопированная U-Net)
                    ↓
            Condition Image (sketch/pose/depth)
                    ↓
              Spatial Conditioning
                    ↓
            Generated Image (управляемое)

Использование ControlNet в Stable Diffusion

from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from PIL import Image
import torch

# Загружаем ControlNet (например, для sketch)
controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/sd-controlnet-scribble",
    torch_dtype=torch.float16
)

pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=controlnet,
    torch_dtype=torch.float16
).to("cuda")

# Загружаем изображение с наброском
sketch = Image.open("sketch.png").convert("RGB")
sketch = sketch.resize((512, 512))

# Генерируем с контролем
prompt = "a beautiful landscape oil painting"
image = pipe(
    prompt,
    image=sketch,
    num_inference_steps=50,
    guidance_scale=7.5
).images[0]

Типы ControlNet

TypeInputИспользование
ScribbleНаброскиБыстрое рисование
PoseПозы людей (KeyPoints)Контроль позы персонажа
DepthКарта глубиныКонтроль композиции
CannyКонтуры образовАрхитектура, объекты
NormalКарты нормалейТекстуры, объёмные объекты
SemanticСемантическая сегментацияКонкретные области
TileТайлингГенерация больших изображений

Примеры типов ControlNet

# Пример 1: Pose Control
from controlnet_aux import OpenposeDetector

openpose = OpenposeDetector.from_pretrained(
    "lllyasviel/ControlNet-pose",
    cache_dir="./pretrained_weights"
)

# Извлекаем позу из эталонного изображения
reference_image = Image.open("person.jpg")
pose = openpose(reference_image)

# Применяем к новому человеку с той же позой
pipe = StableDiffusionControlNetPipeline.from_pretrained(...)
image = pipe(
    "a person in stylized anime",
    image=pose,
    num_inference_steps=50
).images[0]

# Пример 2: Depth Control
from diffusers.utils import load_image
from transformers import DPTImageProcessor, DPTForDepthEstimation

processor = DPTImageProcessor.from_pretrained("Intel/dpt-large")
model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large")

image = load_image("scene.jpg")
inputs = processor(images=image, return_tensors="pt")

with torch.no_grad():
    outputs = model(**inputs)
    predicted_depth = outputs.predicted_depth

depth_image = predicted_depth[0].unsqueeze(0).unsqueeze(0)

Преимущества ControlNet

✓ Точный пространственный контроль
✓ Может комбинироваться (несколько ControlNet одновременно)
✓ Работает со всеми моделями (не нужен переобучение)
✓ Интуитивно — feed изображение с условием
✓ Высокое качество результатов

Недостатки

✗ Требует подготовки condition images
✗ Вычислительно дороже (extra U-Net)
✗ Требует точности condition (плохой sketch → плохой результат)

Сравнение LoRA и ControlNet

ПараметрLoRAControlNet
НазначениеFine-tuning стиля/содержанияПространственный контроль
Входные данныеТекст + веса моделиТекст + изображение условия
Параметры~100K - 1M~10M (дополнительно)
Время обученияЧасы на одной GPUДни (но дают готовые)
ИспользованиеОбучение новых стилейНаправление генерации
КомбинированиеДа (несколько LoRA)Да (несколько Control)
РезультатОпределённый стильКонтролируемая форма/поза

Практический пример: Комбинация LoRA + ControlNet

from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import torch

# 1. Загружаем базовую модель + ControlNet (Pose)
controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/sd-controlnet-openpose"
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=controlnet
)

# 2. Загружаем LoRA (например, стиль аниме)
pipe.load_lora_weights("anime_style_lora")

# 3. Используем оба вместе
pose_image = Image.open("pose.png").resize((512, 512))
image = pipe(
    "anime girl, beautiful face, detailed",
    image=pose_image,
    num_inference_steps=50,
    guidance_scale=7.5
).images[0]
# Результат: аниме стиль (LoRA) + контролируемая поза (ControlNet)

Итого

LoRA — лёгкий способ адаптировать модель к новому стилю/содержанию с минимальными ресурсами.

ControlNet — способ добавить пространственный контроль над генерацией (поза, глубина, контуры).

Вместе они позволяют точно контролировать как содержание (стиль), так и форму (геометрию) сгенерированного изображения.

Оба метода революционизировали текст-в-изображение генерацию, сделав её более практичной и управляемой.

Что такое ControlNet и LoRA? | PrepBro