En este tutorial, diseñamos un flujo de trabajo práctico de generación de imágenes utilizando la biblioteca Difusores. Comenzamos estabilizando el entorno y luego generamos imágenes de alta calidad a partir de mensajes de texto utilizando Stable Diffusion con un programador optimizado. Aceleramos la inferencia con un enfoque de consistencia latente basado en LoRA, guiamos la composición con ControlNet bajo acondicionamiento de bordes y, finalmente, realizamos ediciones localizadas mediante pintura interna. Además, nos centramos en técnicas del mundo real que equilibran la calidad de la imagen, la velocidad y la controlabilidad.
Preparamos un tiempo de ejecución limpio y compatible resolviendo conflictos de dependencia e instalando todas las bibliotecas necesarias. Nos aseguramos de que el procesamiento de imágenes funcione de manera confiable fijando la versión correcta de Pillow y cargando el ecosistema de Difusores. También importamos todos los módulos principales necesarios para los flujos de trabajo de generación, control y pintura.
w, h = imágenes[0].size filas = math.ceil(len(images) / cols) grid = Image.new(“RGB”, (cols*w, filas*h), (bg, bg, bg)) for i, estoy en enumerate(images): grid.paste(im, ((i % cols)*w, (i // cols)*h)) return grid dispositivo = “cuda” if torch.cuda.is_available() else “cpu” dtype = torch.float16 if dispositivo == “cuda” else torch.float32 print(“dispositivo:”, dispositivo, “| dtype:”, dtype)
Definimos funciones de utilidad para garantizar la reproducibilidad y organizar los resultados visuales de manera eficiente. Establecemos semillas aleatorias globales para que nuestras generaciones sigan siendo consistentes en todas las ejecuciones. También detectamos el hardware disponible y configuramos la precisión para optimizar el rendimiento en la GPU o CPU.
Inicializamos el proceso base de Difusión Estable y cambiamos a un programador UniPC más eficiente. Generamos una imagen de alta calidad directamente a partir de un mensaje de texto utilizando configuraciones de resolución y orientación cuidadosamente elegidas. Esto establece una base sólida para mejoras posteriores en velocidad y control.
para pasos en [4, 6, 8]: fast_images.append( pipe( aviso=prompt_rápido, aviso_negativo=prompt_negativo, num_inference_steps=pasos, guiado_escala=1.5, ancho=768, alto=512, ).images[0]
) grid_fast = to_grid(fast_images, cols=3) print(“LoRA fusionado:”, lora_fused) An, Al = 768, 512 diseño = Imagen.new(“RGB”, (An, Al), “blanco”) dibujar = ImageDraw.Draw(diseño) dibujar.rectangle([40, 80, 340, 460]contorno=”negro”, ancho=6) draw.ellipse([430, 110, 720, 400]contorno=”negro”, ancho=6) draw.line([0, 420, W, 420]fill=”negro”, ancho=5) bordes = cv2.Canny(np.array(layout), 80, 160) bordes = np.stack([edges]*3, eje=-1) canny_image = Image.fromarray(edges) CONTROLNET = “lllyasviel/sd-controlnet-canny” controlnet = ControlNetModel.from_pretrained( CONTROLNET, torch_dtype=dtype, ).to(dispositivo) cn_pipe = StableDiffusionControlNetPipeline.from_pretrained( BASE_MODEL, controlnet=controlnet, torch_dtype=dtype, safety_checker=None, ).to(device) cn_pipe.scheduler = UniPCMultistepScheduler.from_config(cn_pipe.scheduler.config) if device == “cuda”: cn_pipe.enable_attention_slicing() cn_pipe.enable_vae_slicing() cn_prompt = “el interior de una cafetería moderna, representación arquitectónica, luz natural suave, gran nivel de detalle” img_controlnet = cn_pipe( solicitud=cn_prompt, negativa_prompt=negativa_prompt, imagen=canny_image, num_inference_steps=25, guiado_escala=6.5, controlnet_conditioning_scale=1.0, ).images[0]
Aceleramos la inferencia cargando y fusionando un adaptador LoRA y demostramos un muestreo rápido con muy pocos pasos de difusión. Luego construimos una imagen de acondicionamiento estructural y aplicamos ControlNet para guiar el diseño de la escena generada. Esto nos permite preservar la composición y al mismo tiempo beneficiarnos de la guía creativa del texto.
os.makedirs(“salidas”, exist_ok=True) img_text.save(“salidas/text2img.png”) grid_fast.save(“salidas/lora_fast_grid.png”) layout.save(“salidas/layout.png”) canny_image.save(“salidas/canny.png”) img_controlnet.save(“salidas/controlnet.png”) mask.save(“salidas/mask.png”) img_inpaint.save(“salidas/inpaint.png”) print(“Salidas guardadas:”, sorted(os.listdir(“salidas”))) print(“Listo.”)
Creamos una máscara para aislar una región específica y aplicamos pintura para modificar solo esa parte de la imagen. Refinamos el área seleccionada utilizando un mensaje específico mientras mantenemos el resto intacto. Finalmente, guardamos todos los resultados intermedios y finales en el disco para su inspección y reutilización.
En conclusión, demostramos cómo un único proceso de Difusores puede evolucionar hasta convertirse en un sistema de generación de imágenes flexible y listo para producción. Explicamos cómo pasar de la generación pura de texto a imagen al muestreo rápido, el control estructural y la edición de imágenes dirigida sin cambiar los marcos ni las herramientas. Este tutorial destaca cómo podemos combinar programadores, adaptadores LoRA, ControlNet e inpainting para crear canalizaciones generativas controlables y eficientes que sean fáciles de ampliar para casos de uso creativos o aplicados más avanzados.
Consulte los códigos completos aquí. Además, no dude en seguirnos en Twitter y no olvide unirse a nuestro SubReddit de más de 100.000 ML y suscribirse a nuestro boletín. ¡Esperar! estas en telegrama? Ahora también puedes unirte a nosotros en Telegram.