Accelerate documentation
Comparación del rendimiento en configuraciones distribuidas
Comparación del rendimiento en configuraciones distribuidas
Evaluar y comparar el rendimiento de diferentes configuraciones puede ser bastante complicado si no sabes en qué fijarte. Por ejemplo, no puedes ejecutar el mismo script con el mismo tamaño de lote en TPU, multi-GPU y single-GPU con Accelerate y esperar que tus resultados coincidan.
¿Pero por qué?
Hay tres razones para esto que este tutorial abordará:
- Establecer las semillas correctas
- Tamaños de lote observados
- Tasas de aprendizaje
Establecer la semilla
Aunque este problema no ha surgido con tanta frecuencia, asegúrate de usar utils.set_seed() para establecer completamente la semilla en todos los casos distribuidos, de modo que el entrenamiento sea reproducible:
from accelerate.utils import set_seed
set_seed(42)¿Por qué es importante? Internamente, esto configurará 5 ajustes de semilla diferentes:
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed) # or torch.xpu.manual_seed_all, etc
# ^^ safe to call this function even if cuda is not available
if is_torch_xla_available():
xm.set_rng_state(seed)El estado aleatorio, el estado de numpy, torch, el estado del dispositivo de torch y, si están disponibles TPUs, el estado cuda de torch_xla.
Tamaños de lote observados
Al entrenar con Accelerate, el tamaño de lote que se pasa al dataloader es el tamaño de lote por GPU. Esto implica que un tamaño de lote de 64 en dos GPUs es en realidad un tamaño de lote de 128. Como resultado, al probar en una sola GPU, esto debe tenerse en cuenta, así como de manera similar para las TPU.
La siguiente tabla puede usarse como referencia rápida para probar diferentes tamaños de lote:
En este ejemplo, hay dos GPUs para “Multi-GPU” y un pod de TPU con 8 workers
| Tamaño de lote por GPU | Tamaño de lote equivalente multi-GPU | Tamaño de lote equivalente en TPU |
|---|---|---|
| 256 | 128 | 32 |
| 128 | 64 | 16 |
| 64 | 32 | 8 |
| 32 | 16 | 4 |
Tasas de aprendizaje
Como se señala en varias fuentes[1][2], la tasa de aprendizaje debe escalarse de forma lineal en función del número de dispositivos presentes. El siguiente fragmento de código muestra cómo hacerlo con Accelerate:
Dado que los usuarios pueden tener sus propios programadores de tasa de aprendizaje definidos, dejamos a criterio del usuario decidir si desea escalar su tasa de aprendizaje o no.
learning_rate = 1e-3
accelerator = Accelerator()
learning_rate *= accelerator.num_processes
optimizer = AdamW(params=model.parameters(), lr=learning_rate)También observará que accelerate ajusta la tasa de aprendizaje en función del número de procesos en los que se está entrenando. Esto se debe al tamaño de lote observado mencionado anteriormente. Por lo tanto, en el caso de 2 GPUs, la tasa de aprendizaje se ajustará el doble de veces que con una sola GPU para compensar que el tamaño de lote sea el doble de grande (si no se realizan cambios en el tamaño de lote de la instancia de una sola GPU).
Acumulación de gradientes y precisión mixta
Al usar acumulación de gradientes y precisión mixta, debido a cómo funciona el promedio de gradientes (acumulación) y la pérdida de precisión (precisión mixta), se espera cierta degradación en el rendimiento. Esto se observará explícitamente al comparar la pérdida por lote entre diferentes configuraciones de cómputo. Sin embargo, la pérdida general, la métrica y el rendimiento general al final del entrenamiento deberían ser aproximadamente los mismos.
Update on GitHub