Fine-Tuning Image Models
This guide covers everything you need to train custom image models: from choosing a fine-tuning method and preparing your dataset, through configuring training parameters, to evaluating and deploying the result. The focus is on LoRA (Low-Rank Adaptation) as the most practical method for consumer hardware, with coverage of alternatives for specialized use cases.
Methods Comparison
There are several approaches to customizing image generation models. Each makes different trade-offs between output quality, training cost, composability, and hardware requirements.
| Method | Output Size | VRAM | Training Time | Composable? | Best For |
|---|---|---|---|---|---|
| LoRA | 4–200 MB | 8+ GB | 30–90 min | Yes | Styles, characters, concepts |
| QLoRA | 4–200 MB | 6+ GB | 45–120 min | Yes | Same as LoRA on lower VRAM |
| DreamBooth | 2–7 GB | 12+ GB | 1–4 hours | No | Specific subjects with high fidelity |
| Textual Inversion | 4–16 KB | 8+ GB | 2–8 hours | Yes | Simple concepts, embeddings |
| Full Fine-Tune | 2–7 GB | 24+ GB | 4–24 hours | No | Massive style shifts, new domains |
| LyCORIS | 8–300 MB | 10+ GB | 45–120 min | Yes | Complex styles needing more expressiveness than LoRA |
Decision Flowchart
Start with LoRA — it covers 90% of use cases with the best balance of quality, speed, and composability. Only move to other methods when LoRA falls short:
- Need to stack multiple concepts? → LoRA (composable, apply multiple at inference)
- Only 6–8 GB VRAM? → QLoRA (quantized base model during training)
- Need exact likeness of a face/object? → DreamBooth + LoRA (DreamBooth precision, LoRA file size)
- Just need a trigger word for a concept? → Textual Inversion (tiny output, fast to share)
- LoRA can’t capture the style complexity? → LyCORIS (LoHA or LoKr for higher expressiveness)
- Entire model needs to change domain? → Full Fine-Tune (requires 24+ GB VRAM or cloud)
Dataset Preparation
Dataset quality is the single biggest factor in training results. A well-curated 20-image dataset beats a sloppy 200-image one every time.
Resolution by Model
| Base Model | Native Resolution | Bucket Range | Notes |
|---|---|---|---|
| SD 1.5 | 512×512 | 256–768 | Oldest, widest compatibility |
| SDXL | 1024×1024 | 512–1536 | Best balance for most use cases |
| FLUX | 1024×1024 | 512–2048 | Requires more VRAM; best prompt adherence |
Captioning Strategies
Every training image needs a text caption describing its content. The captioning strategy you choose affects how the model learns and how you prompt it later.
| Strategy | Format | Best For | Example |
|---|---|---|---|
| Natural Language | Full sentences | SDXL, FLUX | A woman with red hair standing in a garden at sunset |
| Booru Tags | Comma-separated tags | SD 1.5, anime models | 1girl, red hair, garden, sunset, standing |
| Hybrid | Tags + description | Any model | a photo of sks woman, red hair, standing in a garden at sunset |
Auto-Captioning Tools
Manual captioning is most accurate but time-consuming. These tools auto-generate captions that you can review and refine:
| Tool | Output Style | Speed | Quality | Notes |
|---|---|---|---|---|
| BLIP-2 | Natural language | ~1s/image | Good | Best for photo-realistic datasets |
| WD14 Tagger | Booru tags | ~0.5s/image | Good | Best for anime/illustration datasets |
| Florence-2 | Natural language | ~2s/image | Very good | Most detailed; handles complex scenes |
Multi-Concept Directory Structure
When training multiple concepts (e.g., a character and a style), organize images into separate directories with repeats:
# Directory structure for multi-concept trainingdataset/10_sks_character/ # 10 repeats, trigger: sks_characterimage01.pngimage01.txt # caption fileimage02.pngimage02.txt...5_xyz_style/ # 5 repeats, trigger: xyz_stylestyle01.pngstyle01.txt...reg/ # regularization images (optional)1_person/reg001.png...
The number prefix (e.g., "10_") controls how many times each image is repeated per epoch. Use higher repeats for smaller concept sets and lower repeats for larger ones to balance training.
Regularization Images
Regularization images prevent "language drift" — where the model forgets what a generic person/object looks like and always generates your trained subject. Generate 200–500 images using the base model with generic prompts matching your subject class (e.g., "a photo of a person" for a character LoRA).
Trigger Words
A trigger word is a unique token that activates your trained concept at inference time. Choose something that doesn’t exist in the model’s vocabulary to avoid collisions:
| Approach | Example | Pros | Cons |
|---|---|---|---|
| Random letters | sks, ohwx, zxy | No vocabulary collision | Hard to remember |
| Descriptive prefix | sks_character, xyz_style | Readable and unique | Slightly longer |
| Common word | portrait, landscape | Easy to remember | Collides with existing vocabulary — avoid |
Place the trigger word at the beginning of every caption. Consistency is critical: if some captions omit the trigger word, the model may not learn to associate it with your concept.
Image Preprocessing
Before adding images to your dataset, preprocess them for consistency:
- Remove images with text overlays, watermarks, or borders
- Crop to focus on the subject (leave some context but remove unnecessary background)
- Ensure consistent lighting direction across the set if possible
- Remove near-duplicate images — they waste training compute on redundant data
- For face training: include at least 3 different angles (front, 3/4 view, profile)
Dataset Quality Scoring
Before training, score your dataset against this checklist. Aim for all items checked:
- All images at or above native resolution (no upscaled low-res)
- Consistent subject across all images (same character/style/concept)
- Variety of angles, lighting, and backgrounds
- No watermarks, text overlays, or compression artifacts
- Every image has a reviewed caption (auto-generated captions manually checked)
- Trigger word consistently present in all captions
- 15–50 images for characters, 50–200 for styles
- Regularization images prepared (for subject LoRAs)
Kohya SS Reference
Kohya SS is the most widely used LoRA training tool. It provides a GUI that maps to the underlying training script parameters. Here’s a tab-by-tab walkthrough of the key settings.
Source Model Tab
- Pretrained model — path to the base model checkpoint (e.g., sd_xl_base_1.0.safetensors)
- Model type — SD 1.5, SD 2.x, or SDXL (must match your checkpoint)
- V2 / V-parameterization — enable only for SD 2.x models
- Save precision — fp16 recommended (half the file size, negligible quality loss)
Folders Tab
- Image folder — parent directory containing your concept subfolders (e.g., dataset/)
- Regularization folder — directory with class-generic images (leave empty to skip)
- Output folder — where trained LoRA files are saved
- Log folder — TensorBoard logs for monitoring training
Parameters Tab
- Learning rate — controls how fast the model learns (see Training Parameters section)
- Network rank (dim) — LoRA rank; higher = more expressive but larger file
- Network alpha — scaling factor; typically set equal to rank or half of rank
- Batch size — images per step; limited by VRAM
- Epochs — number of full passes through the dataset
- Optimizer — algorithm for weight updates (see Optimizer Selection section)
- LR scheduler — how learning rate changes over time (cosine, constant, linear)
Advanced Tab
- Noise offset — improves dark/light scene generation (see Optimizer Selection)
- Clip skip — skip final CLIP layers; 1 for realism, 2 for anime
- Mixed precision — fp16 or bf16 to reduce VRAM usage
- Gradient checkpointing — trades speed for VRAM; enable on 8–12 GB cards
- Cache latents — pre-compute VAE latents; saves VRAM and speeds up training
- Shuffle captions — randomize tag order per step (recommended for booru-style captions)
Complete Field Reference
Here is a quick-reference table of the most commonly adjusted fields across all tabs:
| Field | Tab | Default | Recommended Range |
|---|---|---|---|
| Pretrained model | Source Model | (none) | Path to .safetensors base model |
| Network rank | Parameters | 4 | 8–128 (see VRAM tier table) |
| Network alpha | Parameters | 1 | Equal to rank or half of rank |
| Batch size | Parameters | 1 | 1–4 (VRAM dependent) |
| Noise offset | Advanced | 0 | 0.0–0.1 (style dependent) |
| Clip skip | Advanced | 1 | 1 (realism) or 2 (anime) |
Training Parameters
These recommended parameters are starting points organized by VRAM tier. Adjust based on your dataset size and target quality.
| Parameter | What It Controls | 8 GB VRAM | 12 GB VRAM | 24 GB VRAM |
|---|---|---|---|---|
| Network Rank | LoRA expressiveness / file size | 8–16 | 16–32 | 32–128 |
| Network Alpha | Scaling factor (affects effective LR) | 8 | 16 | 16–64 |
| Batch Size | Images per training step | 1 | 1–2 | 2–4 |
| Learning Rate | Speed of weight updates | 1e-4 | 1e-4 | 1e-4 – 5e-5 |
| Text Encoder LR | Prompt understanding adaptation | 5e-5 | 5e-5 | 5e-5 |
| Epochs | Full dataset passes | 6–15 | 6–15 | 6–20 |
| LR Scheduler | How LR changes over training | cosine | cosine | cosine |
| Mixed Precision | VRAM usage reduction | fp16 | fp16 or bf16 | bf16 |
| Gradient Checkpointing | Trades speed for VRAM | Required | Recommended | Optional |
| Cache Latents | Pre-compute VAE latents | Required | Required | Recommended |
The total number of training steps is: (images × repeats × epochs) / batch_size. For a 30-image dataset with 10 repeats, 10 epochs, and batch size 1, that’s 3,000 steps — typically a good starting point.
Optimizer Selection
The optimizer controls how weight updates are computed. The right choice depends on whether you want to tune the learning rate manually or let the optimizer handle it.
| Optimizer | LR Tuning Required? | VRAM Overhead | Speed | Best For |
|---|---|---|---|---|
| AdamW8bit | Yes | Low | Fast | Default choice; reliable with known LR |
| Prodigy | No (auto) | Medium | Medium | Best for beginners; auto-tunes LR |
| DAdaptation | No (auto) | High | Slow | Alternative to Prodigy; more conservative |
| SGD | Yes | Very low | Fast | Minimal VRAM; less stable convergence |
| Adafactor | No (auto) | Very low | Medium | Lowest VRAM of adaptive optimizers |
Noise Offset by Style
Noise offset helps the model generate very dark or very bright scenes that are underrepresented in typical training data. The ideal value depends on your target art style:
| Target Style | Noise Offset | Rationale |
|---|---|---|
| Flat anime / cel-shading | 0.0–0.02 | Flat colors rarely need extreme brightness/darkness |
| Semi-realistic | 0.03–0.06 | Moderate range for mixed lighting scenarios |
| Hyper-realistic / photography | 0.06–0.1 | Photos often have deep shadows and bright highlights |
Output Formats & Usage
Trained LoRAs are saved in SafeTensors format (.safetensors). This is the standard format supported by all major inference tools.
Using LoRAs in Different Tools
| Tool | LoRA Directory | How to Apply |
|---|---|---|
| ComfyUI | models/loras/ | Add a LoRA Loader node, select the file, set strength |
| Fooocus | models/loras/ | Advanced tab → LoRA section → select file and weight |
| A1111 WebUI | models/Lora/ | Add <lora:filename:weight> to your prompt |
Strength Guidance
LoRA strength (also called weight) controls how strongly the LoRA affects the output. The ideal range depends on how the LoRA was trained:
- 0.5–0.7 — subtle influence; good for style mixing
- 0.7–1.0 — standard range for most LoRAs
- 1.0–1.5 — strong effect; may cause artifacts if LoRA was overtrained
Stacking Multiple LoRAs
LoRAs are composable — you can apply multiple simultaneously. Rules for stacking:
- Keep total combined weight under 1.5 (e.g., two LoRAs at 0.7 each = 1.4 total)
- Style + subject LoRAs stack well; two subject LoRAs often conflict
- Apply the most important LoRA first (highest in the chain/prompt)
- If results degrade, reduce individual weights before removing a LoRA
Base Model Compatibility
LoRAs are locked to their base model architecture. An SDXL LoRA only works with SDXL-based models; an SD 1.5 LoRA only works with SD 1.5-based models. Custom finetunes of the same architecture (e.g., DreamShaper XL, which is based on SDXL) are compatible.
Evaluating Your LoRA
Training a LoRA is only half the work. Systematic evaluation tells you whether the training was successful and whether more epochs or parameter changes would help.
Visual A/B Testing
Generate the same prompt with and without the LoRA, using the same seed. Compare side by side:
- Does the LoRA add the intended concept without degrading other elements?
- Is the trigger word necessary to activate the concept, or does it leak into all generations?
- Are colors, composition, and detail level consistent with the base model?
Generalization Test
Test the LoRA with prompts it was NOT trained on. A well-trained LoRA generalizes to new contexts:
# If you trained a character LoRA, try:sks_character in a spacesuit, standing on Mars, dramatic lightingsks_character as a medieval knight, oil painting stylesks_character reading a book in a cozy library, warm lighting# If you trained a style LoRA, try:a cyberpunk city at night, neon lights, xyz_stylea still life of fruit on a table, xyz_stylea portrait of an elderly man, xyz_style
If the LoRA only works with prompts very similar to the training data, it may be overtrained. Reduce epochs or increase dataset diversity.
Strength Sweep
Generate the same prompt at strengths 0.4, 0.6, 0.8, 1.0, and 1.2 using the same seed. A healthy LoRA shows a smooth gradient from subtle to strong effect. Red flags:
- Artifacts or color shifts at 0.8+ → overtrained
- No visible effect until 1.0+ → undertrained or rank too low
- Sudden quality collapse at 1.2 → normal; stay within 0.6–1.0 range
Checkpoint Comparison
If you saved checkpoints at multiple epochs (recommended: every 2–3 epochs), compare them with the same prompt and seed. Pick the epoch that gives the best balance between concept fidelity and generalization. Earlier checkpoints generalize better; later ones capture the concept more precisely.
TensorBoard Monitoring
Kohya SS outputs TensorBoard logs that let you monitor training in real-time. Key metrics to watch:
| Metric | Healthy Range | Red Flag |
|---|---|---|
| loss/epoch | Gradual decrease, stabilizing at 0.05–0.15 | Flat line (not learning) or spikes (instability) |
| lr/epoch | Smooth cosine curve (with cosine scheduler) | Erratic jumps (optimizer issue) |
| loss variance | Decreasing over time | Increasing (model oscillating, LR too high) |
# Launch TensorBoard to view training logstensorboard --logdir /path/to/log/folder --port 6006# Then open http://localhost:6006 in your browser
Stop training early if loss starts increasing (overfitting) or if visual inspection of checkpoint outputs shows degradation. The last checkpoint before quality drops is typically the best.
Advanced Techniques
Once you’re comfortable with basic LoRA training, these techniques can improve results for specific use cases.
Network Types (LyCORIS)
LyCORIS is a family of LoRA-like methods that decompose weight updates differently. Available types in Kohya SS:
| Type | Expressiveness | File Size | When to Use |
|---|---|---|---|
| LoRA (standard) | Good | Small | Default for most use cases |
| LoHA | Higher | Medium | Complex styles that LoRA can’t capture |
| LoKr | Highest | Larger | Maximum expressiveness needed |
| DyLoRA | Variable | Variable | Automatically finds optimal rank during training |
Aspect Ratio Bucketing
Instead of cropping all images to squares, aspect ratio bucketing groups images by similar dimensions and trains on each group. This preserves composition and avoids cropping out important content.
- Enable in Kohya SS: check "Enable bucket" in the Parameters tab
- Set min/max resolution to match your model (e.g., 512–1536 for SDXL)
- Bucket resolution step: 64 (default; smaller steps = more buckets = more VRAM)
Caption Dropout
Randomly dropping captions during training forces the model to associate the visual concept with the trigger word alone, improving trigger word reliability. Set caption dropout rate to 0.05–0.1 (5–10% of steps use empty captions).
Tag Weighting
When using booru-style captions, you can weight specific tags to control training emphasis. In Kohya SS, use parentheses: "(important_tag:1.5), normal_tag, (minor_tag:0.5)". Higher weights make the model pay more attention to that tag during training.
Target Modules Selection
By default, LoRA trains on the UNet attention layers. You can target additional modules for different effects:
- UNet attention only (default) — fastest training, good for most styles and subjects
- UNet attention + text encoder — better prompt response; use lower LR for text encoder (5e-5)
- All UNet layers — maximum expressiveness; larger file, longer training
- Conv layers — can help with texture/pattern-heavy concepts
FLUX-Specific Training
FLUX models use a different architecture (DiT/MMDiT) than Stable Diffusion (UNet). Key differences for LoRA training:
- FLUX requires more VRAM: 12 GB minimum for QLoRA, 24 GB for standard LoRA
- Use lower learning rates (1e-5 to 5e-5) compared to SDXL (1e-4)
- Training is slower per step but often needs fewer total steps
- Captions should be natural language (FLUX was trained on detailed descriptions, not tags)
- Rank 16–32 is usually sufficient; FLUX responds well to low-rank adaptation
Multi-Resolution Training
For maximum quality, train at multiple resolutions simultaneously. This teaches the model to generate consistent results across different output sizes:
- Enable aspect ratio bucketing (covers resolution variety)
- Provide images at the highest resolution you can (the trainer downsamples as needed)
- For SDXL: include images in portrait (768×1344), landscape (1344×768), and square (1024×1024) orientations
Troubleshooting
Common problems and their solutions. Most training issues come from three sources: dataset quality, learning rate, and VRAM limits.
| Problem | Symptoms | Cause | Fix |
|---|---|---|---|
| Overtrained / fried | Artifacts at strength 0.8+, colors burned, poor generalization | Too many epochs or LR too high | Use an earlier checkpoint; reduce epochs by 30–50%; lower LR |
| Undertrained | No visible effect even at strength 1.0+ | Too few steps, LR too low, or rank too low | Increase epochs, raise LR slightly, or increase network rank |
| Concept leaking | Trained concept appears without trigger word | Trigger word missing from captions; no regularization | Add trigger word to all captions; add regularization images |
| Color shift | All outputs have a color tint not in training data | Biased dataset or noise offset too high | Diversify training images; reduce noise offset |
| CUDA OOM during training | RuntimeError: CUDA out of memory | Insufficient VRAM for current settings | Enable gradient checkpointing + cache latents; reduce batch size to 1; reduce rank |
| Loss not decreasing | Training loss stays flat in TensorBoard | LR too low, wrong optimizer settings, or corrupted dataset | Try Prodigy optimizer (auto-LR); verify captions match images; check for corrupt images |
| NaN loss | Training crashes with NaN values | LR too high, fp16 overflow, or corrupt image | Switch to bf16 if supported; reduce LR by 50%; remove corrupt images from dataset |
| LoRA works on base but not finetune | Good results on base SDXL, broken on custom model | Custom model architecture differs from training base | Verify the custom model is based on the same architecture; retrain on the target base if needed |
Key Takeaways
- Start with LoRA — it covers 90% of use cases with 8+ GB VRAM
- Dataset quality matters more than dataset size: 20 good images beat 200 sloppy ones
- Use Prodigy optimizer if you don’t want to tune the learning rate manually
- Save checkpoints every 2–3 epochs and pick the best one after training
- Test LoRA strength at 0.4–1.2 and generalization with unseen prompts
- LoRAs are architecture-locked: SDXL LoRAs only work on SDXL-based models