Commit graph

6,166 commits

Author SHA1 Message Date
Daniel Han
41bdc116be Reject unknown union ControlNet control types instead of defaulting to canny
union_control_mode fell back to control_mode=0 (the canny head) for ANY unmapped control
type, so a typo'd or unsupported value like 'detph' silently conditioned the map as canny
instead of failing. preprocess_control passes non-canny maps through unchanged, so that map
would be interpreted under the wrong mode with no error. Now only 'passthrough' (or an empty
type) keeps the deliberate mode-0 default; any other unknown type raises ValueError, which
the generate route maps to a 400. Known modes are unchanged.
2026-07-07 14:55:37 +00:00
Daniel Han
46a0a21d53 Drop piecewise_constant from the diffusion training API scheduler enum
Follow-up to removing piecewise_constant from the trainable scheduler allow-list: the
DiffusionTrainingStartRequest.lr_scheduler Literal still advertised it, so a client that
picked it straight from the schema passed request validation and then hit the 400 from
normalized(). Remove it from the enum too so the API only offers schedulers the trainers
can actually run, and add a test asserting the enum never advertises a scheduler outside
the validation allow-list.
2026-07-07 14:23:14 +00:00
Daniel Han
0d0a6d2b96 Drop piecewise_constant from the trainable lr_scheduler allow-list
piecewise_constant is the only diffusers scheduler that needs a step_rules string, and
neither diffusion trainer passes one (get_scheduler is called with only warmup/training
steps, and there is no config field for it). Accepting it let /diffusion/start pass
normalized(), free the resident GPU workloads, spawn the trainer, and only then crash in
the subprocess (get_piecewise_constant_schedule does step_rules.split(",") on None) -- the
exact evict-then-fail the up-front validation exists to prevent. Reject it now with a clear
400. The remaining six schedulers all run with only warmup/training steps.
2026-07-07 13:39:34 +00:00
pre-commit-ci[bot]
04ddf5449c [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-06 13:18:23 +00:00
oobabooga
1681d7265e Merge remote-tracking branch 'ooba/fix/imggen-review-bugs' into fix/imggen-review-bugs 2026-07-06 10:17:39 -03:00
oobabooga
35dccf2da6 Drop redundant transformer_quant re-normalization in the dense-quant gate 2026-07-06 10:08:19 -03:00
oobabooga
9d8bf002f8 Merge remote-tracking branch 'origin/image-generation' into fix/imggen-review-bugs
# Conflicts:
#	studio/backend/core/inference/diffusion.py
#	studio/backend/core/training/diffusion_train_common.py
#	studio/backend/routes/training.py
#	studio/backend/tests/test_diffusion_dataset_api.py
2026-07-06 09:16:30 -03:00
oobabooga
01d0aa1a83 Preserve pre-existing files on upload rollback and budget the dense transformer in the quant preflight 2026-07-06 03:07:57 -03:00
Daniel Han
14dc3b86a7 Merge remote-tracking branch 'origin/image-generation' into pr6872
# Conflicts:
#	studio/backend/core/inference/diffusion.py
#	studio/backend/routes/training.py
#	studio/backend/tests/test_diffusion_dataset_api.py
2026-07-05 12:22:02 +00:00
pre-commit-ci[bot]
e800675128 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-05 11:40:35 +00:00
Daniel Han
fc1e099124 Harden ControlNet loads, thumbnail cache keys, API training guard, and picker roving keys
Review follow-ups on the image-generation PR:

- ControlNet: resolve_controlnet accepts a bare owner/name repo without the
  non-GGUF base trust gate, and _controlnet_pipe hands it straight to
  from_pretrained. A malicious pickle .bin would deserialize on load, so run
  the same Hugging Face malware preflight (evaluate_file_security) the chat and
  export loaders use before any remote ControlNet load; local dirs are exempt.
- Dataset thumbnails: key the cache on the full filename instead of the stem so
  sample.png and sample.jpg no longer collide on one .thumbs file (which could
  serve or delete the wrong image); the delete cleanup globs the same key.
- Diffusion training start: mirror start_training's API-key guard so an API
  client cannot start training (which frees VRAM by unloading chat) while an
  inference request is streaming; it now returns 409 before any GPU is freed.
- Model picker: include the curated safetensors row keys in the recommended
  roving key list so arrow-key navigation reaches those rows instead of hitting
  the duplicate option-missing id.

Tests: ControlNet malware gate (remote blocked before from_pretrained, local
skipped), thumbnail same-stem cache separation, API-key diffusion-start 409
before GPU free. Full diffusion suites green.
2026-07-05 11:36:58 +00:00
Daniel Han
f313cfd7e5 Security audit: baseline the new huggingface-hub Sandboxes findings
The latest huggingface-hub release added the Sandboxes feature. Its
bootstrap (_sandbox.py) fetches the static sbx-server binary into /tmp with
an Authorization header and marks it executable, which is exactly the
staged-dropper pattern the scanner hunts, and three while True polling loops
in _sandbox.py / hf_api.py / utils/_http.py match the beaconing heuristic.
All four verified against the official huggingface/huggingface_hub
repository: the snippet is the documented sandbox server injection and the
loops are deadline-style job and sandbox polling. Entries generated with
--write-baseline and reviewed line by line; scan_packages.py huggingface-hub
now exits 0 with the four findings suppressed.
2026-07-05 07:40:45 +00:00
Daniel Han
7a05d8655b Stream every DiT through group offload, not just the primary transformer
A dual-DiT pipeline (Ideogram 4's unconditional tower) placed its second
denoiser resident under the group tier, which defeats the tier since the
pair rarely fits where one alone did not. Stream transformer_2 and
unconditional_transformer alongside the transformer and keep only the
smaller companions resident.
2026-07-05 05:30:58 +00:00
pre-commit-ci[bot]
bcf25ca569 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-05 04:56:29 +00:00
Daniel Han
e3ad2263fb Merge branch 'image-generation' of https://github.com/unslothai/unsloth into image-generation 2026-07-05 04:53:43 +00:00
Daniel Han
c53a6cb65e Address review findings: dataset preflight, sd.cpp unload barrier, caption tombstone, ControlNet cache race
- Run the trainer's caption discovery in the start route BEFORE freeing GPU
  residents, so a missing or uncaptionable dataset 400s without evicting the
  loaded chat/Images model.
- sd.cpp unload now waits out a cancelled one-shot generation on the generate
  lock before reporting the device free, matching the diffusers backend.
- Clearing a caption that came from metadata.jsonl writes an empty sidecar
  tombstone instead of unlinking (both readers treat an existing sidecar as
  authoritative), so the cleared label cannot resurface.
- The ControlNet wrapper pipe is only cached while its load is still current,
  closing the unload race the model cache already handled.
2026-07-05 04:53:37 +00:00
pre-commit-ci[bot]
919661ddf0 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-05 04:42:18 +00:00
Daniel Han
62cae5fe71 Load image pipelines from the prefetched snapshot instead of re-sweeping the hub
The prefetch already scopes the file list (no packaged root singles, no
dtype-variant twins, no ONNX/Flax exports), but from_pretrained was then
called with the hub id, and its own snapshot sweep re-downloaded the
skipped files anyway: 24 GB per FLUX.1 repo and 65 GB on FLUX.2-dev, as
found in the blob cache. Return the snapshot dir from the prefetch (keyed
on the pipeline manifest) and hand it to every pipeline-assembly
from_pretrained site; any prefetch failure keeps the hub id and the old
behavior.
2026-07-05 04:41:43 +00:00
Daniel Han
e41718ed24 Merge remote-tracking branch 'origin/image-generation' into pr6872
# Conflicts:
#	studio/backend/core/inference/diffusion.py
#	studio/backend/core/training/diffusion_train_common.py
2026-07-05 02:38:13 +00:00
pre-commit-ci[bot]
f6f198fd5f [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-05 02:07:49 +00:00
Daniel Han
25d9cf9604 Stub diffusers.hooks too in the no-diffusers cache test 2026-07-05 02:04:16 +00:00
Daniel Han
e605075508 Fix diffusion training validation and honor lr_scheduler and batch size in the DiT trainer 2026-07-05 01:51:34 +00:00
Daniel Han
098809d2fe Reject sd-cli batch runs and clear stale output targets before a run 2026-07-05 01:49:19 +00:00
Daniel Han
76eee534ea Gate explicit attention kernels on NVIDIA CUDA and roll back partial FBCache hooks 2026-07-05 01:48:12 +00:00
Daniel Han
f1d9c88606 Validate load modes before eviction and wait out a cancelled denoise on unload 2026-07-05 01:47:02 +00:00
Daniel Han
6a8b0b47e7 Fix review findings on image generation: failed-load VRAM, API defaults, preflights
- Free reserved VRAM in the diffusion load worker's failure path: a load-time OOM
  never commits _state and the next load's _unload_locked early-returns, so nothing
  else reclaimed the half-built pipeline's memory
- Use a monotonic clock for the denoise ETA rate
- Sync _GENERATION_DEFAULTS with the UI table: kontext, flux.2-dev, sdxl-turbo and
  SDXL base rows so /v1/images/generations stops falling back to 9 steps / CFG 0
- 400 (not sanitized 500) when /v1/images/generations hits an edit-only model
- Fail fast on pre-Ampere CUDA in the DiT trainer instead of dying in model load
- Run the trainer trust gate in the diffusion training route before freeing GPU
  residents so an untrusted base cannot tear down loaded chat/Images models
- Protect native sd.cpp companion VAE/text-encoder repos from cache deletion while
  a load is downloading them
- Exempt the task-scoped Images picker from the chat-only GGUF/MLX format gate so
  local diffusers pipelines stay selectable on no-GPU hosts
2026-07-05 01:00:47 +00:00
Daniel Han
ee61c7b650 Fix hub error test construction for huggingface_hub 1.x for PR #6872
huggingface_hub 1.x makes HfHubHTTPError's response argument required and
reads only .headers and .request from it, while 0.x defaults it to None.
Pass a small stub response so the test constructs the error on both,
verified against 0.36.2 and the 1.22.0 wheel.
2026-07-04 23:36:40 +00:00
oobabooga
639d4061af Revert the LoRA target-module default change (already fixed upstream) 2026-07-04 20:26:27 -03:00
oobabooga
756c715721 Trim the verbose comments added by the fixes 2026-07-04 13:25:08 -03:00
pre-commit-ci[bot]
3bb3734879 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 14:11:00 +00:00
oobabooga
4161d5d87a Dedup the HF hub cache-dir path construction into a helper 2026-07-04 11:09:37 -03:00
oobabooga
2d13015a83 Merge remote-tracking branch 'origin/image-generation' into fix/imggen-review-bugs 2026-07-04 11:03:01 -03:00
Daniel Han
c241886c67 Merge branch 'image-generation' of https://github.com/unslothai/unsloth into image-generation 2026-07-04 13:47:00 +00:00
Daniel Han
24de50062c Enable conv-direct in the default native speed profile
Measured on the fresh linux x64 prebuilt (z-image Q8_0, sd-cli, 192 CPU
threads, 512x512, 9 steps, steady state): sampling 56.1s vs 51.3s (about
9 percent faster), VAE decode unchanged, peak RSS identical. The sd.cpp
engine only serves the no-GPU tier, so the default profile now matches
max: --diffusion-fa plus --diffusion-conv-direct.
2026-07-04 13:46:59 +00:00
oobabooga
31ee7bae16 Merge remote-tracking branch 'origin/image-generation' into fix/imggen-review-bugs 2026-07-04 10:44:13 -03:00
pre-commit-ci[bot]
ab56d81935 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:51:46 +00:00
Daniel Han
7bf80f6a4e Deny fp8/mxfp8/nvfp4 dense quant for the Qwen DiT (black frames, measured)
A 28-pair accuracy gate on a B200 (same-seed vs the dense bf16 reference)
found per-row fp8 dynamic quant renders EVERY qwen-image frame black
(mean luma 0.0000, SSIM 0.016), reproduced identically with on-the-fly
quantize_ on the dense transformer, so it is the model's activation range,
not a checkpoint artifact. mxfp8 shows real semantic damage at 1024px
(CLIP delta mean 0.0146, worst cases 0.064/0.102) and nvfp4 measures
LPIPS mean 0.51. int8 dynamic (per-token scales) is excellent on Qwen:
LPIPS mean 0.069, SSIM 0.958.

The per-scheme smoke probe only proves the GEMM kernel runs, so it cannot
catch model-level breakage. Add _FAMILY_SCHEME_DENY consulted by
select_transformer_quant_scheme: auto skips denied schemes (Qwen lands on
int8) and an explicit denied request returns None, the same GGUF-fallback
contract as an unsupported scheme. Family is threaded from the three
diffusion.py call sites; existing behavior is unchanged for every other
family. 4 new tests; 529 diffusion tests green; CI-sim green.
2026-07-04 08:51:10 +00:00
Daniel Han
d146209f88 Rename the GGUF compute control to Dtype and simplify the empty-state copy
The always-visible description under the select is gone (the hint tooltip keeps the
full detail) and the no-model gallery placeholder now reads 'Select a diffusion model
to load'.
2026-07-04 06:17:45 +00:00
oobabooga
e5c63cdfff Fix diffusion training validation, dataset upload atomicity, and LoRA error mapping 2026-07-04 03:17:12 -03:00
oobabooga
26a81c5e17 Fix diffusion quant gating, MPS load OOM, and native sd-server discovery 2026-07-04 02:35:51 -03:00
pre-commit-ci[bot]
e6d775d0fc [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 05:08:43 +00:00
Daniel Han
1d3aa53d1f Validate the training config before importing diffusers and pin the arbiter test's device
The fp16-on-bf16-family refusal in run_dit_lora_training now fires before the heavy
imports, so a host without diffusers gets the real validation error instead of
ModuleNotFoundError. test_in_progress_returns_409_after_validation_passes pins the
resolved device to cuda because the load route only takes the GPU arbiter for non-CPU
loads, which made the ownership assert host-dependent.
2026-07-04 05:01:58 +00:00
Daniel Han
630689032e Merge branch 'image-generation' of https://github.com/unslothai/unsloth into image-generation 2026-07-04 05:01:57 +00:00
Daniel Han
8ad8a58742 Add grad norm chart, clearer completion state, Windows caption keys, GGUF compute copy
- Trainers emit the pre-clip gradient norm; the service keeps a bounded
  grad_norm history and the Train tab renders a Grad Norm chart next to
  Loss and LR
- Completed runs show 'Training complete' with a celebratory marker in
  the success color instead of a plain status word
- metadata.jsonl caption keys now match on Windows (as_posix relative
  paths) in both the trainer discovery and the dataset image records
- RMSNorm eager patch skips installation on torch builds without
  F.rms_norm instead of failing at forward time
- GGUF compute description no longer says the GGUF is dequantised: the
  INT8/FP8/FP4 modes load the base model's bf16 transformer and quantise
  that directly; label no longer wraps in the Advanced panel
2026-07-04 04:31:04 +00:00
pre-commit-ci[bot]
07f27b23e8 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 03:29:17 +00:00
Daniel Han
6f9d8b356c Merge branch 'image-generation' of https://github.com/unslothai/unsloth into image-generation 2026-07-04 03:23:05 +00:00
Daniel Han
bfbb902610 Fix review findings: engine unload before training, caption precedence, dataset caption counts, local diffusers tagging, family LoRA targets
- Unload the ACTIVE image engine (sd_cpp or diffusers) before diffusion training starts, not just the diffusers singleton
- Count metadata.jsonl captions in dataset summaries so metadata-captioned datasets are not reported as uncaptioned
- Sidecar captions now override metadata rows everywhere (grid edits win); trainer and dataset API agree
- Tag local diffusers image checkpoints with text-to-image so they appear in the Images picker
- Family LoRA targets (_FLUX_TARGETS etc) apply when the config carries the generic defaults; explicit overrides still win
2026-07-04 03:23:05 +00:00
pre-commit-ci[bot]
bbca561d38 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 02:20:19 +00:00
Daniel Han
71ab68fd55 Merge remote-tracking branch 'origin/main' into image-generation
# Conflicts:
#	studio/frontend/src/app/router.tsx
2026-07-04 02:18:20 +00:00
oobabooga
87ea2ca231 Drop accidentally committed test files 2026-07-03 18:37:42 -03:00