Logotipo de VRAMfarm VRAMfarm
ES
Registrarse

12 de noviembre de 2026 · Equipo de VRAMfarm

Entrenamiento multi-GPU: DDP, FSDP y ZeRO en una máquina alquilada de 2 a 8 GPU

Cuatro GPU en un servidor unidas por carriles de datos, con fragmentos del modelo repartidos entre ellas: entrenamiento multi-GPU con DDP, FSDP y ZeRO

Cuatro tarjetas alquiladas, el script lanzado con python train.py, y nvidia-smi muestra una tarjeta al 100 % y tres al 0 %. No hay nada roto. Un script de entrenamiento usa una sola GPU salvo que lo arranque un lanzador que ejecute un proceso por tarjeta, y el trabajo hay que repartirlo de una forma que encaje con tu modelo. Hay dos maneras de repartirlo: dar a cada tarjeta una copia del modelo y una parte de los datos, o cortar el propio modelo en trozos. Cuál necesitas depende de si el modelo cabe en una tarjeta.

Primero: ¿necesitas más de una tarjeta?

Solo hay dos razones para usar varias GPU: el trabajo no cabe en la memoria de una tarjeta, o tarda demasiado en una. Antes de ir a por una máquina multi-GPU, comprueba si una sola tarjeta más grande lo resuelve. Una tarjeta siempre es más sencilla: sin lanzador, sin comunicación entre tarjetas, sin errores de NCCL.

Trabajo Una tarjeta que lo hace Cuándo tienen sentido varias tarjetas
LoRA o QLoRA de un modelo de hasta 70B 24–80 GB, mira la guía de VRAM Pocas veces; para entrenar más rápido con un dataset grande
Ajuste fino completo de un modelo de 7–8B Una tarjeta de 80 GB con un optimizador de 8 bits, o una H200 (141 GB) Para usar el optimizador estándar, secuencias más largas o un entrenamiento más corto
Ajuste fino completo de un modelo de 13–70B Ninguna con el optimizador estándar; un modelo de 13B cabe en una tarjeta de 141–192 GB solo con un optimizador de 8 bits Casi siempre: 4–8 tarjetas con FSDP o ZeRO-3
Entrenar un modelo pequeño con muchos datos Cualquier tarjeta en la que quepa Para pasar de 40 horas de entrenamiento a 10
Servir un modelo de 70B en fp8 H200 2 × H100 con vLLM, mira H200 vs H100

Las tarjetas individuales más grandes del catálogo son la B200 con 192 GB, la H200 con 141 GB y la RTX PRO 6000 con 96 GB. Si tu trabajo cabe en una de ellas, empieza por ahí.

Paralelismo de datos: el mismo modelo en cada tarjeta

El entrenamiento con paralelismo de datos (DDP de PyTorch) ejecuta un proceso por GPU. Cada proceso tiene una copia completa del modelo, coge una porción distinta de cada lote, calcula sus gradientes y luego todas las tarjetas promedian sus gradientes antes del paso del optimizador. Las tarjetas se mantienen idénticas, y N tarjetas procesan N veces más datos por paso.

Necesita una sola cosa: el modelo, sus gradientes, los estados del optimizador y las activaciones tienen que caber en una tarjeta. Si caben, DDP es la forma más fácil de ir más rápido. Arrancas el script con un lanzador en lugar de python:

torchrun --nproc_per_node=4 train.py        # PyTorch normal, Trainer de Hugging Face
accelerate launch --num_processes 4 train.py  # Hugging Face Accelerate

El Trainer de Hugging Face y la mayoría de las herramientas de ajuste fino (Axolotl, LLaMA-Factory, torchtune) pasan a DDP por sí solas cuando se arrancan así. En PyTorch normal envuelves el modelo en DistributedDataParallel y añades un DistributedSampler.

El precio es la comunicación: después de cada paso, las tarjetas intercambian una copia de los gradientes. Para un modelo de 1B en bf16 son unos 2 GB por paso, algo que PCIe asume mientras todavía se ejecuta el backward. Cuenta con que dos tarjetas den entre 1,7 y 1,9 veces la velocidad de una, y cuatro tarjetas, entre 3 y 3,7 veces, menos con modelos más grandes en máquinas sin NVLink.

Cuando el modelo no cabe: FSDP y DeepSpeed ZeRO

Con el optimizador AdamW estándar en precisión mixta, cada parámetro cuesta unos 16 bytes: 2 de los pesos en bf16, 2 de los gradientes y 12 del optimizador (una copia maestra en fp32 y dos estimaciones de momentos). Para un modelo de 8B son 128 GB antes de las activaciones, más que cualquier tarjeta de 80 GB.

El sharding reparte esos 16 bytes entre las tarjetas en lugar de copiarlos. DeepSpeed lo llama ZeRO y tiene tres etapas; FSDP de PyTorch hace lo mismo con otros nombres. Para un modelo de 8B:

Método Qué tiene cada tarjeta Por tarjeta, 4 tarjetas Por tarjeta, 8 tarjetas
DDP Todo 128 GB 128 GB
ZeRO-1 Pesos, gradientes, 1/N del optimizador 56 GB 44 GB
ZeRO-2, FSDP SHARD_GRAD_OP Pesos, 1/N de gradientes y optimizador 44 GB 30 GB
ZeRO-3, FSDP FULL_SHARD 1/N de todo 32 GB 16 GB

Las activaciones van aparte, desde unos pocos GB hasta decenas de GB por tarjeta según la longitud de secuencia y el tamaño de lote; el gradient checkpointing las reduce a cambio de aproximadamente un tercio más de cálculo. Cómo leer la tabla: 4 tarjetas de 80 GB hacen un ajuste fino completo de un 8B con holgura con ZeRO-2 o ZeRO-3, 4 tarjetas de 48 GB con ZeRO-3, y las tarjetas de 24 GB solo si son 8, o con offload del optimizador a la RAM de la CPU.

FSDP forma parte de PyTorch; DeepSpeed se configura con un archivo JSON. El Trainer de Hugging Face y Accelerate admiten los dos. El offload a CPU (ZeRO-Offload, FSDP cpu_offload) mueve los estados del optimizador a la RAM del sistema y permite que tarjetas pequeñas entrenen modelos grandes, despacio y solo si la máquina tiene esa RAM.

ZeRO-3 tiene un precio que importa en máquinas alquiladas: los propios pesos viajan entre tarjetas en cada paso. Para un modelo de 8B en cuatro tarjetas son unos 35–50 GB por tarjeta y paso. Por NVLink en una máquina con H100 tarda una fracción de segundo; por PCIe puede tardar segundos, y las tarjetas esperan. Por eso importa el tipo de enlace.

Paralelismo tensorial y de pipeline, y qué se usa en inferencia

El paralelismo tensorial corta cada matriz de pesos en porciones, una por tarjeta, e intercambia datos en cada capa, así que solo funciona bien por NVLink. El paralelismo de pipeline pone capas distintas en tarjetas distintas, con menos tráfico, pero con tarjetas paradas mientras se llena el pipeline. Los frameworks de preentrenamiento como Megatron los combinan; para ajuste fino, FSDP o ZeRO suelen bastar.

En inferencia el panorama es más sencillo. vLLM reparte un modelo con --tensor-parallel-size 2 (o 4, 8), y llama.cpp y Ollama reparten las capas entre tarjetas por sí solos. La inferencia envía pocos datos entre tarjetas, así que funciona aceptablemente incluso por PCIe.

Una trampa: device_map="auto" en Hugging Face Transformers reparte las capas entre las tarjetas y las ejecuta una detrás de otra. El modelo cabe, pero solo trabaja una tarjeta en cada momento. Sirve para probar un modelo grande, no para entrenar rápido.

Enlace Velocidad entre tarjetas, aproximada Dónde lo encuentras
PCIe 4.0 x16 25–32 GB/s por sentido RTX 3090, RTX 4090, A6000, la mayoría de las tarjetas PCIe
PCIe 5.0 x16 50–64 GB/s por sentido RTX 5090, RTX PRO 6000, servidores más nuevos
Puente NVLink, RTX 3090 unos 112 GB/s Poco habitual en máquinas alquiladas
NVLink, A100 SXM 600 GB/s Placas A100 SXM de 4 y 8 tarjetas
NVLink, H100 / H200 SXM 900 GB/s Placas SXM de 4 y 8 tarjetas

Las tarjetas de consumo añaden un límite más: la RTX 4090 no admite transferencias directas peer-to-peer, así que los datos entre tarjetas pasan por la memoria del sistema. Las máquinas con varias 4090 van bien para inferencia y para DDP con modelos pequeños, y mal para ZeRO-3 con modelos grandes.

El catálogo muestra el nombre de la tarjeta antes de lanzar. «SXM» o «SXM4» significa que las tarjetas van en una placa hecha para NVLink; las tarjetas PCIe pueden tener puentes o no. El filtro «PCIe» del catálogo es la velocidad del bus entre la CPU y las GPU. Importa para cargar datos y modelos (una tarjeta en una ranura estrecha x4 carga despacio), pero no dice nada de los enlaces entre tarjetas. Para eso, ejecuta esto justo después de lanzar:

nvidia-smi topo -m

NV4, NV12 o NV18 entre dos tarjetas significa NVLink. PIX y PXB indican un switch PCIe, PHB el puente PCIe de la CPU, y NODE o SYS un camino que atraviesa la CPU, el más lento.

Alquilar una máquina multi-GPU en VRAMfarm

  1. Elige la máquina. En el catálogo de servidores, pon «Tarjetas por máquina» en 2×, 4× u 8×. El precio es por hora para toda la máquina, más o menos el número de tarjetas por el precio de una: desde 2,36 € la hora por 4 × RTX 4090, desde 31,20 € por 8 × H100. Cada fila muestra el nombre de la tarjeta, los núcleos de CPU, la RAM, el disco, el driver, la versión de CUDA y el país.
  2. Usa los filtros que importan para entrenar. VRAM por máquina, RAM (como mínimo la VRAM total), núcleos de CPU (4–8 por tarjeta), disco libre (un checkpoint completo de un modelo de 8B con los estados del optimizador pasa de 100 GB) y «Periodo de alquiler», cuántos días seguidos se puede mantener la máquina. Deja margen para los entrenamientos largos.
  3. Elige un servidor vacío. PyTorch con Jupyter, o tu propia imagen de Docker. Para lanzar, tu saldo tiene que cubrir una hora de toda la máquina; es una comprobación, no un cargo, y la facturación es por minuto.
  4. Revisa la máquina en los primeros minutos. Ejecuta nvidia-smi, nvidia-smi topo -m y python -c "import torch; print(torch.cuda.device_count())". Si algo va mal, detén el servidor: pagas el mínimo de 15 minutos, no la hora.
  5. Haz una prueba corta de comunicación antes del trabajo real:
# nccl_check.py: arráncalo con  torchrun --nproc_per_node=4 nccl_check.py
import os, time, torch, torch.distributed as dist
rank = int(os.environ["LOCAL_RANK"]); torch.cuda.set_device(rank)
dist.init_process_group("nccl")
x = torch.ones(512 * 1024**2, dtype=torch.bfloat16, device="cuda")  # 1 GiB
for _ in range(3): dist.all_reduce(x)
torch.cuda.synchronize(); t = time.time()
for _ in range(10): dist.all_reduce(x)
torch.cuda.synchronize()
if rank == 0: print(f"{10 / (time.time() - t):.1f} all-reduces of 1 GiB per second")
dist.destroy_process_group()

Si muestra un número, las tarjetas se comunican; una máquina con NVLink debería ser muchas veces más rápida que una PCIe. Si se queda colgado, mira el primer problema de la lista siguiente.

La API recibe el número de tarjetas como count, así que un script puede arrancar una máquina de 8 tarjetas para un trabajo nocturno y detenerla cuando termine.

Problemas habituales

  • NCCL se cuelga o da «unhandled system error». Arranca con NCCL_DEBUG=INFO para ver dónde se para. En tarjetas de consumo, NCCL_P2P_DISABLE=1 suele arreglar los cuelgues. Si un proceso ha fallado, los demás lo esperan hasta el timeout, así que busca el primer error del log, no el último.
  • Memoria compartida demasiado pequeña. Dentro de los contenedores, /dev/shm a veces tiene solo unas decenas de megas, lo que rompe NCCL y los data loaders con «bus error». Compruébalo con df -h /dev/shm; baja num_workers o prueba con NCCL_SHM_DISABLE=1.
  • El tamaño de lote ha cambiado sin que te des cuenta. Lote global = lote por tarjeta × número de tarjetas × pasos de acumulación de gradientes. Pasar de 1 a 4 tarjetas con la misma configuración hace el lote cuatro veces más grande y la época cuatro veces más corta en pasos. O bajas los pasos de acumulación para mantener el lote global, o subes la tasa de aprendizaje: más o menos de forma lineal con SGD, con más cautela (raíz cuadrada) con Adam, y con warm-up.
  • Todas las tarjetas ven los mismos datos. Sin un DistributedSampler, todas las tarjetas entrenan con lotes idénticos; sin sampler.set_epoch(epoch), todas las épocas tienen el mismo orden. El Trainer de Hugging Face se encarga de las dos cosas.
  • Cuatro copias de cada log y de cada checkpoint. Escribe archivos solo en el rank 0. Un checkpoint completo de FSDP se reúne en la RAM de la CPU de un solo proceso; los checkpoints fragmentados lo evitan.
  • «System not yet initialized» en una máquina SXM de 8 tarjetas. Viene del NVLink fabric del anfitrión, no de tu código. Detén el servidor, elige otra máquina y avisa a soporte.

Los entrenamientos largos piden dos costumbres. Arranca el entrenamiento dentro de tmux, para que sobreviva a que cierres el portátil. Guarda checkpoints cada 30–60 minutos en /workspace, conserva solo los dos últimos y cópialos fuera de la máquina en entrenamientos de más de un día: el disco del servidor se elimina al detenerlo, salvo que guardes la carpeta (qué pasa con tus archivos). Mientras las GPU están ocupadas, la detección de inactividad deja el servidor en paz. Cuando el entrenamiento termina, empieza a contar: tras 2 horas sin carga en la GPU ni conexiones por SSH o Jupyter recibes un correo, y una hora después se guarda la carpeta y el servidor se detiene. Puedes desactivarlo, y los servidores arrancados con tu propia imagen de Docker no se detienen automáticamente. Una opción más barata es una última línea en tu script que detenga el servidor a través de la API.

Empieza con dos tarjetas y un entrenamiento corto, mide el tiempo por paso y luego escala a cuatro u ocho. Si dos tarjetas no van casi el doble de rápido, más tarjetas no lo van a arreglar; revisa primero el enlace entre ellas.

Preguntas sobre el tema

¿Puedo mezclar GPU distintas en una misma máquina?

No. Cada máquina del catálogo tiene tarjetas de un solo modelo, que se muestran, por ejemplo, como "4× RTX 4090". Y es lo que te conviene: en el entrenamiento con paralelismo de datos, todas las tarjetas esperan a la más lenta en cada paso.

¿ComfyUI u Ollama usan todas las tarjetas?

Ollama, llama.cpp y vLLM pueden repartir un modelo de lenguaje entre varias tarjetas. ComfyUI ejecuta un workflow en una sola tarjeta, así que en una máquina de 4 GPU lanzarías cuatro instancias de ComfyUI, cada una en su tarjeta con CUDA_VISIBLE_DEVICES, para generar cuatro lotes en paralelo.

¿Cuántos núcleos de CPU y cuánta RAM necesito por GPU?

Como regla general, 4–8 núcleos de CPU por GPU para que la carga de datos no se quede atrás, y como mínimo tanta RAM del sistema como VRAM total tenga la máquina. El offload a CPU de DeepSpeed o FSDP necesita mucha más: solo descargar el optimizador de un modelo de 8B ocupa unos 100 GB de RAM.

¿Qué pasa con mi entrenamiento si la máquina falla?

La facturación se para desde el momento en que la máquina dejó de responder y recibes una notificación, pero el disco del servidor se pierde con ella. En entrenamientos de más de unas horas, copia los checkpoints fuera de la máquina con regularidad, por ejemplo a un repositorio privado de Hugging Face o a tu propio bucket de S3.

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.