"Stable Diffusion" now spans several model families with different VAEs, schedulers, and prompt encoders.
SD 1.5 (512×512, CLIP) is the legacy workhorse;
SDXL (1024×1024, dual-CLIP) is the everyday default;
SD 3 / 3.5 moves to MMDiT + T5; Flux (Black Forest Labs) is the current quality leader but isn’t formally "Stable Diffusion".
Pipeline classes follow the architecture — mismatch a checkpoint and pipeline class and you get cryptic shape errors.
All snippets here use the diffusers library.
Install · authSetup
bash
# Core — the Hugging Face Diffusers library
pip install -U diffusers transformers accelerate safetensors
# Speedups — pick what your GPU supports
pip install xformers # memory-efficient attention (CUDA)
pip install bitsandbytes # 4/8-bit quantization for big checkpoints
# Adapters / utilities
pip install peft # LoRA / IP-Adapter helpers
pip install controlnet-aux # canny / depth / openpose preprocessors
pip install invisible-watermark
# Auth — many SDXL / Flux checkpoints are gated
pip install huggingface_hub
hf auth login # paste token from huggingface.co/settings/tokens
Where things liveCommon imports
from diffusers import StableDiffusionPipeline
SD 1.5 txt2img.
from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline, StableDiffusionXLInpaintPipeline
SDXL family. Three classes, three modes.
from diffusers import StableDiffusion3Pipeline
SD 3 / 3.5 MMDiT.
from diffusers import FluxPipeline
Flux.1 by Black Forest Labs.
from diffusers import ControlNetModel, StableDiffusionXLControlNetPipeline
Conditioning by edges / depth / pose.
from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image
Auto-detect pipeline class from checkpoint config.
from diffusers import DPMSolverMultistepScheduler, EulerAncestralDiscreteScheduler, DDIMScheduler, …
Samplers / schedulers. Swap via pipe.scheduler.
from diffusers.utils import load_image, make_image_grid
Convenience helpers.
Pick the right oneModels
runwayml/stable-diffusion-v1-5
Legacy 512×512, CLIP. Largest LoRA ecosystem.
stabilityai/stable-diffusion-2-1
Legacy 768×768, OpenCLIP. Skipped by community.
stabilityai/stable-diffusion-xl-base-1.0
SDXL base. 1024×1024, dual text encoders. The everyday default.
SDXL with two stacked LoRAs (pixel-art + cyberpunk), a fast Euler-A scheduler, xformers, CPU offload, and VAE tiling for headroom.
python
import torch
from diffusers import StableDiffusionXLPipeline, EulerAncestralDiscreteScheduler
pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
pipe.enable_xformers_memory_efficient_attention()
# Load two LoRAs from the Hub and assign weights
pipe.load_lora_weights("nerijs/pixel-art-xl", adapter_name="pixel")
pipe.load_lora_weights("CiroN2022/cyberpunk-style", adapter_name="cyber")
pipe.set_adapters(["pixel", "cyber"], adapter_weights=[0.7, 0.4])
# Memory savers — useful when you stack adapters
pipe.enable_model_cpu_offload() # weights to CPU between calls
pipe.enable_vae_tiling() # tiled VAE for high-res
gen = torch.Generator(device="cuda").manual_seed(7)
image = pipe(
prompt="pixel art, cyberpunk neon market street, rain, vending machines",
negative_prompt="blurry, jpeg, photoreal, text",
num_inference_steps=28,
guidance_scale=7.0,
generator=gen,
).images[0]
image.save("market.png")
pipe.unload_lora_weights() # release adapter memory
Best practiceGood to know
Match resolution to the model. SD1.5 was trained on 512×512; SDXL on 1024×1024.
Generate at the trained size, then upscale — off-aspect-ratio output at the wrong resolution produces extra limbs and tiled subjects.
Seed everything you want to compare.torch.Generator(device).manual_seed(42) is the only way to A/B prompts, samplers, or LoRAs honestly. Re-running without a seed reshuffles noise and hides the effect of your change.
DPM++ 2M Karras at 20–30 steps is a strong default. Don’t over-step — quality plateaus around 30 for most SDXL workloads, and going to 50 wastes time.
Common trapsWatch out for
VAE in fp16 produces black images on some GPUs.
Symptom: the diffusion looks fine, then decoding returns pure black. Fix: load the VAE in fp32, or use the "fp16 fix" VAE (madebyollin/sdxl-vae-fp16-fix).
Loading a Civitai checkpoint with the wrong pipeline class fails silently or noisily.
A SD1.5 single-file in StableDiffusionXLPipeline gives shape mismatches. Use AutoPipelineForText2Image or read the model card.
Stacking too many LoRAs blurs everything.
Beyond 2–3 active adapters, outputs collapse into mush. Drop weights, fuse the ones you always use, or train a single LoRA combining them.
Stable Diffusion is an open-source latent diffusion model for text-to-image generation. It encodes images into a compact latent space, adds noise, and trains a U-Net to denoise iteratively guided by a CLIP text encoder. Modern variants include SDXL (higher resolution), SD3 (multi-modal diffusion transformer), and Flux (flow matching architecture), all runnable via the Hugging Face diffusers library.
How do samplers and schedulers work in Stable Diffusion?
A scheduler (sampler) defines the denoising algorithm applied at each step. DPM++ 2M Karras and DDIM converge in 20-30 steps with high quality; Euler a is fast and creative; UniPC is efficient for SDXL. Fewer steps produce faster but lower-quality images. Change the scheduler with pipe.scheduler = SchedulerClass.from_config(pipe.scheduler.config) without reloading model weights.
What is ControlNet in Stable Diffusion?
ControlNet adds spatial conditioning to a diffusion model by feeding a preprocessed control image (edge map, depth map, pose skeleton, etc.) through a trainable copy of the encoder. This constrains the composition of the generated image without fine-tuning the base model. Load a ControlNet checkpoint with ControlNetModel.from_pretrained() and pass the condition image to the pipeline.
What is LoRA in Stable Diffusion?
LoRA (Low-Rank Adaptation) is a fine-tuning technique that injects small trainable rank-decomposition matrices into the U-Net attention layers, adding a specific style, character, or concept without modifying the full model. Load a LoRA with pipe.load_lora_weights(path) and control its strength with the cross_attention_kwargs scale parameter. Multiple LoRAs can be composed with fuse_lora().
How do I reduce VRAM usage with Stable Diffusion?
Enable CPU offloading with pipe.enable_model_cpu_offload() to move model components to CPU between uses, reducing peak VRAM from 10+ GB to around 4 GB. Use half-precision weights (torch_dtype=torch.float16) and enable_xformers_memory_efficient_attention() for additional savings. For SDXL on consumer GPUs, sequential CPU offload and fp16 together typically fit a 12 GB card.