Commit graph

6,294 commits

Author SHA1 Message Date
Daniel Han
c2b25feaee Guard inference loads and worker lifetime against diffusion training
Teach the chat and image load guards about an active diffusion (SDXL) LoRA
job: a chat load is refused (its footprint cannot be fit-checked against the
trainer) and an image load is refused outright, mirroring the existing LLM
training guards, so a load can no longer allocate GPU memory alongside the
trainer and undo the pre-start cleanup.

Bind the diffusion trainer subprocess to the parent's lifetime and scrub the
native path lease secret from it by running the child through
run_without_native_path_secret, matching the inference/export/LLM workers, so
a Studio crash or kill no longer leaves the trainer holding the GPU.

Reset in_model_load on the complete and error terminal events: a stop or
failure during model loading otherwise leaves the status reporting a stale
loading indicator after the job has ended.
2026-07-02 05:47:50 +00:00
pre-commit-ci[bot]
f6b1270071 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-02 04:38:56 +00:00
Daniel Han
2b3d75df0b Merge remote-tracking branch 'origin/diffusion-lora-training' into diffusion-lora-training-api 2026-07-02 04:34:50 +00:00
Daniel Han
e3d8e5ef0f Merge remote-tracking branch 'origin/diffusion-lora-ux' into diffusion-lora-training 2026-07-02 04:34:48 +00:00
Daniel Han
9ca4b9ee3a Merge remote-tracking branch 'origin/diffusion-sdxl' into diffusion-lora-ux 2026-07-02 04:34:47 +00:00
Daniel Han
939ba33b1d Merge branch 'diffusion-sdxl' of https://github.com/unslothai/unsloth into diffusion-sdxl 2026-07-02 04:34:21 +00:00
Daniel Han
5987caf940 Align the VAE to the denoiser's first FLOATING dtype, not its first parameter
A GGUF-quantized transformer's leading parameters are packed uint8 storage,
so reading next(parameters()).dtype handed nn.Module.to() an integer dtype
and every image-conditioned generation on a GGUF model (Qwen-Image-Edit)
failed with a 500. Probe the parameters for the first floating dtype, treat
an all-integer module as a no-op, and also catch TypeError so an unexpected
dtype can never break generation. Regression test included.
2026-07-02 04:34:21 +00:00
Daniel Han
d773ce00fa Merge remote-tracking branch 'origin/diffusion-lora-training' into diffusion-lora-training-api 2026-07-02 04:01:45 +00:00
Daniel Han
3e4469bb9f Merge remote-tracking branch 'origin/diffusion-lora-ux' into diffusion-lora-training 2026-07-02 04:01:44 +00:00
Daniel Han
61b12676b9 Merge remote-tracking branch 'origin/diffusion-sdxl' into diffusion-lora-ux 2026-07-02 04:01:42 +00:00
pre-commit-ci[bot]
57c6e11c36 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-02 04:01:09 +00:00
Daniel Han
9e3aa584c6 Merge remote-tracking branch 'origin/diffusion-controlnet' into diffusion-sdxl
# Conflicts:
#	studio/backend/core/inference/diffusion.py
2026-07-02 04:00:09 +00:00
Daniel Han
23b2c13c75 Merge remote-tracking branch 'origin/diffusion-lora' into diffusion-controlnet
# Conflicts:
#	studio/backend/core/inference/diffusion.py
2026-07-02 03:57:51 +00:00
Daniel Han
89ff99475d Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora 2026-07-02 03:56:32 +00:00
Daniel Han
c58856709a Merge remote-tracking branch 'origin/image-generation' into diffusion-image-workflows
# Conflicts:
#	studio/backend/core/inference/diffusion.py
2026-07-02 03:55:35 +00:00
Daniel Han
a4277a01e4 Honor memory_mode over legacy cpu_offload and prefetch dense-quant transformer shards
plan_diffusion_memory only applies the legacy cpu_offload override when no
memory_mode was supplied, matching the documented API contract that
memory_mode overrides cpu_offload when set; an explicit fast request now
stays resident even if the old flag is also enabled.

The transformer-quant dense path fetches the base repo's transformer/
shards inside the locked finalize phase, where unload and cancellation
cannot preempt the multi-GB download. The load worker now widens the
preemptible prefetch to include those shards when that path can actually
run: quant requested and supported for the device, scheme resolvable, and
no pre-quantized checkpoint shortcutting the dense build.
2026-07-02 03:51:53 +00:00
Daniel Han
d9a118af95 Merge remote-tracking branch 'origin/diffusion-lora-training' into diffusion-lora-training-api 2026-07-02 03:38:54 +00:00
Daniel Han
370544c8ee Merge remote-tracking branch 'origin/diffusion-lora-ux' into diffusion-lora-training 2026-07-02 03:38:52 +00:00
Daniel Han
8af8db0b8b Merge remote-tracking branch 'origin/diffusion-sdxl' into diffusion-lora-ux 2026-07-02 03:38:50 +00:00
Daniel Han
4dbd3e538d Merge remote-tracking branch 'origin/diffusion-controlnet' into diffusion-sdxl 2026-07-02 03:38:49 +00:00
Daniel Han
d06b68c83a Merge remote-tracking branch 'origin/diffusion-lora' into diffusion-controlnet 2026-07-02 03:38:46 +00:00
Daniel Han
ecb797ab42 Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora 2026-07-02 03:36:58 +00:00
Daniel Han
c800e89206 Merge remote-tracking branch 'origin/image-generation' into diffusion-image-workflows
# Conflicts:
#	studio/backend/core/inference/diffusion.py
#	studio/frontend/src/features/images/images-page.tsx
2026-07-02 03:36:50 +00:00
pre-commit-ci[bot]
dd792c6312 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-02 03:30:16 +00:00
Daniel Han
a9e5a80654 Address the round of Codex review findings on the merged diffusion phases
Memory planning and dense-quant path: size a local diffusers base's
resident companions from its on-disk VAE and text-encoder weights instead
of folding them to zero, feed the distilled variant hint into the runtime
headroom estimate so turbo and schnell models are not over-reserved, place
group-offload companions resident before attaching the transformer hooks
so a failed placement falls back to whole-module offload instead of
crashing, and bail out of the dense transformer download before it starts
when the requested quant scheme is unsupported so the load falls back to
GGUF cleanly.

sd.cpp stack: scrub the native path lease secret from sd-cli child env,
redact native load-progress errors, forward the resolved accelerator when
auto-installing a forced-native binary, release stale diffusion GPU
ownership on CPU-native loads, and remove the sd.cpp install tree on
uninstall.

Prequant and scripts: reject prequant artifacts missing base_model_id
when a base is requested, expanduser before checkpoint existence checks,
record and validate the int8 exclusion filter and fp8 fast-accum in
checkpoint metadata, make verify_prequant_backend allowlist its local
checkpoint and fail on missing or bad LPIPS and on load-peak regressions,
average only finite PSNR values in diffusion_quality, and reset the
process-wide attention backend between perf probe variants.

API and UI: normalize attention_backend casing before Literal validation,
close hidden popovers when leaving the Images page, and clear the stale
quant label when loading a direct local GGUF file.
2026-07-02 03:29:18 +00:00
Daniel Han
b33418e14a Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora 2026-07-02 02:39:00 +00:00
Daniel Han
2aa379d9cc Merge remote-tracking branch 'origin/image-generation' into diffusion-image-workflows 2026-07-02 02:37:52 +00:00
Daniel Han
22f49b5ac2 Merge remote-tracking branch 'origin/main' into image-generation
# Conflicts:
#	scripts/scan_packages_baseline.json
2026-07-02 02:36:18 +00:00
Daniel Han
7c080f3222 Merge remote-tracking branch 'origin/diffusion-lora-training' into diffusion-lora-training-api 2026-07-02 02:32:10 +00:00
Daniel Han
2ce0bdbdf6 Merge remote-tracking branch 'origin/diffusion-lora-ux' into diffusion-lora-training 2026-07-02 02:31:18 +00:00
Daniel Han
8c5cdeb331 Merge remote-tracking branch 'origin/diffusion-sdxl' into diffusion-lora-ux 2026-07-02 02:30:23 +00:00
Daniel Han
e6bf4c4cd6 Merge remote-tracking branch 'origin/diffusion-controlnet' into diffusion-sdxl 2026-07-02 02:28:33 +00:00
Daniel Han
c3196cb8bd Merge remote-tracking branch 'origin/diffusion-lora' into diffusion-controlnet 2026-07-02 02:27:40 +00:00
Daniel Han
b9b80a4c83 Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora
# Conflicts:
#	studio/backend/core/inference/diffusion.py
2026-07-02 02:26:46 +00:00
Daniel Han
a4d02dda73 Merge remote-tracking branch 'origin/image-generation' into diffusion-image-workflows
# Conflicts:
#	studio/backend/core/inference/diffusion.py
#	studio/frontend/src/features/images/images-page.tsx
2026-07-02 02:25:16 +00:00
Daniel Han
a8f7b3de57 Address review findings on the image-generation PR
Backend:
- Sanitize a blank hf_token to None in begin_load and load_pipeline, so the
  default empty Studio token loads anonymously instead of 401ing as an explicit
  empty credential.
- Free the ACTIVE diffusion engine before LLM training and in the delete-cached
  guard: on a native (sd_cpp) selection the diffusers singleton reports
  unloaded, so training could start against a live sd-cli generation and
  delete-cached could remove a GGUF the native engine is using. Both now go
  through diffusion_engine_router.get_active_diffusion_engine().
- Refuse delete-cached while a background image load is downloading the repo
  (or its companion base): status().loaded is False in that window, but the
  delete would yank blobs from under the in-flight assembly. Both engines
  expose the in-flight ids via a new loading_repo_ids().
- Cap request seeds at 2**53-1: seeds round-trip through JSON gallery recipes,
  where JavaScript rounds larger integers, so a restored recipe generated a
  different image. Random seeds were already masked to this range.
- Add the task field to CachedModelRepo: the handler sets it for cached
  diffusers image repos but response_model silently dropped it, letting
  image-only repos pass the chat picker's task gate.

Frontend:
- Offset sequential run seeds by the batch size: the native engine seeds image
  j of a run at seed+j, so a +1 run offset regenerated the previous run's
  batch-mates.
- Revert the optimistic quant selection when a load fails to start.
- Stop disabling the Images page on chat-only hosts: the native sd.cpp engine
  exists exactly for the no-GPU route.
2026-07-02 02:17:57 +00:00
Daniel Han
7f59cd6c1e Review pass over the merged diffusion phases: seven correctness fixes
Re-reviewed each merged phase PR against this branch's tip and fixed what is
still real:

- A superseded background load no longer cancels the current model's in-flight
  generation: the load-token check now runs BEFORE the cancel signal, with a
  re-check under the generate lock (Phase 1 review).
- enable_model_cpu_offload / enable_sequential_cpu_offload now forward the
  resolved target device; diffusers defaults to CUDA, which broke offloaded
  loads on non-CUDA accelerators such as Intel XPU (Phase 2 review).
- build_sd_cpp_command rejects a None prompt (str(None) previously slipped
  into argv as the literal "None") and a mask without an init image, which
  is an invalid sd-cli inpaint invocation (Phase 4/6 review).
- The dense-quant OOM fallback drops the caught exception before
  clear_gpu_cache(): the traceback pinned the partially built dense
  transformer, so the VRAM this cleanup exists to reclaim stayed allocated
  through the GGUF rebuild (Phase 8 review).
- Pre-quantized transformers (built via from_config) are eval()'d to match
  the from_pretrained paths, so train-mode layers cannot make prequant
  inference nondeterministic (Phase 9 review).
- FBCache state is reset before each generation when a step cache is engaged:
  diffusers never clears the stateful first-block residuals on the resident
  transformer, so a resolution or batch change on the next request hit a
  shape mismatch, and an unchanged request could reuse stale residuals
  (Phase 12 review).

Each fix carries a regression test; the full diffusion battery passes.
2026-07-02 02:06:08 +00:00
Daniel Han
49ea887312 CI: baseline the fastapi/gguf scan findings for the studio dependency set
The pip scan-packages job keys its baseline on the matched-code hash (main's
scanner). This branch's dependency set resolves a newer fastapi (its routing
while-True loop hashes differently than the baselined one) and adds gguf,
whose HF_TOKEN-authenticated download helper trips the env+network check.
Both reviewed benign: the fastapi hit is its own websocket routing loop and
the gguf hit is the official package's Hub download path. Sync the scanner
and baseline from main and add the two reviewed entries.
2026-07-02 02:04:28 +00:00
Daniel Han
e9e9d82836 Merge remote-tracking branch 'origin/diffusion-lora-training' into diffusion-lora-training-api 2026-07-02 01:24:12 +00:00
Daniel Han
e0db8f4612 Merge remote-tracking branch 'origin/diffusion-lora-ux' into diffusion-lora-training 2026-07-02 01:23:23 +00:00
Daniel Han
76b5ee354d Merge diffusion-sdxl into diffusion-lora-ux; keep options-only LoRA catch
The catalog-refresh .catch from the lower branch clears the selected adapters
too, which is right for its catalog-only picker but wrong here: this picker
holds free-text HF repo ids that are valid without being in the catalog, so a
transient refresh failure must not wipe them. Family swaps still clear the
selection and hidden LoRAs are never sent.
2026-07-02 01:23:15 +00:00
Daniel Han
2ac1e77dfc Merge remote-tracking branch 'origin/diffusion-sdxl' into diffusion-lora-ux 2026-07-02 01:21:52 +00:00
Daniel Han
74c3aa8a6d Merge remote-tracking branch 'origin/diffusion-controlnet' into diffusion-sdxl
# Conflicts:
#	studio/backend/core/inference/diffusion.py
2026-07-02 01:21:41 +00:00
Daniel Han
582e2dcf39 Merge remote-tracking branch 'origin/diffusion-lora' into diffusion-controlnet 2026-07-02 01:18:40 +00:00
Daniel Han
bb78742718 Merge remote-tracking branch 'origin/diffusion-image-workflows' into diffusion-lora 2026-07-02 01:17:02 +00:00
pre-commit-ci[bot]
dcf6cf5117 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-02 01:14:22 +00:00
Daniel Han
e05c9cc947 Images: preserve restored LoRAs through model load and never send hidden LoRAs
- The LoRA effect cleared the selection on every load->capable transition, which
  wiped adapters restored from a gallery recipe before the model finished loading.
  Track the previously-loaded family in a ref and clear only on a real family swap;
  keep the selection on the initial load and on unload.
- Gate the generate payload's loras on loraCapable so a restored selection that is
  hidden (loaded model does not support LoRA) is never sent to the backend.
2026-07-02 01:13:39 +00:00
Daniel Han
a4fb348f9f SDXL: reject GGUF up front, skip unused base weights, drop refiner, and harden helpers
Addresses review findings on the SDXL family:
- Reject a GGUF load for single_file_is_pipeline families (SDXL) in validate_load_request,
  before the route evicts the current model; SDXL has no transformer-only GGUF variant.
- Skip base-repo weight files when a whole-pipeline single file is loaded: from_single_file
  (config=base) needs only the base config/tokenizer/scheduler, so a local .safetensors no
  longer triggers a multi-GB base download.
- Remove the SDXL refiner from the non-GGUF trust allowlist: it is an img2img-only pipeline
  but this backend loads every sdxl repo as the base txt2img pipeline.
- Normalize a blank/whitespace hf_token to None once in load_pipeline so every load branch
  degrades to anonymous instead of erroring on a malformed token.
- Read the denoiser dtype from a parameter (compile-wrapped modules may lack .dtype) and
  access state.family.denoiser_attr directly.

Adds/updates regression tests for the trust allowlist, GGUF rejection, and base-config filter.
2026-07-02 01:13:18 +00:00
Daniel Han
94d74e8bbe Diffusion: guard trust check against OSError and validate conditioning inputs
- _is_trusted_diffusion_repo: wrap Path.exists() so a repo id with invalid
  characters (or a bare owner/name id) can't raise OSError; treat any failure as
  not-a-local-path and fall through to the unsloth/ allowlist. validate_load_request
  still raises the clear FileNotFoundError for a genuinely missing local pick.
- generate(): reject mask_image / upscale / reference_images supplied without an
  input image, and reject reference_images on a family that does not support
  reference conditioning, instead of silently degrading to txt2img / img2img.
2026-07-02 01:13:04 +00:00
pre-commit-ci[bot]
1d4461b23b [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-02 01:12:15 +00:00