How to Implement Mixed Precision (FP16) Inference in Stable Diffusion for Faster Generation
Use the --precision autocast flag in the official CompVis/stable-diffusion scripts to enable automatic mixed precision, or convert model weights to FP16 during loading to halve VRAM usage and accelerate inference by up to 50%.
Mixed precision (FP16) inference reduces memory bandwidth and leverages Tensor Cores on NVIDIA GPUs to generate images faster without sacrificing quality. The CompVis/stable-diffusion repository provides built-in support for automatic mixed precision through torch.autocast, while also allowing advanced users to force FP16 weights for maximum efficiency. This guide covers both approaches using the actual source code implementation.
How torch.autocast Enables Mixed Precision
The inference pipeline in scripts/txt2img.py uses PyTorch’s automatic mixed precision context manager to handle FP16 conversion dynamically.
The Precision Scope Context
In [scripts/txt2img.py](https://github.com/CompVis/stable-diffusion/blob/main/scripts/txt2img.py#L14-L16), the script imports both autocast and nullcontext:
from torch import autocast
from contextlib import nullcontext
At line 288, the script selects the appropriate context based on the --precision argument:
precision_scope = autocast if opt.precision == "autocast" else nullcontext
When autocast is active, CUDA kernels automatically cast compatible operations (like matrix multiplications) to FP16 while keeping numerically sensitive operations in FP32. This happens inside the sampling loop without requiring changes to the model architecture or sampler code in [ldm/models/diffusion/ddim.py](https://github.com/CompVis/stable-diffusion/blob/main/ldm/models/diffusion/ddim.py).
Memory and Speed Benefits
Reduced VRAM consumption occurs because FP16 tensors occupy half the memory of FP32, allowing larger batch sizes or higher resolution generation on consumer GPUs. Tensor Core acceleration provides 2×–8× speedup for compatible operations by utilizing NVIDIA’s mixed-precision hardware units.
Enabling FP16 Inference via Command Line
The simplest method requires no code changes—just add the precision flag when running the standard inference scripts.
Text-to-Image with Autocast
Run the following command to enable mixed precision for txt2img generation:
python scripts/txt2img.py \
--prompt "A beautiful sunrise over mountains" \
--ckpt_path models/ldm/stable-diffusion-v1/model.ckpt \
--precision autocast \
--n_samples 4 \
--ddim_steps 50
The --precision autocast argument triggers the precision_scope context manager at line 288 of [scripts/txt2img.py](https://github.com/CompVis/stable-diffusion/blob/main/scripts/txt2img.py), wrapping the sampling loop in torch.autocast("cuda"). The same flag works identically in [scripts/img2img.py](https://github.com/CompVis/stable-diffusion/blob/main/scripts/img2img.py) for image-to-image generation.
Converting Model Weights to FP16 for Maximum Performance
For advanced scenarios, you can convert the entire model to FP16 once during loading rather than relying on per-operation autocasting. This eliminates overhead and maximizes VRAM savings.
Custom FP16 Model Loader
Replace the standard load_model_from_config call in [scripts/txt2img.py](https://github.com/CompVis/stable-diffusion/blob/main/scripts/txt2img.py#L55-L59) with this helper function:
import torch
from omegaconf import OmegaConf
from ldm.util import instantiate_from_config
def load_model_fp16(config_path: str, ckpt_path: str, device: str = "cuda"):
"""
Load Stable Diffusion checkpoint and convert all weights to FP16.
"""
config = OmegaConf.load(config_path)
pl_sd = torch.load(ckpt_path, map_location="cpu")
sd = pl_sd["state_dict"]
# Convert every parameter to half-precision before GPU transfer
for k in sd:
sd[k] = sd[k].half()
model = instantiate_from_config(config.model)
model.load_state_dict(sd, strict=False)
model.to(device) # FP16 tensors on GPU
model.eval()
return model
Then modify the loading call:
model = load_model_fp16(opt.config, opt.ckpt, device)
Key differences from autocast:
- All parameters reside permanently in
torch.float16, reducing VRAM usage by approximately 50%. - You can use
nullcontextinstead ofautocastsince the tensors are already FP16. - Warning: Some operations (batch normalization, certain activations) may become numerically unstable in pure FP16.
Safest Implementation Strategy
Combine both approaches for optimal stability and performance. Convert weights to FP16 for memory savings, but retain the autocast context to protect numerically sensitive operations:
with torch.autocast("cuda"):
samples, _ = sampler.sample(S=50,
batch_size=4,
shape=(4, 64, 64),
conditioning=cond,
verbose=False)
This configuration runs the model weights in FP16 while allowing PyTorch to automatically upcast specific operations to FP32 where necessary.
Performance Optimization Checklist
Follow these steps to maximize inference speed and minimize memory usage:
-
Enable cuDNN benchmarking before model loading to optimize kernel selection:
torch.backends.cudnn.benchmark = True -
Start with the CLI flag (
--precision autocast) for an immediate 30–50% speedup with approximately 2GB VRAM savings at 512×512 resolution. -
Convert weights to FP16 using the custom loader for an additional 10–20% speedup and further VRAM reduction, enabling larger batch sizes.
-
Verify output quality by comparing FP16 samples against full-precision runs; FP16 should produce visually indistinguishable results for most prompts, though rare numerical artifacts may require falling back to autocast-only mode.
Summary
- Automatic mixed precision is available out-of-the-box via
--precision autocastinscripts/txt2img.pyandscripts/img2img.py, utilizingtorch.autocastto dynamically cast operations to FP16. - Weight conversion to FP16 during model loading halves VRAM usage by calling
.half()on state dict tensors beforemodel.to(device). - Sampler agnostic implementation means
DDIMSampler,PLMSSampler, andDPMSolverSamplerinldm/models/diffusion/require no modifications to support mixed precision. - Combined approach of FP16 weights plus autocast context provides the best balance of speed, memory efficiency, and numerical stability.
Frequently Asked Questions
Does mixed precision inference reduce image quality in Stable Diffusion?
No, FP16 inference produces visually identical results to FP32 for most prompts and seeds. The torch.autocast context automatically keeps sensitive operations (like softmax and logarithms) in FP32 to prevent numerical instability. If you notice artifacts with pure FP16 weights, use the autocast wrapper to maintain quality while preserving most performance gains.
Which GPUs benefit most from FP16 inference?
NVIDIA GPUs with Tensor Cores (RTX 20 series and newer, Tesla V100/A100/H100) see the largest speedups—often 2× faster than FP32. Older Pascal architecture cards (GTX 10 series) support FP16 but lack Tensor Cores, providing only memory bandwidth benefits rather than computational acceleration. Always ensure your CUDA version supports the torch.autocast API (PyTorch 1.6+).
Can I use mixed precision with the img2img script?
Yes, the --precision autocast flag works identically in [scripts/img2img.py](https://github.com/CompVis/stable-diffusion/blob/main/scripts/img2img.py) because both scripts share the same precision_scope logic at line 288. The DDIM sampler and other diffusion samplers in ldm/models/diffusion/ are dtype-agnostic and operate correctly under autocast regardless of whether you are performing text-to-image or image-to-image generation.
How much VRAM does FP16 inference save?
Converting to FP16 reduces model weight memory consumption by approximately 50%, typically saving 1.5–2.5GB for the standard Stable Diffusion v1.4/v1.5 checkpoint. This allows you to increase batch sizes from 1 to 2-4 on 8GB consumer GPUs, or generate at 768×768 resolution where 512×512 previously exhausted memory. Additional savings come from activation checkpointing when using torch.autocast.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →