Commit graph

2,320 commits

Author SHA1 Message Date
Daniel Han
f77fa80007 Add HunyuanVideo-1.5 family and the video quality gate
HunyuanVideo-1.5 (the 8.3B DiT with Qwen2.5-VL + ByT5 text encoders) loads
through the hunyuanvideo-community Diffusers repacks; tencent's own repo is
the original non-diffusers layout and cannot load as a pipeline, so only the
community 480p/720p t2v repos are trusted. Two pipeline quirks, both verified
against pipeline_hunyuan_video1_5.py in diffusers 0.39, shape the wiring:

- __call__ takes no guidance kwarg: CFG lives on the pipeline's guider
  component (ClassifierFreeGuidance, shipped at scale 6.0). The family gains
  guidance_via_guider and generate() writes the requested scale onto
  pipe.guider instead of passing cfg_kwarg, which the pipeline would reject.
- __call__ has no callback_on_step_end: progress and cancellation fall back
  to a scheduler.step wrapper (one call per denoise step), installed for the
  duration of the call and always restored. Cancellation unwinds the loop by
  raising through the wrapper and surfaces the same cancelled sentinel the
  callback path uses.

The VAE compresses 16x spatial / 4x temporal, so sizes snap to /16 and frame
counts to 4k+1. The transformer declares _repeated_blocks and CacheMixin, so
the regional compile profile and the step cache both apply unchanged.

scripts/video_quality.py is the video accuracy gate, the analogue of
scripts/diffusion_quality.py with the same pure-numpy PSNR/SSIM math so image
and video budgets compare: fixed prompt/seed/shape, one short clip per
candidate against a reference clip, per-frame SSIM/PSNR over sampled frames,
a temporal-consistency deviation (motion-energy series error, catching
flicker SSIM alone misses), black-frame/NaN collapse checks, an audio RMS
silence trip-wire for LTX-2, and wall time + peak VRAM per candidate.
Verdicts map the standing budget: ssim >= 0.75 passes, >= 0.50 warns,
anything lower or any collapse fails. --selftest runs the metric path on
synthetic clips with no GPU or model.
2026-07-04 14:22:10 +00:00
Daniel Han
e1221f3a47 Point Wan gguf_repo at the QuantStack community quants
The unsloth Wan2.2 GGUF repos referenced before do not exist on the Hub
(verified via the API: RepositoryNotFoundError for both). QuantStack's
are the community standard (30k and 82k downloads over 30 days), so the
picker's GGUF expander now points there.
2026-07-04 14:09:10 +00:00
Daniel Han
9f83d387c2 Add Wan2.2 text-to-video families to the video backend
Register two new video families and wire them through the backend, routes,
and frontend picker: wan2.2-ti2v-5b (single DiT) and wan2.2-t2v-a14b (the
dual-expert MoE). Both share diffusers' WanPipeline + WanTransformer3DModel
+ AutoencoderKLWan, which the VideoFamily dataclass already reserved fields
for (transformer2_class, is_moe, cfg2_kwarg).

Verified against the installed diffusers 0.39.0 before writing code:
- WanPipeline, WanTransformer3DModel, and AutoencoderKLWan are all exported
  from top-level diffusers 0.39.0.
- WanPipeline.__call__ (pipeline_wan.py:383) defaults to num_frames=81,
  num_inference_steps=50, guidance_scale=5.0. guidance_scale_2 DOES exist
  in 0.39 (line 392) and its check_inputs raises if it is passed when the
  pipeline's boundary_ratio is None (line 322), so the second guidance is
  threaded ONLY for the MoE family and only when inspect.signature accepts
  it (the same gate frame_rate already uses).
- The Wan VAE temporal factor is 4 (autoencoder_kl_wan.py scale_factor_temporal),
  and the pipeline snaps num_frames to 4k+1 (line 493), so frame_step is 4,
  unlike LTX-2's 8k+1. Sizes patchify at spatial 8 * patch 2 = 16, so
  resolution_multiple is 16.
- boundary_ratio and transformer_2 come from model_index.json: TI2V-5B ships
  boundary_ratio=null and transformer_2=[null,null] (single DiT), while A14B
  ships boundary_ratio=0.875 and transformer_2=WanTransformer3DModel (dual
  DiT). boundary_ratio lives in the pipeline config, so it needs no per-call
  plumbing.
- WanTransformer3DModel declares _repeated_blocks=["WanTransformerBlock"] and
  inherits CacheMixin (transformer_wan.py:508/551), so regional compile and
  First-Block-Cache both work.

bf16-resident component sizes, measured from each diffusers repo's on-disk
safetensors (all stored bf16), feed the auto memory table:
  TI2V-5B: transformer 20.0, UMT5 text encoder 11.4, VAE 2.8 GB.
  A14B:    two experts 57.2 each (114.3 total), text encoder 11.4, VAE 0.5 GB.

Backend changes make the optimisation layers dual-DiT aware: a small
_SecondDiTView proxy presents transformer_2 as pipe.transformer so the
existing single-DiT helpers (apply_speed_optims, apply_attention_backend,
apply_step_cache, quantize_transformer) cover BOTH experts on an is_moe load
without forking any helper; single-DiT loads are unchanged (views is just
(pipe,)). The two Wan base repos are added to the trusted non-GGUF allowlist.
A transformer_quant option is added to the load path, mirroring the image
backend's dense torchao fast path: on a pipeline-kind load the dense DiT(s)
are quantised in place onto the low-precision tensor cores and the engaged
scheme is surfaced in status. generate() threads guidance_2 through the
family's cfg2_kwarg when the loaded pipeline accepts it.

Routes and Pydantic models gain the optional transformer_quant (load /
status) and guidance_2 (generate) fields. The frontend picker gains the two
Wan models with 50-step / CFG 5.0 defaults; fps is supplied per family by
the backend.

Tests extend the fake runtime with WanPipeline and per-DiT transformer fakes
(single-DiT and dual-DiT), and cover family detection for both repos, 4k+1
frame snapping, default application, dual-DiT speed/cache/attention/quant
coverage on both experts, cfg2 threading gated on the pipeline signature,
trusted-repo validation, and the new route fields. Both the standard and the
diffusers/torchao-blocked CI-sim runs are green.
2026-07-04 14:06:47 +00:00
Daniel Han
ffce9b8ba8 Merge branch 'video-inference' into video-tab 2026-07-04 13:52:26 +00:00
Daniel Han
b58098b219 LTX-2.3 checkpoint support: full pipeline assembly
diffusers 0.39 ships every LTX-2.3 model class but its single-file loader
maps all LTX-2 checkpoints to the 2.0 config, so 2.3 checkpoints (9-row
modulation tables, gated attention, per-modality connectors) fail a shape
check at load. The community transformer-only GGUFs also lack the text
projections, VAEs, and vocoder that 2.3 moved out of the transformer.

New core/inference/video_ltx2.py detects a 2.3 checkpoint from its header
(6 vs 9 modulation rows, no weight data read) and assembles the full
pipeline: the DiT through from_single_file with the 2.3 config overrides
and the prompt_adaln key renames the stock converter lacks, the 8-layer
per-modality connectors from the same checkpoint plus the text projection
companion file, and the 2.3 video VAE, audio VAE, and BWE vocoder from
the companion files in unsloth/LTX-2.3-GGUF. Configs and rename tables
mirror diffusers' own scripts/convert_ltx2_to_diffusers.py, which the
library loader has not absorbed yet. Assembled through the constructor
because the base repo pins LTX2Vocoder while 2.3 needs LTX2VocoderWithBWE
and the from_pretrained type gate rejects the substitution.

Verified on a B200: distilled-1.1 Q4_K_M GGUF loads in 37s, generates a
49-frame 768x512 clip with synchronized audio in 18s (8 steps), frames
on-prompt and non-black, container decodes fully. Meta-tensor validation
confirms exact key and shape match for all five converted components.
Unit tests cover 2.3 detection (gguf + safetensors headers), combined
checkpoint partitioning, and companion-set choice.
2026-07-04 13:50:44 +00:00
Daniel Han
a487f3c1c0 Add Video tab to Studio frontend
Add a Video generation page that mirrors the Images feature's create
workflow. It loads a text-to-video model, generates a clip, and plays it
back inline with the gallery of past clips.

- src/features/video/api.ts: typed client for the /api/inference/video
  routes (load, load-progress, generate, generate-progress, cancel,
  status, unload, gallery CRUD, and an auth-protected MP4 blob fetch).
- src/features/video/video-page.tsx: the page. Curated model picker
  (LTX 2.3 distilled GGUF, LTX 2 base pipeline), prompt and negative
  prompt, resolution preset select, duration select over the family's
  temporal lattice, fixed fps display, steps and guidance sliders seeded
  from per-model defaults, seed box. Generate polls per-step progress
  with a phase label and ETA and a Cancel button, then plays the result
  in a video player with a download button and an audio badge. Gallery
  strip below with per-card delete and clear all. Right-docked Advanced
  panel for memory, speed, attention, and step-cache with Auto badges
  fed from the resolved status.
- Register the page: router child, /video route, sidebar nav item with a
  video icon after Images, and the __root keep-alive mount so an
  in-flight generation survives leaving the tab.
- Add the text-to-video task to the model picker so video models never
  appear in the chat picker.
- Add the video nav label to the en and zh-CN locales.
2026-07-04 13:30:42 +00:00
Daniel Han
e24df85f12 Video HTTP surface: /api/inference/video routes + request/response models
routes/video.py mirrors the /images/* routes one-for-one: validate-before-evict
load ordering (a bad pick must not evict a working chat model and then 400),
the training-active interlock, the device-gated GPU arbiter handoff with the
new VIDEO owner, the exact-match sentinel mapping (VIDEO_NOT_LOADED_MSG /
VIDEO_CANCELLED_MSG to 409, ValueError/FileNotFoundError to 400 with native
paths redacted, everything else a sanitized 500), and the gallery CRUD shape
with fetch-one-extra has_more paging. Generate persists the encoded MP4 plus
its full recipe through video_gallery.save and returns the gallery record; the
file endpoint serves video/mp4 with an immutable Cache-Control, 404 on any id
that fails the containment check.

models/inference.py gains the video request/response set (VideoLoadRequest,
VideoGenerateRequest/Response, GalleryVideo, gallery list, both progress
shapes, VideoGenerationDefaults nested in VideoStatusResponse), reusing
DiffusionResolvedControl for the resolved-provenance badges. The router is
registered in main.py after the images router under the same /api/inference
prefix and auth dependency.

Tests: 20 route tests on a stubbed backend + real tmp gallery (load happy path
and arbiter acquisition, 400/409 mappings, generate persistence round trip,
mp4 file serving + 404, delete/clear, unload releases ownership); the
diffusion route suite stays green after the shared models edit.
2026-07-04 13:17:01 +00:00
Daniel Han
1b4a66dcca Video inference engine: LTX-2 family registry, VideoBackend, MP4 gallery
Text-to-video lands as a SIBLING of the image diffusion backend, not a mode of
it: video pipelines take frame/fps arguments, return frame stacks plus, for
LTX-2, synchronized audio, and persist MP4s -- none of the image module's
img2img/inpaint/ControlNet/LoRA surface applies. The image backend's hardware
and optimisation layers are imported unchanged (device/dtype resolution, memory
planning + offload tiers, attention backends, speed profiles, FBCache), and the
load-token/cancel-event concurrency skeleton is copied verbatim so lifecycle
behaviour cannot diverge.

core/inference/video_families.py: a pure VideoFamily registry (no torch) with
the ltx-2 entry -- LTX2Pipeline + LTX2VideoTransformer3DModel, base
Lightricks/LTX-2, unsloth/LTX-2.3-GGUF as the curated GGUF source, audio on,
frame lattice k*8+1, /32 resolutions with a vertical preset, and measured bf16
component sizes (the Gemma3-27B text encoder outweighs the 19B DiT itself).
MoE fields (transformer_2, guidance_scale_2) are declared now so the Wan2.2
A14B family lands later without churning the schema.

core/inference/video.py: VideoBackend with async begin_load + cache-scan
download progress, GGUF / single-file / full-pipeline loads (the GGUF DiT
assembles onto the base repo exactly like the image path), generation with
frame/size snapping BEFORE latents allocate, per-step progress + ETA and
cooperative cancel via the standard diffusers callback, and MP4 (H.264) export
through diffusers' PyAV encoder with the audio track muxed when the family
produces one. VAE tiling is always on: decoding a 100+ frame clip is the
memory peak, and the frames-aware estimate_video_runtime_mib (new, in
diffusion_memory) feeds the planner where the pixel-area image estimate would
badly undershoot. Loads are gated to unsloth/*, the official Lightricks base
repos, or local paths; PyAV availability is checked at load time so a missing
encoder cannot fail a clip after a multi-minute denoise.

core/inference/video_gallery.py: {id}.mp4 + {id}.json recipe sidecar pairs
under studio_root()/videos (an MP4 has no PNG text chunk to embed the recipe
in), with the image gallery's id/containment guards, newest-first listing that
skips orphans, delete/clear.

gpu_arbiter gains the VIDEO owner: ownership is exclusive, so the existing
evict-the-current-owner already generalises to chat/image/video all evicting
each other. The av (PyAV) dependency joins requirements/studio.txt.

Tests: video family detection/snapping/defaults, backend lifecycle on a faked
torch/diffusers runtime (GGUF assembly, shape snapping, distilled defaults,
cancel/progress, sentinel), gallery roundtrip/containment/orphans. 52 new
tests green plus the arbiter suite.
2026-07-04 13:08:43 +00:00
Daniel Han
cbfc43215d Add Ideogram 4 family, structured HunyuanImage exclusion, curated Krea 2 LoRAs
Ideogram 4 (diffusers 0.39 Ideogram4Pipeline) as a new image family. The vendor
publishes no bf16 checkpoint, so ideogram-ai/ideogram-4-fp8 (raw float8 DiTs,
upcast by from_pretrained) is the family base and ideogram-4-nf4-diffusers is
the bnb-4bit pipeline artifact (ideogram-4-nf4 is byte-identical and detects to
the same family). All three repos join the trusted non-GGUF allowlist and the
frontend safetensors catalog.

Family specifics handled:
- Dual-branch CFG runs through a SEPARATE unconditional_transformer, so the
  auto-policy size table entry counts two ~9.3B DiTs (37.2 GB bf16), and the
  pipeline-kind memory plan now takes max(cached bytes, family table) for the
  family base repo: the fp8 repo's cached bytes undershoot the bf16-resident
  footprint by ~2x, which would let auto planning pick a resident placement
  that OOMs.
- The pipeline accepts EITHER guidance_scale OR a per-step guidance_schedule
  (its default: the recommended 45x7.0 + 3x3.0 taper, valid only at 48 steps)
  and raises when both are set. At the advertised defaults (48 steps, guidance
  7) generate() drops the constant so the recommended taper engages; any other
  request nulls the schedule so the constant broadcasts legally.
- Generation defaults per the model card: 48 steps, guidance 7 (both tables).

tencent/HunyuanImage-3.0 is deliberately excluded: it has no diffusers pipeline
(an 80B autoregressive MoE behind trust_remote_code). A structured exclusion
map now surfaces that reason verbatim from validate_load_request instead of
the generic unknown-family error.

The curated diffusion LoRA catalog gains the nine official krea/Krea-2-LoRA-*
style adapters (family-tagged krea-2, explicit weight filenames), so they show
up in the picker instead of requiring a typed repo id.

Tests: new test_diffusion_more_families.py (detection, trust, defaults, size
table, exclusion reason, curated catalog + family filter), two generate()
tests for the guidance_scale/guidance_schedule pairing, and the local-scan
LoRA test updated for a non-empty curated list. Backend suite + CI-sim
(block_diffusers/block_torchao) green; frontend builds.
2026-07-04 12:46:24 +00:00
Daniel Han
04396ec507 Merge diffusion-auto-install: request type accepts explicit Dtype off 2026-07-04 09:47:04 +00:00
Daniel Han
566163f696 Merge diffusion-fp16-accum: request type accepts explicit Dtype off 2026-07-04 09:46:55 +00:00
Daniel Han
ba3b521fa7 Merge diffusion-auto-policy: request type accepts explicit Dtype off 2026-07-04 09:46:47 +00:00
pre-commit-ci[bot]
3347ef5a24 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 09:46:42 +00:00
Daniel Han
c38ae1cef5 Widen the load request type for the explicit Dtype off value
The Dtype select now sends none through instead of omitting it, so the
request type must accept it (tsc caught the mismatch at the badges tip).
2026-07-04 09:46:38 +00:00
pre-commit-ci[bot]
df8c128fe3 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 09:45:40 +00:00
pre-commit-ci[bot]
e673425648 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 09:45:08 +00:00
Daniel Han
45fe22d8eb Merge diffusion-auto-install: Dtype defaults to auto with disk gate 2026-07-04 09:44:58 +00:00
pre-commit-ci[bot]
4719a51601 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 09:44:31 +00:00
Daniel Han
18fe3469a4 Merge diffusion-fp16-accum: Dtype defaults to auto with disk gate 2026-07-04 09:44:20 +00:00
Daniel Han
b9809d0ad8 Merge diffusion-auto-policy: Dtype defaults to auto with disk gate 2026-07-04 09:44:10 +00:00
Daniel Han
56636401aa Merge branch 'diffusion-auto-policy' of https://github.com/unslothai/unsloth into diffusion-auto-policy 2026-07-04 09:43:56 +00:00
Daniel Han
9a34934030 Dtype defaults to auto: unset resolves by hardware, explicit off pins the GGUF
An unset transformer_quant used to mean off (run the GGUF as-is), so the
hardware ladder only engaged when auto was explicitly chosen and the panel
showed Off as the default. Unset (or auto) now hands the decision to the
ladder: a dense-capable GPU gets at least int8, data-center silicon fp8,
falling back to the GGUF when the device, VRAM, family deny table or disk
cannot take it. An explicit none/off pins GGUF-as-is and is now
expressible in the API (previously only omission meant off, so pinned-off
and unset were indistinguishable); an explicit scheme pins that scheme.

The dense candidate also gains a free-disk gate: with auto as the default
the bf16 base download (up to ~40 GB) must never wedge a nearly-full
model-cache disk, so the candidate is dropped (GGUF build kept) when free
space cannot hold it plus a 10 GiB margin. Unprobeable disk passes.

Frontend: the Dtype select defaults to Auto (fastest for GPU), keeps Off
as an explicit choice, and sends none through instead of omitting it.

Suite: 622 diffusion tests green (default-load test rewritten to the new
contract, explicit-off short-circuit covered), CI-sim green.
2026-07-04 09:43:43 +00:00
pre-commit-ci[bot]
94470a83ea [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:57:23 +00:00
pre-commit-ci[bot]
f073ac5c1c [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:56:50 +00:00
pre-commit-ci[bot]
e715d57a75 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:56:18 +00:00
pre-commit-ci[bot]
bc612370f2 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:55:46 +00:00
Daniel Han
382eeaa2e9 Merge diffusion-auto-install: qwen dense-quant family deny + policy threading 2026-07-04 08:55:35 +00:00
Daniel Han
f56ba6dab6 Merge diffusion-fp16-accum: qwen dense-quant family deny + policy threading 2026-07-04 08:55:28 +00:00
Daniel Han
ab06352c47 Merge diffusion-auto-policy: qwen dense-quant family deny + policy threading 2026-07-04 08:55:20 +00:00
Daniel Han
4c4f432330 Thread the family into the auto-policy dense-quant candidate
resolve_dense_quant_candidate now passes fam.name to
select_transformer_quant_scheme so the policy's proposed scheme honors the
family deny table (qwen-image lands on int8 instead of proposing fp8 that
the execution path would refuse). Test stub updated for the new keyword.
2026-07-04 08:55:11 +00:00
Daniel Han
a4833a5c37 Merge diffusion-train-perf2: qwen dense-quant family deny (black frames, measured) 2026-07-04 08:54:07 +00:00
Daniel Han
243b7b5dbd Merge diffusion-krea2: qwen dense-quant family deny (black frames, measured) 2026-07-04 08:53:03 +00:00
Daniel Han
ef03dd2780 Merge diffusion-train-tab-2: qwen dense-quant family deny (black frames, measured) 2026-07-04 08:52:32 +00:00
Daniel Han
200543daca Merge diffusion-train-precision: qwen dense-quant family deny (black frames, measured) 2026-07-04 08:52:22 +00:00
Daniel Han
7aac4770cd Merge diffusion-train-perf: qwen dense-quant family deny (black frames, measured) 2026-07-04 08:52:13 +00:00
Daniel Han
92ac400bbb Merge image-generation: qwen dense-quant family deny (black frames, measured) 2026-07-04 08:52:03 +00: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
pre-commit-ci[bot]
2d812f45e1 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:24:22 +00:00
pre-commit-ci[bot]
3747b3fedf [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:23:20 +00:00
pre-commit-ci[bot]
84d9c62172 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:22:47 +00:00
pre-commit-ci[bot]
21bdb9741d [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:22:15 +00:00
pre-commit-ci[bot]
310849726e [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 08:21:43 +00:00
Daniel Han
56619fafb9 Merge diffusion-auto-install: torchao probe stub in precision-mode tests 2026-07-04 08:21:38 +00:00
Daniel Han
93dcf37426 Merge diffusion-fp16-accum: torchao probe stub in precision-mode tests 2026-07-04 08:21:31 +00:00
Daniel Han
28dd6d1f19 Merge diffusion-auto-policy: torchao probe stub in precision-mode tests 2026-07-04 08:21:21 +00:00
Daniel Han
5fb79d39ad Merge diffusion-train-perf2: torchao probe stub in precision-mode tests 2026-07-04 08:21:14 +00:00
Daniel Han
5df56c0804 Stub the torchao probe in the precision-mode capability tests
train_precision_modes gates int8/fp8/mxfp8 on has_functional_torchao, and the
Backend CI runner does not install torchao, so the three capability-gating
tests collapsed to nf4/bf16/auto and failed. They exercise the CAPABILITY
gate, not torchao presence: stub the probe functional alongside the CUDA
capability patch. Validated with a torchao-blocked run (22 passed).
2026-07-04 08:21:07 +00:00
pre-commit-ci[bot]
e73444ed99 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-04 07:47:51 +00:00
Daniel Han
02256d1820 Advertise per-family footprints and surface Auto badges for resolved controls
GET /api/inference/images/info returns each family's bf16 component sizes and
the estimated resident GB under bf16/int8/fp8/mxfp8/nvfp4, computed purely from
the auto-policy tables (no GPU probing, torch-free), so the panel can show the
Dtype tradeoff before anything is loaded.

DiffusionStatusResponse gains an additive resolved field: per-control
{value, source, reason} provenance the loader already records. The Advanced
panel renders a muted Auto: X pill next to Speed / Dtype / Attention / Memory /
Step cache / CPU offload when the backend decided that control (source auto),
with the reason as the tooltip; an explicit user choice renders no badge.
2026-07-04 07:47:01 +00:00