AI/TLDR

What Is bitsandbytes? On-the-Fly Quantization

You will understand what bitsandbytes is, how it quantizes weights to 8-bit or NF4 4-bit on the fly at load time, and why it underpins QLoRA fine-tuning.

ADVANCED10 MIN READUPDATED 2026-06-14

In plain English

A large language model stores its knowledge as weights — millions or billions of numbers. By default each weight is a 16-bit floating-point value, so a model with billions of parameters needs many gigabytes of GPU memory just to load, before you run a single token through it. On a modest GPU, the model simply won't fit.

bitsandbytes — illustration
bitsandbytes — b3688296.smushcdn.com

bitsandbytes is a small library that shrinks those weights as the model loads. Instead of keeping every weight in 16 bits, it stores them in 8 bits or even 4 bits — far fewer numbers to remember — so a model that needed 16 GB might now fit in 4–6 GB. This squeezing-down is called quantization, and bitsandbytes does it on the fly rather than asking you to download a separately-prepared file.

Think of it like vacuum-sealing winter clothes for storage. The sweater is the same sweater; you've just squeezed the air out so it takes a fraction of the shelf space. When you need it, it puffs back to usable size. bitsandbytes does the same trick with weights: store them compressed, then expand the relevant ones back to higher precision for the actual math, on the spot.

Why it matters

The single biggest wall when working with open models locally is GPU memory (VRAM). It is scarce, expensive, and fixed — you can't add more without buying a new card. bitsandbytes is one of the most common ways to get under that ceiling, and it earns its place for a few concrete reasons.

  • It fits big models on small GPUs. Cutting weights from 16-bit to 4-bit roughly quarters the memory they occupy. That can be the difference between a model loading on a single consumer GPU and not loading at all.
  • It needs no extra preparation step. You don't have to find or build a pre-quantized version of the model. You point bitsandbytes at the normal full-precision weights and pass one flag — it quantizes them during loading. Any standard Hugging Face model just works.
  • It powers single-GPU fine-tuning. Its 4-bit NF4 format is the foundation of QLoRA, the technique that made it possible to fine-tune large models on one affordable GPU. Without cheap 4-bit weights, that wouldn't fit in memory at all.
  • It's deeply integrated. It plugs straight into the Hugging Face Transformers and PEFT ecosystems, so most tutorials and training scripts can turn it on with a single configuration object.

Who cares? Anyone running or training open models on limited hardware: hobbyists on a single gaming GPU, researchers stretching a lab budget, and engineers prototyping before they pay for bigger machines. If your model almost fits but not quite, on-the-fly quantization is often the first lever you reach for.

How it works

The key idea is that bitsandbytes separates storage from compute. Weights are stored in a tiny low-bit form to save memory, but when the model actually multiplies numbers together, the relevant weights are dequantized back up to a higher precision for that operation. You get the memory savings of 4-bit storage with math that stays accurate enough to be useful.

Quantization at load time

When you load a model with bitsandbytes enabled, it reads the full-precision weights and, layer by layer, maps each block of numbers onto a small set of low-bit codes. To do this without wrecking accuracy, it stores a scale factor per small block of weights, so values in that block can be reconstructed close to their originals. This is why it's called on-the-fly: the quantization happens during loading, in memory, not in a file you prepared earlier.

Dequantize for the math, then forget

During a forward pass, a layer needs its weights to multiply against the incoming activations. bitsandbytes dequantizes the compressed weights for that operation, does the matrix multiply at higher precision, and doesn't keep a full-precision copy lying around. The compact version stays in memory; the expanded version exists only for the instant the math needs it.

NF4 and the 4-bit trick

Why a special NF4 format instead of plain 4-bit integers? Neural-network weights are not spread evenly — they cluster tightly around zero in a roughly bell-shaped (normal) distribution. NF4's 16 possible codes are spaced to match that distribution, putting more resolution where the weights actually live. The result is that 4-bit NF4 preserves accuracy noticeably better than a naive 4-bit scheme, which is exactly what makes it a good base for fine-tuning.

loading a model in 4-bit NF4python
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

# Describe the quantization once.
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,            # use 4-bit storage
    bnb_4bit_quant_type="nf4",   # the NormalFloat-4 format
    bnb_4bit_compute_dtype="bfloat16",  # precision used during the math
    bnb_4bit_use_double_quant=True,     # also quantize the scale factors
)

# Transformers quantizes the weights on the fly as it loads them.
model = AutoModelForCausalLM.from_pretrained(
    "some-org/some-open-model",
    quantization_config=bnb_config,
    device_map="auto",
)

Notice the two separate settings: storage is 4-bit NF4, but bnb_4bit_compute_dtype controls the precision of the actual multiplication. That single config object is usually the entire integration — Transformers handles the rest.

On-the-fly vs pre-quantized formats

bitsandbytes is one of several ways to run a model in low precision, and the biggest distinction is when the quantization happens. bitsandbytes quantizes at load time, inside your training or inference stack. Formats like GGUF, GPTQ, and AWQ ship the model already quantized as a file you download and run.

bitsandbytesPre-quantized files (GGUF / GPTQ / AWQ)
When it quantizesAt load time, in memoryAhead of time, saved to disk
What you downloadThe normal full-precision modelA separate, already-shrunk file
Best fit forTraining & fine-tuning (QLoRA), quick PyTorch inferenceFast, repeated inference & serving
Load behaviourRe-quantizes every time you loadLoads the compact file directly
Calibration stepNone neededGPTQ/AWQ use a calibration dataset

A simple way to remember it: reach for *bitsandbytes when you want to train or fine-tune* a model that won't otherwise fit, because it slots into the PyTorch training loop and is the basis of QLoRA. Reach for a pre-quantized format when you just want to serve the model fast and repeatedly**, because the heavy quantization work is already baked into the file. For a deeper side-by-side of the serving formats, see GGUF vs GPTQ vs AWQ.

QLoRA: the killer use case

The reason bitsandbytes is so widely known is QLoRA, and it's worth seeing how the pieces snap together. Normally, fine-tuning a large model means holding its weights, gradients, and optimizer state in memory all at once — far more than fits on a single affordable GPU. QLoRA shrinks the dominant cost.

The trick is that the giant base model is loaded once in 4-bit and frozen — it never changes, so it costs only memory, not training overhead. The only weights that actually learn are the small LoRA adapters bolted on top, and those are tiny. bitsandbytes supplies the cheap 4-bit base; LoRA supplies the cheap trainable part. Together they bring fine-tuning of a large model within reach of one GPU. The dedicated QLoRA explainer walks through the full method.

Practical tips and pitfalls

bitsandbytes is easy to switch on, which makes it easy to switch on without thinking about the trade-offs. A few things to keep in mind.

  • 8-bit vs 4-bit is a quality/memory dial. 8-bit keeps quality closest to the original and roughly halves memory; 4-bit (NF4) saves the most but accepts a little more error. Start at 8-bit if quality is critical, drop to 4-bit when memory forces your hand.
  • It re-quantizes on every load. Because the work happens at load time, large models can take noticeably longer to load than a pre-quantized file that's read straight off disk. For a service that restarts often, a pre-quantized format may serve better.
  • Compute dtype matters. Storing weights in 4-bit while computing in bfloat16 keeps the math stable. Mismatched or overly aggressive settings can hurt output quality for no extra memory gain.
  • It is GPU-centric. bitsandbytes is built around CUDA-style GPU kernels; it is not the tool for CPU-only or Apple Silicon inference, where formats like GGUF (via llama.cpp) are the usual choice.
  • Inference of a quantized model is not the same as deploying a pre-quantized one. A bitsandbytes-loaded model lives inside your Python/PyTorch process; it is great for experimentation, less ideal as a hardened serving artefact.

Going deeper

Once the basics click, a few finer points explain why bitsandbytes behaves the way it does — and when to look past it.

Outliers and the int8 path. A core finding behind bitsandbytes' 8-bit mode is that a small number of weight values are unusually large — outliers — and they carry disproportionate importance. Naively quantizing them destroys quality. The LLM.int8() approach handles those rare large values separately at higher precision while compressing the bulk of ordinary weights to 8-bit. The lesson generalises: good quantization is less about averaging everything down and more about protecting the values that matter most.

Double quantization. In 4-bit mode, bitsandbytes also quantizes the scale factors themselves (the per-block numbers used to reconstruct weights). It sounds like a small thing, but across a large model those scales add up, and quantizing them too — "double quantization" — squeezes out extra memory for a negligible quality cost. It's a neat example of how the savings come from many small, careful decisions rather than one big switch.

Where it sits among formats. bitsandbytes shines for training and quick PyTorch inference. For serving — where you load once and answer many requests as fast as possible — purpose-built inference formats and engines often win, because they can fuse the dequantization into highly optimised kernels and skip the per-load quantization. Understanding Q4 vs Q8 vs FP16 and the broader GGUF format helps you pick the right tool for each stage.

The honest limits. Quantization buys memory by spending precision, and there is no free lunch: every bit you drop is information the model no longer has. NF4, double quantization, and outlier handling push that trade as far as it sensibly goes, but they don't repeal it. The durable mental model is the one we started with — store small, compute when needed — and the durable discipline is to measure what the squeeze cost you on the work you actually care about.

FAQ

What is bitsandbytes used for?

It quantizes a model's weights to 8-bit or 4-bit at load time so large models fit into limited GPU memory. Its most famous use is QLoRA, where its 4-bit NF4 format lets you fine-tune big models on a single affordable GPU.

What is the difference between 8-bit and 4-bit (NF4) in bitsandbytes?

8-bit stores each weight in 8 bits, roughly halving memory while keeping quality very close to the original. 4-bit NF4 stores weights in just 4 bits using a format tuned to how neural-network weights are distributed, saving more memory at the cost of a little more accuracy loss. Pick 8-bit for quality, 4-bit when memory forces it.

Is bitsandbytes the same as GGUF or GPTQ?

No. bitsandbytes quantizes on the fly at load time inside your PyTorch stack, starting from the normal full-precision model. GGUF, GPTQ, and AWQ are pre-quantized file formats you download already shrunk. bitsandbytes is favoured for training and fine-tuning; the file formats are favoured for fast, repeated serving.

Does bitsandbytes reduce model quality?

A little. Lower precision means weights are stored less exactly, so some accuracy is lost. NF4, double quantization, and outlier-aware 8-bit are designed to keep that loss small, but it is never exactly zero — always evaluate the quantized model on your own task.

Why does QLoRA depend on bitsandbytes?

QLoRA freezes a large base model in 4-bit and trains only small LoRA adapters on top. bitsandbytes supplies that 4-bit NF4 base — the part that makes the model small enough to fit on one GPU. The "Q" in QLoRA refers to that quantized base model.

Can I use bitsandbytes on a CPU or a Mac?

It is built around GPU (CUDA-style) kernels, so it is not the right tool for CPU-only or Apple Silicon inference. For those, formats and engines like GGUF with llama.cpp, or Apple's MLX on Mac, are the usual choices.

Further reading