1 puntos por GN⁺ 2023-12-25 | 1 comentarios | Compartir por WhatsApp
  • StreamDiffusion es un pipeline que mejora la generación de imágenes basada en difusión para adaptarla a la generación interactiva en tiempo real, con el objetivo de mejorar el rendimiento de las técnicas existentes de generación de imágenes por difusión
  • Sus funciones principales incluyen Stream Batch, Residual Classifier-Free Guidance, Stochastic Similarity Filter, IO Queues, precálculo de KV-cache y herramientas de aceleración de modelos
  • En un entorno con RTX 4090, Core i9-13900K y Ubuntu 22.04.3 LTS, SD-turbo registró Txt2Img 106.16fps e Img2Img 93.897fps con 1 denoising step
  • Las demos en tiempo real están en demo/realtime-txt2img y demo/realtime-img2img, y la demo de Img2Img usa feed en vivo de la webcam o captura de pantalla desde el navegador web
  • Se usa envolviendo StableDiffusionPipeline de Diffusers, y puede configurarse para una ejecución más rápida mediante fusión de LCM-LoRA, Tiny VAE, xformers y aceleración con TensorRT

Objetivo y rendimiento de StreamDiffusion

  • StreamDiffusion es un pipeline de difusión para generación interactiva en tiempo real
  • Su objetivo es ofrecer mejoras de rendimiento para las técnicas actuales de generación de imágenes basadas en difusión
  • El paper está enlazado en arXiv 2312.12491 y Hugging Face Papers
  • El entorno de medición de rendimiento para la generación de imágenes con el pipeline propuesto es el siguiente
    • GPU: RTX 4090
    • CPU: Core i9-13900K
    • OS: Ubuntu 22.04.3 LTS
  • Tabla de rendimiento
    • SD-turbo: denoising step 1, Txt2Img 106.16fps, Img2Img 93.897fps
    • LCM-LoRA + KohakuV2: denoising step 4, Txt2Img 38.023fps, Img2Img 37.133fps

Funciones principales

  • Stream Batch

    • Simplifica el procesamiento de datos mediante operaciones de batch eficientes
  • Residual Classifier-Free Guidance

    • Es un mecanismo de guidance mejorado que reduce la duplicación de cálculo
  • Stochastic Similarity Filter

    • Es una técnica avanzada de filtrado que mejora la eficiencia de uso de la GPU
  • IO Queues

    • Gestiona de forma eficiente las tareas de entrada y salida para lograr una ejecución más fluida
  • Pre-Computation for KV-Caches

    • Optimiza la estrategia de caché para aumentar la velocidad de procesamiento
  • Model Acceleration Tools

    • Usa varias herramientas para optimización del modelo y mejora de rendimiento

Instalación y forma de ejecución

  • StreamDiffusion puede instalarse con pip, conda o Docker
  • Los ejemplos de entorno Python recomendados se basan en un entorno conda con python=3.10 o en venv
  • Los ejemplos de instalación de PyTorch distinguen entre CUDA 11.8 y CUDA 12.1
    • CUDA 11.8: torch==2.1.0, torchvision==0.16.0, xformers
    • CUDA 12.1: torch==2.1.0, torchvision==0.16.0, xformers
  • Métodos de instalación para usuarios
  • En Windows, si se instaló la versión estable, puede ser necesario instalar adicionalmente pywin32
  • La instalación con Docker está orientada a entornos preparados para TensorRT y se ejecuta con la opción --gpus all después de docker build

Demos y ejemplos de uso

  • Los ejemplos pueden ejecutarse desde el directorio examples
  • La demo de Txt2Img en tiempo real está en el directorio demo/realtime-txt2img
  • La demo de Img2Img en tiempo real está en el directorio demo/realtime-img2img
    • Se puede usar feed en vivo de la webcam o captura de pantalla desde el navegador web
  • El flujo de uso básico consiste en cargar StableDiffusionPipeline de Diffusers y luego envolverlo con StreamDiffusion
  • El ejemplo de Img2Img carga el modelo KBlueLeaf/kohaku-v2.1 y configura el stream con t_index_list=[32, 45]
    • Si el modelo no es LCM, se usan load_lcm_lora() y fuse_lora()
    • Para aceleración adicional, se usa Tiny VAE de madebyollin/taesd
    • Se activa la atención eficiente en memoria de xformers con enable_xformers_memory_efficient_attention()
  • El ejemplo de Txt2Img usa t_index_list=[0, 16, 32, 45] y, para texto a imagen, se recomienda cfg_type="none"
  • La cantidad de warmup debe ser al menos len(t_index_list) x frame_buffer_size

Aceleración con TensorRT

  • Para una generación más rápida, el código para activar xformers puede reemplazarse por código de aceleración con TensorRT
  • Se usa accelerate_with_tensorrt de streamdiffusion.acceleration.tensorrt
  • La configuración de ejemplo pasa stream, "engines" y max_batch_size=2
  • Se requiere la extensión de TensorRT, y la construcción del engine toma tiempo
  • Después de construir el engine, la ejecución es más rápida que en los ejemplos anteriores

Stochastic Similarity Filter

  • Stochastic Similarity Filter reduce el trabajo de transformación en entradas de video cuando hay pocos cambios respecto al frame anterior
  • Al reducir ese trabajo de transformación, alivia la carga de procesamiento de la GPU
  • Se usa llamando a stream.enable_similar_image_filter()
  • Argumentos configurables
    • similar_image_filter_threshold: umbral de similitud entre el frame anterior y el actual antes de pausar el procesamiento
    • similar_image_filter_max_skip_frame: intervalo máximo permitido durante la pausa antes de reanudar la transformación

Residual CFG

  • RCFG es una forma de aproximar CFG con una complejidad computacional comparable a cuando no se usa CFG
  • Puede especificarse con el argumento cfg_type de StreamDiffusion
  • Hay dos tipos de RCFG
    • RCFG Self-Negative: método sin elemento de negative prompt especificado
    • RCFG Onetime-Negative: método que permite especificar un negative prompt
  • Comparación de complejidad computacional
    • Sin CFG: N
    • CFG normal: 2N
    • RCFG Self-Negative: N
    • RCFG Onetime-Negative: N+1
  • Los valores de cfg_type son los siguientes
    • Sin CFG: "none"
    • CFG normal: "full"
    • RCFG Self-Negative: "self"
    • RCFG Onetime-Negative: "initialize"
  • delta tiene un efecto de mitigación para ajustar el efecto de RCFG

Modelos y recursos usados

1 comentarios

 
GN⁺ 2023-12-25
Comentarios en Hacker News
  • El paper de arXiv está aquí: https://arxiv.org/abs/2312.12491
    Parece que se podría hacer aún más rápido que la medición base en una 4090. Con SDXL Turbo llegó hasta 10 fps en una sola iteración incluso sin optimización.
    Aun así, mejoras como un filtro de similitud probabilística para evitar generaciones innecesarias parecen útiles para obtener resultados rápidos sin mantener la GPU siempre al 100%

  • Es tan impresionante que casi no parece real. Se siente como si 10 años hubieran pasado en 1 año.

    • Si esto llega a poder reemplazar mi trabajo, estoy esperando poder correrlo en mi PC y conectarlo a Slack. Así mi empleador recibiría resultados parecidos a los que obtendría si yo lo hiciera a mano, yo podría seguir cobrando sin gastar tiempo realmente trabajando y por fin concentrarme en mis hobbies. ¿Al final así es como termina todo, no?
    • Así se siente ahora mismo todo el ecosistema de IA open source. Casi todos los días sale un avance nuevo que hace posible algo que se consideraba imposible, y de verdad cuesta muchísimo seguirle el ritmo a todos estos cambios.
    • Como desarrollador frontend, ahora entiendo a la gente que se quejaba de que el mundo frontend cambiaba demasiado rápido como para mantenerse al día.
    • Este software evoluciona más rápido de lo que yo tardo en hacer apt-get install.
    • Me recuerda a los juegos incrementales (https://www.reddit.com/r/incremental_games/). Aunque mejor no empezar con esos juegos; te pueden arruinar las vacaciones.
  • Acabo de probar la demo de realtime-text2img, y usar npm en el frontend me parece excesivo para este caso de uso. La cambié para que genere solo 1 imagen en lugar de 16, y funciona bien incluso en una laptop RTX-3080. Parece que da unas 2 imágenes por segundo.
    Edit: la demo examples\screen se siente casi en tiempo real. En la ventana aparece 4 fps, pero no sé exactamente qué significa.
    Edit: eso sí, la fuerza de denoising en img2img es muy baja, así que la imagen que devuelve difiere muy poco de la original.

    • Me da curiosidad cómo serán la calidad real, la diversidad y la fidelidad al prompt. Llevo unos días sin poder usar la GPU, así que no puedo comprobarlo por mi cuenta.
      Con papers de modelos generativos siempre es difícil juzgar antes de correrlos uno mismo. Como hay que mostrárselos a los reviewers, no queda otra que incluir resultados seleccionados. No digo que eso esté bien, pero así son las cosas ahora.
      ¿Aquí usan un autoencoder pequeño? Artspew también hizo eso y obtuvo más FPS, pero sin usar TensorRT, sí usando Triton, y la calidad era terrible. Aun así estaba cool.
      En cualquier caso, aunque la calidad real quede muy por debajo de lo que muestran, sigue siendo impresionante, pero en la práctica es difícil saberlo.
  • Me pregunto si 100 fps significa que puedes meter una entrada nueva cada 10 ms y recibir una salida nueva cada 10 ms. ¿O hace falta agrupar entradas en batch para obtener ese throughput promedio?

    • No lo he probado directamente, pero por intuición diría que no haría falta procesamiento por lotes.
      La parte lenta del modelo es cargarlo. Una vez que el modelo ya está levantado, deberías poder enviarle la entrada que quieras.
      No me da la impresión de que parsear y enviar los datos de imagen vaya a ser el cuello de botella aquí.
  • Funcionó casi exactamente como decía la documentación. En la mayoría de estas demos algo se rompe y te lanza algún error profundo y rarísimo, pero esta salió bien.
    Está bien hecho. Vale la pena probarlo. Si quieres generar algo que no sea estilo anime, puedes cambiar el modelo en server.py de realtime-txt2img. Por ejemplo, también funciona bien si apuntas a https://huggingface.co/runwayml/stable-diffusion-v1-5.
    Los resultados sí son realmente rápidos. No son increíbles, pero son rápidos. Si cambias a SDXL mediante LCM-LoRA https://huggingface.co/latent-consistency tal vez obtengas mejores resultados, pero desde ahí ya se complica y empiezas a encontrarte con esos crashes crípticos que mencioné antes. Ese es el punto donde ya hace falta trabajo real.
    Mi entorno es 4090/3990x/CUDA 12.2/debian sid, pero eso puede variar según el entorno.

  • ¿Cómo funciona la demo donde el personaje femenino se mueve dentro y fuera del cuadro? ¿Es ControlNet?

    • Es entrada de video. Según el post, el filtro de similitud probabilística reduce el trabajo de transformación cuando en la entrada de video hay pocos cambios respecto al frame anterior, bajando así la carga de procesamiento de la GPU. Los cuadros rojos del GIF de arriba son un ejemplo de eso.
    • Hay un issue abierto en GitHub para agregar soporte de ControlNet, así que parece que no es ControlNet. Más bien se ve como img2img usando solo prompt y escala rcfg.
    • Entonces, ¿eso significa que la izquierda es la imagen original y la derecha es la imagen resultante?
  • ¿Qué tal los fps en Apple Silicon?

    • Como no hay soporte para MPS, es 0.
      Aun así, por unos 1,800 dólares al precio actual de reacondicionado en la misma gama, un Studio con M1 Max de 64 GB es aproximadamente 13 veces más lento que una RTX 4090 de 24 GB en IA generativa con SD1.5 y SDXL.
    • Estoy corriendo SDXL Turbo en DrawThings con un M1 Pro y 32 GB de RAM.
      Una imagen de 512x512 y 5 pasos se genera en 5 segundos. No uso refiner, upscaler ni restauración facial.
      Hasta donde sé, DrawThings todavía no está optimizado para SDXL Turbo ni para generación por pipeline.
      Como referencia, si genero una imagen de 2k x 2k y 50 pasos con SDXL Base+Refiner y restauración facial activada, tarda unos 120 segundos.
    • Yo diría que por lo menos podría llegar a 1/8 de eso, pero si Apple lograra mover esto a al menos 24 fps sería enorme. Quizá con algo de interpolación hasta se podría.
      Sobre todo en estilo animado, donde de por sí muchas veces se dibuja un cuadro cada 2 frames, así que hasta 12 fps podría ser suficiente.
  • ¿Hay algún video en algún lado donde se pueda ver?