Cómo funcionan los LoRA y cómo usarlos en Stable Diffusion
Entiende LoRA: cambios de peso en inferencia, fuerza, apilamiento de adaptadores, modelos base y cómo instalarlos.
On this page
Cómo funcionan los LoRA y cómo usarlos en Stable Diffusion
Un LoRA (Low-Rank Adaptation) es un parche pequeño que modifica los modelos de Stable Diffusion sin reemplazarlos. En lugar de descargar un checkpoint completamente nuevo, cargas un archivo LoRA que inyecta ajustes entrenables en capas específicas. Este artículo explica la matemática detrás de los LoRA, cómo controlar su fuerza y cómo hacerlos coincidir con tu modelo base.
Para una guía práctica sobre preparar tu primer dataset y entrenar, consulta nuestro tutorial entrena tu primer LoRA gratis. Si estás construyendo una biblioteca de estilos, nuestra guía gestión de biblioteca de LoRA cubre organización y versionado. Para consejos específicos de SDXL, consulta consejos de LoRA fotorrealista para SDXL.
TL;DR
- Matemática: La fórmula clave es $h = W_0 x + BAx$, donde $W_0$ es el peso original congelado y $BA$ es la actualización entrenable
- Control de fuerza: El peso en inferencia (p. ej.,
<lora:model:0.7>) controla el efecto del LoRA - Apilamiento: Múltiples LoRA suman sus efectos (encadena nodos de ComfyUI o usa
set_adaptersen Diffusers) - Compatibilidad: Haz coincidir la arquitectura del LoRA con las dimensiones del modelo base (SDXL vs SD1.5)
- Instalación:
models/loras/para ComfyUI,models/Lora/para AUTOMATIC1111
Cómo funciona LoRA en tiempo de inferencia
El fundamento matemático
Cuando cargas un LoRA, no reemplazas los pesos del modelo base. Les añades pequeños ajustes entrenables.
La actualización sigue una fórmula simple:
$$h = W_0 x + BAx$$
Cada término:
- $W_0$: La matriz de pesos original de tu modelo base. Permanece congelada—nunca cambia durante el entrenamiento ni la inferencia.
- $x$: Activaciones de entrada (de los embeddings de texto o de capas intermedias).
- $B$: Primera matriz de bajo rango. Forma: dimensión de salida × rango (p. ej., dmodel × r).
- $A$: Segunda matriz de bajo rango. Forma: rango × dimensión de entrada (p. ej., r × dmodel).
- $BA$: La actualización entrenable. Multiplicarlas da una aproximación de rango r de la actualización completa de pesos que se entrenaría en un fine-tuning.
El artículo original de LoRA encontró que los pesos del modelo viven en una variedad de baja dimensión intrínseca, lo que significa que las actualizaciones de pesos pueden representarse con muchos menos parámetros que los pesos originales.
"We hypothesize that the change in weights during model adaptation also has a low 'intrinsic rank' during adaptation." — https://arxiv.org/abs/2106.09685
Por qué esto importa para Stable Diffusion
Para las capas de atención del UNet de Stable Diffusion, las matrices de pesos estándar son de rango completo (p. ej., 768×768 para SDXL). En lugar de actualizar 768² parámetros, LoRA actualiza solo r×768 + 768×r = 1536r parámetros.
Con r = 8, eso son 12.288 parámetros entrenables frente a 589.824 pesos de rango completo—una reducción de 48×.
"At inference: zero additional latency versus a fully fine-tuned model by construction." — https://arxiv.org/abs/2106.09685
La mayoría de las UIs fusionan permanentemente el LoRA en el modelo base durante la carga. La actualización $W_0 + BA$ se calcula una vez y se almacena como nuevos pesos. Esto elimina la sobrecarga en tiempo de ejecución—los pesos fusionados son parámetros normales del modelo sin coste de memoria adicional.
Controles de fuerza: Alpha frente a Weight
Confundir "alpha" y "weight" es el error más común al usar LoRAs. Operan en niveles distintos:
Alpha (α) en tiempo de entrenamiento:
- Parte de los hiperparámetros de entrenamiento (kohya-ss:
--network_alpha, por defecto 1; PEFT:lora_alpha, por defecto igual al rango) - Controla el escalado de la tasa de aprendizaje durante el entrenamiento:
(α/r)escala la actualización - Referencia: https://github.com/kohya-ss/sd-scripts/blob/main/docs/train_network.md
Peso en tiempo de inferencia (el número en <lora:model:1>):
- Multiplicador en tiempo de ejecución aplicado a toda la actualización ΔW = BA
- Weight = 1 → efecto completo del LoRA
- Weight = 0 → sin efecto (solo modelo base)
- Weight = 0.5 → la mitad del efecto
El artículo original establece el escalado como (α/r)·BA. Las distintas implementaciones lo manejan de forma diferente—el repositorio cloneofsimo sugiere que el peso de inferencia reemplaza por completo el escalado por alpha, mientras que otras implementaciones multiplican ambos.
Cómo se apilan varios LoRA
Cuando aplicas varios LoRA, sus efectos se suman:
$$h = W_0 x + \frac{\alpha_1}{r_1} B_1 A_1 x + \frac{\alpha_2}{r_2} B_2 A_2 x$$
Si dos LoRA apuntan a la misma capa de atención (p. ej., ambos modifican Wq), sus actualizaciones se suman.
Encadenar LoRAs
ComfyUI: Encadena nodos LoraLoader de forma secuencial:
LoraLoader node 1 → LoraLoader node 2 → [...]
Cada nodo añade sus propias matrices de bajo rango a los pesos base. Referencia: https://comfyanonymous.github.io/ComfyUI_examples/lora/
Diffusers: Usa set_adapters() para control ponderado:
pipeline.set_adapters(["style1", "style2"], adapter_weights=[0.7, 0.8])
Fusión avanzada: El método add_weighted_adapter() de PEFT admite los métodos TIES y DARE para combinación sin conexión.
"LoRA is orthogonal to many other parameter-efficient methods and can be combined with many of them, such as prefix-tuning." — https://arxiv.org/abs/2106.09685
Cómo hacer coincidir LoRAs con modelos base
Las matrices del LoRA tienen dimensiones que coinciden con la arquitectura del modelo base en el que fueron entrenadas. Un LoRA de SD1.5 tiene matrices B/A dimensionadas para las capas de atención del UNet de SD1.5; un LoRA de SDXL tiene dimensiones mayores.
Ejemplos de desajuste de arquitectura:
- LoRA de SDXL → base SD1.5: ❌ desajuste de dimensiones de matriz
- LoRA de SD1.5 → base SD1.5: ✅ las dimensiones coinciden
"LoRAs also need to be used with another model." — https://huggingface.co/docs/diffusers/main/en/using-diffusers/loading_adapters
Los distintos modelos base también tienen cantidades variables de capas de atención y pueden apuntar a tipos de capa distintos (self-attention frente a cross-attention).
Dónde instalar los archivos LoRA
UI | Ruta
|---|---
ComfyUI | models/loras/ AUTOMATIC1111 / Forge | models/Lora/ Diffusers (código) | Cualquier ruta; se carga con load_lora_weights("path/to/loras") Entrenamiento kohya-ss | Especificado por --output_dir Referencia: https://comfyanonymous.github.io/ComfyUI_examples/lora/
Common Errors and Fixes
Error | Causa probable | Solución
|---|---|---
El LoRA no tiene efecto visible | Peso en 0 o LoRA no activado en la UI | Revisa la sintaxis <lora:name:1>; asegúrate de que el peso > 0 Error de desajuste de arquitectura | LoRA de SDXL cargado en modelo SD1.5 (o viceversa) | Verifica que el modelo base coincida con la arquitectura de entrenamiento del LoRA El segundo LoRA anula al primero | Apilamiento no activado en la UI | Encadena nodos LoraLoader (ComfyUI) o usa set_adapters() (Diffusers) Error de archivo corrupto | Descarga incompleta o formato incorrecto | Vuelve a descargar el archivo .safetensors de una fuente confiable
Preguntas frecuentes (FAQ)
¿Cuánta VRAM añade un LoRA? Las matrices del LoRA en sí son pequeñas (1–6 MB para rango bajo, hasta ~200 MB para rangos mayores). El modelo base se carga con normalidad. Tras la fusión, no hay coste adicional de VRAM.
¿Puedo aplicar LoRAs a capas que no son de atención? En principio, LoRA puede apuntar a cualquier matriz de pesos. En la práctica, la mayoría de los LoRA de SD apuntan solo a capas de atención (Wq, Wk, Wv, Wo). kohya-ss admite capas Conv2d mediante LoRA-C3Lier (referencia: https://github.com/kohya-ss/sd-scripts/blob/main/docs/train_network.md).
¿Cuál es el rango óptimo para los LoRA? El artículo original probó rangos 4–8 para modelos de lenguaje. Para SD, los rangos 8–128 son comunes; los rangos bajos (4–16) intercambian calidad por velocidad y eficiencia de VRAM.
¿Cuántos LoRA puedo apilar? No hay un límite estricto. Cada LoRA añade matrices pequeñas a las mismas capas. Los rendimientos decrecientes aparecen a medida que más LoRA modifican las mismas matrices de pesos, pero apilar varios LoRA en la práctica es común.
¿Necesito software especial para usar LoRAs? Cualquier UI que admita LoRAs sirve—AUTOMATIC1111, ComfyUI, Forge y Diffusers los manejan de forma nativa.
¿Cómo sé si un LoRA funcionará con mi modelo base? Revisa la ficha del modelo o la descripción. La mayoría lista los modelos base compatibles (p. ej., "SDXL v1.0 base", "SD 1.5"). Ante la duda, inspecciona las dimensiones del archivo .safetensors.
Sources
Afirmación | Source
|---|---
LoRA congela los pesos e inyecta matrices de descomposición de rango entrenables | https://arxiv.org/abs/2106.09685 Formulación matemática h = W₀x + BAx | https://arxiv.org/abs/2106.09685 Latencia de inferencia cero al fusionar | https://arxiv.org/abs/2106.09685 Compatibilidad de arquitectura LoRA | https://civitai.com/articles/2099 Rutas de instalación de LoRA | https://civitai.com/articles/2099 Distinción entre alpha y weight | https://github.com/kohya-ss/sd-scripts/blob/main/docs/train_network.md Rank-Stabilized LoRA | https://huggingface.co/docs/peft/main/en/conceptual_guides/lora Estrategia de inicialización de pesos | https://arxiv.org/abs/2106.09685 Factor de escalado de LoRA α/r | https://arxiv.org/abs/2106.09685 Ortogonalidad de LoRA con otros métodos | https://arxiv.org/abs/2106.09685 Parámetros de configuración LoRA de PEFT | https://huggingface.co/docs/peft/main/en/conceptual_guides/lora Carga en ComfyUI con LoraLoader | https://comfyanonymous.github.io/ComfyUI_examples/lora/ Diffusers load_lora_weights | https://huggingface.co/docs/diffusers/main/en/using-diffusers/loading_adapters Encadenado Diffusers set_adapters | https://huggingface.co/docs/diffusers/main/en/using-diffusers/merge_loras Tipos y argumentos de LoRA de Kohya-ss | https://github.com/kohya-ss/sd-scripts/blob/main/docs/train_network.md Formato de archivo checkpoint de LoRA | https://github.com/kohya-ss/sd-scripts/blob/main/docs/train_network.md Fórmula de fusión LoRA de Cloneofsimo | https://github.com/cloneofsimo/lora