opción
HogarHogar Skill Ciencia de datos y aprendizaje automático nemo-mbridge-perf-cpu-offloading

nemo-mbridge-perf-cpu-offloading

NVIDIA/skills NVIDIA/skills

Configurar y validar la descarga de carga de la CPU para el entrenamiento de Megatron Bridge, incluida la descarga de la activación y la descarga del estado del optimizador con HybridDeviceOptimizer.

...Expandir todo
2
Tiempo actualizado 28 de septiembre de 2026

Descarga de la CPU

Referencias

  • Documentación estable: @docs/training/cpu-offloading.md
  • Metadatos estructurados: @skills/nemo-mbridge-perf-cpu-offloading/card.yaml

Qué es

Dos mecanismos independientes para trasladar datos de la memoria de la GPU a la de la CPU:

Mecanismo Espacio de nombres de configuración Qué se descarga Restricción de PP
Descarga de activaciones model.cpu_offloading* Activaciones (y, opcionalmente, pesos) por capa del transformador PP debe ser 1
Descarga del optimizador optimizer.optimizer_cpu_offload Estados del optimizador Adam (impulso + varianza) a través de HybridDeviceOptimizer Ninguno

Decisión rápida

Situación Recomendación
Modelo MoE grande (más de 30 mil millones), requiere PP > 1 Descarga del optimizador: la descarga de activación queda bloqueada por PP = 1
Modelo pequeño/mediano, PP = 1 es adecuado, la memoria de activación es predominante Descarga de activaciones
Se busca un equilibrio ajustable entre memoria y velocidad Descarga del optimizador con un valor fraccionario: optimizer_offload_fraction
El rendimiento es la máxima prioridad No lo habilites: la descarga siempre añade sobrecarga
Se necesitan gráficos CUDA Solo descarga del optimizador: la descarga de activación es incompatible
La presión sobre la memoria es moderada Descarga del optimizador en un porcentaje del 25-50 % para obtener la máxima eficiencia

Activación

Descarga del optimizador a la CPU (recomendado para modelos grandes)

cfg.optimizer.optimizer_cpu_offload = True
cfg.optimizer.optimizer_offload_fraction = 1.0
cfg.optimizer.overlap_cpu_optimizer_d2h_h2d = True

Modificaciones en la CLI:

optimizer.optimizer_cpu_offload=True \
optimizer.optimizer_offload_fraction=0,5 \
optimizer.overlap_cpu_optimizer_d2h_h2d=True

Descarga de activaciones a la CPU (solo modelos pequeños y medianos)

cfg.model.cpu_offloading = True
cfg.model.cpu_offloading_num_layers = 16
cfg.model.cpu_offloading_activations = True
cfg.model.cpu_offloading_weights = False

cfg.model.pipeline_model_parallel_size = 1
cfg.model.recompute_granularity = None
cfg.model.cuda_graph_impl = "none"

Referencia de parámetros de configuración

Descarga del optimizador

Parámetro Valor por defecto Descripción
optimizer_cpu_offload Falso Interruptor principal
optimizer_offload_fraction 0,0 Fracción de estados del optimizador en la CPU (0,0–1,0)
overlap_cpu_optimizer_d2h_h2d Falso Superponer las transferencias GPU↔CPU con el cálculo
use_torch_optimizer_for_cpu_offload Falso Utilizar torch.optim en lugar del optimizador fusionado para la parte de la CPU

Descarga de activaciones

Parámetro Por defecto Descripción
cpu_offloading Falso Interruptor principal
cpu_offloading_num_layers 0 Número de capas del transformador que se van a descargar (de 0 a num_layers-1)
cpu_offloading_activations Verdadero Descargar activaciones
pesos_de_descarga_de_la_CPU Falso Ponderaciones de descarga
cpu_offloading_double_buffering Falso Búfer doble entre capas durante la recarga

Compatibilidad y restricciones

Descarga de activación

  • pipeline_model_parallel_size debe ser 1
  • recompute_granularity debe ser None
  • No se puede combinar con fine_grained_activation_offloading
  • No se puede combinar con grafos CUDA
  • cpu_offloading_num_layers debe estar en el intervalo [0, num_layers-1)

Descarga del optimizador

  • Requiere que use_distributed_optimizer = True (valor por defecto en la mayoría de las recetas)
  • Sin restricciones de PP, recomputación ni gráficos CUDA
  • optimizer_offload_fraction debe estar en el interval o [0,0; 1,0]

Aplicación práctica: modelos MoE de gran tamaño

La descarga de activaciones está bloqueada para Qwen3-30B-A3B y otros modelos MoE de gran tamaño similares. La restricción PP=1 implica que cada GPU alberga las 48 capas; solo los pesos del modelo y los estados del optimizador (~70 GB) superan la capacidad de 80 GB de la H100.

Comando mínimo ejecutable

uv run python scripts/training/run_recipe.py \
  --recipe qwen3_30b_a3b_pretrain_config \
  optimizer.optimizer_cpu_offload=True \
  optimizer.optimizer_offload_fraction=0.5 \
  train.train_iters=20 \
  train.global_batch_size=8 \
  train.micro_batch_size=1

Verificación

Pruebas unitarias

uv run python -m pytest \
  tests/unit_tests/models/test_gpt_full_te_layer_autocast_spec.py -k "cpu_offload" \
  tests/unit_tests/peft/test_utils.py -k "cpu_offload" -q

Criterios de éxito

  • La validación de la configuración se supera para el modo de descarga seleccionado
  • El entrenamiento se completa sin errores OOM ni NCCL
  • La pérdida coincide con la línea de base sin descarga (delta máximo < 0,001)
  • El uso de memoria se reduce proporcionalmente a la fracción de descarga

Anclajes de código

Restricciones de descarga de activación de MCore

       if self.cpu_offloading and (
            self.cpu_offloading_num_layers < 0 or self.cpu_offloading_num_layers >=self.num_layers
        ):
            raise ValueError(...)

        si self.cpu_offloading y self.pipeline_model_parallel_size > 1:
            raise ValueError(
                «Actualmente no se admite el paralelismo de Pipeline con descarga a la CPU»
            )

        si self.cpu_offloading y self.recompute_granularity no es None:
            raise ValueError(
                "La descarga a la CPU no funciona cuando está habilitado el recálculo de activaciones"
            )

Incompatibilidad del gráfico CUDA de MCore

           si self.cpu_offloading:
                raise ValueError("Los gráficos CUDA no son compatibles con la descarga a la CPU.")

Exclusión mutua de la descarga de activación de grano fino de MCore

       si self.fine_grained_activation_offloading:
            assert (
                not self.cpu_offloading
            ), «fine_grained_activation_offloading no se puede habilitar con cpu_offloading.»

Instanciación de HybridDeviceOptimizer de MCore

       si config.optimizer_cpu_offload:
            # ... configuración de las clases del optimizador de CPU/GPU ...
            optimizer = HybridDeviceOptimizer(
                param_groups,
                offload_fraction=config.optimizer_offload_fraction,
                cpu_optimizer_cls=cpu_optimizer_cls,
                gpu_optimizer_cls=gpu_optimizer_cls,
                overlap_cpu_optimizer_d2h_h2d=config.overlap_cpu_optimizer_d2h_h2d,
                pin_cpu_grads=config.pin_cpu_grads,
                pin_cpu_params=config.pin_cpu_params,
            )

Protección del gráfico CUDA de Bridge

       assert not config.cpu_offloading and config.recompute_granularity is None, «Cudagraphs no compatibles»

Descarga de activaciones de Bridge en PEFT

       si self.config.cpu_offloading y self.config.cpu_offloading_activations:
            x.activation_offloading = True
        x, _ = self.linear_in(x)
        x = self.activation(x)
        si self.config.cpu_offloading y self.config.cpu_offloading_activations:
            x.activation_offloading = True
        x, _ = self.linear_out(x)

Diagnóstico de fallos

Síntoma Causa probable Cómo confirmarlo Solución
Actualmente no hay compatibilidad con el paralelismo de pipeline con descarga de la CPU Descarga de activación + PP > 1 Comprueba pipeline_model_parallel_size Establece PP=1 o utiliza la descarga del optimizador
La descarga de la CPU no funciona cuando está habilitado el recálculo de activación Descarga de activación + recálculo Comprueba recompute_granularity Establece «recompute_granularity» en «null»
La descarga de activación de grano fino (fine_grained_activation_offloading) no se puede habilitar con la descarga de la CPU (cpu_offloading) Ambos modos de descarga están habilitados Comprueba ambos indicadores Utiliza uno u otro
Los gráficos CUDA no son compatibles con la descarga a la CPU Gráficos CUDA + descarga de activación Comprueba cuda_graph_impl Establezca cuda_graph_impl="none"
Error de memoria insuficiente (OOM) con descarga de activación Modelo demasiado grande para PP=1 Comprueba la memoria asignada frente a 80 GB Utilice la descarga del optimizador con PP > 1
Ralentización extrema (>4x) Descarga del optimizador al 100 %, cuello de botella de la CPU Adam Comparar el tiempo de iteración con diferentes fracciones Reducir la fracción o habilitar overlap_cpu_optimizer_d2h_h2d
Error de memoria insuficiente (OOM) con descarga parcial del optimizador Descarga insuficiente para esta configuración Comprueba la memoria con diferentes fracciones Aumenta la fracción o añade PP

Limitaciones conocidas

  • La descarga de activación requiere PP=1, lo que la hace poco práctica para modelos grandes (más de 30 000 millones de MoE) que necesitan paralelismo en la canalización.
  • La penalización en el rendimiento por la descarga del optimizador se escala linealmente (~1,9 veces al 25 %, ~4,2 veces al 100 % para Qwen3-30B-A3B).
  • La superposición D2H/H2D solo proporciona una aceleración de ~7 %, ya que el cálculo de Adam en la CPU es el cuello de botella principal.
  • «fine_grained_activation_offloading» es un enfoque independiente a nivel de módulo que funciona con PP > 1, pero no se puede combinar con«cpu_offloading» a nivel de capa .
Ver en GitHub
---
name: nemo-mbridge-perf-cpu-offloading
description: Configure and validate CPU offloading for Megatron Bridge training, including activation offloading and optimizer state offloading with HybridDeviceOptimizer.
license: Apache-2.0
---

# CPU Offloading

## References

- Stable docs: @docs/training/cpu-offloading.md
- Structured metadata: @skills/nemo-mbridge-perf-cpu-offloading/card.yaml

## What It Is

Two independent mechanisms to move data from GPU to CPU memory:

| Mechanism | Config namespace | What gets offloaded | PP restriction |
|---|---|---|---|
| Activation offloading | `model.cpu_offloading*` | Activations (and optionally weights) per transformer layer | PP must be 1 |
| Optimizer offloading | `optimizer.optimizer_cpu_offload` | Adam optimizer states (momentum + variance) via `HybridDeviceOptimizer` | None |

## Quick Decision

| Situation | Recommendation |
|---|---|
| Large MoE model (30B+), needs PP > 1 | Optimizer offloading — activation offloading is blocked by PP=1 |
| Small/medium model, PP=1 fits, activation memory dominates | Activation offloading |
| Want tunable memory-speed tradeoff | Optimizer offloading with fractional `optimizer_offload_fraction` |
| Throughput is top priority | Don't enable — offloading always adds overhead |
| CUDA graphs are needed | Only optimizer offloading — activation offloading is incompatible |
| Memory pressure is moderate | Optimizer offload at 25–50% fraction for best efficiency |

## Enablement

### Optimizer CPU offloading (recommended for large models)

```python
cfg.optimizer.optimizer_cpu_offload = True
cfg.optimizer.optimizer_offload_fraction = 1.0
cfg.optimizer.overlap_cpu_optimizer_d2h_h2d = True
```

CLI overrides:

```bash
optimizer.optimizer_cpu_offload=True \
optimizer.optimizer_offload_fraction=0.5 \
optimizer.overlap_cpu_optimizer_d2h_h2d=True
```

### Activation CPU offloading (small/medium models only)

```python
cfg.model.cpu_offloading = True
cfg.model.cpu_offloading_num_layers = 16
cfg.model.cpu_offloading_activations = True
cfg.model.cpu_offloading_weights = False

cfg.model.pipeline_model_parallel_size = 1
cfg.model.recompute_granularity = None
cfg.model.cuda_graph_impl = "none"
```

## Config Parameter Reference

### Optimizer offloading

| Parameter | Default | Description |
|-----------|---------|-------------|
| `optimizer_cpu_offload` | `False` | Master switch |
| `optimizer_offload_fraction` | `0.0` | Fraction of optimizer states on CPU (0.0–1.0) |
| `overlap_cpu_optimizer_d2h_h2d` | `False` | Overlap GPU↔CPU transfers with compute |
| `use_torch_optimizer_for_cpu_offload` | `False` | Use `torch.optim` instead of fused optimizer for CPU portion |

### Activation offloading

| Parameter | Default | Description |
|-----------|---------|-------------|
| `cpu_offloading` | `False` | Master switch |
| `cpu_offloading_num_layers` | `0` | Number of transformer layers to offload (0 to num_layers-1) |
| `cpu_offloading_activations` | `True` | Offload activations |
| `cpu_offloading_weights` | `False` | Offload weights |
| `cpu_offloading_double_buffering` | `False` | Double-buffer across layers while reloading |

## Compatibility And Constraints

### Activation offloading

- `pipeline_model_parallel_size` must be 1
- `recompute_granularity` must be `None`
- Cannot combine with `fine_grained_activation_offloading`
- Cannot combine with CUDA graphs
- `cpu_offloading_num_layers` must be in `[0, num_layers-1)`

### Optimizer offloading

- Requires `use_distributed_optimizer = True` (default in most recipes)
- No PP, recompute, or CUDA graph restrictions
- `optimizer_offload_fraction` must be in `[0.0, 1.0]`

### Practical: large MoE models

Activation offloading is blocked for Qwen3-30B-A3B and similar large MoE
models. The PP=1 constraint means each GPU holds all 48 layers; model
weights + optimizer states alone (~70 GB) exceed H100 80 GB capacity.

## Minimal Runnable Command

```bash
uv run python scripts/training/run_recipe.py \
  --recipe qwen3_30b_a3b_pretrain_config \
  optimizer.optimizer_cpu_offload=True \
  optimizer.optimizer_offload_fraction=0.5 \
  train.train_iters=20 \
  train.global_batch_size=8 \
  train.micro_batch_size=1
```

## Verification

### Unit tests

```bash
uv run python -m pytest \
  tests/unit_tests/models/test_gpt_full_te_layer_autocast_spec.py -k "cpu_offload" \
  tests/unit_tests/peft/test_utils.py -k "cpu_offload" -q
```

### Success criteria

- Config validation passes for the selected offloading mode
- Training completes without OOM or NCCL errors
- Loss matches the non-offloaded baseline (max delta < 0.001)
- Memory usage drops proportionally to offload fraction

## Code Anchors

### MCore activation offload constraints

```1296:1310:3rdparty/Megatron-LM/megatron/core/transformer/transformer_config.py
        if self.cpu_offloading and (
            self.cpu_offloading_num_layers < 0 or self.cpu_offloading_num_layers >= self.num_layers
        ):
            raise ValueError(...)

        if self.cpu_offloading and self.pipeline_model_parallel_size > 1:
            raise ValueError(
                "Currently there is no support for Pipeline parallelism with CPU offloading"
            )

        if self.cpu_offloading and self.recompute_granularity is not None:
            raise ValueError(
                "CPU offloading does not work when activation recomputation is enabled"
            )
```

### MCore CUDA graph incompatibility

```1943:1944:3rdparty/Megatron-LM/megatron/core/transformer/transformer_config.py
            if self.cpu_offloading:
                raise ValueError("CUDA graphs not supported with CPU offloading.")
```

### MCore fine-grained offloading mutual exclusion

```1427:1430:3rdparty/Megatron-LM/megatron/core/transformer/transformer_config.py
        if self.fine_grained_activation_offloading:
            assert (
                not self.cpu_offloading
            ), "fine_grained_activation_offloading cannot be enabled with cpu_offloading."
```

### MCore HybridDeviceOptimizer instantiation

```480:518:3rdparty/Megatron-LM/megatron/core/optimizer/__init__.py
        if config.optimizer_cpu_offload:
            # ... setup cpu/gpu optimizer classes ...
            optimizer = HybridDeviceOptimizer(
                param_groups,
                offload_fraction=config.optimizer_offload_fraction,
                cpu_optimizer_cls=cpu_optimizer_cls,
                gpu_optimizer_cls=gpu_optimizer_cls,
                overlap_cpu_optimizer_d2h_h2d=config.overlap_cpu_optimizer_d2h_h2d,
                pin_cpu_grads=config.pin_cpu_grads,
                pin_cpu_params=config.pin_cpu_params,
            )
```

### Bridge CUDA graph guard

```232:234:src/megatron/bridge/models/gpt_full_te_layer_autocast_spec.py
        assert not config.cpu_offloading and config.recompute_granularity is None, "Cudagraphs not supported"
```

### Bridge activation offloading in PEFT

```621:631:src/megatron/bridge/peft/utils.py
        if self.config.cpu_offloading and self.config.cpu_offloading_activations:
            x.activation_offloading = True
        x, _ = self.linear_in(x)
        x = self.activation(x)
        if self.config.cpu_offloading and self.config.cpu_offloading_activations:
            x.activation_offloading = True
        x, _ = self.linear_out(x)
```

## Failure Diagnosis

| Symptom | Likely Cause | How To Confirm | Fix |
|---|---|---|---|
| `Currently there is no support for Pipeline parallelism with CPU offloading` | Activation offload + PP > 1 | Check `pipeline_model_parallel_size` | Set PP=1 or use optimizer offloading |
| `CPU offloading does not work when activation recomputation is enabled` | Activation offload + recompute | Check `recompute_granularity` | Set `recompute_granularity=null` |
| `fine_grained_activation_offloading cannot be enabled with cpu_offloading` | Both offloading modes enabled | Check both flags | Use one or the other |
| `CUDA graphs not supported with CPU offloading` | CUDA graphs + activation offload | Check `cuda_graph_impl` | Set `cuda_graph_impl="none"` |
| OOM with activation offloading | Model too large for PP=1 | Check allocated memory vs 80 GB | Use optimizer offloading with PP > 1 |
| Extreme slowdown (>4x) | 100% optimizer offload, CPU Adam bottleneck | Compare iter time at different fractions | Reduce fraction or enable `overlap_cpu_optimizer_d2h_h2d` |
| OOM at partial optimizer offload | Insufficient offload for this config | Check memory at different fractions | Increase fraction or add PP |

## Known Limitations

- Activation offloading requires PP=1, making it impractical for large models
  (30B+ MoE) that need pipeline parallelism.
- Optimizer offloading throughput penalty scales linearly (~1.9x at 25%,
  ~4.2x at 100% for Qwen3-30B-A3B).
- D2H/H2D overlap provides only ~7% speedup because CPU Adam compute is
  the dominant bottleneck.
- `fine_grained_activation_offloading` is a separate module-level approach
  that works with PP > 1 but cannot be combined with layer-level
  `cpu_offloading`.

Todos los archivos

6 archivos
SKILL.md 9.1k
Ver

Instalar nemo-mbridge-perf-cpu-offloading

Descarga y descomprime los archivos de habilidades en tu directorio .claude/skills/.

Descargar ZIP

Clona el repositorio y copia los archivos de la habilidad a tu proyecto.

git clone https://github.com/NVIDIA/skills/tree/main/skills/nemo-mbridge-perf-cpu-offloading # Copy SKILL.md to your .claude/skills/ directory

Copiar Copiar
Configuración rápida: Copia la carpeta de la habilidad en .claude/skills/ Claude detectará y utilizará automáticamente la habilidad
Repositorio NVIDIA/skills

Habilidades relacionadas

web-search
Tiempo actualizado 29 de junio de 2026
webapp-testing
Tiempo actualizado 29 de junio de 2026
lark-base
Tiempo actualizado 5 de julio de 2026
agentmail
Tiempo actualizado 29 de junio de 2026
OR