Blog
How to Train a Krea 2 LoRA on a 12GB GPU
Mickael
mediapixel team
A low-VRAM Musubi Tuner workflow for Krea 2 Raw training and Krea 2 Turbo inference.

A low-VRAM Musubi Tuner workflow for Krea 2 Raw training and Krea 2 Turbo inference.
After exploring local training for Ideogram 4, it is time to tackle another major challenge: Krea 2 (Krea-2-Raw).
While Krea 2 shines in inference (anatomical stability, rendering style, and excellent support for structured JSON/BOX prompts), training a local LoRA on this model is notoriously resource-heavy. With a base model weighing over 24 GB and a Qwen3-VL 4B text encoder of over 8 GB, the hardware barrier seems insurmountable at first glance for a consumer 12GB GPU like the popular RTX 3060.
However, with the right tools and aggressive memory transfer optimizations, it is fully possible to stabilize local training at 512 px and accelerate training speeds by up to nearly 2.5x in my tests.
This guide documents the step-by-step method using Musubi Tuner, the official Krea 2 Raw model, CPU block-swapping optimizations, and dataset preparation.
Experimental & Workflow Note: Krea 2 support in Musubi Tuner is currently experimental. Both Musubi Tuner and ComfyUI documentation explicitly recommend a hybrid workflow: train your LoRA on Krea 2 Raw (which is the malleable, un-distilled base checkpoint designed specifically for fine-tuning and adaptation), and then apply the resulting LoRA weights directly to Krea 2 Turbo (the fast, distilled 8-step checkpoint) during inference. This hybrid setup gives you the best of both worlds: robust feature learning during training and ultra-fast generation during production. This guide is based on my local tests and may need adjustments if Musubi Tuner changes.
The 12GB GPU VRAM Challenge
To understand why these optimizations are necessary, let’s look at the default setup requirements:
- Krea 2 Raw Base Model (
raw.safetensors): ~24.48 GB - Text Encoder (
qwen3vl_4b_bf16.safetensors): ~8.27 GB - VAE (
qwen_image_vae.safetensors): ~1.1 GB
Attempting to load these weights in native precision (BF16/FP16) on a 12GB RTX 3060 will trigger an immediate Out of Memory (OOM) crash. Even quantizing the base model to FP8 (--fp8_base) without additional settings remains unstable, extremely slow (over 85 to 113 seconds per step), and prone to regular crashes (CUDA exit code 4294967295).
The Solution: Musubi Tuner Memory Optimizations
To make local training feasible and productive, we combine four major memory management techniques implemented in Musubi Tuner:
- Base Model FP8 Quantization (
--fp8_base --fp8_scaled): Drastically reduces the base model memory footprint during training passes. - CPU Block-Swapping (
--blocks_to_swap 20): Offloads inactive transformer blocks from the GPU to the system RAM (CPU) when they are not actively participating in gradient computation. - Asymmetric Host-to-Device Transfer Only (
--block_swap_h2d_only): Since the base model weights are frozen during LoRA training, there is no need to copy modified blocks back from the GPU to the CPU. Eliminating this return transfer reduces host-to-device wait times by about 25%. - Double-Buffering (
--block_swap_ring_size 2): Overlaps the memory transfer of the next block with the active computation of the current block, eliminating GPU idle times.
System RAM note: This workflow relies heavily on CPU offloading. It was tested on a machine with 64 GB of system RAM. It may still work with less, but 32 GB can become tight depending on the dataset, caching, Windows background usage, and swap settings.
Required Tools and Files
Before starting, prepare your local folder structure:
C:\krea2_models\
├─ DiffusionModels\
│ └─ raw.safetensors (24.48 GB)
├─ text_encoders\
│ └─ qwen3vl_4b_bf16.safetensors (8.27 GB)
└─ VAE\
└─ qwen_image_vae.safetensors
C:\musubi-tuner\
Download links for official weights:
- Krea-2-Raw: huggingface.co/krea/Krea-2-Raw
- Text Encoder & VAE: huggingface.co/Comfy-Org/Qwen3-VL
License note: Krea 2 is released under the Krea 2 Community License. Before using trained LoRAs or outputs commercially, check the current license terms and make sure your use case is allowed.
Installing Musubi Tuner
To train Krea 2 locally, we use Musubi Tuner, a highly memory-efficient training UI and CLI designed by kohya-ss for advanced architectures.
Prerequisites
Before running the installation commands, make sure you have the following prerequisites installed on Windows:
- Git for Windows: Required to clone the repository and manage version control.
- Python 3.10 or 3.11: Required for running the tuner environment. Make sure to check the option to add Python to your PATH during installation.
- NVIDIA GPU Driver (Recent): Required for CUDA and PyTorch GPU acceleration.
- Microsoft Visual Studio Build Tools: (Optional but recommended) Useful if any compiled Python dependency packages need to compile C++ extensions locally.
Installation Steps on Windows:
-
Clone the repository:
Open your terminal and clone Musubi Tuner to your C drive:cd C:\ git clone https://github.com/kohya-ss/musubi-tuner.git C:\musubi-tuner cd C:\musubi-tuner -
Create and Activate a Virtual Environment:
python -m venv .venv .\.venv\Scripts\activate -
Install PyTorch and CUDA Dependencies:
Ensure you install the correct PyTorch package matching your GPU’s CUDA runtime (verified with CUDA 12.4):pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124 -
Install Musubi Tuner and Common Dependencies:
Install the tuner in editable mode so it registers all network modules correctly:pip install -e . pip install ascii-magic matplotlib tensorboard prompt-toolkit
1. Preparing the Dataset and Captions
For Krea 2, I reuse the same structured JSON captioning approach that worked well in my Ideogram 4 workflow. This is not required as a universal Krea 2 rule, but it keeps the dataset consistent and makes each caption easier to audit. It is recommended to clean your dataset by removing automatic tagging metadata and explicitly inserting your target trigger word and specific concept terms.
Expected Dataset Directory Structure:
C:\krea2_lora_training\mp_concept_krea2\
├─ krea2_images\
│ ├─ image_0001.png
│ ├─ image_0001.txt (raw JSON string, no markdown fences)
│ ├─ image_0002.png
│ └─ ...
├─ krea2_cache_512\ (automatically generated)
└─ output_krea2\
Example JSON Caption (image_0001.txt):
{"high_level_description":"A clean game-art reference image of a futuristic off-road utility buggy, mp_concept_krea2.","style_description":{"aesthetics":"production-friendly vehicle concept art, readable silhouette, game asset clarity","lighting":"soft studio lighting with clear material readability","medium":"digital vehicle concept art","art_style":"hard-surface game vehicle design with large wheels, protective roll cage, modular panels, elevated suspension, and clean forms"},"compositional_deconstruction":{"background":"A simple neutral studio background with subtle shading.","elements":[{"type":"obj","desc":"A single futuristic off-road utility buggy shown in a clean three-quarter view, with large wheels, exposed frame, protective roll cage, compact chassis, and readable game-asset proportions, mp_concept_krea2."}]}}
2. Dataset TOML Configuration (dataset_512.toml)
Create the Musubi dataloader configuration file under the name mp_concept_krea2_dataset_512.toml:
[general]
resolution = [512, 512]
caption_extension = ".txt"
batch_size = 1
enable_bucket = true
bucket_no_upscale = false
[[datasets]]
image_directory = "C:/krea2_lora_training/mp_concept_krea2/krea2_images"
cache_directory = "C:/krea2_lora_training/mp_concept_krea2/krea2_cache_512"
num_repeats = 1
3. Optimized Training Launcher (run_krea2_train.ps1)
Here is the complete PowerShell script that handles caching image latents, caching text encoder outputs, and starting the training run with Krea 2 LoRA parameters.
This script should be placed in your companion repository on GitHub.
$ErrorActionPreference = "Stop"
$env:PYTHONIOENCODING = "utf-8"
$MusubiRoot = "C:\musubi-tuner"
$DatasetConfig = "C:\krea2_lora_training\mp_concept_krea2\mp_concept_krea2_dataset_512.toml"
$OutputDir = "C:\krea2_lora_training\mp_concept_krea2\output_krea2"
$OutputName = "mp_concept_krea2_lora_512"
$RawDit = "C:\krea2_models\DiffusionModels\raw.safetensors"
$Vae = "C:\krea2_models\VAE\qwen_image_vae.safetensors"
$TextEncoder = "C:\krea2_models\text_encoders\qwen3vl_4b_bf16.safetensors"
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
Push-Location $MusubiRoot
try {
# 1. Cache VAE image latents (very fast)
Write-Host "Caching image latents..." -ForegroundColor Cyan
.\.venv\Scripts\python.exe src\musubi_tuner\krea2_cache_latents.py `
--dataset_config $DatasetConfig `
--vae $Vae
# 2. Cache Text Encoder outputs (executed once at startup)
Write-Host "Caching text encoder embeddings..." -ForegroundColor Cyan
.\.venv\Scripts\python.exe src\musubi_tuner\krea2_cache_text_encoder_outputs.py `
--dataset_config $DatasetConfig `
--text_encoder $TextEncoder `
--batch_size 1
# 3. Launch LoRA training with memory swapping and GPU acceleration
Write-Host "Launching network training..." -ForegroundColor Green
.\.venv\Scripts\accelerate.exe launch --num_cpu_threads_per_process 1 --mixed_precision bf16 `
src\musubi_tuner\krea2_train_network.py `
--dit $RawDit `
--fp8_base `
--fp8_scaled `
--vae $Vae `
--dataset_config $DatasetConfig `
--sdpa `
--mixed_precision bf16 `
--timestep_sampling shift `
--weighting_scheme none `
--discrete_flow_shift 2.5 `
--optimizer_type adamw8bit `
--learning_rate 1e-4 `
--gradient_checkpointing `
--blocks_to_swap 20 `
--block_swap_h2d_only `
--block_swap_ring_size 2 `
--max_data_loader_n_workers 2 `
--persistent_data_loader_workers `
--network_module networks.lora_krea2 `
--network_dim 16 `
--network_alpha 16 `
--max_train_steps 500 `
--save_every_n_steps 50 `
--save_state `
--save_precision bf16 `
--seed 42 `
--output_dir $OutputDir `
--output_name $OutputName
}
finally {
Pop-Location
}
4. Performance & Benchmarking Summary
Our local testing highlights the critical impact of memory swapping configurations on a 12GB GPU:
| Configuration | Stability | Step Speed | 500 Steps Time |
|---|---|---|---|
| Krea 2 Raw BF16 (768px, No Swap) | CUDA OOM Crash | ~154 s / step | ~21h 20m (Theoretical) |
| Krea 2 Raw FP8 (512px, No Swap) | Random Crash | ~85-113 s / step | ~12h - 15h 40m |
| Krea 2 Raw FP8 (512px, Optimized Swap) | Stable | ~30-43 s / step | ~4h 10m - 6h |
Key takeaways from these benchmarks:
- Block-swapping is mandatory: Without
--blocks_to_swap 20, training at 512 px eventually fills the 12GB VRAM and crashes. - Massive speed gains: Limiting copying to CPU -> GPU (
--block_swap_h2d_only) and overlapping transfers (--block_swap_ring_size 2) reduces step times from ~100s to just ~35s on average. - Comparison to Ideogram 4: While Krea 2 training is stable, it remains about 3 times slower than Ideogram 4 FP8 (which runs at ~11s/step at 768px on the same machine). Krea 2 is not the fastest model to train locally on a 12GB GPU. The reason to use it is different: if Krea 2 Turbo is your preferred inference model, training on Krea 2 Raw gives you LoRAs that are better aligned with your final generation target.
5. Inference and Validation in ComfyUI
Once training completes, copy the generated .safetensors model to ComfyUI\models\loras.
For inference:
- Recommended base inference model:
krea2_turbo_fp8_scaled.safetensors. - Apply the LoRA on the model path with a standard LoraLoader node (Strength:
0.8to1.2). - Use a structured JSON/BOX prompt builder such as the KJNodes prompt builder if you want to keep the same layout-oriented prompting workflow used in the Ideogram 4 tutorial. This allows you to feed structured JSON prompts and embed your trigger token into the descriptions to prompt the style or object cleanly.

–
This project demonstrates that with careful memory offloading and bottleneck management under Windows, advanced visual models like Krea 2 remain accessible to local, mid-range hardware setups.