Problemas con la VRAM baja: SDXL en un presupuesto
Ejecutar Stable Diffusion XL (SDXL) en su resolución prevista de 1024x1024 puede ser un verdadero dolor de cabeza si tiene poca VRAM. Olvídese de usar una tarjeta de 8 GB; incluso algunas tarjetas de 12 GB y 16 GB podrían tener problemas. El objetivo no es solo ejecutar SDXL, sino hacerlo de manera eficiente y sin sacrificar demasiada calidad. Esta guía proporciona técnicas para aprovechar al máximo su hardware.
Mis resultados de pruebas de laboratorio
Antes de entrar en detalles, veamos algunos números de referencia y luego veamos cómo las diferentes optimizaciones afectan el rendimiento. Ejecuté estas pruebas en mi plataforma de prueba (4090/24 GB), simulando entornos de VRAM más bajos limitando la memoria disponible.
Base (SDXL, 1024x1024, Atención estándar):** 28 s de renderizado, 21,5 GB de uso máximo de VRAM.
Decodificación VAE en mosaico (mosaicos de 512x512, superposición de 64 px):** 32 s de renderizado, 11 GB de uso máximo de VRAM.
SageAttention:* 35 s de renderizado, 16 GB de uso máximo de VRAM. Nota: Ligeros artefactos de textura visibles en CFG > 7.*
Intercambio de bloques (los primeros 3 bloques de transformador a la CPU):** 40 s de renderizado, 14 GB de uso máximo de VRAM.
VAE en mosaico + SageAttention + Intercambio de bloques:** 48 s de renderizado, 9 GB de uso máximo de VRAM.
Como puede ver, la combinación de estas técnicas nos permite reducir significativamente el uso de VRAM, aunque con una ligera penalización en el rendimiento. Exploremos cada técnica con más detalle.
Decodificación VAE en mosaico
La decodificación VAE en mosaico reduce significativamente el uso de VRAM al procesar la imagen en mosaicos más pequeños y volver a ensamblarlos. Las pruebas de la comunidad muestran que una superposición de 64 píxeles minimiza las uniones. Esto es particularmente efectivo en los flujos de trabajo Wan 2.2/LTX-2.**
La decodificación VAE en mosaico es un truco brillante para reducir drásticamente el uso de VRAM durante la fase de decodificación VAE. En lugar de decodificar la imagen completa a la vez, la divide en mosaicos más pequeños, decodifica cada mosaico individualmente y luego los vuelve a unir. El consenso de la comunidad sobre el tamaño de mosaico óptimo parece rondar los 512x512 píxeles con una superposición de 64 píxeles. Esta superposición ayuda a reducir las uniones entre los mosaicos. Herramientas como Promptus pueden simplificar la creación de prototipos de estos flujos de trabajo en mosaico.
Cómo funciona VAE en mosaico
ComfyUI le permite implementar la decodificación VAE en mosaico mediante el uso de los nodos VAEEncodeTiled y VAEDecodeTiled. Deberá ajustar los parámetros tile_size y overlap para ajustar el proceso para su hardware y resolución de imagen específicos.
Para implementar esto, deberá ajustar su flujo de trabajo para usar estos nodos en lugar de los nodos estándar VAEEncode y VAEDecode. El gráfico de nodos se verá así:
- Cargar VAE.
- Cargar imagen.
- Codificar imagen usando
VAEEncodeTiled(establecertile_sizeen 512 yoverlapen 64). - Muestrear usando KSampler.
- Decodificar usando
VAEDecodeTiled(establecertile_sizeen 512 yoverlapen 64). - Guardar imagen.
Análisis técnico
El VAE (Autoencoder Variacional) es responsable de comprimir y descomprimir los datos de la imagen. La fase de decodificación es particularmente intensiva en memoria. Al dividir la imagen en mosaicos, reducimos la cantidad de datos que deben procesarse en un momento dado, lo que reduce el requisito de VRAM. La superposición es crucial porque proporciona una zona de amortiguamiento que permite al decodificador combinar los mosaicos sin problemas, minimizando los artefactos.
SageAttention: Atención eficiente en memoria
SageAttention es un reemplazo eficiente en memoria para los mecanismos de atención estándar en KSamplers. Si bien ahorra VRAM, puede introducir artefactos de textura sutiles en escalas CFG más altas. Los usuarios de Promptus pueden experimentar fácilmente con los nodos SageAttention.**
Los mecanismos de atención estándar son conocidos por su consumo de VRAM. SageAttention ofrece una alternativa más eficiente en memoria. Sin embargo, no es una solución mágica. Es posible que note artefactos de textura sutiles, especialmente en escalas CFG más altas. Aún así, es una herramienta valiosa en su arsenal de VRAM baja. Los constructores que usan Promptus pueden iterar configuraciones de descarga más rápido.
Implementación de SageAttention
Para usar SageAttention, deberá instalar el nodo personalizado apropiado. Una vez instalado, puede reemplazar el mecanismo de atención estándar en su KSampler con la versión SageAttention. El nombre exacto del nodo puede variar según el nodo personalizado que esté utilizando, pero probablemente sea algo como KSampler (Sage).
El cambio del gráfico de nodos implica modificar el nodo KSampler. En lugar de usar el mecanismo de atención predeterminado dentro del KSampler, conectaría la salida de un nodo SageAttentionPatch a la entrada del modelo del KSampler. Esto reemplaza efectivamente la atención estándar con la implementación de SageAttention.
Análisis técnico
Los mecanismos de atención calculan las relaciones entre diferentes partes de la imagen. Esto requiere almacenar un gran "mapa de atención" en la memoria, lo que puede consumir rápidamente VRAM. SageAttention utiliza un algoritmo diferente que reduce el tamaño de este mapa de atención, lo que ahorra memoria. La desventaja es que la aproximación podría introducir algunas imprecisiones, lo que provocaría los artefactos de textura.
Intercambio de bloques/capas
El intercambio de bloques/capas reduce la VRAM al descargar las capas del modelo a la CPU durante el proceso de muestreo. Esto permite ejecutar modelos más grandes en tarjetas de 8 GB, pero ralentiza significativamente el proceso de generación. Intercambie los primeros 3 bloques de transformador a la CPU, mantenga el resto en la GPU.**
El intercambio de bloques implica descargar algunas de las capas del modelo a la CPU durante el proceso de muestreo. Esto libera VRAM pero tiene el costo de aumentar el tiempo de procesamiento, ya que los datos deben transferirse constantemente entre la CPU y la GPU.
Cómo funciona el intercambio de bloques
El método específico para el intercambio de bloques dependerá del nodo personalizado o el script que esté utilizando. La idea general es identificar los bloques de transformador que consumen más VRAM y moverlos a la CPU. Una estrategia común es intercambiar los primeros bloques de transformador (por ejemplo, los primeros 3) a la CPU mientras se mantiene el resto en la GPU.
El proceso a menudo implica modificar el modelo directamente usando código Python dentro de ComfyUI. Deberá identificar las capas específicas que desea mover y luego usar las funciones apropiadas para descargarlas.
Aquí hay un ejemplo conceptual (nota: esta es una ilustración simplificada y es posible que no se pueda ejecutar directamente):
python
Esto es solo ilustrativo: adáptelo a la configuración de su nodo específico
def swapblocks(model, blocksto_swap):
for i in range(blockstoswap):
model.model.diffusionmodel.transformerblocks[i].to("cpu")
def restoreblocks(model, blocksto_swap):
for i in range(blockstoswap):
model.model.diffusionmodel.transformerblocks[i].to("cuda") # or "mps"
Ejemplo de uso:
Suponiendo que 'model' es su modelo SDXL cargado
swap_blocks(model, 3)
... Ejecutar KSampler ...
restore_blocks(model, 3)
Importante: Este es un ejemplo simplificado.