mirror of
https://github.com/unslothai/unsloth.git
synced 2026-08-31 02:15:56 +00:00
Applies the video round-2 accuracy findings to the image diffusion stack and fixes two real image-path bugs found while measuring. All numbers B200, production settings (family default steps/guidance, 1024px, seed 42, 4 fixed prompts), LPIPS (AlexNet) via the new scripts/image_speedmem_bench.py, which drives the production lever functions in the loader's own order. - inductor precision parity: emulate_precision_casts=True on the regional-compile path (fused pointwise kernels keep fp32 intermediates where eager rounds to bf16 between ops). Pairwise LPIPS of the compiled tier vs the same-stack eager tier: Qwen-Image 0.019 to 0.006 at identical speed (72.4 vs 72.5 ms/step), FLUX.1-dev 0.046 to 0.029 at +2% step time (69.8 vs 68.3, reproduced), FLUX.2-klein-4B 0.018 to 0.017 at identical speed. Snapshot/restored with the other process-wide backend flags so an off load never inherits it. - cache x compile composition: re-point each cache hook's fn_ref.original_forward at a torch.compile'd wrapper of the same bound method (armed only where the speed layer compiled the block; restored before every disable_cache and before the partial-hook cleanup). Qwen-Image FBCache computed steps 91.8 to 71.2 ms (back at the uncached compiled rate), 1.21x end to end (7.36 to 6.06 s per 4 images); FLUX.1-dev already traced through its FBCache hook and is measured neutral (same-process armed vs unarmed latents bit-identical). Skip counts within noise (13 vs 11 of 76; pairwise LPIPS 0.005). - FBCache mid-session toggle crash: diffusers 0.39 caches the HookRegistry child list on first cache_context use, so an uncached generation followed by a 20+-step generation (the auto toggle path) enabled hooks the context never reached and crashed with "No context is set" (reproduced live on FLUX.1-dev). Invalidate the stale child cache after every enable_cache. - TE fp8_dynamic zero-row guard: torchao per-row fp8 derives a per-output-channel scale from the row amax, so an all-zero weight row is 0/0 = NaN. SDXL's text_encoder_2 (OpenCLIP bigG) ships exactly such a row, and every explicit fp8_dynamic SDXL render came out black; keep zero-row Linears dense (LPIPS 0.976 black to 0.096 working). Other families' encoders have no such rows and are byte-identical. - No AUTO TE quant exists on the image branch (text_encoder_quant defaults dense, explicit-only), so the video round's auto-dense retune has no image analogue; the explicit lever's cost is now measured (TE fp8_dynamic alone, LPIPS vs bit-exact: Qwen-Image 0.038, FLUX.1-dev 0.084, SDXL 0.096; no speed win, VRAM -6.5 GB on Qwen-Image) for the docs. Tests: 96 passing across the cache/speed/precision suites (11 new arming, 2 child-registry, 2 zero-row, 4 inductor-flag); ruff clean. |
||
|---|---|---|
| .. | ||
| data | ||
| build_prequant_checkpoint.py | ||
| check_frontend_dep_removal.py | ||
| check_new_install_scripts.py | ||
| compare_engines.py | ||
| compile_probe.py | ||
| diffusion_bench.py | ||
| diffusion_quality.py | ||
| enforce_kwargs_spacing.py | ||
| fbcache_flux_probe.py | ||
| fp8_overflow_check.py | ||
| image_speedmem_bench.py | ||
| install_gemma4_mlx.sh | ||
| install_qwen3_6_mlx.sh | ||
| install_rocm_wsl_strixhalo.sh | ||
| int8_linear_probe.py | ||
| leverage_probe.py | ||
| lint_workflow_triggers.py | ||
| lockfile_supply_chain_audit.py | ||
| notebook_to_python.py | ||
| notebook_validator.py | ||
| nvfp4_probe.py | ||
| nvfp4_t211_probe.py | ||
| perf_levers_probe.py | ||
| perf_verify.py | ||
| prequant_probe.py | ||
| quant_probe.py | ||
| run_ruff_format.py | ||
| scan_npm_packages.py | ||
| scan_npm_packages_baseline.json | ||
| scan_packages.py | ||
| scan_packages_baseline.json | ||
| sd_cpp_smoke.py | ||
| sparse_accum_probe.py | ||
| stamp_studio_release.py | ||
| sync_allow_scripts_pins.py | ||
| uninstall.ps1 | ||
| uninstall.sh | ||
| verify_comment_only_diff.py | ||
| verify_import_hoist.py | ||
| verify_prequant_backend.py | ||
| video_quality.py | ||