Commit graph

6,203 commits

Author SHA1 Message Date
Daniel Han
c86f0cc2a1 Merge branch 'diffusion-lora-training-ui' of https://github.com/unslothai/unsloth into diffusion-lora-training-ui 2026-07-01 22:12:28 +00:00
Daniel Han
18f71583e6 Merge remote-tracking branch 'origin/diffusion-lora-training-api' into diffusion-lora-training-ui 2026-07-01 22:12:21 +00:00
Daniel Han
6ff245f3e1 Merge branch 'diffusion-lora-training-api' of https://github.com/unslothai/unsloth into diffusion-lora-training-api 2026-07-01 22:11:51 +00:00
Daniel Han
2e56ee7920 Import diffusion training schemas from models.training directly
The import-hoist lint flags newly re-exported names in the models/__init__.py hub as
unused (it does not treat __all__ membership as a use). Import the three diffusion
training schemas straight from models.training in routes/training.py, where they are
used in the route annotations and calls, and drop the __init__ re-export.
2026-07-01 22:11:43 +00:00
oobabooga
92963164ca Merge remote-tracking branch 'origin/diffusion-lora-training-api' into diffusion-lora-training-ui 2026-07-01 14:33:17 -03:00
oobabooga
156097731e Merge remote-tracking branch 'origin/diffusion-lora-training' into diffusion-lora-training-api 2026-07-01 14:27:25 -03:00
oobabooga
fa901a61ec Merge remote-tracking branch 'origin/diffusion-lora-ux' into diffusion-lora-training 2026-07-01 14:23:02 -03:00
oobabooga
1437f48e08 Merge remote-tracking branch 'origin/diffusion-sdxl' into diffusion-lora-ux 2026-07-01 13:56:05 -03:00
oobabooga
0813849aed Merge remote-tracking branch 'origin/diffusion-controlnet' into diffusion-sdxl 2026-07-01 13:50:07 -03:00
oobabooga
1d4b551a61 Merge remote-tracking branch 'origin/diffusion-lora' into diffusion-controlnet 2026-07-01 13:37:13 -03:00
oobabooga
9ffb28b923 Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora 2026-07-01 13:30:26 -03:00
oobabooga
30f40ed44c Merge remote-tracking branch 'origin/diffusion-phase16-native-engine-routing' into diffusion-image-workflows 2026-07-01 13:15:13 -03:00
oobabooga
7d9a59c722 Merge remote-tracking branch 'origin/diffusion-phase15-int8-prequant' into diffusion-phase16-native-engine-routing 2026-07-01 12:54:08 -03:00
oobabooga
707983642a Merge remote-tracking branch 'origin/diffusion-phase14-int8-modulation' into diffusion-phase15-int8-prequant 2026-07-01 12:44:49 -03:00
oobabooga
761cc21157 Merge remote-tracking branch 'origin/diffusion-phase12-fbcache' into diffusion-phase14-int8-modulation 2026-07-01 12:34:16 -03:00
oobabooga
ff9dcf847c Merge remote-tracking branch 'origin/diffusion-phase11-consumer-int8' into diffusion-phase12-fbcache 2026-07-01 12:28:36 -03:00
oobabooga
ed4336dbf7 Merge remote-tracking branch 'origin/diffusion-phase10-attention' into diffusion-phase11-consumer-int8 2026-07-01 12:19:17 -03:00
Daniel Han
556b4cc346 Images: add a Train LoRA (SDXL) dialog
Surface the diffusion training API in the Images page. A "Train LoRA" button in the top
bar opens a self-contained dialog to fine-tune an SDXL LoRA on a folder of images: pick
the base model, dataset folder, output folder, an optional instance prompt, and the core
hyperparameters (steps, rank, resolution, batch, learning rate), then Start. The dialog
polls the training status while open and shows a progress bar, step count, live loss, and
the saved adapter path, with a Stop button for a clean stop.

The dialog is independent of the loaded generation model (training runs in its own
subprocess), and prefills the base model with the loaded checkpoint when it is SDXL, else
the SDXL base. api.ts gains startDiffusionTraining / stopDiffusionTraining /
getDiffusionTrainingStatus plus their types, matching the /api/train/diffusion routes.
2026-07-01 15:18:50 +00:00
oobabooga
6ebaf64dc6 Merge remote-tracking branch 'origin/diffusion-phase9-prequant' into diffusion-phase10-attention 2026-07-01 12:13:04 -03:00
oobabooga
731fb20bde Merge remote-tracking branch 'origin/diffusion-phase8-quant' into diffusion-phase9-prequant 2026-07-01 12:07:42 -03:00
oobabooga
b02eacd64f Merge remote-tracking branch 'origin/diffusion-phase7-perf' into diffusion-phase8-quant 2026-07-01 12:02:11 -03:00
oobabooga
6adbb45eb9 Merge remote-tracking branch 'origin/diffusion-phase6-features' into diffusion-phase7-perf 2026-07-01 11:56:04 -03:00
oobabooga
1fa8e307ea Merge remote-tracking branch 'origin/diffusion-phase4-native' into diffusion-phase6-features 2026-07-01 11:50:02 -03:00
pre-commit-ci[bot]
0f1c4a35ba [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 14:48:19 +00:00
Daniel Han
fbeb6dfc6f Wire diffusion LoRA training into the Studio API
Make the SDXL LoRA trainer reachable from the app with a small, self-contained job
service and JSON routes, deliberately separate from the LLM TrainingBackend (whose
lifecycle -- LLM config build, per-run SQLite rows, matplotlib plots, transfer-to-chat-
inference -- is text-training specific and would mis-handle a diffusion run).

core/training/diffusion_training_service.py: DiffusionTrainingService runs one job at a
time -- validate the config cheaply (before any spawn), spawn the trainer subprocess
(spawn context, parent-lifetime bound), pump its events (model_load_* / progress /
complete / error) into an in-memory status snapshot, and support a clean stop. The
subprocess context and target are injectable so the full start -> pump -> status ->
complete path is unit-tested without real multiprocessing or torch.

routes/training.py: POST /api/train/diffusion/start (400 on a bad config, 409 when a job
is already running), POST /api/train/diffusion/stop, GET /api/train/diffusion/status
(JSON poll). models/training.py: DiffusionTrainingStartRequest + response schemas
mirroring DiffusionLoraConfig, so model_dump() passes straight through.

Tests: test_diffusion_training.py -- service happy path, bad-config-before-spawn,
concurrent-job rejection, clean stop, crash-without-terminal-event, event transitions;
plus route wiring via the FastAPI TestClient (start / 422 / 400 / 409 / status / stop)
with a mocked service. The diffusion trainer's progress events already use the field
names this path expects.
2026-07-01 14:47:06 +00:00
oobabooga
d285a4d250 Merge remote-tracking branch 'origin/image-generation' into diffusion-phase4-native 2026-07-01 11:36:04 -03:00
Daniel Han
731a5171f7 Merge branch 'diffusion-lora-training' of https://github.com/unslothai/unsloth into diffusion-lora-training
# Conflicts:
#	studio/backend/core/training/diffusion_lora_trainer.py
2026-07-01 14:22:47 +00:00
Daniel Han
1eeb1067d4 diffusion trainer: emit learning_rate in progress events (Studio pump compatibility)
The Studio training pump reads 'learning_rate' from progress events; the diffusion
trainer emitted 'lr'. Rename the field (and the CLI reader) so the trainer's events are
directly consumable by the existing training status/SSE machinery when it is wired into
the worker, without a translation shim.
2026-07-01 14:21:42 +00:00
pre-commit-ci[bot]
15ba6a1760 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 14:17:41 +00:00
Daniel Han
14727cc744 Add diffusion LoRA training (SDXL text-to-image)
First diffusion training path in Studio: train a LoRA on the SDXL U-Net from an
image + caption dataset and export it as a diffusers .safetensors that the existing
diffusion LoRA loader (and any diffusers pipeline) can load.

core/training/diffusion_lora_trainer.py:
- DiffusionLoraConfig with validation/defaults (rank, alpha, targets, lr, steps, grad
  accumulation, resolution, min-SNR gamma, gradient checkpointing, lr scheduler, seed,
  mixed precision).
- discover_image_caption_pairs: captions from metadata.jsonl / captions.jsonl, per-image
  .txt/.caption sidecars, or a dreambooth instance_prompt fallback (pure, unit-tested).
- run_diffusion_lora_training: the loop -- freeze base, PEFT-wrap the U-Net attention
  projections, VAE-encode (fp32 VAE to avoid the SDXL fp16 overflow), sample noise +
  timesteps, predict, MSE loss with optional min-SNR weighting (epsilon / v-prediction),
  AdamW + get_scheduler + grad accumulation + grad clipping, then export via
  save_lora_weights. Emits worker-protocol events (model_load_*, progress, complete) and
  polls should_stop for a clean stop with a partial save.
- run_diffusion_training_process: mp.Queue subprocess adapter (event_queue / stop_queue),
  so the training worker can spawn it; plus a CLI entry point.

Only SDXL (U-Net) is trained here; DiT families and the Studio UI form + route wiring are
follow-ups. The trainer is decoupled and worker-ready.

Tests: test_diffusion_lora_trainer.py covers caption discovery (metadata / sidecar /
instance prompt / skip-uncaptioned / errors), config normalisation + validation, the SDXL
add-time-ids, and the dict->config adapter. Verified live on GPU: a 60-step SDXL LoRA run
lowers the loss, exports a ~45 MB adapter, and loading it back shifts generation from
baseline (mean abs pixel diff ~55/255).
2026-07-01 14:16:45 +00:00
Daniel Han
3d187f1bab Images: LoRA free-text Hugging Face entry + recipe round-trip
The backend has always accepted a bare Hugging Face repo id (owner/name, or
owner/name:weight-file.safetensors) as a LoRA, downloading and applying it. But the
picker only rendered when the curated catalog had entries, and the catalog is empty,
so there was no UI path to apply any LoRA. Show the LoRA section whenever the loaded
model supports LoRA, and replace the curated-only dropdown with a text input: type a
Hub repo id, or pick a discovered adapter from a datalist of suggestions when the
catalog is populated.

Also restore LoRAs when loading a recipe. restoreSettings now parses the recipe's
"id:weight" strings (splitting on the last colon, since the id itself may contain one
for a specific weight file) back into the selection, so replaying a saved image
reproduces its adapters. The generate payload trims hand-typed ids and drops empty /
zero-weight rows, and a model swap clears the selection (a LoRA is family-specific)
without discarding a free-text pick that is not in the curated list.
2026-07-01 14:05:16 +00:00
pre-commit-ci[bot]
a927f4dc1e [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 13:58:13 +00:00
Daniel Han
977c9b7dd0 Add SDXL diffusion family (U-Net pipeline support)
SDXL is the first U-Net family in the diffusion backend: its denoiser is
pipe.unet (UNet2DConditionModel), not a DiT pipe.transformer, and a single-file
.safetensors is the whole pipeline rather than a transformer-only file. The
backend previously assumed a DiT transformer everywhere, so add the two hooks a
U-Net family needs and register SDXL.

DiffusionFamily gains denoiser_attr ("transformer" for DiT, "unet" for SDXL) and
single_file_is_pipeline (SDXL loads a single file via pipeline_class.from_single_file
with the base repo as config, instead of transformer_class.from_single_file plus a
companion assembly). _align_vae_dtype now reads the denoiser generically so img2img
and inpaint keep the VAE and U-Net dtypes aligned.

The non-GGUF trust gate is extended with a short, exact-match, safetensors-only
allowlist of official base repos (the SDXL base/refiner and sdxl-turbo), because
SDXL ships only as a full pipeline and has no unsloth-hosted GGUF. Local paths stay
trusted as before; a random repo, even one that detects as SDXL, is still rejected.

The image-conditioned and ControlNet workflows are the standard SDXL pipelines,
built around the resident modules via from_pipe like every other family, so SDXL
gets txt2img, img2img, inpaint, outpaint, upscale, LoRA and ControlNet. There is no
native sd.cpp mapping yet, so the no-GPU route falls back to diffusers.

Frontend catalog gains SDXL Base 1.0 and SDXL Turbo entries with SDXL step/guidance
defaults (Turbo: few steps, no CFG; base: ~30 steps, real CFG).

Tests: new test_diffusion_sdxl.py (family shape, detection, trust allowlist, model
kind, U-Net VAE-dtype alignment, LoRA gate) plus loader-branch tests in
test_diffusion_backend.py (pipeline-kind from_pretrained, single-file whole-pipeline
from_single_file, allowlist accept/reject). Verified live on GPU: sdxl-turbo loads
both as a pipeline and as a single file and generates coherent txt2img + img2img.
2026-07-01 13:57:07 +00:00
Daniel Han
355f54f6e4 Merge remote-tracking branch 'origin/diffusion-lora' into diffusion-controlnet 2026-07-01 11:57:56 +00:00
pre-commit-ci[bot]
5728670f6e [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:57:22 +00:00
Daniel Han
9637e85311 Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora 2026-07-01 11:56:47 +00:00
Daniel Han
38ed3ce5b5 Merge remote-tracking branch 'origin/diffusion-phase16-native-engine-routing' into diffusion-image-workflows
# Conflicts:
#	studio/backend/core/inference/diffusion.py
#	studio/backend/core/inference/diffusion_families.py
#	studio/backend/tests/test_sd_cpp_install.py
#	studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx
#	studio/frontend/src/features/images/api.ts
#	studio/frontend/src/features/images/images-page.tsx
#	studio/install_sd_cpp_prebuilt.py
2026-07-01 11:48:33 +00:00
pre-commit-ci[bot]
44beb54df5 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:36:08 +00:00
pre-commit-ci[bot]
db081d67de [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:34:22 +00:00
pre-commit-ci[bot]
ffe5b69773 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:33:51 +00:00
pre-commit-ci[bot]
a8e87ac77b [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:33:20 +00:00
pre-commit-ci[bot]
c1b4ed1233 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:32:45 +00:00
pre-commit-ci[bot]
1ab9db02ff [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:32:13 +00:00
Daniel Han
91edf06748 Merge branch 'diffusion-phase15-int8-prequant' into diffusion-phase16-native-engine-routing
# Conflicts:
#	studio/backend/routes/inference.py
2026-07-01 11:31:54 +00:00
pre-commit-ci[bot]
ab27ea8520 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:31:18 +00:00
pre-commit-ci[bot]
394f7985df [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-01 11:30:40 +00:00
Daniel Han
f899927652 Merge branch 'diffusion-phase14-int8-modulation' into diffusion-phase15-int8-prequant 2026-07-01 11:30:29 +00:00
Daniel Han
5951dbe145 Merge branch 'diffusion-phase12-fbcache' into diffusion-phase14-int8-modulation 2026-07-01 11:30:28 +00:00
Daniel Han
2a5713aff5 Merge branch 'diffusion-phase11-consumer-int8' into diffusion-phase12-fbcache 2026-07-01 11:30:26 +00:00
Daniel Han
2f26a785b1 Merge branch 'diffusion-phase10-attention' into diffusion-phase11-consumer-int8 2026-07-01 11:30:24 +00:00