#3787·axolotl

Expert-granularity CPU offload for quantized MoE: 30B-A3B QLoRA in ~7 GB (single resident expert layer, extends the layer_offloading idea)

Author: pjordanandrsnCreated Jul 2, 2026Updated Jul 19, 2026
Labelswaiting for reporter

Use case

quantize_moe_experts (#3439) got fused-expert 4-bit working, and #3747's selective dequant lowered the ceiling further — but the floor for a 30B-class MoE QLoRA is still ~17–24 GiB reserved, so 12–16 GB cards are out. Demand for exactly that exists in the tracker (#3530 OOMs a 32 GB card on gpt-oss-20b; #3402 asks for lower-VRAM MoE training generally).

The missing piece is granularity: layer_offloading (#3512) already proves the pinned-CPU + prefetch-stream pattern in-tree, but at whole-decoder-layer scope its measured savings are modest (~3 GB on Qwen3.5-35B) because attention/router params are small — in a fine-tuned MoE, ~90 % of frozen bytes are the experts. Offloading only the quantized expert tensors, with a single resident expert layer on GPU and prefetch of layer N+1 during layer N's compute, moves almost all of those bytes off-device while touching nothing else.

Evidence it works (measured, single GPU)

I've implemented this out of tree (experts4bit-qlora, MIT) against transformers-v5 fused experts, and measured on a 12 GB RTX A2000:

model peak VRAM with expert offload without
Qwen3-30B-A3B QLoRA 7.16 GB OOM
Gemma-4-26B-A4B QLoRA 8.47 GB OOM
OLMoE-1B-7B QLoRA 2.57 GB (from 5.97) 5.97 GB

Cost is ~+11 % s/step (OLMoE; pinned-memory H2D copies overlap compute for the larger models). Correctness: the frozen 4-bit forward is bit-identical with offload on/off, including through use_reentrant=False gradient-checkpoint recompute (the recompute re-fetches the same quantized bytes; adapters stay resident and trainable).

Proposed shape

An expert-granularity mode that composes with quantize_moe_experts — conceptually layer_offloading restricted to the expert parametrizations: pin the packed 4-bit expert storage in CPU RAM at load, keep one layer's experts on GPU, prefetch the next layer's on a side stream during compute, evict after use. Scope for a first PR: single-GPU only (explicitly out of scope: FSDP/DDP interaction, expert-parallel), gated behind a config flag, with the checkpointing-recompute path covered by tests.

I'm happy to write the PR against axolotl's parametrization representation (either in-tree as an extension of the layer_offloading mixin, or as an axolotl.integrations plugin — maintainer preference). The numbers above are reproducible from the linked repo; the same primitive is also proposed upstream in bitsandbytes (bitsandbytes-foundation/bitsandbytes#1965, draft until their v0.50), and an in-tree implementation here could switch to that once it lands.

Source: axolotl-ai-cloud/axolotl