diff --git a/studio/frontend/src/features/images/images-page.tsx b/studio/frontend/src/features/images/images-page.tsx index 8d8f0a38f3..bff5f93e9d 100644 --- a/studio/frontend/src/features/images/images-page.tsx +++ b/studio/frontend/src/features/images/images-page.tsx @@ -1956,21 +1956,22 @@ export function ImagesPage({ active = true }: { active?: boolean }) { shared element matches. The load progress shows in a chat-style toast, not here. ── */}
- setSelectorOpen(active && o)} - />
- {/* Create | Train page-mode switch, next to the model selector. Create is the - generation workspace; Train is the full-page LoRA training workspace. */} + setSelectorOpen(active && o)} + /> + {/* Create | Train page-mode switch, on the left next to the model selector + (the selector itself stays leftmost: its position is shared with Chat's). + Create is the generation workspace; Train is the LoRA training workspace. */} setPageMode(v as "create" | "train")}> @@ -1981,6 +1982,8 @@ export function ImagesPage({ active = true }: { active?: boolean }) { +
+
{/* Single fixed toggle for the right-docked Advanced panel (mirrors Chat's settings toggle, same icon in both states so it never moves). Highlighted when open. Only meaningful in Create mode (load-time tuning), so hidden while training. */} diff --git a/studio/frontend/src/features/images/train/diffusion-train-panel.tsx b/studio/frontend/src/features/images/train/diffusion-train-panel.tsx index 9eebcf9bb6..5a38d24910 100644 --- a/studio/frontend/src/features/images/train/diffusion-train-panel.tsx +++ b/studio/frontend/src/features/images/train/diffusion-train-panel.tsx @@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { LayoutAlignRightIcon, Settings02Icon } from "@hugeicons/core-free-icons"; +import { Settings02Icon } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; import { @@ -205,10 +205,6 @@ export function DiffusionTrainPanel({ const [outputDir, setOutputDir] = useState(""); const [instancePrompt, setInstancePrompt] = useState(""); - // The right-docked Advanced settings panel (mirrors the Create tab's / Chat's settings - // panel). Open by default -- on a training tab the hyperparameters are primary content, - // like the LLM Train page's right rail; the fixed top-right button hides it. - const [advancedOpen, setAdvancedOpen] = useState(true); const [steps, setSteps] = useState(500); const [learningRate, setLearningRate] = useState(family?.defaults.lr ?? 0.0001); const [rank, setRank] = useState(family?.defaults.rank ?? 16); @@ -651,12 +647,12 @@ export function DiffusionTrainPanel({ return "fp8 (experimental)"; }; - // The Advanced training settings, rendered inside the right-docked panel (mirrors the - // Create tab's advancedControls). Numeric hyperparameters, the sdxl/DiT precision control, - // and the DiT speed levers (base precision + torch.compile). - const advancedControls = ( -
-
+ // The training settings, shown as the run area's MAIN content before a run starts + // (settings are set once, up front); once training starts the run view (progress + + // charts) replaces them. Laid out as a wide grid for the center column. + const trainingSettings = ( +
+
{numberField("Steps", steps, setSteps, 1)} {numberField("LoRA rank", rank, setRank, 1)} {numberField("Resolution", resolution, setResolution, 512, { min: 64, step: 64 })} @@ -664,111 +660,117 @@ export function DiffusionTrainPanel({ {numberField("Grad accumulation", gradAccum, setGradAccum, 1)} {numberField("Seed", seed, setSeed, 42, { min: 0 })}
- {numberField("Learning rate", learningRate, setLearningRate, 0.0001, { - min: 0, - step: 0.00001, - })} -
- - - {lrScheduler !== "constant" && - numberField("Warmup steps", lrWarmupSteps, setLrWarmupSteps, 0, { min: 0 })} -

- How the learning rate evolves over the run (shown live in the LR chart). -

-
- -
- - -

- Recomputes activations in the backward pass: a large VRAM saving for a modest - per-step slowdown. -

-
- - {isDiT ? ( - <> -
- - -

- How the frozen base weights are quantised. nf4 (4-bit) uses the least VRAM; - bf16 is fastest but needs the most. Auto picks this family's recommended mode. -

-
- {supportsCompile && ( -
- - -

- torch.compile the transformer. Adds a one-time warmup, then speeds up each step. -

-
- )} - - ) : ( +
+ {numberField("Learning rate", learningRate, setLearningRate, 0.0001, { + min: 0, + step: 0.00001, + })}
- +

- Mixed-precision autocast for the U-Net. bf16 suits modern GPUs. + How the learning rate evolves over the run (shown live in the LR chart).

- )} + {lrScheduler !== "constant" && + numberField("Warmup steps", lrWarmupSteps, setLrWarmupSteps, 0, { min: 0 })} +
+ +
+
+ + +

+ Recomputes activations in the backward pass: a large VRAM saving for a modest + per-step slowdown. +

+
+ + {isDiT ? ( + <> +
+ + +

+ How the frozen base weights are quantised. nf4 (4-bit) uses the least VRAM; + bf16 is fastest but needs the most. Auto picks this family's recommended + mode. +

+
+ {supportsCompile && ( +
+ + +

+ torch.compile the transformer. Adds a one-time warmup, then speeds up each + step. +

+
+ )} + + ) : ( +
+ + +

+ Mixed-precision autocast for the U-Net. bf16 suits modern GPUs. +

+
+ )} +
); @@ -978,18 +980,6 @@ export function DiffusionTrainPanel({ />
- {/* Training settings now live in the right-docked Advanced panel (opened by the - top-right toggle), so the left rail stays focused on the dataset + trigger. */} - -
{running ? (
- {/* Right: run view. The progress card + charts are ALWAYS mounted; before a run they - render grayed as a preview (with an overlaid hint), so the layout never jumps when - training starts. A single fixed top-right button toggles the Advanced panel. */} + {/* Right: the run area. Before a run it shows the training settings (they are set + once, up front); the moment a run exists the settings give way to the run view + (progress + live charts), and come back after "Train another". */}
- {/* Fixed Advanced toggle (mirrors Chat's / the Create tab's settings toggle: same icon - in both states so it never moves, highlighted when open). */} -
- -
- -
-
+ {!hasRun ? ( +
- - {hasRun ? status?.status : "Idle"} + + + Training settings - {hasRun && (status?.total_steps ?? 0) > 0 - ? `${status?.step}/${status?.total_steps} steps` - : ""} + Applied when you press Start training
-
-
-
-
- - - - -
- {hasRun && status?.message && ( -

{status.message}

- )} + {trainingSettings} +

+ Once training starts, live progress and the Training Loss / Learning Rate + charts take over this area. +

- - -
- - {/* Placeholder hint overlaid on the grayed preview until a run exists. */} - {!hasRun && ( -
-
-

No training run yet

-

- Pick a family and dataset on the left, then Start training. Progress and the loss - chart fill in here live. -

+ ) : ( + <> +
+
+ {status?.status} + + {(status?.total_steps ?? 0) > 0 + ? `${status?.step}/${status?.total_steps} steps` + : ""} + +
+
+
+
+
+ + + + +
+ {status?.message && ( +

{status.message}

+ )}
-
+ + + )} {(completed || stoppedWithAdapter) && ( @@ -1140,34 +1108,6 @@ export function DiffusionTrainPanel({ )}
- {/* Right-docked Advanced settings panel (mirrors the Create tab / Chat settings panel): - closed by default, opened by the top-right toggle above. Holds every training - hyperparameter and the DiT speed levers so the left rail stays focused on data. */} - {advancedOpen && ( -
-
- - - Advanced - - -
-
-

- Defaults suit a first run. Changes apply to the next Start training. -

- {advancedControls} -
-
- )} - {/* Confirm-stop dialog (mirrors the LLM Train tab): Continue / Stop / Stop and save. */}