Train LoRA
ComfyUI's built-in trainer actually trains — and it's less scary than it looks
- model
- latents
- positive
- lora
- loss_map
- steps
This is the node that turns your ComfyUI from a generation tool into a training tool. Train LoRA doesn't load or apply a LoRA - it creates brand-new weights from scratch, using your latents and captions as the dataset. It ships inside ComfyUI core (no install, no second Python environment, no YAML config), and it's been quietly getting good since mid-2025.
The honest framing up front: if you're a serious trainer, the community default is still ai-toolkit, kohya, or OneTrainer, and you'll get told "the ComfyUI training stuff is not fully baked" if you ask. That's true in the sense that these nodes are still marked experimental and shift between releases. But baked enough - plenty of people train real, working LoRAs inside ComfyUI, and it's the only trainer that gets day-one support for whatever architecture just shipped.
How it actually works
Training is a diffusion objective, not a pixel-matching exercise. The node deep-copies your model, freezes the original weights, and bolts low-rank adapters on top (pick algorithm: LoRA by default, plus LoHa, LoKr, or OFT - LoKr is worth a try for character work on modern bases). Then it runs a loop where each step grabs a random latent from the dataset, adds noise at a random timestep, asks the model to predict the clean latent back, and measures the error. That error is what your loss_function scores - MSE by default, or L1, Huber, SmoothL1. Rinse and repeat steps times.
The inputs that matter
The first three are the dataset trio: model (the base model to train on), latents (pre-encoded images - wire them straight from Make Training Dataset or Load Training Dataset), and positive (the captions, one per image; give one and it repeats for all). Then the knobs:
steps- how many optimizer updates. The default of 16 is a smoke-test number, not a real run. Small character sets typically want a few thousand.learning_rate- default 5e-4 is SDXL-era thinking. Modern bases want lower: the KB's rule of thumb is ~1e-4 ceiling for Flux-class models, lower still on big batches.rank- the size of the adapter. 8 default; go higher for more capacity, lower for style.batch_sizeandgrad_accumulation_steps- accumulate gradients to fake a bigger batch on limited VRAM.training_dtype- bf16 default. Set tononeto keep the model's native compute dtype; fp16 models automatically get GradScaler.existing_lora- pick one frommodels/lorasto keep training it instead of starting fresh.bucket_mode- flip this on when feeding pre-bucketed latents from Resolution Bucket, andbypass_modefor quantized models whose weights can't be modified directly.
What comes out
Three outputs: lora (the trained weights), loss_map (feed it to Plot Loss Graph), and steps (total step count). The lora output doesn't go back into a normal LoraLoader - it wires into Save LoRA Weights to write a .safetensors, or Load LoRA Model to test it immediately in the same graph.
Here's the workflow shape:
Load Image → Make Training Dataset → Train LoRA → Save LoRA Weights
└──→ Plot Loss Graph
Where people get burned
- The save node. People hunt for "Extract and Save LoRA" and find inputs called
model_diffandtext_encoder_diffthat nothing connects to. That's a legacy node. The trainer'sloraoutput goes into Save LoRA Weights (alias "export lora"), which drops a file likeComfyUI_trained_lora_2000_steps_00000_.safetensorsunder your output folder. - Macs. If you're on Apple silicon, the
offloadingtoggle won't save you the way it does on CUDA - unified memory means there's no separate VRAM to spill into, and training Flux on an M4 Max has been known to OOM at 88 GB. Keep the memory budget small. - It's experimental. Settings and defaults move between ComfyUI releases. If a tutorial's knobs don't match what you see, trust the tooltips.
- The 16-step default is a trap. Anyone who runs the default and concludes training is broken should read the loss graph first - it's learning, you just asked for almost no learning.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | The model to train the LoRA on. | |
| latents | LATENT | The Latents to use for training, serve as dataset/input of the model. | |
| positive | CONDITIONING | The positive conditioning to use for training. | |
| batch_size | INT | 11–10000 | The batch size to use for training. |
| grad_accumulation_steps | INT | 11–1024 | The number of gradient accumulation steps to use for training. |
| steps | INT | 161–100000 | The number of steps to train the LoRA for. |
| learning_rate | FLOAT | 01e-7–1 | The learning rate to use for training. |
| rank | INT | 81–128 | The rank of the LoRA layers. |
| optimizer | COMBO | AdamW | The optimizer to use for training. |
| loss_function | COMBO | MSE | The loss function to use for training. |
| seed | INT | 00–18446744073709550000 | The seed to use for training (used in generator for LoRA weight initialization and noise sampling) |
| training_dtype | COMBO | bf16 | The dtype to use for training. 'none' preserves the model's native compute dtype instead of overriding it. For fp16 models, GradScaler is automatically enabled. |
| lora_dtype | COMBO | bf16 | The dtype to use for lora. |
| quantized_backward | BOOLEAN | false | When using training_dtype 'none' and training on quantized model, doing backward with quantized matmul when enabled. |
| algorithm | COMBO | LoRA | The algorithm to use for training. |
| gradient_checkpointing | BOOLEAN | true | Use gradient checkpointing for training. |
| checkpoint_depth | INT | 11–5 | Depth level for gradient checkpointing. |
| offloading | BOOLEAN | false | Offload model weights to CPU during training to save GPU memory. |
| existing_lora | COMBO | [None] | The existing LoRA to append to. Set to None for new LoRA. |
| bucket_mode | BOOLEAN | false | Enable resolution bucket mode. When enabled, expects pre-bucketed latents from ResolutionBucket node. |
| bypass_mode | BOOLEAN | false | Enable bypass mode for training. When enabled, adapters are applied via forward hooks instead of weight modification. Useful for quantized models where weights cannot be directly modified. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| lora | LORA_MODEL | LoRA weights |
| loss_map | LOSS_MAP | Loss history |
| steps | INT | Total training steps |