Logotipo de VRAMfarm VRAMfarm
ES
Registrarse

11 de noviembre de 2026 · Equipo de VRAMfarm

CUDA out of memory: cómo solucionarlo en ComfyUI, en LLM y en entrenamiento

Terminal con un error CUDA out of memory junto a la barra de memoria de nvidia-smi en una GPU alquilada
torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 2.00 GiB.
GPU 0 has a total capacity of 23.65 GiB of which 1.12 GiB is free.
Of the allocated memory 20.10 GiB is allocated by PyTorch, and 1.31 GiB
is reserved by PyTorch but unallocated.

Ese mensaje dice una sola cosa: en ese momento el programa pidió 2 GiB más de memoria de vídeo de los que quedaban. La tarjeta está bien y no siempre se queda pequeña. La mayoría de los casos se arreglan en minutos con una de cuatro palancas: menos precisión, una unidad de trabajo más pequeña (lote, resolución, contexto), liberar la memoria que tiene ocupada otra cosa o corregir la fragmentación. Cuando ninguna funciona sin destrozar la calidad o la velocidad, una tarjeta más grande es la respuesta más barata.

Lee el error antes de cambiar nada

Cada parte del mensaje te dice algo:

  • «Tried to allocate 2.00 GiB» es la petición concreta que ha fallado, no el total que necesita tu trabajo. Bajar un poco los ajustes puede que solo retrase el fallo unos pasos.
  • «Total capacity of 23.65 GiB» en una tarjeta de 24 GB es normal. El driver se queda una pequeña parte de la memoria y el contexto de CUDA ocupa unos cientos de megas más antes de que cargue tu modelo.
  • «Reserved by PyTorch but unallocated» es memoria que PyTorch tiene retenida pero no puede usar para esta petición. Si son varios gigas, el problema es la fragmentación; lo vemos más abajo.
  • Las líneas «Process 1234 has 9.80 GiB memory in use», cuando aparecen, significan que otro proceso comparte la tarjeta.

RuntimeError: CUDA error: out of memory sin más detalles suele venir de una librería como cuBLAS o de un kernel propio, muchas veces durante el arranque. Las soluciones son las mismas.

Mira qué ocupa la memoria con nvidia-smi

Ejecuta nvidia-smi en la terminal de Jupyter o por SSH. La línea que importa es la de cada GPU:

| 0  NVIDIA GeForce RTX 4090  ...  | 21540MiB / 24564MiB |  97%  Default |

La primera cifra es la memoria en uso; la segunda, el total de la tarjeta; después, la carga de la GPU. Para verlo en directo mientras se ejecuta tu trabajo:

nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csv -l 1

En un servidor alquilado, la lista de procesos de abajo suele estar vacía aunque haya memoria en uso. El servidor es un contenedor, y nvidia-smi no ve los nombres de los procesos a través de ese límite. Usa ps aux | grep python en su lugar.

Hay tres cosas que suelen ocupar memoria sin que te lo esperes:

  1. La caché de PyTorch. Los tensores liberados siguen reservados para reutilizarlos, así que nvidia-smi los muestra como usados. torch.cuda.memory_allocated() muestra lo que de verdad está en uso y torch.cuda.memory_reserved(), lo que está retenido. torch.cuda.empty_cache() devuelve la caché, lo cual solo ayuda si otro proceso la necesita.
  2. Otro proceso en la misma tarjeta. Un kernel de Jupyter que cargó un modelo hace tres celdas, un ComfyUI viejo que sigue en marcha, un script de entrenamiento que se cayó a medias. Reinicia el kernel o haz kill del PID. Si tu script muere cada vez que arranca otra app en la tarjeta, es por esto: las dos compiten por la misma memoria.
  3. La reserva de vLLM. vLLM ocupa por defecto el 90 % de la tarjeta al arrancar. Cualquier otra cosa que lances a su lado se quedará sin memoria.

ComfyUI, Flux y Wan: soluciones por orden

Ve bajando por la lista y para cuando funcione:

  1. Usa pesos en FP8 o GGUF. Flux.1 dev en 16 bits ocupa unos 24 GB solo en pesos; en FP8, unos 12 GB. Su codificador de texto T5-XXL baja de unos 9,5 GB a unos 5 GB en FP8. Las versiones GGUF (con los nodos ComfyUI-GGUF) van más allá: Q8 va bien en tarjetas de 16 GB, Q5 y Q4 caben en 12 GB, y con Q4 el detalle fino empieza a resentirse. Nuestra plantilla de Flux ya trae Flux.1 schnell en FP8.
  2. Cambia VAE Decode por VAE Decode (Tiled). La decodificación final es un punto clásico de fallo, sobre todo con imágenes grandes y vídeo. La decodificación por mosaicos trabaja por partes, a cambio de unos segundos.
  3. Baja el tamaño de lote en Empty Latent Image. Cuatro imágenes seguidas necesitan más o menos una cuarta parte de la memoria de activaciones de un lote de cuatro.
  4. Baja la resolución y escala después. La memoria de activaciones crece con el número de píxeles: 2048×2048 tiene cuatro veces los píxeles de 1024×1024. Genera al tamaño nativo y usa un escalador por mosaicos.
  5. En vídeo, recorta fotogramas o resolución. Con Wan 2.2, pasar de 81 a 49 fotogramas o de 720p a 480p ahorra varios gigas. El modelo 14B son dos expertos de 14B que ComfyUI carga por turnos; en tarjetas de 24–32 GB, el block swap de los nodos Wan video wrapper pasa parte del modelo a la RAM del sistema.
  6. Descarga a la RAM como último recurso. Si arrancas ComfyUI tú mismo, --lowvram mantiene partes del modelo en la RAM del sistema y --reserve-vram 2 deja 2 GB libres para otras cosas. Cuenta con que la generación vaya varias veces más lenta.

Los botones del Manager para descargar modelos y liberar la caché ayudan cuando cambias de workflow en una misma sesión, por ejemplo de Flux a Wan, porque el modelo anterior puede seguir cargado.

LLM: pesos más caché KV

Un modelo de lenguaje necesita memoria para tres cosas: los pesos, la caché KV y 1–2 GB de margen de trabajo.

Los pesos son los parámetros por los bytes por parámetro:

Modelo 16 bits FP8 / 8 bits 4 bits
8B ~16 GB ~8 GB ~5 GB
32B ~66 GB ~33 GB ~20 GB
70B ~141 GB ~71 GB ~43 GB

La caché KV crece con cada token del contexto, y por cada petición simultánea. En 16 bits ocupa unos 128 KB por token en Llama 3.1 8B, 256 KB en Qwen3 32B y 320 KB en Llama 3.x 70B. Una sola conversación de 32 000 tokens con Qwen3 32B necesita unos 8 GB de caché; una de 128 000 tokens con un modelo de 70B, unos 42 GB, tanto como los pesos en 4 bits. Por eso un modelo carga bien y luego falla en un chat largo o cuando llegan diez usuarios a la vez.

Soluciones según la herramienta:

  • Ollama. Fija un contexto más corto con num_ctx u OLLAMA_CONTEXT_LENGTH, y reduce la caché a la mitad con OLLAMA_FLASH_ATTENTION=1 y OLLAMA_KV_CACHE_TYPE=q8_0. Ollama rara vez se cae; en su lugar pasa capas a la CPU. Si ollama ps muestra algo como 35%/65% CPU/GPU, el modelo no cabe y va varias veces más lento.
  • llama.cpp. Limita el contexto con -c 16384, elige cuántas capas se quedan en la GPU con -ngl y cuantiza la caché con --cache-type-k q8_0 --cache-type-v q8_0. Una caché V cuantizada necesita flash attention: los builds actuales la activan solos cuando la GPU lo admite, y -fa on la fuerza.
  • vLLM. --gpu-memory-utilization (0,9 por defecto) es la parte de toda la memoria de la tarjeta que vLLM ocupa para pesos y caché al arrancar. Bájalo a 0,8 si el arranque falla porque otra cosa usa la tarjeta. Si vLLM dice que la max seq len del modelo es mayor de lo que cabe en la caché KV, súbelo a 0,95 o fija --max-model-len 32768. --kv-cache-dtype fp8 reduce la caché a la mitad, --max-num-seqs limita las peticiones en paralelo, --enforce-eager ahorra la memoria que ocupan los CUDA graphs a costa de algo de velocidad y --tensor-parallel-size 2 reparte el modelo entre dos tarjetas. La plantilla de vLLM te da una API compatible con OpenAI para probar estos ajustes.
  • Cuantiza los pesos. Un checkpoint AWQ o GPTQ en 4 bits deja los pesos en más o menos una cuarta parte de los de 16 bits. FP8 los reduce a la mitad y funciona de forma nativa en tarjetas Ada, Hopper y Blackwell.

Entrenamiento: reduce el lote, las activaciones y el optimizador

Un ajuste fino completo con AdamW en precisión mixta necesita unos 16 bytes por parámetro antes de las activaciones: 2 para los pesos, 2 para los gradientes, 4 para una copia maestra en 32 bits y 8 para los estados del optimizador. Un modelo de 7B son unos 112 GB, más de lo que tiene cualquier tarjeta individual salvo la H200 y la B200. Soluciones, más o menos por orden de cuánto ahorran para lo poco que cuestan:

  1. Lote más pequeño, mismo lote efectivo. Un lote de 2 con 8 pasos de acumulación de gradientes entrena como un lote de 16.
  2. Gradient checkpointing. Las activaciones se recalculan durante el paso hacia atrás en vez de guardarse. Ahorra buena parte de la memoria de activaciones y cuesta un 20–30 % de velocidad. En Hugging Face: gradient_checkpointing=True.
  3. Precisión mixta BF16 en cualquier tarjeta a partir de Ampere.
  4. Optimizadores de 8 bits. AdamW8bit de bitsandbytes (optim="adamw_bnb_8bit") reduce los estados del optimizador de 8 bytes por parámetro a unos 2.
  5. LoRA o QLoRA en vez de ajuste fino completo. Entrenas adaptadores pequeños; QLoRA carga la base en 4 bits. Un modelo de 8B se entrena con QLoRA en 10–16 GB; uno de 70B necesita unos 48 GB y va cómodo con 80 GB.
  6. Secuencias más cortas o menos resolución. Para un LoRA de Flux, entrena primero a 512–768 px y guarda en caché los latentes y los embeddings de texto.
  7. Varias tarjetas. FSDP o DeepSpeed ZeRO reparten pesos, gradientes y estados del optimizador entre varias GPU.

Si el fallo llega tras cientos de pasos y no de golpe, busca una fuga: total_loss += loss mantiene vivo todo el grafo, total_loss += loss.item() no. Evaluar sin torch.no_grad() provoca lo mismo.

Fragmentación: PYTORCH_CUDA_ALLOC_CONF

Cuando el error muestra varios gigas «reserved but unallocated», la memoria está ahí, pero partida en trozos demasiado pequeños para la petición. Pasa sobre todo con formas que cambian: imágenes de distintos tamaños, longitudes de secuencia variables o modelos que se cargan y descargan por turnos. Configura esto antes de que arranque Python:

export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True

En un notebook, pon os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True" en la primera celda, antes de import torch. Las versiones más recientes de PyTorch también leen el mismo ajuste como PYTORCH_ALLOC_CONF. En versiones antiguas, la alternativa es max_split_size_mb:128. Este ajuste no crea memoria; solo te deja usar la que está libre.

Para dimensionar tu trabajo, mide el pico en vez de adivinarlo: torch.cuda.max_memory_allocated() después de un paso completo o de una imagen, y torch.cuda.memory_summary() para el desglose.

Cuándo dejar de ajustar y coger una tarjeta más grande

Sube de tarjeta cuando la solución te cueste calidad (bajar de FP8 a Q4), velocidad (descarga a la CPU) o más tiempo tuyo de lo que vale la diferencia de precio. Para comparar, una hora cuesta desde 0,59 € en una RTX 4090 con 24 GB, 0,76 € en una RTX 5090 con 32 GB, 1,06 € en una L40S con 48 GB y 3,90 € en una H100 con 80 GB.

Qué se sigue quedando sin memoria Tamaño de tarjeta que sirve
Flux dev en 16 bits, o Flux con varios LoRA y ControlNet 24–32 GB
Wan 2.2 14B a 720p sin descarga a la RAM 32 GB para clips cortos, 48 GB para ir con margen
Modelo de 32B con más de 32 000 tokens de contexto o varios usuarios 48–80 GB
Modelo de 70B en 4 bits 48 GB con contexto normal, 80 GB para contexto largo o para servirlo
70B en FP8 80–96 GB con contexto corto, 141 GB o dos tarjetas para contexto largo
Ajuste fino completo de un modelo de 7–8B 80 GB o más, o varias tarjetas (QLoRA cabe en 16–24 GB)

El selector de VRAM te muestra qué tarjetas sirven para tu modelo y cuánto cuestan ahora; la guía sobre cuánta VRAM necesitas tiene la tabla completa por modelo. Una prueba rápida en la tarjeta más grande cuesta solo 15 minutos de su precio, y si guardas /workspace al detenerla, se restaura en el siguiente servidor aunque tenga otra tarjeta.

Preguntas sobre el tema

¿Por qué nvidia-smi muestra la memoria casi llena cuando mi script no está haciendo nada?

PyTorch mantiene reservada la memoria liberada para reutilizarla, así que sigue contando como usada. vLLM también ocupa a propósito un 90 % de la tarjeta al arrancar. Si nada de eso lo explica, un kernel viejo de Jupyter o un proceso que se ha caído sigue teniendo un modelo en memoria.

¿Por qué mi LLM carga bien y luego falla en una conversación larga?

La caché KV crece con cada token de contexto y con cada usuario en paralelo. Un modelo que cabe con un chat de 4000 tokens puede quedarse sin memoria a los 30 000. Limita la longitud del contexto o cuantiza la caché.

¿Dos GPU solucionan CUDA out of memory?

En modelos de lenguaje, normalmente sí: vLLM, llama.cpp y Ollama pueden repartir un modelo entre varias tarjetas. Los modelos de imagen y vídeo en ComfyUI por lo general tienen que caber en una sola tarjeta, así que para ellos la solución es una tarjeta con más memoria.

¿La descarga a la CPU o --lowvram son una solución de verdad?

Hacen que el trabajo funcione, a menudo varias veces más lento. Para algo puntual, vale. Para trabajo habitual, una tarjeta en la que quepa el modelo suele salir más barata por resultado.

Encuentra la GPU en la que cabe tu modelo

Elige un modelo y verás la tarjeta más barata con VRAM suficiente, con facturación por minuto en euros.