From 498eb731b68ffe6e0193152ef22a5ac5bc513735 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Oct 2026 19:34:17 +0000 Subject: [PATCH] feat: training learning rate defaults to musubi-tuner's 0.0001 and the H3 note carries its recipe Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01MpnF7GwNGMbngU11wjym7P --- app/ui/features/training/train.js | 4 ++-- modules/training/lora/nodes.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/ui/features/training/train.js b/app/ui/features/training/train.js index f5424885..8dd96a6b 100644 --- a/app/ui/features/training/train.js +++ b/app/ui/features/training/train.js @@ -3,7 +3,7 @@ import { composer as c } from "../../composer/composer.js"; /** The node's own defaults. A set remembers what was changed from them. */ export const DEFAULTS = { - name: "funpack_lora", use: "normal", steps: 500, learning_rate: 0.0005, rank: 16, algorithm: "LoRA", optimizer: "AdamW", loss: "MSE", + name: "funpack_lora", use: "normal", steps: 500, learning_rate: 0.0001, rank: 16, algorithm: "LoRA", optimizer: "AdamW", loss: "MSE", batch_size: 1, grad_accumulation: 1, resolution: 512, aspect_buckets: false, frames: 33, fps: 0, start: "start", seed: 0, training_dtype: "bf16", lora_dtype: "bf16", gradient_checkpointing: true, offloading: false, bypass: false, swap_blocks: 0, }; @@ -74,7 +74,7 @@ export function trainStep({ app, session, go, ui }) { return c.region.stack({ gap: "md", children: [ c.hint.default({ text: used.length ? `${used.length} item${used.length > 1 ? "s" : ""} will be learned from (${caption} with tags). ${used.length - caption ? "Items without a caption are learned from with only the prefix and postfix." : ""}`.trim() : `Nothing in "${session.name}" fits "${(USES.find((u) => u.value === v.use) || {}).label}". Add media or change the choice below.` }), - hasAudioVae ? c.banner.info({ text: "This pipeline has an audio VAE, so it trains picture and sound together (H3). One clip at a time, so training is slow and needs a lot of memory." }) : null, + hasAudioVae ? c.banner.info({ text: "This pipeline has an audio VAE, so it trains picture and sound together (H3). One clip at a time, so training is slow and needs a lot of memory. musubi-tuner's H3 recipe: learning rate 0.0001, rank 16, batch 1, bf16, gradient checkpointing, plus block swap. Its plain flow-matching loss undoes the few-step quality of a distilled (turbo) model; musubi adds a training adapter, guidance loss or teacher matching for that, which this trainer does not have." }) : null, c.group.default({ label: "Basics", rows: [name, preset, pickOf("use", "What to learn", "Liked results and your own media teach what you want. Disliked results teach what to avoid: apply that LoRA at a negative strength.", USES), num("steps", "Steps", "More steps learn more and can overdo it.", { min: 1, max: 100000, step: 10 }), diff --git a/modules/training/lora/nodes.py b/modules/training/lora/nodes.py index 9385e7ac..7e711081 100644 --- a/modules/training/lora/nodes.py +++ b/modules/training/lora/nodes.py @@ -25,7 +25,7 @@ class FunPackTrainLora(io.ComfyNode): io.Combo.Input("use", options=list(train.USES), default="normal", tooltip="normal: liked results and your own media. avoid: only the disliked results, for a LoRA you apply at negative strength. all: everything."), io.Int.Input("steps", default=500, min=1, max=100000, tooltip="How many training steps."), - io.Float.Input("learning_rate", default=0.0005, min=0.0000001, max=1.0, step=0.0000001, tooltip="How big each learning step is. Lower is safer and slower."), + io.Float.Input("learning_rate", default=0.0001, min=0.0000001, max=1.0, step=0.0000001, tooltip="How big each learning step is. Lower is safer and slower."), io.Int.Input("rank", default=16, min=1, max=128, tooltip="How much the LoRA can learn. Higher holds more detail and makes a bigger file."), io.Combo.Input("algorithm", options=list(train.ALGORITHMS), default="LoRA", tooltip="The adapter kind. LoRA is the common one."), io.Combo.Input("optimizer", options=["AdamW", "Adam", "SGD", "RMSprop"], default="AdamW", tooltip="How the weights are updated."),