Home

Awesome

MARS: Unleashing the Power of Variance Reduction for Training Large Models

This repository contains the official code for the paper MARS: Unleashing the Power of Variance Reduction for Training Large Models.

Authors: Huizhuo Yuan*, Yifeng Liu*, Shuang Wu, Xun Zhou, Quanquan Gu

đź”” NEWS

About MARS

MARS (Make vAriance Reduction Shine) is a unified optimization framework designed to address the inherent challenges of training large models. Traditional adaptive gradient methods like Adam and AdamW often suffer from high stochastic gradient variance, while variance reduction techniques have struggled to gain practical impact in deep learning. At its core, MARS comprises two major components: (1) a scaled stochastic recursive momentum, which provides a variance-reduced estimator of the full gradient for better gradient complexity; and (2) the preconditioned update, which approximates the second-order Newton's method for better per-iteration complexity. By combining preconditioned gradient methods with variance reduction, MARS achieves the best of both worlds, accelerating the search for critical points in optimization.

The MARS framework is built on the following preconditioned variance-reduced updates

$$ \mathbf{c}_t = \nabla f(\mathbf{x}_t, \mathbf{\xi}_t)+\underbrace{{\color{red}\gamma_t} \frac{\beta_{1}}{1-\beta_{1}} \left(\nabla f(\mathbf{x}_t, \mathbf{\xi}_t)-\nabla f(\mathbf{x}_{t-1}, \mathbf{\xi}_t)\right)}_{\text{scaled gradient correction}} $$

$$ \tilde{\mathbf{c}}_t = \text{Clip}(\mathbf{c}_t,1) = \begin{cases} \frac{\mathbf{c}_t}{\|\mathbf{c}_t\|_2} & \text{if } \|\mathbf{c}_t\|_2 > 1,\ \mathbf{c}_t & \text{otherwise}. \end{cases} $$

$$ \mathbf{m}_t = \beta_1 \mathbf{m}_{t-1} + (1-\beta_{1})\tilde{\mathbf{c}}_t $$

$$ \mathbf{x}_{t+1} = \arg\min_{\mathbf{x} \in \mathbb{R}^d} \left\{\eta_t \left\langle \mathbf{m}_t, \mathbf{x} \right\rangle + \frac{1}{2} \|\mathbf{x} - \mathbf{x}_t \|_{\mathbf{H}_t}^2\right\} $$

Here ${\color{red}\gamma_t}$ is a scaling parameter that controls the strength of gradient correction.

Instantiations of MARS

Under the MARS framework, we provide three instantiations based on different Hessian matrix approximations: MARS-AdamW, MARS-Lion, and MARS-Shampoo. Please note that the hyperparameters in this framework are tuned on MARS-AdamW. When using other instantiations, it is essential to tune the hyperparameters—particularly the learning rates—for optimal performance.

MARS-AdamW

(Enable with mars_type="mars-adamw" in mars.py)

The Hessian matrix approximation is defined as:

$$ \mathbf{v}_t =\beta_2 \mathbf{v}_{t-1}+(1-\beta_2) \big(\nabla f(\mathbf{x}_t, \mathbf{\xi}_t)\big)^2 $$

$$ \mathbf{H}_t := \sqrt{\text{diag}\Big(\mathbf{v}_t\Big)}\cdot \frac{1 - \beta_1^t}{\sqrt{1 - \beta_2^t}}. $$

MARS-Lion

(Enable with mars_type="mars-lion" in mars.py)

The Hessian matrix approximation is defined as:

$$ \mathbf{H}_t := \sqrt{\text{diag}(\mathbf{m}_t^2)}. $$

MARS-Shampoo

(Enable with mars_type="mars-shampoo" in mars.py)

The preconditioner can be seen as an orthogonal mapping operator:

$$ \mathbf{U}_t, \mathbf{\Sigma}_t, \mathbf{V}_t = \text{SVD}(\mathbf{G}_t),\qquad \mathbf{x}_{t+1} =\mathbf{x}_t-\eta_t\mathbf{U}_t\mathbf{V}_t^\top. $$

In practice, we use the Newton-Schulz iteration to accelerate and approximate the solution of SVD problem.

Performance of MARS Compared to Baselines

Experimental results for MARS are based on the MARS-AdamW instantiation, unless otherwise stated. In our experiments, gradients are calculated once per sample and per update (MARS-approx in our paper). Performing exact gradient computation with two evaluations per update, as in the exact form of MARS, can slightly enhance performance but at the cost of doubling the computational expense. For more details, refer to our paper.

MARS consistently outperforms AdamW and the Muon optimizers across GPT-2 models:

GPT-2 smallGPT-2 mediumGPT-2 large
<img src="assets/val_small.png" width="350"><img src="assets/val_medium.png" width="350"><img src="assets/val_large.png" width="350">
Best Val LossGPT-2 Small (5B tokens)GPT-2 Medium (5B tokens)GPT-2 Large (5B tokens)GPT-2 Small (20B tokens)GPT-2 Medium (20B tokens)GPT-2 Large (20B tokens)GPT-2 Small (50B tokens)GPT-2 Medium (50B tokens)GPT-2 Large (50B tokens)
AdamW3.1933.0843.0133.0242.8212.7412.8852.6912.561
Muon3.1653.0092.9153.0062.8132.6912.9012.6882.573
MARS-exact3.107TBDTBD2.980TBDTBD2.847TBDTBD
MARS-approx3.1082.9692.8762.9812.7632.6472.8492.6362.518

MARS can achieve better test loss and accuracy than AdamW and the Muon optimizers on CIFAR-10 and CIFAR-100 datasets with ResNet-18 and MultiStepLR(optimizer, milestones=[100, 150], gamma=0.1) scheduler (We display the best results for each optimizer with grid search of base learning rate within [1e-5, ..., 1e-1]):

DatasetCIFAR-10CIFAR-100
Test loss<img src="assets/cifar10_test_loss.png" width="350"><img src="assets/cifar100_test_loss.png" width="350">
Test Accuracy<img src="assets/cifar10_test_acc.png" width="350"><img src="assets/cifar100_test_acc.png" width="350">
Best Test lossCIFAR-10CIFAR-100
AdamW0.3062.608
Muon0.2301.726
MARS-approx0.1990.971
Best Test Accuracy (%)CIFAR-10CIFAR-100
AdamW73.794.81
Muon74.6495.08
MARS-approx76.9795.29

Efficiency of MARS

The MARS algorithm can achieve better performance not only within the same number of training steps, but also within the same training time:

GPT-2 smallGPT-2 mediumGPT-2 large
<img src="assets/time_small.png" width="350"><img src="assets/time_medium.png" width="350"><img src="assets/time_large.png" width="350">

Training GPT-2 from Scratch:

Install Dependencies

$ pip install torch==2.1.2 transformers==4.33.0 datasets tiktoken numpy==1.26.4 wandb

Data Preparation

Prepare the OpenWebText data following nanoGPT:

$ python data/openwebtext/prepare.py

Start Training

To train a model using the MARS optimizer, run the following command:

$ torchrun --standalone --nproc_per_node=8 MARS/train_mars.py config/${your_config_file}

This command initiates the training of a GPT-2 model on the OpenWebText dataset using the MARS optimizer. All relevant hyperparameters—training, model, and optimizer—are specified in the configuration file (${your_config_file}). These parameters can be adjusted directly in the configuration file or through the bash script.

Hyperparameter Details

Model Hyperparameters:

Optimizer Hyperparameters:

Training Hyperparameters:

For more detailed hyperparameter examples, refer to:


Reproducing Our Results

Reproducing GPT-2 Small (125M) Results

Training with MARS using

$ bash scripts/run_mars_small.sh

or

$ torchrun --standalone --nproc_per_node=8 \
      MARS/train_mars.py \
      config/train_gpt2_small_mars.py \
      --batch_size=15 \
      --gradient_accumulation_steps=4

Reproducing GPT2 Medium (355M) Results

Training with MARS using

$ bash scripts/run_mars_medium.sh

or

$ torchrun --standalone --nproc_per_node=8 \
      MARS/train_mars.py \
      config/train_gpt2_medium_mars.py \
      --batch_size=15 \
      --gradient_accumulation_steps=4

Reproducing GPT2 Large (770M) Results

Training with MARS using

$ bash scripts/run_mars_large.sh

or

$ torchrun --standalone --nproc_per_node=8 \
      MARS/train_mars.py \
      config/train_gpt2_large_mars.py \
      --batch_size=5 \
      --gradient_accumulation_steps=12

Reproducing Baseline Results

To reproduce the AdamW baseline:

bash scripts/run_adamw_{small/medium/large}.sh

To reproduce the Muon baseline following modded-nanogpt:

bash scripts/run_muon_{small/medium/large}.sh

Please adjust nproc_per_node, batch_size, and gradient_accumulation_steps accordingly if you use other hardware setup. Make sure their product equals 480.

Hyperparameters for GPT-2 models

Model NameModel Sizelr for AdamWlr for Muonlr for MARSlr_1d for MARSwd for AdamWwd for Muonwd for MARS
GPT-2 small125M6e-42e-26e-33e-31e-10.01e-2
GPT-2 medium355M3e-41e-23e-31.5e-31e-10.01e-2
GPT-2 large770M2e-46.67e-32e-31e-31e-10.01e-2

Note that different hyperparameters may benefit different stages of training. For the GPT-2 Small model, our MARS optimizer is tuned to prioritize the best final validation performance. If faster progress in the earlier stages of training is desired, using wd=1e-3 may provide better results.

Customized Training

To build your own training pipeline on other architectures and datasets, use the following template as an example:

import torch
import torch.nn.functional as F
from mars import MARS

# init model loss function and input data
model = Model()
data_loader = ...

# init the optimizer
optimizer = MARS(model.parameters(), lr=1e-3, betas=(0.9, 0.95), gamma=0.025)

total_bs = len(data_loader)
bs = total_bs * block_size
k = 10
iter_num = -1

# training loop
for epoch in range(epochs):
    for X, Y in data_loader:
        # standard training code
        logits, loss = model(X, Y)
        loss.backward()
        optimizer.step(bs=bs)
        optimizer.zero_grad(set_to_none=True)
        optimizer.update_last_grad()
        iter_num += 1

Star History

Star History Chart

Citation

If you find this repo useful for your research, please consider citing the paper

@article{yuan2024mars,
  title={MARS: Unleashing the Power of Variance Reduction for Training Large Models},
  author={Yuan, Huizhuo and Liu, Yifeng and Wu, Shuang and Zhou, Xun and Gu, Quanquan},
  journal={arXiv preprint arXiv:2411.10438},
  year={2024}
}

Acknowledgements

This repo is built upon nanoGPT, levanter and Sophia, we thank the authors for their great work!