ComfyUI Node

ADMD_TrainLora

Where the GPU burn actually happens — the MotionDirector dual-loss loop

By kijai·Created 3 years ago·Updated 2 years ago· 187
ADMD_TrainLora
  • admd_pipeline
  • trigger_input
  • opt_images_override
  • admd_pipeline
steps100

ADMD_TrainLora is the training loop itself. Everything before this node was setup; this is the node that takes admd_pipeline, grinds through however many steps you ask for, and hands back an updated admd_pipeline with the LoRA weights baked in. In the example workflows you chain several of these together - five ADMD_TrainLora nodes at 100 steps each, with validation and a save between them - which is why max_train_steps on InitializeTraining needs to be the combined total.

You only set two real things here: admd_pipeline (from InitializeTraining or a previous TrainLora/ValidationSampler/SaveLora) and steps (default 100). The two optional inputs are convenience: opt_images_override lets you swap in different frames mid-run without rebuilding the whole pipeline, and trigger_input is a VHS_FILENAMES socket whose only job is to force ComfyUI's execution order (it's a "don't run me until the video loader has run" hint). Ignore both for a first run.

How it actually trains

MotionDirector splits each step into two losses, and this node runs them back to back:

  1. Spatial loss. The latent frames are noised, squeezed so the UNet sees a single spatial frame per timestep, and the model predicts the noise on the spatial task. This shapes what the subject looks like within a frame. The spatial LoRA drives it. On ~20% of steps the spatial LoRA is masked to zero and that loss is skipped - the anti-overfit beat that keeps the spatial LoRA from memorizing the video's look.
  2. Temporal loss. The full video latent is noised and run through the UNet with the temporal LoRA active. The MSE against the true noise, plus an extra temporal-motion term, is what teaches the across-frame movement.

Both losses backprop into the same 3D UNet (the spatial one keeps the graph alive with retain_graph), each into its own optimizer - Lion/AdamW/Prodigy, per your InitializeTraining choice - under a mixed-precision GradScaler. Random timesteps, gradient checkpointing on, and the text embedding is cached once so the CLIP encoder doesn't sit on the GPU during the loop.

The workflow shape

The intended rhythm is: TrainLoraValidationSampler (preview what the current weights do) → SaveLora (snapshot to disk) → next TrainLora. Each save stamps a checkpoint with the current global step, so you end up with a family of LoRAs at 100/200/300/400/500 steps and can pick the one that didn't overshoot. The progress bar logs Temporal Loss, Temporal LR, Spatial Loss, and Spatial LR per step - if temporal loss plateaus early while spatial keeps falling, that's your signal it's learning the look, not the motion, and you should look at your prompt or lower learning_rate_spatial.

Install and gotchas

Same pack install as everything else (Manager → "ADMotionDirector", or clone + restart), and the dependencies are the ones from requirements.txt - diffusers, transformers, lion-pytorch, peft, loralib, einops, omegaconf, imageio. Make sure your ComfyUI env has a CUDA PyTorch; the requirements file doesn't pin one and the training loop is where a CPU torch would really show.

Practical advice for a first run: keep frames at 16 and resolution small (256–384), use the default rank 64 and Lion, and don't fight the settings table you find online - the workflow's own notes say small sizes are what's known to work. VRAM for SD 1.5 LoRA training with gradient checkpointing is in the 6–8 GB ballpark, and validation between chunks adds a spike on top. AnimateDiff is a legacy ecosystem in 2026 - this trainer is the well-built way to produce its one remaining product, the stylized motion LoRA, not a path to general video generation.

CategoryAD_MotionDirector

Inputs (4)

NameTypeDefaultDescription
admd_pipelineADMDPIPELINE
stepsINT1000–10000
trigger_inputoptVHS_FILENAMES
opt_images_overrideoptIMAGE

Outputs (1)

NameTypeDescription
admd_pipelineADMDPIPELINE