Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"ControlNet","local":"controlnet","sections":[{"title":"Multi-ControlNet","local":"multi-controlnet","sections":[],"depth":2},{"title":"Mode de devinette","local":"guess-mode","sections":[],"depth":2}],"depth":1}"/> | |
| <link href="/docs/diffusers/main/en/_app/immutable/entry/start.0S0_iEoG.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/I9eooN77.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/Bupkjr9f.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/entry/app.CPdOxCbw.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/CyvZ3FS5.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/l0QnnOED.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/DnVIJfC5.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/DsnmJJEf.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/nodes/0.DteTvmQZ.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/CoSrdQax.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/nodes/391.CRavWgDP.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/DSPDl1gz.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/D5eijdnr.js" rel="modulepreload"> | |
| <!--18lijse--><meta name="hf:doc:metadata" content="{"title":"ControlNet","local":"controlnet","sections":[{"title":"Multi-ControlNet","local":"multi-controlnet","sections":[],"depth":2},{"title":"Guess mode","local":"guess-mode","sections":[],"depth":2}],"depth":1}"/><!----> | |
| <link href="/docs/diffusers/main/en/_app/immutable/assets/0.tn0RQdqM.css" rel="modulepreload"> <!--[--><!--[0--><!--[--><!--[0--><!--[--><p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: inline-end; margin-inline-start: 10px; display: inline-flex; position: relative; z-index: 10;"><div dir="ltr" class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----></span> <span dir="auto">Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg><!----></button></div> <!--[-1--><!--]--></div><!----> <!--[0--><h1 class="relative group"><a id="controlnet" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#controlnet"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->ControlNet<!----></span></h1><!--]--><!----> <p><a href="https://huggingface.co/papers/2302.05543" rel="nofollow">ControlNet</a> guide un modèle de diffusion préentraîné à l’aide d’une image de contrôle structurelle (contours, profondeur ou pose) tout en conservant un prompt texte. Il fige le modèle de base et ajoute un réseau parallèle dont les résidus orientent le débruiteur, offrant ainsi un contrôle de la mise en page sans réentraînement.</p> <p>Chargez un ControlNet adapté au contrôle dont vous avez besoin (par exemple canny), puis transmettez-le en tant que <code>controlnet=</code> à <a href="/docs/diffusers/main/fr/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained">from_pretrained()</a>. Utilisez <code>controlnet_conditioning_scale</code> pour définir l’intensité avec laquelle le contrôle oriente la génération.</p> <blockquote class="tip"><p>Les ControlNets sont disponibles pour de nombreux modèles tels que <a href="../api/pipelines/controlnet_flux">Flux</a>, <a href="../api/pipelines/controlnet_hunyuandit">Hunyuan-DiT</a>, <a href="../api/pipelines/controlnet_sd3">Stable Diffusion 3</a>, et d'autres. Les exemples de ce guide utilisent Flux et Stable Diffusion XL. Pour T2I-Adapter sur les anciens points de contrôle de la famille Stable Diffusion, consultez <a href="./legacy_adapters#t2i-adapter">Legacy adapters</a>. Privilégiez ControlNet pour les nouveaux travaux de génération contrôlable.</p></blockquote> <p>Les onglets ci-dessous présentent ControlNet pour la génération d'images à partir de texte, la transformation d'image en image et l'inpainting.</p> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><!--[--><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">texte-vers-image</div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">image-vers-image</div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">inpainting</div><!--]--></div> <div class="language-select"><div><p>Générer une image canny avec <a href="https://github.com/opencv/opencv-python" rel="nofollow">opencv-python</a>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> cv2 | |
| <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np | |
| <span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image | |
| <span class="hljs-keyword">from</span> diffusers.utils <span class="hljs-keyword">import</span> load_image | |
| original_image = load_image( | |
| <span class="hljs-string">"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png"</span> | |
| ) | |
| image = np.array(original_image) | |
| low_threshold = <span class="hljs-number">100</span> | |
| high_threshold = <span class="hljs-number">200</span> | |
| image = cv2.Canny(image, low_threshold, high_threshold) | |
| image = image[:, :, <span class="hljs-literal">None</span>] | |
| image = np.concatenate([image, image, image], axis=<span class="hljs-number">2</span>) | |
| canny_image = Image.fromarray(image)<!----></pre></div><!----> <p>Transmettez l’image canny au pipeline. Utilisez le paramètre <code>controlnet_conditioning_scale</code> pour déterminer le poids à accorder au contrôle.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> diffusers.utils <span class="hljs-keyword">import</span> load_image | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> FluxControlNetPipeline, FluxControlNetModel | |
| controlnet = FluxControlNetModel.from_pretrained( | |
| <span class="hljs-string">"InstantX/FLUX.1-dev-Controlnet-Canny"</span>, dtype=torch.bfloat16 | |
| ) | |
| pipeline = FluxControlNetPipeline.from_pretrained( | |
| <span class="hljs-string">"black-forest-labs/FLUX.1-dev"</span>, controlnet=controlnet, dtype=torch.bfloat16 | |
| ).to(<span class="hljs-string">"cuda"</span>) <span class="hljs-comment"># or "mps", "xpu", "cpu"</span> | |
| prompt = <span class="hljs-string">""" | |
| 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. | |
| """</span> | |
| pipeline( | |
| prompt, | |
| control_image=canny_image, | |
| controlnet_conditioning_scale=<span class="hljs-number">0.5</span>, | |
| num_inference_steps=<span class="hljs-number">50</span>, | |
| guidance_scale=<span class="hljs-number">3.5</span>, | |
| ).images[<span class="hljs-number">0</span>]<!----></pre></div><!----> <div style="display: flex; gap: 10px; justify-content: space-around; align-items: flex-end;"><figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" width="300" alt="Generated image (prompt only)"/> <figcaption style="text-align: center;">image d'origine</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat.png" width="300" alt="Control image (Canny edges)"/> <figcaption style="text-align: center;">image canny</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat-generated.png" width="300" alt="Generated image (ControlNet + prompt)"/> <figcaption style="text-align: center;">image générée</figcaption></figure></div><!----></div><!----> <div hidden=""><p>Générer une carte de profondeur avec un pipeline d'estimation de profondeur de Transformers.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np | |
| <span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image | |
| <span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> DPTImageProcessor, DPTForDepthEstimation | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> ControlNetModel, StableDiffusionXLControlNetImg2ImgPipeline, AutoencoderKL | |
| <span class="hljs-keyword">from</span> diffusers.utils <span class="hljs-keyword">import</span> load_image | |
| device = <span class="hljs-string">"cuda"</span> <span class="hljs-comment"># or "mps", "xpu", "cpu"</span> | |
| depth_estimator = DPTForDepthEstimation.from_pretrained(<span class="hljs-string">"Intel/dpt-hybrid-midas"</span>).to(device) | |
| feature_extractor = DPTImageProcessor.from_pretrained(<span class="hljs-string">"Intel/dpt-hybrid-midas"</span>) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_depth_map</span>(<span class="hljs-params">image</span>): | |
| image = feature_extractor(images=image, return_tensors=<span class="hljs-string">"pt"</span>).pixel_values.to(device) | |
| <span class="hljs-keyword">with</span> torch.no_grad(), torch.autocast(device): | |
| depth_map = depth_estimator(image).predicted_depth | |
| depth_map = torch.nn.functional.interpolate( | |
| depth_map.unsqueeze(<span class="hljs-number">1</span>), | |
| size=(<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>), | |
| mode=<span class="hljs-string">"bicubic"</span>, | |
| align_corners=<span class="hljs-literal">False</span>, | |
| ) | |
| depth_min = torch.amin(depth_map, dim=[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>], keepdim=<span class="hljs-literal">True</span>) | |
| depth_max = torch.amax(depth_map, dim=[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>], keepdim=<span class="hljs-literal">True</span>) | |
| depth_map = (depth_map - depth_min) / (depth_max - depth_min) | |
| image = torch.cat([depth_map] * <span class="hljs-number">3</span>, dim=<span class="hljs-number">1</span>) | |
| image = image.permute(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>).cpu().numpy()[<span class="hljs-number">0</span>] | |
| image = Image.fromarray((image * <span class="hljs-number">255.0</span>).clip(<span class="hljs-number">0</span>, <span class="hljs-number">255</span>).astype(np.uint8)) | |
| <span class="hljs-keyword">return</span> image | |
| image = load_image( | |
| <span class="hljs-string">"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png"</span> | |
| ).resize((<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>)) | |
| depth_image = get_depth_map(image)<!----></pre></div><!----> <p>Transmettez la carte de profondeur au pipeline. Utilisez le paramètre <code>controlnet_conditioning_scale</code> pour déterminer le poids à accorder au contrôle.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!---->controlnet = ControlNetModel.from_pretrained( | |
| <span class="hljs-string">"diffusers/controlnet-depth-sdxl-1.0-small"</span>, | |
| dtype=torch.float16, | |
| ) | |
| vae = AutoencoderKL.from_pretrained(<span class="hljs-string">"madebyollin/sdxl-vae-fp16-fix"</span>, dtype=torch.float16) | |
| pipeline = StableDiffusionXLControlNetImg2ImgPipeline.from_pretrained( | |
| <span class="hljs-string">"stabilityai/stable-diffusion-xl-base-1.0"</span>, | |
| controlnet=controlnet, | |
| vae=vae, | |
| dtype=torch.float16, | |
| ).to(device) | |
| prompt = <span class="hljs-string">""" | |
| 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. | |
| """</span> | |
| controlnet_conditioning_scale = <span class="hljs-number">0.5</span> | |
| pipeline( | |
| prompt, | |
| image=image, | |
| control_image=depth_image, | |
| controlnet_conditioning_scale=controlnet_conditioning_scale, | |
| strength=<span class="hljs-number">0.99</span>, | |
| num_inference_steps=<span class="hljs-number">100</span>, | |
| ).images[<span class="hljs-number">0</span>]<!----></pre></div><!----> <div style="display: flex; gap: 10px; justify-content: space-around; align-items: flex-end;"><figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" width="300" alt="Generated image (prompt only)"/> <figcaption style="text-align: center;">image d'origine</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl_depth_image.png" width="300" alt="Depth map"/> <figcaption style="text-align: center;">carte de profondeur</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl_depth_cat.png" width="300" alt="Generated image (ControlNet + prompt)"/> <figcaption style="text-align: center;">image générée</figcaption></figure></div><!----></div><!----> <div hidden=""><p>Générez une image de masque qui indique quels pixels remplacer, puis transmettez-la en tant que <code>mask_image</code> avec l'image de contrôle.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> cv2 | |
| <span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np | |
| <span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image | |
| <span class="hljs-keyword">from</span> diffusers.utils <span class="hljs-keyword">import</span> load_image | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> StableDiffusionXLControlNetInpaintPipeline, ControlNetModel | |
| init_image = load_image( | |
| <span class="hljs-string">"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png"</span> | |
| ) | |
| init_image = init_image.resize((<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>)) | |
| mask_image = load_image( | |
| <span class="hljs-string">"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat_mask.png"</span> | |
| ) | |
| mask_image = mask_image.resize((<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>)) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">make_canny_condition</span>(<span class="hljs-params">image</span>): | |
| image = np.array(image) | |
| image = cv2.Canny(image, <span class="hljs-number">100</span>, <span class="hljs-number">200</span>) | |
| image = image[:, :, <span class="hljs-literal">None</span>] | |
| image = np.concatenate([image, image, image], axis=<span class="hljs-number">2</span>) | |
| image = Image.fromarray(image) | |
| <span class="hljs-keyword">return</span> image | |
| control_image = make_canny_condition(init_image)<!----></pre></div><!----> <p>Transmettez le masque et l’image de contrôle au pipeline. Utilisez le paramètre <code>controlnet_conditioning_scale</code> pour déterminer le poids à accorder au contrôle.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!---->controlnet = ControlNetModel.from_pretrained( | |
| <span class="hljs-string">"diffusers/controlnet-canny-sdxl-1.0"</span>, dtype=torch.float16 | |
| ) | |
| pipeline = StableDiffusionXLControlNetInpaintPipeline.from_pretrained( | |
| <span class="hljs-string">"stabilityai/stable-diffusion-xl-base-1.0"</span>, controlnet=controlnet, dtype=torch.float16 | |
| ).to(<span class="hljs-string">"cuda"</span>) <span class="hljs-comment"># or "mps", "xpu", "cpu"</span> | |
| pipeline( | |
| <span class="hljs-string">"a cute and fluffy bunny rabbit"</span>, | |
| num_inference_steps=<span class="hljs-number">100</span>, | |
| strength=<span class="hljs-number">0.99</span>, | |
| controlnet_conditioning_scale=<span class="hljs-number">0.5</span>, | |
| image=init_image, | |
| mask_image=mask_image, | |
| control_image=control_image, | |
| ).images[<span class="hljs-number">0</span>]<!----></pre></div><!----> <div style="display: flex; gap: 10px; justify-content: space-around; align-items: flex-end;"><figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" width="300" alt="Generated image (prompt only)"/> <figcaption style="text-align: center;">image d'origine</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat_mask.png" width="300" alt="Mask image"/> <figcaption style="text-align: center;">masque d'image</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl_rabbit_inpaint.png" width="300" alt="Generated image (ControlNet + prompt)"/> <figcaption style="text-align: center;">image générée</figcaption></figure></div><!----></div><!----><!----></div><!----> <!--[1--><h2 class="relative group"><a id="multi-controlnet" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#multi-controlnet"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Multi-ControlNet<!----></span></h2><!--]--><!----> <p>Composez plusieurs ControlNets (par exemple canny + depth) en les passant sous forme de liste. Masquez les régions qui se chevauchent lorsque c’est possible, et ajustez chaque <code>controlnet_conditioning_scale</code>. Construisez <code>canny_image</code> avec OpenCV Canny (comme pour le texte-vers-image) et <code>depth_image</code> avec DPT (comme pour l’image-vers-image). Redimensionnez chaque image de contrôle à la taille du pipeline avant d’appeler le pipeline.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> cv2 | |
| <span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np | |
| <span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image | |
| <span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> DPTImageProcessor, DPTForDepthEstimation | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> StableDiffusionXLControlNetPipeline, ControlNetModel, AutoencoderKL | |
| <span class="hljs-keyword">from</span> diffusers.utils <span class="hljs-keyword">import</span> load_image | |
| original_image = load_image( | |
| <span class="hljs-string">"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png"</span> | |
| ) | |
| image = np.array(original_image) | |
| canny_image = Image.fromarray( | |
| np.concatenate([cv2.Canny(image, <span class="hljs-number">100</span>, <span class="hljs-number">200</span>)[:, :, <span class="hljs-literal">None</span>]] * <span class="hljs-number">3</span>, axis=<span class="hljs-number">2</span>) | |
| ) | |
| device = <span class="hljs-string">"cuda"</span> <span class="hljs-comment"># or "mps", "xpu", "cpu"</span> | |
| depth_estimator = DPTForDepthEstimation.from_pretrained(<span class="hljs-string">"Intel/dpt-hybrid-midas"</span>).to(device) | |
| feature_extractor = DPTImageProcessor.from_pretrained(<span class="hljs-string">"Intel/dpt-hybrid-midas"</span>) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_depth_map</span>(<span class="hljs-params">image</span>): | |
| image = feature_extractor(images=image, return_tensors=<span class="hljs-string">"pt"</span>).pixel_values.to(device) | |
| <span class="hljs-keyword">with</span> torch.no_grad(), torch.autocast(device): | |
| depth_map = depth_estimator(image).predicted_depth | |
| depth_map = torch.nn.functional.interpolate( | |
| depth_map.unsqueeze(<span class="hljs-number">1</span>), | |
| size=(<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>), | |
| mode=<span class="hljs-string">"bicubic"</span>, | |
| align_corners=<span class="hljs-literal">False</span>, | |
| ) | |
| depth_min = torch.amin(depth_map, dim=[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>], keepdim=<span class="hljs-literal">True</span>) | |
| depth_max = torch.amax(depth_map, dim=[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>], keepdim=<span class="hljs-literal">True</span>) | |
| depth_map = (depth_map - depth_min) / (depth_max - depth_min) | |
| image = torch.cat([depth_map] * <span class="hljs-number">3</span>, dim=<span class="hljs-number">1</span>) | |
| image = image.permute(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>).cpu().numpy()[<span class="hljs-number">0</span>] | |
| image = Image.fromarray((image * <span class="hljs-number">255.0</span>).clip(<span class="hljs-number">0</span>, <span class="hljs-number">255</span>).astype(np.uint8)) | |
| <span class="hljs-keyword">return</span> image | |
| depth_image = get_depth_map(original_image.resize((<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>))) | |
| controlnets = [ | |
| ControlNetModel.from_pretrained( | |
| <span class="hljs-string">"diffusers/controlnet-canny-sdxl-1.0"</span>, dtype=torch.float16 | |
| ), | |
| ControlNetModel.from_pretrained( | |
| <span class="hljs-string">"diffusers/controlnet-depth-sdxl-1.0-small"</span>, dtype=torch.float16 | |
| ), | |
| ] | |
| vae = AutoencoderKL.from_pretrained(<span class="hljs-string">"madebyollin/sdxl-vae-fp16-fix"</span>, dtype=torch.float16) | |
| pipeline = StableDiffusionXLControlNetPipeline.from_pretrained( | |
| <span class="hljs-string">"stabilityai/stable-diffusion-xl-base-1.0"</span>, controlnet=controlnets, vae=vae, dtype=torch.float16 | |
| ).to(device) | |
| prompt = <span class="hljs-string">""" | |
| 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 | |
| """</span> | |
| negative_prompt = <span class="hljs-string">"lowres, bad anatomy, worst quality, low quality, deformed, ugly"</span> | |
| images = [canny_image.resize((<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>)), depth_image.resize((<span class="hljs-number">1024</span>, <span class="hljs-number">1024</span>))] | |
| pipeline( | |
| prompt, | |
| negative_prompt=negative_prompt, | |
| image=images, | |
| num_inference_steps=<span class="hljs-number">100</span>, | |
| controlnet_conditioning_scale=[<span class="hljs-number">0.5</span>, <span class="hljs-number">0.5</span>], | |
| ).images[<span class="hljs-number">0</span>]<!----></pre></div><!----> <div style="display: flex; gap: 10px; justify-content: space-around; align-items: flex-end;"><figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat.png" width="300" alt="Canny image"/> <figcaption style="text-align: center;">image canny</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/multicontrolnet_depth.png" width="300" alt="Depth map"/> <figcaption style="text-align: center;">carte de profondeur</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl_multi_controlnet.png" width="300" alt="Generated image (ControlNet + prompt)"/> <figcaption style="text-align: center;">image générée</figcaption></figure></div> <!--[1--><h2 class="relative group"><a id="guess-mode" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#guess-mode"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Mode de devinette<!----></span></h2><!--]--><!----> <p><a href="https://github.com/lllyasviel/ControlNet/discussions/188" rel="nofollow">Le mode Guess</a> génère une image à partir d’un seul contrôle lorsque vous n’avez pas (ou ne souhaitez pas) de prompt texte. Il met à l’échelle les résidus de ControlNet en fonction de la profondeur des blocs, passant d’environ <code>0.1</code> dans les blocs de descente initiaux jusqu’à <code>1.0</code> au niveau du bloc intermédiaire. Cela empêche les couches initiales de sur-contraindre, tout en permettant aux blocs plus profonds de conserver la structure.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copié</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> diffusers.utils <span class="hljs-keyword">import</span> load_image | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> StableDiffusionXLControlNetPipeline, ControlNetModel | |
| controlnet = ControlNetModel.from_pretrained( | |
| <span class="hljs-string">"diffusers/controlnet-canny-sdxl-1.0"</span>, dtype=torch.float16 | |
| ) | |
| pipeline = StableDiffusionXLControlNetPipeline.from_pretrained( | |
| <span class="hljs-string">"stabilityai/stable-diffusion-xl-base-1.0"</span>, | |
| controlnet=controlnet, | |
| dtype=torch.float16 | |
| ).to(<span class="hljs-string">"cuda"</span>) <span class="hljs-comment"># or "mps", "xpu", "cpu"</span> | |
| canny_image = load_image(<span class="hljs-string">"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat.png"</span>) | |
| pipeline( | |
| <span class="hljs-string">""</span>, | |
| image=canny_image, | |
| guess_mode=<span class="hljs-literal">True</span> | |
| ).images[<span class="hljs-number">0</span>]<!----></pre></div><!----> <div style="display: flex; gap: 10px; justify-content: space-around; align-items: flex-end;"><figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat.png" width="300" alt="Canny image"/> <figcaption style="text-align: center;">image canny</figcaption></figure> <figure><img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/guess_mode.png" width="300" alt="Generated image (Guess mode)"/> <figcaption style="text-align: center;">image générée</figcaption></figure></div> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/diffusers/blob/main/docs/source/en/using-diffusers/controlnet.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg><!----> <span><span class="underline">Update</span> on GitHub</span></a><!----> <p></p><!--]--><!----><!--]--><!--]--><!--]--> <!--[-1--><!--]--><!--]--> | |
| <script> | |
| { | |
| __sveltekit_1qsdbwf = { | |
| base: "/docs/diffusers/main/en", | |
| assets: "/docs/diffusers/main/en" | |
| }; | |
| const element = document.currentScript.parentElement; | |
| Promise.all([ | |
| import("/docs/diffusers/main/en/_app/immutable/entry/start.0S0_iEoG.js"), | |
| import("/docs/diffusers/main/en/_app/immutable/entry/app.CPdOxCbw.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 391], | |
| data: [null,null], | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 42.6 kB
- Xet hash:
- d06253fa6f730b054e3ce0629130ed2ebe4b7108b11ac339490050f52943bce1
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.