> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-fr/traitement-dimages/controlnet-advanced.md).

# ControlNet

Contrôle précis de la génération d'images IA avec ControlNet

Maîtrisez ControlNet pour un contrôle précis de la génération d'images par IA.

{% hint style="success" %}
Tous les exemples peuvent être exécutés sur des serveurs GPU loués via [la place de marché CLORE.AI](https://clore.ai/marketplace).
{% endhint %}

## Louer sur CLORE.AI

1. Visitez [la place de marché CLORE.AI](https://clore.ai/marketplace)
2. Filtrez par type de GPU, VRAM et prix
3. Choisissez **À la demande** (tarif fixe) ou **Spot** (prix d'enchère)
4. Configurez votre commande :
   * Sélectionnez l'image Docker
   * Définissez les ports (TCP pour SSH, HTTP pour les interfaces web)
   * Ajoutez des variables d'environnement si nécessaire
   * Entrez la commande de démarrage
5. Sélectionnez le paiement : **CLORE**, **BTC**, ou **USDT/USDC**
6. Créez la commande et attendez le déploiement

### Accédez à votre serveur

* Trouvez les détails de connexion dans **Mes commandes**
* Interfaces web : utilisez l'URL du port HTTP
* SSH : `ssh -p <port> root@<proxy-address>`

## Qu'est-ce que ControlNet ?

ControlNet ajoute un contrôle conditionnel à Stable Diffusion :

* **Canny** - Détection des contours
* **Profondeur** - Cartes de profondeur 3D
* **Pose** - Poses humaines
* **Gribouillage** - Croquis approximatifs
* **Segmentation** - Masques sémantiques
* **Art linéaire** - Lignes nettes
* **IP-Adapter** - Transfert de style

## Exigences

| Type de contrôle  | VRAM minimale | Recommandé |
| ----------------- | ------------- | ---------- |
| ControlNet unique | 8 Go          | RTX 3070   |
| Multi-ControlNet  | 12 Go         | RTX 3090   |
| ControlNet SDXL   | 16 Go         | RTX 4090   |

## Déploiement rapide avec A1111

**Commande :**

```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
```

### Télécharger les modèles

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

# ControlNets 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

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

## Python avec Diffusers

### Contrôle des contours 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

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

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

# Préparer l'image de contrôle
image = load_image("input.jpg")
canny = CannyDetector()
control_image = canny(image)

# Générer
output = pipe(
    prompt="une belle femme dans un jardin, haute qualité",
    negative_prompt="laid, flou",
    image=control_image,
    num_inference_steps=30,
    controlnet_conditioning_scale=1.0
).images[0]

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

### Contrôle de la profondeur

```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")

# Obtenir la carte de profondeur
depth_estimator = MidasDetector.from_pretrained("lllyasviel/Annotators")
depth_image = depth_estimator(image)

# Générer avec la profondeur
output = pipe(
    prompt="une ville futuriste, science-fiction, détaillée",
    image=depth_image,
    num_inference_steps=30
).images[0]
```

### OpenPose (Poses humaines)

```python
from controlnet_aux import OpenposeDetector

# Obtenir la pose
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="une ballerine dansant, élégante, éclairage de studio",
    image=pose_image,
    num_inference_steps=30
).images[0]
```

### Gribouillage/Croquis

```python
from controlnet_aux import HEDdetector

# Détecter les contours sous forme de gribouillage
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="une peinture détaillée d'un paysage",
    image=scribble_image,
    num_inference_steps=30
).images[0]
```

## Multi-ControlNet

Combinez plusieurs contrôles :

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

# Charger plusieurs ControlNets
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
)

# Créer un pipeline avec plusieurs ControlNets
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=[controlnet_canny, controlnet_depth],
    torch_dtype=torch.float16
).to("cuda")

# Générer avec plusieurs contrôles
output = pipe(
    prompt="un beau portrait",
    image=[canny_image, depth_image],
    controlnet_conditioning_scale=[1.0, 0.8],  # Ajuster les poids
    num_inference_steps=30
).images[0]
```

## ControlNet SDXL

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

# Charger ControlNet SDXL
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")

# Préparer l'image Canny
canny = CannyDetector()
control_image = canny(image, low_threshold=100, high_threshold=200)

output = pipe(
    prompt="une photographie professionnelle, détaillée, 8k",
    image=control_image,
    controlnet_conditioning_scale=0.5,
    num_inference_steps=30
).images[0]
```

## IP-Adapter (Transfert de style)

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

# Charger 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)

# Image de référence de style
style_image = load_image("style_reference.jpg")

output = pipe(
    prompt="un chat assis sur une chaise",
    ip_adapter_image=style_image,
    num_inference_steps=30
).images[0]
```

## Préprocesseurs

Tous les préprocesseurs disponibles :

```python
from controlnet_aux import (
    CannyDetector,           # Détection des contours
    HEDdetector,             # Contours doux/gribouillage
    MidasDetector,           # Estimation de profondeur
    OpenposeDetector,        # Pose humaine
    MLSDdetector,            # Détection de lignes
    LineartDetector,         # Art linéaire
    LineartAnimeDetector,    # Art linéaire anime
    NormalBaeDetector,       # Cartes de normales
    ContentShuffleDetector,  # Mélange du contenu
    ZoeDetector,             # Meilleure profondeur
    MediapipeFaceDetector,   # Maillage du visage
)

# Exemple d'utilisation
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)
```

## Poids de contrôle

Ajuster l'influence par ControlNet :

```python

# Contrôle total
output = pipe(..., controlnet_conditioning_scale=1.0)

# Contrôle partiel (plus de liberté créative)
output = pipe(..., controlnet_conditioning_scale=0.5)

# Guidage très léger
output = pipe(..., controlnet_conditioning_scale=0.3)
```

### Contrôle par étape

```python

# Contrôler uniquement pendant certaines étapes
output = pipe(
    prompt="...",
    image=control_image,
    controlnet_conditioning_scale=1.0,
    control_guidance_start=0.0,  # Commencer au début
    control_guidance_end=0.5,    # Arrêter à 50 % des étapes
    num_inference_steps=30
).images[0]
```

## Inpainting avec 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="une voiture de sport rouge",
    image=init_image,
    mask_image=mask,
    control_image=canny_image,
    num_inference_steps=30
).images[0]
```

## Traitement par lots

```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 = "peinture de paysage magnifique, détaillée, artistique"

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}"))
```

## Guide des types de contrôle

| Contrôle     | Idéal pour             | Atout   |
| ------------ | ---------------------- | ------- |
| Canny        | Architecture, objets   | 0.8-1.0 |
| Profondeur   | Scènes 3D, perspective | 0.6-0.8 |
| Pose         | Personnes, personnages | 0.8-1.0 |
| Gribouillage | Croquis, concepts      | 0.6-0.8 |
| Art linéaire | Illustrations          | 0.7-0.9 |
| Softedge     | Guidage général        | 0.5-0.7 |
| Seg          | Composition de scène   | 0.6-0.8 |

## Performances

| Configuration     | GPU      | Résolution | Temps |
| ----------------- | -------- | ---------- | ----- |
| CN unique SD1.5   | RTX 3090 | 512x512    | \~3 s |
| CN multiple SD1.5 | RTX 3090 | 512x512    | \~5 s |
| CN unique SDXL    | RTX 4090 | 1024x1024  | \~8 s |

## Optimisation de la mémoire

```python

# Activer l'attention économe en mémoire
pipe.enable_xformers_memory_efficient_attention()

# Déchargement sur CPU
pipe.enable_model_cpu_offload()

# Découpage de l'attention
pipe.enable_attention_slicing()
```

## Dépannage

### Effet de contrôle faible

* Augmentez `controlnet_conditioning_scale`
* Vérifier la qualité de la sortie du préprocesseur
* Utiliser une image de contrôle à plus haute résolution

### Artefacts

* Réduire l'échelle de contrôle
* Utiliser un préprocesseur plus doux (softedge vs canny)
* Ajouter un prompt négatif pour les artefacts

### Problèmes de VRAM

* Utiliser le déchargement CPU
* Réduire la résolution
* Utiliser un seul ControlNet à la fois

## Estimation des coûts

Tarifs typiques du marché CLORE.AI (en 2024) :

| GPU        | Tarif horaire | Tarif journalier | Session de 4 heures |
| ---------- | ------------- | ---------------- | ------------------- |
| 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 40 Go | \~$0.17       | \~$4.00          | \~$0.70             |
| A100 80 Go | \~$0.25       | \~$6.00          | \~$1.00             |

*Les prix varient selon le fournisseur et la demande. Vérifiez* [*la place de marché CLORE.AI*](https://clore.ai/marketplace) *les tarifs actuels.*

**Économisez de l'argent :**

* Utilisez le **Spot** marché pour les travaux interrompables — environ un tiers des serveurs ont un prix spot inférieur au tarif à la demande (médiane \~13 % de remise), les autres s'alignent dessus
* Payez avec **CLORE** jetons
* Comparez les prix entre différents fournisseurs

## Étapes suivantes

* Interface web Stable Diffusion
* Workflows ComfyUI
* [Entraînement Kohya](/guides/guides_v2-fr/entrainement/kohya-training.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-fr/traitement-dimages/controlnet-advanced.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
