# ControlNet

Овладейте ControlNet для точного контроля генерации изображений ИИ.

{% hint style="success" %}
Все примеры можно запускать на GPU-серверах, арендуемых через [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Аренда на CLORE.AI

1. Посетите [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Отфильтруйте по типу GPU, объему VRAM и цене
3. Выберите **On-Demand** (фиксированная ставка) или **Spot** (цена по ставке)
4. Настройте ваш заказ:
   * Выберите Docker-образ
   * Установите порты (TCP для SSH, HTTP для веб-интерфейсов)
   * Добавьте переменные окружения при необходимости
   * Введите команду запуска
5. Выберите способ оплаты: **CLORE**, **BTC**, или **USDT/USDC**
6. Создайте заказ и дождитесь развертывания

### Доступ к вашему серверу

* Найдите данные для подключения в **Моих заказах**
* Веб-интерфейсы: используйте URL HTTP-порта
* SSH: `ssh -p <port> root@<proxy-address>`

## Что такое ControlNet?

ControlNet добавляет условный контроль к Stable Diffusion:

* **Canny** - Обнаружение краев
* **Depth** - 3D-карты глубины
* **Pose** - Пози человека
* **Scribble** - Черновые наброски
* **Segmentation** - Семантические маски
* **Line Art** - Чистые линии
* **IP-Adapter** - Перенос стиля

## Требования

| Тип контроля         | Мин. VRAM | Рекомендуется |
| -------------------- | --------- | ------------- |
| Один ControlNet      | 8GB       | RTX 3070      |
| Несколько ControlNet | 12GB      | RTX 3090      |
| SDXL ControlNet      | 16GB      | RTX 4090      |

## Быстрое развертывание с A1111

**Команда:**

```bash
cd /workspace/stable-diffusion-webui && \
cd extensions && \
git clone https://github.com/Mikubill/sd-webui-controlnet && \
cd .. && \
python launch.py --listen --enable-insecure-extension-access
```

### Загрузка моделей

```bash
cd /workspace/stable-diffusion-webui/extensions/sd-webui-controlnet/models

# ControlNet для SD 1.5
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny.pth
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1p_sd15_depth.pth
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble.pth
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_lineart.pth
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_softedge.pth
wget https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_seg.pth

# ControlNet для SDXL
wget https://huggingface.co/diffusers/controlnet-canny-sdxl-1.0/resolve/main/diffusion_pytorch_model.safetensors -O controlnet-canny-sdxl.safetensors
```

## Python с Diffusers

### Контроль краев Canny

```python
import torch
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from diffusers.utils import load_image
from controlnet_aux import CannyDetector
import cv2
import numpy as np

# Загрузить ControlNet
controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_canny",
    torch_dtype=torch.float16
)

# Загрузить pipeline
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=controlnet,
    torch_dtype=torch.float16
)
pipe.to("cuda")
pipe.enable_model_cpu_offload()

# Подготовить управляющее изображение
image = load_image("input.jpg")
canny = CannyDetector()
control_image = canny(image)

# Генерация
output = pipe(
    prompt="красивая женщина в саду, высокое качество",
    negative_prompt="уродливый, размытый",
    image=control_image,
    num_inference_steps=30,
    controlnet_conditioning_scale=1.0
).images[0]

output.save("canny_output.png")
```

### Контроль глубины

```python
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from controlnet_aux import MidasDetector
import torch

controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11f1p_sd15_depth",
    torch_dtype=torch.float16
)

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

# Получить карту глубины
depth_estimator = MidasDetector.from_pretrained("lllyasviel/Annotators")
depth_image = depth_estimator(image)

# Генерация с учетом глубины
output = pipe(
    prompt="футуристический город, научная фантастика, детализированно",
    image=depth_image,
    num_inference_steps=30
).images[0]
```

### OpenPose (позы человека)

```python
from controlnet_aux import OpenposeDetector

# Получить позу
pose_detector = OpenposeDetector.from_pretrained("lllyasviel/Annotators")
pose_image = pose_detector(image)

controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_openpose",
    torch_dtype=torch.float16
)

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

output = pipe(
    prompt="балерина танцует, элегантно, студийное освещение",
    image=pose_image,
    num_inference_steps=30
).images[0]
```

### Scribble/Эскиз

```python
from controlnet_aux import HEDdetector

# Обнаружить края как набросок
hed = HEDdetector.from_pretrained("lllyasviel/Annotators")
scribble_image = hed(image, scribble=True)

controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_scribble",
    torch_dtype=torch.float16
)

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

output = pipe(
    prompt="детализированная картина пейзажа",
    image=scribble_image,
    num_inference_steps=30
).images[0]
```

## Много- ControlNet

Комбинировать несколько контролей:

```python
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import torch

# Загрузить несколько ControlNet
controlnet_canny = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_canny",
    torch_dtype=torch.float16
)

controlnet_depth = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11f1p_sd15_depth",
    torch_dtype=torch.float16
)

# Создать конвейер с несколькими ControlNet
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=[controlnet_canny, controlnet_depth],
    torch_dtype=torch.float16
).to("cuda")

# Генерация с несколькими контролями
output = pipe(
    prompt="красивый портрет",
    image=[canny_image, depth_image],
    controlnet_conditioning_scale=[1.0, 0.8],  # Настроить веса
    num_inference_steps=30
).images[0]
```

## SDXL ControlNet

```python
from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel
from controlnet_aux import CannyDetector
import torch

# Загрузить SDXL ControlNet
controlnet = ControlNetModel.from_pretrained(
    "diffusers/controlnet-canny-sdxl-1.0",
    torch_dtype=torch.float16
)

pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    controlnet=controlnet,
    torch_dtype=torch.float16
).to("cuda")

# Подготовить изображение canny
canny = CannyDetector()
control_image = canny(image, low_threshold=100, high_threshold=200)

output = pipe(
    prompt="профессиональная фотография, детализированно, 8k",
    image=control_image,
    controlnet_conditioning_scale=0.5,
    num_inference_steps=30
).images[0]
```

## IP-Adapter (перенос стиля)

```python
from diffusers import StableDiffusionPipeline
from transformers import CLIPVisionModelWithProjection
import torch

# Загрузить IP-Adapter
pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16
).to("cuda")

pipe.load_ip_adapter(
    "h94/IP-Adapter",
    subfolder="models",
    weight_name="ip-adapter_sd15.bin"
)

pipe.set_ip_adapter_scale(0.6)

# Изображение-референс стиля
style_image = load_image("style_reference.jpg")

output = pipe(
    prompt="кот сидит на стуле",
    ip_adapter_image=style_image,
    num_inference_steps=30
).images[0]
```

## Препроцессоры

Все доступные препроцессоры:

```python
from controlnet_aux import (
    CannyDetector,           # Обнаружение краев
    HEDdetector,             # Мягкие края/набросок
    MidasDetector,           # Оценка глубины
    OpenposeDetector,        # Поза человека
    MLSDdetector,            # Обнаружение линий
    LineartDetector,         # Линейная графика
    LineartAnimeDetector,    # Аниме-линарт
    NormalBaeDetector,       # Карты нормалей
    ContentShuffleDetector,  # Перемешивание содержимого
    ZoeDetector,             # Улучшенная глубина
    MediapipeFaceDetector,   # Сетка лица
)

# Пример использования
canny = CannyDetector()
canny_image = canny(image, low_threshold=100, high_threshold=200)

depth = MidasDetector.from_pretrained("lllyasviel/Annotators")
depth_image = depth(image)

pose = OpenposeDetector.from_pretrained("lllyasviel/Annotators")
pose_image = pose(image, hand_and_face=True)
```

## Веса контроля

Отрегулируйте влияние для каждого ControlNet:

```python

# Полный контроль
output = pipe(..., controlnet_conditioning_scale=1.0)

# Частичный контроль (больше творческой свободы)
output = pipe(..., controlnet_conditioning_scale=0.5)

# Очень слабое руководство
output = pipe(..., controlnet_conditioning_scale=0.3)
```

### Контроль по шагам

```python

# Контролировать только в определенные шаги
output = pipe(
    prompt="...",
    image=control_image,
    controlnet_conditioning_scale=1.0,
    control_guidance_start=0.0,  # Начать с начала
    control_guidance_end=0.5,    # Остановиться на 50% шагов
    num_inference_steps=30
).images[0]
```

## Инпейнтинг с ControlNet

```python
from diffusers import StableDiffusionControlNetInpaintPipeline, ControlNetModel
import torch

controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_canny",
    torch_dtype=torch.float16
)

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

output = pipe(
    prompt="красный спортивный автомобиль",
    image=init_image,
    mask_image=mask,
    control_image=canny_image,
    num_inference_steps=30
).images[0]
```

## Пакетная обработка

```python
import os
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from controlnet_aux import CannyDetector
from PIL import Image
import torch

controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/control_v11p_sd15_canny",
    torch_dtype=torch.float16
)

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

canny = CannyDetector()

input_dir = "./inputs"
output_dir = "./outputs"
os.makedirs(output_dir, exist_ok=True)

prompt = "красивая пейзажная картина, детализированная, художественная"

for filename in os.listdir(input_dir):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        image = Image.open(os.path.join(input_dir, filename))
        control_image = canny(image)

        output = pipe(
            prompt=prompt,
            image=control_image,
            num_inference_steps=30
        ).images[0]

        output.save(os.path.join(output_dir, f"cn_{filename}"))
```

## Руководство по типам контроля

| Контроль | Лучше всего для       | Сильная сторона |
| -------- | --------------------- | --------------- |
| Canny    | Архитектура, объекты  | 0.8-1.0         |
| Depth    | 3D-сцены, перспектива | 0.6-0.8         |
| Pose     | Люди, персонажи       | 0.8-1.0         |
| Scribble | Эскизы, концепты      | 0.6-0.8         |
| Line Art | Иллюстрации           | 0.7-0.9         |
| Softedge | Общее руководство     | 0.5-0.7         |
| Seg      | Композиция сцены      | 0.6-0.8         |

## Производительность

| Настройка          | GPU      | Разрешение | Время |
| ------------------ | -------- | ---------- | ----- |
| Один CN SD1.5      | RTX 3090 | 512x512    | \~3s  |
| Несколько CN SD1.5 | RTX 3090 | 512x512    | \~5 с |
| Один CN SDXL       | RTX 4090 | 1024x1024  | \~8s  |

## Оптимизация памяти

```python

# Включить память-эффективное внимание
pipe.enable_xformers_memory_efficient_attention()

# Выгрузка на CPU
pipe.enable_model_cpu_offload()

# Разбиение внимания
pipe.enable_attention_slicing()
```

## Устранение неполадок

### Слабый эффект контроля

* Увеличьте `controlnet_conditioning_scale`
* Проверьте качество вывода препроцессора
* Используйте управляющее изображение более высокого разрешения

### Артефакты

* Уменьшите масштаб контроля
* Используйте более мягкий препроцессор (softedge вместо canny)
* Добавьте негативный prompt для артефактов

### Проблемы с VRAM

* Используйте выгрузку на CPU
* Уменьшить разрешение
* Используйте по одному ControlNet за раз

## Оценка стоимости

Типичные ставки на маркетплейсе CLORE.AI (по состоянию на 2024):

| GPU       | Почасовая ставка | Дневная ставка | Сессия 4 часа |
| --------- | ---------------- | -------------- | ------------- |
| RTX 3060  | \~$0.03          | \~$0.70        | \~$0.12       |
| RTX 3090  | \~$0.06          | \~$1.50        | \~$0.25       |
| RTX 4090  | \~$0.10          | \~$2.30        | \~$0.40       |
| A100 40GB | \~$0.17          | \~$4.00        | \~$0.70       |
| A100 80GB | \~$0.25          | \~$6.00        | \~$1.00       |

*Цены варьируются в зависимости от провайдера и спроса. Проверьте* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *для текущих тарифов.*

**Экономьте деньги:**

* Используйте **Spot** рынок для гибких рабочих нагрузок (часто на 30–50% дешевле)
* Платите с помощью **CLORE** токенов
* Сравнивайте цены у разных провайдеров

## Дальнейшие шаги

* Stable Diffusion WebUI
* Рабочие процессы ComfyUI
* [Обучение Kohya](/guides/guides_v2-ru/obuchenie/kohya-training.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-ru/obrabotka-izobrazhenii/controlnet-advanced.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
