ADMD_SaveLora
Snapshot your run — write the trained motion LoRA to disk, mid-workflow
- admd_pipeline
- lora_info
- lora_path
- admd_pipeline
ADMD_SaveLora is the node that makes your training run produce something you can keep. It takes the trained admd_pipeline plus the lora_info from ADMD_InitializeTraining, writes the current LoRA weights to disk, and returns the path to the file you'll load later in an AnimateDiff inference graph.
Its real job in a workflow is as the snapshot between training chunks. The example workflows run TrainLora → Validate → SaveLora → TrainLora repeatedly, so you end up with a separate LoRA file at step 100, 200, 300, and so on. That matters more than it sounds: the last checkpoint is usually not the best one, and being able to load each snapshot and compare is the difference between a usable motion LoRA and an overfit one you can't debug.
How it works
MotionDirector trains two LoRA stacks, so this node saves both, into two different places:
- Temporal LoRA →
ComfyUI/models/animatediff_motion_lora/<date>/<time>/<lora_name>/<step>_<lora_name>_r<rank>_temporal_unet.safetensors. This is the file you actually use for inference - the name is the giveaway (use_motion_lora_formatis on for it, so it's compatible with AnimateDiff-Evolved's motion-LoRA format). - Spatial LoRA →
ComfyUI/models/loras/trained_spatial/<date>/<time>/<lora_name>/...as<name>_r<rank>_spatial.safetensors. Kept for completeness/experimentation; the temporal file is the deliverable.
Both are saved via the pack's LoraHandler as safetensors, with the current global_step in the filename. Before saving, the node moves the validation pipeline to CPU so the deep-copy it snapshots doesn't spike VRAM - which is also why saving between chunks costs you a moment of model shuffling, not a crash.
Inputs and output
- admd_pipeline - the trained pipeline, from
ADMD_TrainLora,ADMD_ValidationSampler, or a previousADMD_SaveLora. - lora_info - from
ADMD_InitializeTraining(usually routed through a SetNode/GetNode so it can reach every save). It carrieslora_name,lora_rank, and the output paths.
Outputs: lora_path - a STRING with the temporal LoRA's path relative to models/animatediff_motion_lora/, exactly the format ADMD_LoadLora expects; and admd_pipeline - passed through unchanged so the chain keeps flowing. That lora_path is the number to note down (or wire straight into ADMD_LoadLora).
Gotchas
Save order in the chain matters: put SaveLora after the training chunk whose weights you want to capture, and don't put two saves without a TrainLora between them - they'd write identical files. If lora_info isn't wired, the node has nothing to name or locate the files, so this is one of the few nodes where the "boring" LORAINFO connection is load-bearing. And a small ritual worth adopting: rename or move your final pick out of the dated folder immediately, because the next training run's date/time path will bury it.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| admd_pipeline | ADMDPIPELINE | — | |
| lora_info | LORAINFO | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| lora_path | STRING | — |
| admd_pipeline | ADMDPIPELINE | — |