unsloth/studio/backend/tests/test_diffusion_backend.py
Daniel Han b37ac011e7 Host pre-cast fp8 text encoders for four more families
Round 2 of the hosted TE set, each bit-identical to dense-load-then-cast
and gated through the real backend (marker + status fp8 + same-seed LPIPS
vs dense TEs):

- FLUX.1 T5-XXL (text_encoder_2): 9.52 -> 5.90 GB, one artifact for
  schnell/dev/Krea-dev (T5 shards byte-identical across all three,
  verified sha256). 220 tensors, 144 fp8, LPIPS 0.109.
- Lumina Gemma2-2B: fp32 hub store 10.46 -> 3.20 GB (3.3x download cut).
  288 tensors, 182 fp8, LPIPS 0.041.
- Z-Image Qwen3-4B: 8.04 -> 4.41 GB. 399 tensors, 252 fp8, LPIPS 0.112.
  NOT shared with flux.2-klein-4B: klein retrained layer 35's MLP
  (verified tensor diff, maxdiff 0.86), so klein hosts no entry.
- Krea-2 Qwen3-VL-4B: 8.88 -> 4.83 GB. 713 tensors, 460 fp8, LPIPS 0.082.
  The constructor-assembled krea pipeline takes the encoder directly
  (load_krea2_pipeline text_encoder kwarg); the loader remaps 5.x
  rope_parameters and re-ties weights after assign so the rebuilt encoder
  matches the builder's structure.

HunyuanImage 2.1 reuses the Qwen-Image artifact outright: its Qwen2.5-VL
text encoder is byte-identical (every shard sha256, 16,584,414,544 bytes),
recorded in the new component-level base-equivalence table the checkpoint
validator consults. The injection loop now covers text_encoder.._3 so a
family can host several components. Live check: LPIPS 0.123 vs dense.
2026-07-18 10:25:14 +00:00

3584 lines
151 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
"""CPU-only unit tests for the diffusion backend.
The family helpers are pure functions, tested directly. The backend lifecycle is
exercised with ``torch`` / ``diffusers`` stubbed via ``sys.modules`` so no real
GPU, weights, or network access is needed (sub-second, CI-friendly).
"""
from __future__ import annotations
import contextlib
import sys
import threading
import types
import pytest
from core.inference.diffusion import (
DiffusionBackend,
_LoadState,
_base_file_downloaded,
_clamp_max_side,
_resolve_base_repo,
_resolve_diffusion_compute_dtype,
)
# diffusion.py imports the compile/arch patch modules LAZILY (they pull torch at module level,
# and diffusion.py must stay importable on a torchless native install). Import them here at
# collection time -- under the real torch -- so they're cached in sys.modules before the
# fake-torch fixtures swap it out; else the lazy import would build them against the stub torch.
import core.inference.diffusion_eager_patches # noqa: E402,F401
import core.inference.diffusion_arch_patches # noqa: E402,F401
from core.inference.diffusion_families import (
detect_family,
resolve_base_repo,
resolve_local_gguf_child,
supported_family_names,
)
# Pure family helpers
def test_clamp_max_side_bounds_oversized_init():
# img2img / inpaint derive OUTPUT size from the uploaded image; an oversized upload (up to
# the 4096/side decode cap = 4x the txt2img 2048 ceiling) drives an OOM-scale latent.
# _clamp_max_side bounds the longest side to 2048, preserving aspect ratio.
from PIL import Image
# A 12MP-shaped landscape photo -> longest side clamped to 2048, 4:3 aspect preserved.
out = _clamp_max_side(Image.new("RGB", (4096, 3072)), 2048)
assert out.size == (2048, 1536)
# A portrait upload clamps on its longest (height) side.
assert _clamp_max_side(Image.new("RGB", (1000, 4000)), 2048).size == (512, 2048)
# An image already within bound is returned unchanged (no needless resample).
small = Image.new("RGB", (768, 512))
assert _clamp_max_side(small, 2048) is small
def test_detect_family_from_repo_id():
# Detection is by architecture; Turbo/full and schnell/dev map to one family.
assert detect_family("unsloth/Z-Image-Turbo-GGUF").name == "z-image"
assert detect_family("unsloth/Z-Image-GGUF").name == "z-image"
assert detect_family("unsloth/Qwen-Image-2512-GGUF").name == "qwen-image"
assert detect_family("unsloth/FLUX.1-schnell-GGUF").name == "flux.1"
# FLUX.2-klein is its own pipeline (Qwen3 TE), distinct from FLUX.1.
klein = detect_family("unsloth/FLUX.2-klein-4B-GGUF")
assert klein.name == "flux.2-klein"
assert klein.pipeline_class == "Flux2KleinPipeline"
assert klein.cfg_kwarg == "guidance_scale"
# Both klein sizes share the one family (base repo resolved per-variant).
assert detect_family("unsloth/FLUX.2-klein-9B-GGUF").name == "flux.2-klein"
# FLUX.2-dev is the Mistral-based Flux2Pipeline, a distinct family from klein; its
# gated base repo is reachable with an HF token. It must not collide with klein.
dev = detect_family("unsloth/FLUX.2-dev-GGUF")
assert dev.name == "flux.2-dev"
assert dev.pipeline_class == "Flux2Pipeline"
assert dev.base_repo == "black-forest-labs/FLUX.2-dev"
assert detect_family("black-forest-labs/FLUX.2-dev").name == "flux.2-dev"
# Qwen-Image guides via true_cfg_scale, not guidance_scale.
assert detect_family("unsloth/Qwen-Image-2512-GGUF").cfg_kwarg == "true_cfg_scale"
assert detect_family("unsloth/Z-Image-GGUF").cfg_kwarg == "guidance_scale"
# Qwen-Image-Edit is a SUPPORTED instruction-editing family (its own edit pipeline);
# the most-specific match wins so it doesn't fall back to the generic qwen-image.
edit = detect_family("unsloth/Qwen-Image-Edit-2511-GGUF")
assert edit.name == "qwen-image-edit"
assert edit.pipeline_class == "QwenImageEditPlusPipeline"
assert edit.edit is True
assert detect_family("unsloth/Qwen-Image-Edit-2509-GGUF").name == "qwen-image-edit"
# FLUX Kontext is a SUPPORTED editing family (FluxKontextPipeline); the "kontext"
# keyword is un-rejected for it, and it must win over the generic "flux.1" match.
kontext = detect_family("unsloth/FLUX.1-Kontext-dev-GGUF")
assert kontext.name == "flux.1-kontext"
assert kontext.pipeline_class == "FluxKontextPipeline"
assert kontext.edit is True
assert kontext.cfg_kwarg == "guidance_scale"
# A plain FLUX.1 checkpoint must still resolve to the base flux.1 family, not kontext.
assert detect_family("unsloth/FLUX.1-dev-GGUF").name == "flux.1"
# A plain Qwen-Image checkpoint must still resolve to the base family, not edit.
assert detect_family("unsloth/Qwen-Image-2512-GGUF").name == "qwen-image"
# Krea 2 (diffusers >= 0.39): bf16-only single-stream DiT, no GGUF/sd.cpp mapping.
krea2 = detect_family("krea/Krea-2-Turbo")
assert krea2.name == "krea-2"
assert krea2.pipeline_class == "Krea2Pipeline"
assert krea2.transformer_class == "Krea2Transformer2DModel"
assert krea2.cfg_kwarg == "guidance_scale"
assert krea2.fp16_incompatible is True
assert krea2.sd_cpp_text_encoders == ()
assert detect_family("meta-llama/Llama-3-8B") is None
def test_detect_family_matches_reject_and_alias_by_segment():
# Reject keywords and short aliases must match whole path/name segments, not raw substrings,
# so an unrelated word that CONTAINS one doesn't misroute a valid base model (regression:
# substring matching broke these).
assert detect_family("/models/edited/z-image-turbo-Q4_K_M.gguf").name == "z-image"
assert detect_family("unsloth/Z-Image-Edition-GGUF").name == "z-image"
assert detect_family("/models/kontextual/z-image-turbo-Q4_K_M.gguf").name == "z-image"
# Supported edit families still resolve (edit / kontext are whole tokens there).
assert detect_family("unsloth/Qwen-Image-Edit-2511-GGUF").name == "qwen-image-edit"
assert detect_family("unsloth/FLUX.1-Kontext-dev-GGUF").name == "flux.1-kontext"
# Unsupported variants sharing only a base arch keyword are still rejected.
assert detect_family("unsloth/Qwen-Image-Layered-GGUF") is None
assert detect_family("unsloth/Qwen-Image-2512-Inpaint") is None
def test_detect_family_edit_keyword_scoped_to_basename():
from core.inference.diffusion_families import detect_family_for_pick
# A parent directory named `edit`/`inpaint` must NOT poison a valid pick: only the model id
# / filename basename is scanned for reject keywords. A direct local pick arrives as
# (parent_dir, filename).
assert detect_family("/models/edit") is None # the dir alone is ambiguous
assert detect_family_for_pick("/models/edit", "Z-Image-Turbo-Q4.gguf").name == "z-image"
assert detect_family_for_pick("/models/inpaint", "qwen-image-2512-Q4.gguf").name == "qwen-image"
# A genuinely unsupported variant keyword in the FILENAME still rejects.
assert detect_family_for_pick("/models/misc", "Qwen-Image-Layered-Q4.gguf") is None
def test_detect_family_override():
assert detect_family("local/path", override = "z-image").name == "z-image"
assert detect_family("local/path", override = "zimage").name == "z-image"
assert detect_family("local/path", override = "not-a-family") is None
def test_supported_family_names():
names = supported_family_names()
# The unknown-model error lists these, so the key families must be present.
for expected in ("flux.1", "flux.2-klein", "flux.2-dev", "qwen-image", "z-image", "krea-2"):
assert expected in names
# Every listed name is a valid family_override (round-trips through detect_family).
for name in names:
assert detect_family("some/unknown-repo", override = name) is not None
def test_resolve_base_repo():
fam = detect_family("x", override = "z-image")
assert resolve_base_repo(fam, None) == fam.base_repo
assert resolve_base_repo(fam, " ") == fam.base_repo
assert resolve_base_repo(fam, "custom/base") == "custom/base"
def test_resolve_local_gguf_child(tmp_path):
(tmp_path / "model.gguf").write_bytes(b"x")
assert resolve_local_gguf_child(tmp_path, "model.gguf") == (tmp_path / "model.gguf").resolve()
with pytest.raises(ValueError):
resolve_local_gguf_child(tmp_path, "/etc/passwd")
with pytest.raises(ValueError):
resolve_local_gguf_child(tmp_path, "../secret.gguf")
with pytest.raises(ValueError):
resolve_local_gguf_child(tmp_path, "..\\secret.gguf")
with pytest.raises(FileNotFoundError):
resolve_local_gguf_child(tmp_path, "missing.gguf")
def test_resolve_local_gguf_child_blocks_symlink_escape(tmp_path):
outside = tmp_path / "outside.gguf"
outside.write_bytes(b"secret")
repo = tmp_path / "repo"
repo.mkdir()
try:
(repo / "model.gguf").symlink_to(outside)
except (OSError, NotImplementedError):
pytest.skip("symlinks not supported on this platform")
with pytest.raises(ValueError):
resolve_local_gguf_child(repo, "model.gguf")
# Stubbed runtime for backend lifecycle
class _FakeDtype:
def __init__(self, name: str) -> None:
self._name = name
def __repr__(self) -> str:
return f"torch.{self._name}"
__str__ = __repr__
class _FakeGenerator:
def __init__(self, device = None) -> None:
self.device = device
self.manual = None
def seed(self) -> int:
return 4242
def manual_seed(self, value: int):
self.manual = value
return self
class _FakeImage:
"""Stand-in for a generated PIL image (the route persists it; here we only
count how many come back)."""
class _FakePipe:
def __init__(self) -> None:
self.moved_to = None
self.offloaded = False
self.sequential_offloaded = False
self.vae_tiled = False
self.vae_sliced = False
self.last_kwargs = None
def to(self, device):
self.moved_to = device
return self
def enable_model_cpu_offload(self, device = None) -> None:
self.offloaded = True
self.offload_device = device
def enable_sequential_cpu_offload(self, device = None) -> None:
self.sequential_offloaded = True
self.offload_device = device
def enable_vae_tiling(self) -> None:
self.vae_tiled = True
def enable_vae_slicing(self) -> None:
self.vae_sliced = True
# Explicit signature (not just **kwargs) so generate()'s signature-gated guards for
# negative_prompt / callback_on_step_end take effect -- a **kwargs-only fake would make
# `"negative_prompt" in signature` always False.
def __call__(
self,
*,
prompt = None,
negative_prompt = None,
callback_on_step_end = None,
guidance_scale = None,
true_cfg_scale = None,
cfg_trunc_ratio = None,
**kwargs,
):
self.last_kwargs = {
"prompt": prompt,
"negative_prompt": negative_prompt,
"callback_on_step_end": callback_on_step_end,
"guidance_scale": guidance_scale,
"true_cfg_scale": true_cfg_scale,
"cfg_trunc_ratio": cfg_trunc_ratio,
**kwargs,
}
n = kwargs.get("num_images_per_prompt", 1)
return types.SimpleNamespace(images = [_FakeImage() for _ in range(n)])
class _FakePipeline:
last: dict = {}
last_single_file: dict = {}
@classmethod
def from_pretrained(cls, base, **kwargs):
_FakePipeline.last = {"base": base, **kwargs}
return _FakePipe()
@classmethod
def from_single_file(cls, path, **kwargs):
# SDXL-style single-file: the WHOLE pipeline comes from one .safetensors file.
_FakePipeline.last_single_file = {"path": path, **kwargs}
return _FakePipe()
class _FakeTransformer:
last: dict = {}
@classmethod
def from_single_file(cls, path, **kwargs):
_FakeTransformer.last = {"path": path, **kwargs}
return object()
class _FakeImg2ImgPipe:
"""An img2img pipeline call: records the image-conditioned kwargs. Its signature
declares image/strength but NOT width/height, mirroring real img2img pipelines
(which derive the output size from the input image)."""
last_kwargs: dict = {}
def __call__(
self,
*,
prompt = None,
image = None,
strength = None,
negative_prompt = None,
callback_on_step_end = None,
guidance_scale = None,
true_cfg_scale = None,
**kwargs,
):
_FakeImg2ImgPipe.last_kwargs = {
"prompt": prompt,
"image": image,
"strength": strength,
**kwargs,
}
n = kwargs.get("num_images_per_prompt", 1)
return types.SimpleNamespace(images = [_FakeImage() for _ in range(n)])
class _FakeImg2ImgPipeline:
built_from: object = None
from_pipe_kwargs: dict = {}
@classmethod
def from_pipe(cls, base_pipe, **kwargs):
_FakeImg2ImgPipeline.built_from = base_pipe
_FakeImg2ImgPipeline.from_pipe_kwargs = kwargs
return _FakeImg2ImgPipe()
class _FakeInpaintPipe:
"""An inpaint pipeline call: records image + mask_image + strength. Real inpaint
pipelines take both an init image and a grayscale mask and derive output size from
the input, so width/height are not in its signature."""
last_kwargs: dict = {}
def __call__(
self,
*,
prompt = None,
image = None,
mask_image = None,
strength = None,
negative_prompt = None,
callback_on_step_end = None,
guidance_scale = None,
true_cfg_scale = None,
**kwargs,
):
_FakeInpaintPipe.last_kwargs = {
"prompt": prompt,
"image": image,
"mask_image": mask_image,
"strength": strength,
**kwargs,
}
n = kwargs.get("num_images_per_prompt", 1)
return types.SimpleNamespace(images = [_FakeImage() for _ in range(n)])
class _FakeInpaintPipeline:
built_from: object = None
@classmethod
def from_pipe(cls, base_pipe, **kwargs):
_FakeInpaintPipeline.built_from = base_pipe
return _FakeInpaintPipe()
@pytest.fixture
def fake_runtime(monkeypatch):
torch = types.ModuleType("torch")
torch.bfloat16 = _FakeDtype("bfloat16")
torch.float16 = _FakeDtype("float16")
torch.float32 = _FakeDtype("float32")
torch.Generator = _FakeGenerator
torch.cuda = types.SimpleNamespace(is_available = lambda: False)
torch.backends = types.SimpleNamespace(mps = None)
# generate() wraps the pipe call in torch.inference_mode(); a no-op CM here.
torch.inference_mode = lambda: contextlib.nullcontext()
diffusers = types.ModuleType("diffusers")
diffusers.GGUFQuantizationConfig = lambda compute_dtype = None: ("quant", compute_dtype)
diffusers.ZImagePipeline = _FakePipeline
diffusers.ZImageTransformer2DModel = _FakeTransformer
diffusers.ZImageImg2ImgPipeline = _FakeImg2ImgPipeline
diffusers.ZImageInpaintPipeline = _FakeInpaintPipeline
# Qwen-Image too, so the true_cfg_scale cfg-kwarg path is exercisable.
diffusers.QwenImagePipeline = _FakePipeline
diffusers.QwenImageTransformer2DModel = _FakeTransformer
diffusers.QwenImageImg2ImgPipeline = _FakeImg2ImgPipeline
diffusers.QwenImageInpaintPipeline = _FakeInpaintPipeline
# Instruction-editing pipeline (Qwen-Image-Edit): its own pipeline IS the loaded one.
diffusers.QwenImageEditPlusPipeline = _FakePipeline
# Ideogram 4, so its guidance_scale/guidance_schedule pairing is exercisable. It loads only
# as a full pipeline (two DiTs), assembled per-component by load_ideogram4_pipeline -- stub
# that to a fake pipe so the guidance path is reachable without real weights.
diffusers.Ideogram4Pipeline = _FakePipeline
diffusers.Ideogram4Transformer2DModel = _FakeTransformer
# Lumina 2, so the cfg_trunc_ratio special case is exercisable (the fake pipe's
# signature carries the kwarg, mirroring the real Lumina2Pipeline).
diffusers.Lumina2Pipeline = _FakePipeline
diffusers.Lumina2Transformer2DModel = _FakeTransformer
# SDXL: a U-Net family. Its single-file checkpoint is the whole pipeline, so the pipeline
# class carries from_single_file; UNet2DConditionModel is the denoiser class (fetched but
# unused on the pipeline/single-file-pipeline paths).
diffusers.StableDiffusionXLPipeline = _FakePipeline
diffusers.UNet2DConditionModel = _FakeTransformer
diffusers.StableDiffusionXLImg2ImgPipeline = _FakeImg2ImgPipeline
diffusers.StableDiffusionXLInpaintPipeline = _FakeInpaintPipeline
monkeypatch.setattr(
"core.inference.diffusion.load_ideogram4_pipeline",
lambda repo_id, dtype, hf_token = None: _FakePipe(),
)
monkeypatch.setitem(sys.modules, "torch", torch)
monkeypatch.setitem(sys.modules, "diffusers", diffusers)
# The backend imports clear_gpu_cache by reference; no-op it so unload doesn't
# run real hardware detection against the stubbed torch.
monkeypatch.setattr("core.inference.diffusion.clear_gpu_cache", lambda: None)
_FakePipeline.last = {}
_FakePipeline.last_single_file = {}
_FakeTransformer.last = {}
_FakeImg2ImgPipeline.built_from = None
_FakeImg2ImgPipe.last_kwargs = {}
_FakeInpaintPipeline.built_from = None
_FakeInpaintPipe.last_kwargs = {}
yield
def test_load_generate_unload_gguf(fake_runtime, tmp_path):
(tmp_path / "model.gguf").write_bytes(b"weights")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "base/repo",
family_override = "z-image",
hf_token = "hf_secret",
)
assert status["loaded"] is True
assert status["family"] == "z-image"
assert status["base_repo"] == "base/repo"
assert status["device"] == "cpu"
assert status["dtype"] == "float32"
assert status["cpu_offload"] is False
# Transformer built from the local GGUF, pipeline assembled from the base repo.
assert _FakeTransformer.last["path"] == str((tmp_path / "model.gguf").resolve())
assert _FakeTransformer.last["subfolder"] == "transformer"
# The token reaches the (possibly gated) base config fetch and the pipeline.
assert _FakeTransformer.last["token"] == "hf_secret"
assert _FakePipeline.last["base"] == "base/repo"
assert "transformer" in _FakePipeline.last
gen = backend.generate(
prompt = "a sloth", negative_prompt = "blurry", width = 512, height = 512, steps = 4, guidance = 3.0
)
assert gen["seed"] == 4242 # random seed reported back
assert gen["repo_id"] == str(tmp_path) # echoed so the route can record the model
assert len(gen["images"]) == 1 # PIL images handed to the route for persistence
# z-image guides via guidance_scale (not true_cfg_scale); the signature-gated
# negative_prompt and per-step callback both reach the pipeline call.
call = backend._state.pipe.last_kwargs
assert call["guidance_scale"] == 3.0 and call["true_cfg_scale"] is None
assert call["negative_prompt"] == "blurry"
assert callable(call["callback_on_step_end"])
gen2 = backend.generate(prompt = "again", seed = 99)
assert gen2["seed"] == 99
# batch_size produces that many images in one call, all sharing the seed.
batch = backend.generate(prompt = "batch", seed = 7, batch_size = 3)
assert len(batch["images"]) == 3 and batch["seed"] == 7
assert backend.unload()["loaded"] is False
assert backend.is_loaded is False
def test_generate_progress_active_during_setup(fake_runtime, tmp_path, monkeypatch):
# A generation must report active from the moment it holds the lock, before the slow pre-denoise
# setup. _apply_loras runs inside that window, so probe generate_progress() from there.
(tmp_path / "model.gguf").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "base/repo",
family_override = "z-image",
hf_token = "hf_secret",
)
seen = {}
def fake_apply(self, state, loras, cancel):
seen["progress"] = self.generate_progress()
monkeypatch.setattr(DiffusionBackend, "_apply_loras", fake_apply)
# Idle before the run.
assert backend.generate_progress()["active"] is False
gen = backend.generate(prompt = "a sloth", steps = 4)
assert len(gen["images"]) == 1
# Active was published during setup, with the requested step total and step 0.
assert seen["progress"]["active"] is True
assert seen["progress"]["total_steps"] == 4
assert seen["progress"]["step"] == 0
# And it is cleared once the generation returns.
assert backend.generate_progress()["active"] is False
def test_generate_progress_cleared_on_setup_error(fake_runtime, tmp_path, monkeypatch):
# A setup-time failure skips the inner finally that nulls _gen, so the outer finally must
# clear the published progress; otherwise a crashed generation leaves the UI stuck "active".
(tmp_path / "model.gguf").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "base/repo",
family_override = "z-image",
hf_token = "hf_secret",
)
def boom(self, state, loras, cancel):
raise RuntimeError("setup failed")
monkeypatch.setattr(DiffusionBackend, "_apply_loras", boom)
with pytest.raises(RuntimeError, match = "setup failed"):
backend.generate(prompt = "a sloth", steps = 4)
assert backend.generate_progress()["active"] is False
def test_dense_speed_auto_defers_compile_to_third_generation(fake_runtime, tmp_path, monkeypatch):
# Dense models with speed unset stay bit-identical eager for the first two generations; the
# 3rd engages the `default` profile mid-session (repeated use amortises the one-time compile),
# upgrading attention alongside it.
from core.inference import diffusion as dmod
monkeypatch.setattr(dmod, "compile_eligible", lambda *a, **k: True)
monkeypatch.setattr(
dmod,
"apply_speed_optims",
lambda pipe, target, **k: {"compiled": k.get("speed_mode") == "default"},
)
monkeypatch.setattr(dmod, "apply_attention_backend", lambda pipe, backend, logger = None: backend)
monkeypatch.setattr(
dmod,
"select_attention_backend",
lambda target, requested, speed_active = False: ("_native_cudnn" if speed_active else None),
)
monkeypatch.setattr(dmod.compile_cache, "begin", lambda **k: None)
(tmp_path / "model.safetensors").write_bytes(b"weights")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
)
assert status["speed_mode"] == "off"
assert status["resolved"]["speed_mode"]["value"] == "deferred"
assert status["resolved"]["speed_mode"]["source"] == "auto"
backend.generate(prompt = "one")
backend.generate(prompt = "two")
assert backend.status()["speed_mode"] == "off" # first two stay exact eager
backend.generate(prompt = "three")
status3 = backend.status()
assert status3["speed_mode"] == "default"
assert "compiled" in status3["speed_optims"]
assert status3["attention_backend"] == "_native_cudnn"
assert status3["resolved"]["speed_mode"]["value"] == "default"
# An explicit "off" is pinned: no deferral, still eager after 3 generations.
backend.unload()
status_off = backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
speed_mode = "off",
)
assert status_off["resolved"]["speed_mode"]["value"] == "off"
for p in ("a", "b", "c"):
backend.generate(prompt = p)
assert backend.status()["speed_mode"] == "off"
backend.unload()
def test_deferred_speed_skips_when_lora_requested(fake_runtime, tmp_path, monkeypatch):
# A compiled transformer rejects LoRA (supports_lora False once compiled), and _apply_loras
# raises before its unchanged-selection no-op, so engaging the deferred compile on a LoRA
# generation would permanently break every LoRA generation on this load. The deferral must
# skip while a LoRA is requested and engage only on a later LoRA-free generation.
from core.inference import diffusion as dmod
monkeypatch.setattr(dmod, "compile_eligible", lambda *a, **k: True)
engaged: list = []
def fake_engage(self, state):
engaged.append(state.generation_count)
state.speed_deferred = False # mirror the real helper: engage once, then clear
monkeypatch.setattr(DiffusionBackend, "_engage_deferred_speed", fake_engage)
# LoRA loading is covered elsewhere; stub it so this test needs no adapter file.
monkeypatch.setattr(DiffusionBackend, "_apply_loras", lambda self, state, loras, cancel: None)
(tmp_path / "model.safetensors").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
)
backend.generate(prompt = "one")
backend.generate(prompt = "two")
# 3rd generation requests a LoRA: the deferral must be skipped (pipe stays eager, LoRA-capable).
backend.generate(prompt = "three", loras = [("adapter", 1.0)])
assert engaged == []
# 4th generation without a LoRA: the deferral now engages (the guard is LoRA-specific, not off).
backend.generate(prompt = "four")
assert len(engaged) == 1
def test_deferred_speed_skips_while_adapter_attached(fake_runtime, tmp_path, monkeypatch):
# Even a NO-LoRA generation must defer the compile while an adapter from a PRIOR generation is
# still attached: _apply_loras runs AFTER the engage, so compiling here would bake the resident
# adapter into the graph and the later unload (swallowed on a compiled pipe) would leave it
# active forever -- silent wrong output. Defer until _apply_loras clears it.
from core.inference import diffusion as dmod
monkeypatch.setattr(dmod, "compile_eligible", lambda *a, **k: True)
engaged: list = []
def fake_engage(self, state):
engaged.append(state.generation_count)
state.speed_deferred = False
monkeypatch.setattr(DiffusionBackend, "_engage_deferred_speed", fake_engage)
# Track the attached set on the pipe, mirroring the real _apply_loras marker (_unsloth_loras).
def fake_apply(self, state, loras, cancel):
specs = [(i, w) for (i, w) in (loras or []) if w != 0]
state.pipe._unsloth_loras = tuple(specs)
monkeypatch.setattr(DiffusionBackend, "_apply_loras", fake_apply)
(tmp_path / "model.safetensors").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
)
# Gens 1-2 attach an adapter, so it is still resident going into gen 3.
backend.generate(prompt = "one", loras = [("adapter", 1.0)])
backend.generate(prompt = "two", loras = [("adapter", 1.0)])
# Gen 3 requests NO LoRA but the adapter is still attached -> defer (no compile-with-adapter).
backend.generate(prompt = "three")
assert engaged == []
# Gen 3's _apply_loras([]) cleared the adapter; gen 4 is genuinely LoRA-free -> engage.
backend.generate(prompt = "four")
assert len(engaged) == 1
def test_deferred_speed_preserves_explicit_attention(fake_runtime, tmp_path, monkeypatch):
# A dense model loaded with Speed on Auto but Attention explicitly pinned (e.g. "native" to
# avoid cuDNN) must KEEP that choice when the 3rd generation engages the deferred `default`
# profile. The auto cuDNN upgrade applies only when attention was left on auto, never when the
# caller pinned a backend.
from core.inference import diffusion as dmod
monkeypatch.setattr(dmod, "compile_eligible", lambda *a, **k: True)
monkeypatch.setattr(
dmod,
"apply_speed_optims",
lambda pipe, target, **k: {"compiled": k.get("speed_mode") == "default"},
)
monkeypatch.setattr(dmod, "apply_attention_backend", lambda pipe, backend, logger = None: backend)
# A select mock that -- unlike a bare "auto -> cuDNN" stub -- HONORS an explicit request:
# "native" stays on the default (None) even under a speed profile, and only a left-unset
# ("auto"/None) request upgrades to cuDNN when speed is active.
def fake_select(
target,
requested,
speed_active = False,
):
if requested in (None, "", "auto"):
return "_native_cudnn" if speed_active else None
if str(requested).lower() in ("native", "sdpa"):
return None
return requested
monkeypatch.setattr(dmod, "select_attention_backend", fake_select)
monkeypatch.setattr(dmod.compile_cache, "begin", lambda **k: None)
(tmp_path / "model.safetensors").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
attention_backend = "native",
)
backend.generate(prompt = "one")
backend.generate(prompt = "two")
backend.generate(prompt = "three") # deferred profile engages here
status = backend.status()
assert status["speed_mode"] == "default" # the compile profile still engaged
assert "compiled" in status["speed_optims"]
# The pinned "native" survived: NOT silently upgraded to cuDNN.
assert status["attention_backend"] is None
assert status["resolved"]["attention_backend"]["value"] == "native"
assert status["resolved"]["attention_backend"]["source"] == "explicit"
# Control: with attention left on auto, the same 3rd-generation deferral DOES upgrade
# to cuDNN -- so the assertion above is not vacuously passing.
backend.unload()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
)
for p in ("a", "b", "c"):
backend.generate(prompt = p)
assert backend.status()["attention_backend"] == "_native_cudnn"
backend.unload()
def _tiny_png_b64() -> str:
import base64
import io
from PIL import Image
buf = io.BytesIO()
Image.new("RGB", (64, 64), (120, 30, 30)).save(buf, format = "PNG")
return base64.b64encode(buf.getvalue()).decode()
def test_generate_img2img_uses_from_pipe(fake_runtime, tmp_path):
"""An init_image routes generate() through the family's img2img pipeline, built via
Pipeline.from_pipe around the loaded pipe (no reload), with image + strength passed
and width/height dropped (the img2img pipe derives size from the input image)."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
# The loaded family advertises the image-conditioned workflows for UI gating
# (upscale rides the img2img pipeline, so it appears whenever img2img does).
assert backend.status()["workflows"] == ["txt2img", "img2img", "upscale", "inpaint", "outpaint"]
loaded_pipe = backend._state.pipe
out = backend.generate(
prompt = "a car at sunset",
steps = 4,
guidance = 0.0,
seed = 3,
init_image = _tiny_png_b64(),
strength = 0.5,
)
assert len(out["images"]) == 1
# from_pipe was handed the loaded text-to-image pipe (component reuse, no reload).
assert _FakeImg2ImgPipeline.built_from is loaded_pipe
# ...and with torch_dtype=None so from_pipe SKIPS its default float32 recast, which
# both upcasts the reused bf16 modules and crashes on torchao-quantized weights.
assert _FakeImg2ImgPipeline.from_pipe_kwargs.get("torch_dtype", "MISSING") is None
call = _FakeImg2ImgPipe.last_kwargs
assert call["image"] is not None # decoded source image passed through
assert call["strength"] == 0.5
assert "width" not in call and "height" not in call # img2img derives size from image
# A txt2img call after it still uses the base pipe (no image kwarg).
backend.generate(prompt = "plain", steps = 4, seed = 1)
assert backend._state.pipe.last_kwargs.get("image") is None
def test_generate_img2img_unsupported_family_raises(fake_runtime, tmp_path, monkeypatch):
"""A family with no image-conditioning at all (no img2img/inpaint/edit/reference) rejects
an init_image with a clear error rather than failing deep in the pipeline."""
from core.inference.diffusion_families import DiffusionFamily
# A synthetic txt2img-only family: no img2img/inpaint pipeline, not edit, not reference.
# (Every shipped family now supports some image workflow, so build one for this case.)
plain = DiffusionFamily(
name = "plain-test",
pipeline_class = "ZImagePipeline",
transformer_class = "ZImageTransformer2DModel",
base_repo = "base/repo",
)
monkeypatch.setattr(
"core.inference.diffusion.detect_family_for_pick",
lambda repo_id, gguf_filename = None, override = None: plain,
)
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo")
assert backend.status()["workflows"] == ["txt2img"]
with pytest.raises(ValueError, match = "img2img"):
backend.generate(prompt = "x", steps = 4, init_image = _tiny_png_b64())
def test_generate_rejects_conditioning_without_init_image(fake_runtime, tmp_path):
"""mask / upscale / reference all need an input image; without one they must raise a
clear ValueError rather than silently degrading to txt2img."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
with pytest.raises(ValueError, match = "mask_image requires"):
backend.generate(prompt = "x", steps = 4, mask_image = _mask_b64(64))
with pytest.raises(ValueError, match = "upscale requires"):
backend.generate(prompt = "x", steps = 4, upscale = 2.0)
with pytest.raises(ValueError, match = "reference_images require"):
backend.generate(prompt = "x", steps = 4, reference_images = [_tiny_png_b64()])
def test_generate_rejects_reference_on_unsupported_family(fake_runtime, tmp_path):
"""A non-reference family rejects reference_images instead of silently dropping them."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
with pytest.raises(ValueError, match = "Reference images are not supported"):
backend.generate(
prompt = "x",
steps = 4,
init_image = _tiny_png_b64(),
reference_images = [_tiny_png_b64()],
)
def test_generate_upscale_enlarges_and_low_strength(fake_runtime, tmp_path):
"""An init_image + upscale factor routes generate() through the family's img2img
pipeline (hires fix): the source is enlarged to size*factor (rounded to /16) before the
denoise, the strength defaults low, and the factor is capped so a huge value can't OOM."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
# Upscale rides the img2img pipeline, so it is advertised alongside img2img.
assert "upscale" in backend.status()["workflows"]
loaded_pipe = backend._state.pipe
out = backend.generate(
prompt = "a crisp photo",
steps = 4,
guidance = 0.0,
seed = 3,
init_image = _tiny_png_b64(),
upscale = 2.0, # 64 -> 128, no explicit strength
)
assert len(out["images"]) == 1
# Reuses the resident modules via from_pipe (no reload, no extra VRAM).
assert _FakeImg2ImgPipeline.built_from is loaded_pipe
call = _FakeImg2ImgPipe.last_kwargs
# The image handed to the pipe is the ENLARGED source (64 * 2 = 128, already /16).
assert call["image"].size == (128, 128)
# Strength defaults to the hires-fix value when the caller sends none.
assert call["strength"] == 0.35
# The factor is capped at 4x so a large request can't blow up the VAE/transformer.
backend.generate(
prompt = "x",
steps = 4,
seed = 1,
init_image = _tiny_png_b64(),
upscale = 99.0,
)
assert _FakeImg2ImgPipe.last_kwargs["image"].size == (256, 256) # 64 * 4 (capped)
# An explicit strength overrides the hires-fix default.
backend.generate(
prompt = "x",
steps = 4,
seed = 1,
init_image = _tiny_png_b64(),
upscale = 1.5,
strength = 0.2,
)
assert _FakeImg2ImgPipe.last_kwargs["strength"] == 0.2
# 64 * 1.5 = 96, already a multiple of 16.
assert _FakeImg2ImgPipe.last_kwargs["image"].size == (96, 96)
def _png_b64(side: int) -> str:
import base64
import io
from PIL import Image
buf = io.BytesIO()
Image.new("RGB", (side, side), (10, 20, 30)).save(buf, format = "PNG")
return base64.b64encode(buf.getvalue()).decode()
def test_decode_image_rejects_oversized(fake_runtime, tmp_path):
"""An input image larger than the per-side cap is rejected with a clear error (protects
img2img / inpaint / reference from decompression-bomb / OOM inputs), not a 500."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
with pytest.raises(ValueError, match = "too large"):
backend.generate(prompt = "x", steps = 4, init_image = _png_b64(4112)) # > 4096/side
def test_upscale_output_is_capped(fake_runtime, tmp_path):
"""Upscale bounds the absolute output side to 2048 even when input*factor exceeds it, so a
large upload at 4x can't OOM the VAE/transformer."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
backend.generate(prompt = "x", steps = 4, seed = 1, init_image = _png_b64(1024), upscale = 4.0)
# 1024 * 4 = 4096 -> clamped to 2048 (longest side), still a multiple of 16.
assert _FakeImg2ImgPipe.last_kwargs["image"].size == (2048, 2048)
def _mask_b64(side: int) -> str:
import base64
import io
from PIL import Image
buf = io.BytesIO()
img = Image.new("L", (side, side), 0)
for y in range(side // 4, 3 * side // 4):
for x in range(side // 4, 3 * side // 4):
img.putpixel((x, y), 255)
img.save(buf, format = "PNG")
return base64.b64encode(buf.getvalue()).decode()
def test_img2img_snaps_non_multiple_of_16(fake_runtime, tmp_path):
"""An odd-sized img2img upload (not divisible by 16) is auto-resized to the nearest
multiple of 16 so the pipeline's divisibility check passes instead of erroring."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
backend.generate(prompt = "x", steps = 4, seed = 1, init_image = _png_b64(186), strength = 0.5)
# 186 / 16 = 11.625 -> round to 12 -> 192.
assert _FakeImg2ImgPipe.last_kwargs["image"].size == (192, 192)
def test_inpaint_snaps_image_and_mask_together(fake_runtime, tmp_path):
"""Inpaint snaps the odd-sized input to /16 AND resizes the mask to match, so the image
and mask stay aligned (a mismatch would crash the inpaint pipeline)."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
backend.generate(
prompt = "x",
steps = 4,
seed = 1,
init_image = _png_b64(186),
mask_image = _mask_b64(186),
strength = 0.5,
)
assert _FakeInpaintPipe.last_kwargs["image"].size == (192, 192)
assert _FakeInpaintPipe.last_kwargs["mask_image"].size == (192, 192)
def test_generate_reference_uses_loaded_pipe_at_slider_size(fake_runtime, tmp_path):
"""A reference family (FLUX.2-klein) advertises txt2img + reference, and a generate with
an init_image passes it as the loaded pipe's `image` arg (no from_pipe, no strength) while
the output size stays the REQUESTED slider size (the pipe resizes the reference itself)."""
import diffusers
diffusers.Flux2KleinPipeline = _FakePipeline
diffusers.Flux2KleinInpaintPipeline = _FakeInpaintPipeline
diffusers.Flux2Transformer2DModel = _FakeTransformer
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "base/repo",
family_override = "flux.2-klein",
)
# FLUX.2-klein: txt2img + reference (own pipe) + inpaint (dedicated pipe). No img2img class,
# so no img2img/upscale.
assert backend.status()["workflows"] == ["txt2img", "reference", "inpaint"]
loaded_pipe = backend._state.pipe
out = backend.generate(
prompt = "a portrait in this style",
steps = 6,
guidance = 4.0,
seed = 5,
width = 768,
height = 512,
init_image = _tiny_png_b64(),
strength = 0.5,
)
assert len(out["images"]) == 1
call = loaded_pipe.last_kwargs
assert call["image"] is not None # reference handed to the loaded pipe
assert call["width"] == 768 and call["height"] == 512 # OUTPUT size = sliders, not input
assert "strength" not in call # reference conditioning has no strength
assert "mask_image" not in call
# Guidance flows via guidance_scale (FLUX.2 default behaviour).
assert call["guidance_scale"] == 4.0
# Multi-reference: extra reference_images are combined with init_image into a LIST so the
# model can blend several references (subject + style).
backend.generate(
prompt = "combine these",
steps = 6,
seed = 9,
width = 1024,
height = 1024,
init_image = _tiny_png_b64(),
reference_images = [_tiny_png_b64(), _tiny_png_b64()],
)
img_arg = loaded_pipe.last_kwargs["image"]
assert isinstance(img_arg, list) and len(img_arg) == 3 # primary + 2 extras
# Branch ordering: an init image + MASK on a reference family must route to inpaint (the
# dedicated pipeline), NOT be swallowed by the reference branch (which ignores the mask).
backend.generate(
prompt = "repaint here",
steps = 6,
seed = 2,
init_image = _tiny_png_b64(),
mask_image = _tiny_mask_b64(),
strength = 0.8,
)
assert _FakeInpaintPipeline.built_from is loaded_pipe # built via from_pipe off the load
assert _FakeInpaintPipe.last_kwargs["mask_image"] is not None
assert _FakeInpaintPipe.last_kwargs["strength"] == 0.8
# Without an init image the same family does plain txt2img (no image arg).
backend.generate(prompt = "just text", steps = 6, seed = 1)
assert backend._state.pipe.last_kwargs.get("image") is None
def _tiny_mask_b64() -> str:
import base64
import io
from PIL import Image
buf = io.BytesIO()
# A grayscale mask: white square (repaint) on black (keep).
img = Image.new("L", (64, 64), 0)
for y in range(16, 48):
for x in range(16, 48):
img.putpixel((x, y), 255)
img.save(buf, format = "PNG")
return base64.b64encode(buf.getvalue()).decode()
def test_generate_inpaint_uses_from_pipe(fake_runtime, tmp_path):
"""An init_image + mask_image routes generate() through the family's inpaint pipeline,
built via Pipeline.from_pipe around the loaded pipe (no reload), with the decoded image
+ mask + strength passed through and width/height dropped (size derives from the input)."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
loaded_pipe = backend._state.pipe
out = backend.generate(
prompt = "a red door",
steps = 4,
guidance = 0.0,
seed = 5,
init_image = _tiny_png_b64(),
mask_image = _tiny_mask_b64(),
strength = 0.7,
)
assert len(out["images"]) == 1
# The inpaint pipe (not img2img) was selected and built from the loaded pipe.
assert _FakeInpaintPipeline.built_from is loaded_pipe
assert _FakeImg2ImgPipeline.built_from is None
call = _FakeInpaintPipe.last_kwargs
assert call["image"] is not None and call["mask_image"] is not None
assert call["strength"] == 0.7
assert "width" not in call and "height" not in call # inpaint derives size from image
def test_image_conditioned_passes_image_size_not_slider(fake_runtime, tmp_path):
"""When the workflow pipe DOES accept width/height, an image-conditioned call must pass
the INPUT IMAGE's size, never the txt2img slider size -- otherwise a non-slider-sized
input (e.g. a 1536px outpaint canvas with a 1024 slider) mismatches the latents
("tensor a (128) must match tensor b (192)"). Covers Transform + Extend with any size."""
import base64
import io
from PIL import Image
class _SizePipe:
last: dict = {}
def __call__(
self,
*,
prompt = None,
image = None,
strength = None,
width = None,
height = None,
negative_prompt = None,
callback_on_step_end = None,
guidance_scale = None,
true_cfg_scale = None,
**kwargs,
):
_SizePipe.last = {"width": width, "height": height}
n = kwargs.get("num_images_per_prompt", 1)
return types.SimpleNamespace(images = [_FakeImage() for _ in range(n)])
class _SizePipeline:
@classmethod
def from_pipe(cls, base_pipe, **kwargs):
return _SizePipe()
import diffusers
diffusers.ZImageImg2ImgPipeline = _SizePipeline
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
buf = io.BytesIO()
Image.new("RGB", (96, 64), (10, 20, 30)).save(buf, format = "PNG") # non-square, non-slider
b64 = base64.b64encode(buf.getvalue()).decode()
backend.generate(prompt = "x", steps = 4, width = 1024, height = 1024, init_image = b64, strength = 0.5)
# The pipe got the IMAGE's 96x64, not the 1024x1024 slider.
assert _SizePipe.last == {"width": 96, "height": 64}
def test_compile_shape_dims_follow_workflow():
"""_compile_shape_dims mirrors generate()'s width/height derivation: slider size for
txt2img / reference / controlnet, the input image's size for the image-conditioned
workflows (whose forward runs at init_pil.size, whatever the sliders say)."""
from PIL import Image
from core.inference.diffusion import _compile_shape_dims
img = Image.new("RGB", (96, 64), (10, 20, 30))
assert _compile_shape_dims("txt2img", None, 1024, 512) == (1024, 512)
# reference generates at the slider size even though an init image is present.
assert _compile_shape_dims("reference", img, 1024, 512) == (1024, 512)
assert _compile_shape_dims("controlnet", None, 768, 768) == (768, 768)
for wf in ("img2img", "inpaint", "upscale", "edit"):
assert _compile_shape_dims(wf, img, 1024, 512) == (96, 64)
def test_register_shape_uses_actual_forward_dims(fake_runtime, tmp_path, monkeypatch):
"""The static compile-cache manifest must record the dims the forward ACTUALLY ran
at: an image-conditioned generate derives its output size from the input image, so
registering the slider values would mark a never-compiled shape as covered while the
truly-used shape never re-dirties/saves the bundle (warm restarts keep paying its
compile)."""
from core.inference import diffusion as diff
registered: list = []
monkeypatch.setattr(
diff.compile_cache,
"register_shape",
lambda ctx, shape, *, static: registered.append(tuple(shape)),
)
monkeypatch.setattr(diff.compile_cache, "save", lambda ctx, *, logger = None: True)
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", base_repo = "base/repo", family_override = "z-image"
)
# txt2img registers the requested slider size.
backend.generate(prompt = "x", steps = 4, width = 1024, height = 512, seed = 1)
assert registered[-1] == (1024, 512, 1)
# img2img runs at the INPUT image's 64x64; the 1024x512 slider must not be recorded.
backend.generate(
prompt = "x",
steps = 4,
width = 1024,
height = 512,
seed = 1,
init_image = _tiny_png_b64(),
strength = 0.5,
)
assert registered[-1] == (64, 64, 1)
def test_edit_family_uses_own_pipeline_and_requires_image(fake_runtime, tmp_path):
"""An instruction-editing family (Qwen-Image-Edit) exposes only the 'edit' workflow,
runs the image through its OWN loaded pipeline (no from_pipe), and rejects a call with
no input image."""
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "Qwen/Qwen-Image-Edit-2511",
family_override = "qwen-image-edit",
)
# Edit families advertise only the edit workflow (no txt2img / img2img / inpaint).
assert backend.status()["workflows"] == ["edit"]
loaded_pipe = backend._state.pipe
out = backend.generate(
prompt = "make it night",
steps = 8,
guidance = 4.0,
seed = 1,
init_image = _tiny_png_b64(),
)
assert len(out["images"]) == 1
# The loaded pipe handled it directly -- no from_pipe img2img/inpaint was built.
assert backend._state.pipe is loaded_pipe
assert _FakeImg2ImgPipeline.built_from is None and _FakeInpaintPipeline.built_from is None
assert loaded_pipe.last_kwargs.get("image") is not None
# An edit model with no input image fails fast with a clear message.
with pytest.raises(ValueError, match = "image"):
backend.generate(prompt = "make it night", steps = 8)
def test_load_pipeline_kind_uses_from_pretrained(fake_runtime):
"""A full-pipeline (no single-file) load on an unsloth/* repo builds the pipe with
pipeline_cls.from_pretrained(repo_id) -- NO single-file transformer build, NO GGUF
quant config -- so an embedded bnb-4bit config is reloaded by diffusers itself."""
backend = DiffusionBackend()
status = backend.load_pipeline(
"unsloth/Z-Image-Turbo-unsloth-bnb-4bit", family_override = "z-image"
)
assert status["loaded"] is True
assert status["family"] == "z-image"
# from_pretrained pointed at the repo itself (it IS its own base), with no transformer.
assert _FakePipeline.last["base"] == "unsloth/Z-Image-Turbo-unsloth-bnb-4bit"
assert "transformer" not in _FakePipeline.last
# The GGUF single-file build path was never taken.
assert _FakeTransformer.last == {}
def test_load_single_file_safetensors_no_gguf_config(fake_runtime, tmp_path):
"""A single-file *.safetensors transformer is built with from_single_file WITHOUT the
GGUF dequant config (it carries its own dtype), then assembled from the base repo."""
(tmp_path / "model.safetensors").write_bytes(b"weights")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
base_repo = "base/repo",
family_override = "qwen-image",
)
assert status["loaded"] is True
assert _FakeTransformer.last["path"] == str((tmp_path / "model.safetensors").resolve())
assert _FakeTransformer.last["subfolder"] == "transformer"
# No GGUF quant config on the safetensors path (the GGUF path sets one).
assert "quantization_config" not in _FakeTransformer.last
assert _FakePipeline.last["base"] == "base/repo"
assert "transformer" in _FakePipeline.last
def test_load_sdxl_pipeline_from_pretrained(fake_runtime):
"""SDXL as a full pipeline (no single-file name) loads via pipeline_cls.from_pretrained
on the allowlisted official base repo -- no U-Net single-file build, no GGUF config.
A U-Net family must NOT try to build a transformer from a single file."""
backend = DiffusionBackend()
status = backend.load_pipeline("stabilityai/stable-diffusion-xl-base-1.0")
assert status["loaded"] is True
assert status["family"] == "sdxl"
assert _FakePipeline.last["base"] == "stabilityai/stable-diffusion-xl-base-1.0"
assert "transformer" not in _FakePipeline.last
# Neither single-file path (transformer-only nor whole-pipeline) was taken.
assert _FakeTransformer.last == {}
assert _FakePipeline.last_single_file == {}
def test_load_sdxl_single_file_uses_pipeline_from_single_file(fake_runtime, tmp_path):
"""A single-file SDXL *.safetensors is the WHOLE pipeline: it must load via
pipeline_cls.from_single_file(path, config=base), NOT transformer_cls.from_single_file
(UNet2DConditionModel has no companion-transformer assembly here)."""
(tmp_path / "sdxl.safetensors").write_bytes(b"weights")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path), gguf_filename = "sdxl.safetensors", family_override = "sdxl"
)
assert status["loaded"] is True
assert status["family"] == "sdxl"
# The whole-pipeline single-file path was taken with the base repo as config.
assert _FakePipeline.last_single_file["path"] == str((tmp_path / "sdxl.safetensors").resolve())
assert _FakePipeline.last_single_file["config"] == "stabilityai/stable-diffusion-xl-base-1.0"
# The transformer-only single-file build was NOT taken.
assert _FakeTransformer.last == {}
def test_load_sdxl_allowlisted_turbo_repo_is_trusted(fake_runtime):
"""The official sdxl-turbo repo is on the non-GGUF allowlist, so a full-pipeline load
is permitted even though it is not under unsloth/*."""
backend = DiffusionBackend()
status = backend.load_pipeline("stabilityai/sdxl-turbo")
assert status["loaded"] is True
assert status["family"] == "sdxl"
def test_load_pipeline_rejects_non_unsloth_repo(fake_runtime):
backend = DiffusionBackend()
with pytest.raises(ValueError, match = "unsloth"):
backend.load_pipeline("randomorg/Z-Image-bnb-4bit", family_override = "z-image")
def test_load_sdxl_rejects_untrusted_repo(fake_runtime):
"""A random non-allowlisted, non-unsloth repo is still rejected for a full pipeline
load even when it detects as SDXL -- the allowlist is exact-match only."""
backend = DiffusionBackend()
with pytest.raises(ValueError, match = "unsloth"):
backend.load_pipeline("randomorg/my-sdxl-merge", family_override = "sdxl")
def test_validate_gates_untrusted_base_repo(fake_runtime, tmp_path):
# A companion base_repo also loads via from_pretrained, so a trusted GGUF model_path must not
# smuggle in an arbitrary remote base: base_repo clears the same trust bar as a non-GGUF repo
# id (mirrors the video loader), and the check runs before any GPU handoff.
backend = DiffusionBackend()
with pytest.raises(ValueError, match = "base_repo"):
backend.validate_load_request(
"unsloth/Qwen-Image-2512-GGUF",
gguf_filename = "x.gguf",
model_kind = "gguf",
base_repo = "evil/companions",
)
# A local base_repo dir that is NOT a diffusers pipeline (no model_index.json) is rejected
# HERE, before the GPU handoff: it passes the any-existing-path trust check but the base loads
# via from_pretrained (needs model_index.json), so it would else evict the resident model and
# only then fail in the background load.
bad_base = tmp_path / "bare-base"
bad_base.mkdir()
with pytest.raises(ValueError, match = "model_index.json"):
backend.validate_load_request(
"unsloth/Qwen-Image-2512-GGUF",
gguf_filename = "x.gguf",
model_kind = "gguf",
base_repo = str(bad_base),
)
# A local base_repo that IS a real pipeline dir (model_index.json) passes the gate.
(tmp_path / "model_index.json").write_text("{}")
fam = backend.validate_load_request(
"unsloth/Qwen-Image-2512-GGUF",
gguf_filename = "x.gguf",
model_kind = "gguf",
base_repo = str(tmp_path),
)
assert fam is not None
def test_resolve_local_single_file(tmp_path):
# A bare single-file safetensors directory (no model_index.json) resolves to that checkpoint's
# basename, so the images load route can reinterpret an On-Device "pipeline" pick as a
# single_file load instead of 400ing on the missing model_index.json.
from core.inference.diffusion import resolve_local_single_file
d = tmp_path / "solo"
d.mkdir()
(d / "model.safetensors").write_bytes(b"w")
assert resolve_local_single_file(str(d)) == "model.safetensors"
# A real diffusers pipeline dir (has model_index.json) loads as a pipeline unchanged -> None.
(d / "model_index.json").write_text("{}")
assert resolve_local_single_file(str(d)) is None
# Ambiguous (two checkpoints, e.g. a sharded pipeline) or empty dirs -> None (unchanged load).
d2 = tmp_path / "shards"
d2.mkdir()
(d2 / "a.safetensors").write_bytes(b"w")
(d2 / "b.safetensors").write_bytes(b"w")
assert resolve_local_single_file(str(d2)) is None
assert resolve_local_single_file(str(tmp_path / "empty-nonexistent")) is None
# A remote repo id (not a local dir) -> None.
assert resolve_local_single_file("unsloth/Qwen-Image-2512-GGUF") is None
# A PEFT LoRA adapter folder (adapter_config.json + adapter_model.safetensors), even with a
# family-token name, is NOT a base checkpoint: from_single_file would fail on the adapter
# weights AFTER the route evicted the resident model, so it must not be reinterpreted as a
# single_file pick -> None (the pipeline pick then 400s in validation, before the handoff).
adapter = tmp_path / "flux-style-lora"
adapter.mkdir()
(adapter / "adapter_config.json").write_text("{}")
(adapter / "adapter_model.safetensors").write_bytes(b"w")
assert resolve_local_single_file(str(adapter)) is None
# A bare adapter_model.safetensors (no config) is likewise not treated as the sole checkpoint.
adapter2 = tmp_path / "z-image-lora"
adapter2.mkdir()
(adapter2 / "adapter_model.safetensors").write_bytes(b"w")
assert resolve_local_single_file(str(adapter2)) is None
def test_resolve_base_repo_drops_untrusted_card_tag(monkeypatch):
# With no base_repo, the base is resolved from the GGUF repo's base_model card tag --
# attacker-controlled metadata on any remote repo -- then loaded via from_pretrained. An
# untrusted tag must be dropped for the curated family default, so an attacker GGUF repo can't
# point the base at an arbitrary repo to be deserialized.
import core.inference.diffusion as dmod
fam = detect_family("unsloth/FLUX.1-dev-GGUF")
# A malicious card tag is ignored -> the family default base is used instead.
monkeypatch.setattr(dmod, "_hf_base_model", lambda repo_id, hf_token: "attacker/evil-pipeline")
assert _resolve_base_repo("attacker/flux.1-evil-GGUF", None, fam, None) == fam.base_repo
# A trusted (allowlisted) card tag is still honoured, so variant resolution is not regressed.
monkeypatch.setattr(
dmod, "_hf_base_model", lambda repo_id, hf_token: "black-forest-labs/FLUX.1-dev"
)
assert (
_resolve_base_repo("unsloth/FLUX.1-dev-GGUF", None, fam, None)
== "black-forest-labs/FLUX.1-dev"
)
# An explicit trusted base_repo wins over the card tag; an explicit untrusted one is caught
# earlier at validate_load_request (covered by test_validate_gates_untrusted_base_repo).
assert (
_resolve_base_repo("unsloth/FLUX.1-dev-GGUF", "unsloth/custom-base", fam, None)
== "unsloth/custom-base"
)
def test_detect_family_rejects_layered():
# Qwen-Image-Layered needs a dedicated pipeline (additional_t_cond); it must be
# rejected so it fails fast at load instead of crashing at the first denoise step.
assert detect_family("unsloth/Qwen-Image-Layered-GGUF") is None
assert detect_family("unsloth/qwen_image_layered") is None
def test_failed_load_rolls_back_eager_patches(fake_runtime, tmp_path, monkeypatch):
"""A load failure AFTER the eager patches install but BEFORE the _LoadState commit must
roll the process-wide patches back, so the next bit-identical `off` load is not
contaminated (the asymmetric-cleanup bug the reviewers flagged)."""
from core.inference import diffusion as diff_mod
from core.inference import diffusion_eager_patches as ep
(tmp_path / "model.gguf").write_bytes(b"x")
ep.uninstall_patches() # clean slate
def _boom(*_a, **_k):
raise RuntimeError("placement boom")
# apply_memory_plan runs AFTER the patches are installed, before _LoadState commits.
monkeypatch.setattr(diff_mod, "apply_memory_plan", _boom)
backend = DiffusionBackend()
with pytest.raises(RuntimeError):
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
family_override = "z-image",
base_repo = "base/repo",
speed_mode = "eager", # != off -> installs the shared patches
)
assert ep.is_installed() is False # rolled back by the load-failure finally
assert backend.is_loaded is False
def test_cpu_offload_ignored_off_cuda(fake_runtime, tmp_path):
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
family_override = "z-image",
base_repo = "base/repo",
cpu_offload = True,
)
# No CUDA in the stub, so offload is not engaged.
assert status["cpu_offload"] is False
def test_low_vram_ignored_off_cuda(fake_runtime, tmp_path):
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
family_override = "z-image",
base_repo = "base/repo",
memory_mode = "low_vram",
)
# No CUDA in the stub, so offload is not engaged regardless of the request.
assert status["cpu_offload"] is False
def test_generate_without_load_raises(fake_runtime):
backend = DiffusionBackend()
with pytest.raises(RuntimeError):
backend.generate(prompt = "x")
def test_failed_load_restores_backend_flags(fake_runtime, tmp_path, monkeypatch):
# A failure AFTER apply_speed_optims (here an OOM in apply_memory_plan) must go through the
# load's try/finally and restore the process-global TF32 / cudnn flags, so a later `off` load
# is still bit-identical, and must not commit partial state. Regression: a refactor dropped
# this guard, leaking the flags on a failed load.
(tmp_path / "model.gguf").write_bytes(b"x")
backend = DiffusionBackend()
restored: list = []
cleared: list = []
monkeypatch.setattr(
"core.inference.diffusion.restore_backend_flags", lambda snap: restored.append(snap)
)
monkeypatch.setattr("core.inference.diffusion.clear_gpu_cache", lambda: cleared.append(True))
monkeypatch.setattr(
"core.inference.diffusion.apply_memory_plan",
lambda *a, **k: (_ for _ in ()).throw(RuntimeError("CUDA out of memory")),
)
with pytest.raises(RuntimeError, match = "out of memory"):
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
family_override = "z-image",
base_repo = "base/repo",
speed_mode = "max",
)
assert restored, "restore_backend_flags was not called on the failed-load path"
assert cleared, "clear_gpu_cache was not called on the failed-load path (VRAM leak)"
assert backend._state is None and backend.is_loaded is False
def test_resolve_base_repo_prefers_caller_then_hf_tag_then_fallback(monkeypatch):
from core.inference import diffusion
from core.inference.diffusion_families import detect_family
fam = detect_family("unsloth/Qwen-Image-2512-GGUF")
monkeypatch.setattr(diffusion, "_hf_base_model", lambda repo, tok: "Qwen/Qwen-Image-2512")
# Caller's explicit base wins and the HF tag is not consulted.
assert (
diffusion._resolve_base_repo("unsloth/Qwen-Image-2512-GGUF", "my/base", fam, None)
== "my/base"
)
# No caller base: the repo's base_model tag (the variant base) is used.
assert (
diffusion._resolve_base_repo("unsloth/Qwen-Image-2512-GGUF", None, fam, None)
== "Qwen/Qwen-Image-2512"
)
# No caller base and no tag: the family fallback.
monkeypatch.setattr(diffusion, "_hf_base_model", lambda repo, tok: None)
assert (
diffusion._resolve_base_repo("unsloth/Qwen-Image-2512-GGUF", " ", fam, None)
== fam.base_repo
)
def test_load_without_gguf_raises():
backend = DiffusionBackend()
# No gguf_filename -> a full-pipeline load, gated to unsloth/*; a non-unsloth repo
# is rejected before any GPU/network work.
with pytest.raises(ValueError, match = "unsloth"):
backend.load_pipeline("some-org/Z-Image-bnb-4bit")
def test_load_unknown_family_raises():
backend = DiffusionBackend()
with pytest.raises(ValueError):
backend.load_pipeline("some/unrecognised-repo", gguf_filename = "x.gguf")
# load_progress state machine (no threads / network / real cache)
from core.inference.diffusion import _LoadingState, _LoadState # noqa: E402
def test_load_progress_idle_and_ready():
backend = DiffusionBackend()
assert backend.load_progress()["phase"] is None
backend._state = _LoadState(object(), None, "r", "b", "cpu", "float32", False)
assert backend.load_progress()["phase"] == "ready"
def test_load_progress_error():
backend = DiffusionBackend()
backend._loading = _LoadingState(repo_id = "r", base_repo = "b", error = "boom")
p = backend.load_progress()
assert p["phase"] == "error" and p["error"] == "boom"
def test_load_progress_downloading_then_finalizing(monkeypatch):
backend = DiffusionBackend()
backend._loading = _LoadingState(repo_id = "r", base_repo = "b", expected_bytes = 1000)
monkeypatch.setattr(DiffusionBackend, "_cache_bytes", staticmethod(lambda repo: 150))
p = backend.load_progress()
assert p["phase"] == "downloading"
assert p["bytes_downloaded"] == 300 # summed across repo + base
assert abs(p["fraction"] - 0.3) < 1e-9
monkeypatch.setattr(DiffusionBackend, "_cache_bytes", staticmethod(lambda repo: 500))
assert backend.load_progress()["phase"] == "finalizing" # 1000/1000
def test_base_file_downloaded_excludes_undownloaded():
# Counted: the pipeline manifest + component subfolders from_pretrained fetches.
assert _base_file_downloaded("model_index.json")
assert _base_file_downloaded("text_encoder/model-00001-of-00003.safetensors")
assert _base_file_downloaded("vae/diffusion_pytorch_model.safetensors")
# Excluded: the GGUF supplies the transformer; docs/assets and top-level files
# are never downloaded, so counting them would peg the bar short of 100%.
assert not _base_file_downloaded(
"transformer/diffusion_pytorch_model-00001-of-00003.safetensors"
)
assert not _base_file_downloaded("assets/Z-Image-Gallery.pdf")
assert not _base_file_downloaded("README.md")
assert not _base_file_downloaded(".gitattributes")
def test_load_progress_fraction_clamped(monkeypatch):
# The cache scan can exceed the estimate (e.g. a second cached quant); the
# reported fraction must still clamp to 1.0 rather than overshoot.
backend = DiffusionBackend()
backend._loading = _LoadingState(repo_id = "r", base_repo = "b", expected_bytes = 1000)
monkeypatch.setattr(DiffusionBackend, "_cache_bytes", staticmethod(lambda repo: 900))
p = backend.load_progress() # summed 1800 > expected 1000
assert p["phase"] == "finalizing"
assert p["fraction"] == 1.0
assert p["bytes_downloaded"] == 1000 # clamped to the estimate
def test_estimate_eta():
from core.inference.diffusion import _estimate_eta
# No rate yet until a step has elapsed since the first.
assert _estimate_eta(8, 1, first_step_at = 100.0, now = 100.0) is None
assert _estimate_eta(8, 0, first_step_at = 0.0, now = 100.0) is None
# 3 steps in 3s since the first ⇒ 1s/step ⇒ 4 steps left ⇒ ~4s.
assert _estimate_eta(8, 4, first_step_at = 100.0, now = 103.0) == 4.0
# Last step ⇒ 0 remaining.
assert _estimate_eta(8, 8, first_step_at = 100.0, now = 107.0) == 0.0
def test_generate_qwen_uses_true_cfg_scale(fake_runtime, tmp_path):
(tmp_path / "model.gguf").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "Qwen/Qwen-Image",
family_override = "qwen-image",
)
backend.generate(prompt = "a sloth", guidance = 4.0)
# Qwen-Image's distilled guidance is off; the real CFG must land on true_cfg_scale.
call = backend._state.pipe.last_kwargs
assert call["true_cfg_scale"] == 4.0 and call["guidance_scale"] is None
def _load_ideogram(backend, tmp_path):
# Ideogram 4 loads only as a full pipeline (its two DiTs are assembled per-component
# by the stubbed load_ideogram4_pipeline); a local pipeline dir is enough here.
(tmp_path / "model_index.json").write_text("{}")
backend.load_pipeline(str(tmp_path), family_override = "ideogram-4")
def test_ideogram_rejects_single_file_and_gguf_kinds(fake_runtime, tmp_path):
# Ideogram 4 needs two DiTs assembled per-component, so there's no transformer-only
# single-file or GGUF load: the explicit kinds must be rejected up front (before a load evicts
# a working model), not assembled into a pipeline missing its second DiT.
backend = DiffusionBackend()
(tmp_path / "model.gguf").write_bytes(b"x")
with pytest.raises(ValueError, match = "full diffusers pipeline"):
backend.load_pipeline(
str(tmp_path), gguf_filename = "model.gguf", family_override = "ideogram-4"
)
(tmp_path / "model.safetensors").write_bytes(b"x")
with pytest.raises(ValueError, match = "full diffusers pipeline"):
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.safetensors",
model_kind = "single_file",
family_override = "ideogram-4",
)
def test_generate_ideogram_defaults_keep_recommended_schedule(fake_runtime, tmp_path):
# Ideogram 4's pipeline defaults to its recommended tapered guidance_schedule (45x7.0 + 3x3.0,
# valid only at 48 steps) and REJECTS guidance_scale while the schedule is set. At the family's
# advertised defaults the backend must drop the constant so the recommended taper engages.
backend = DiffusionBackend()
_load_ideogram(backend, tmp_path)
backend.generate(prompt = "a sloth", steps = 48, guidance = 7.0)
call = backend._state.pipe.last_kwargs
assert call["guidance_scale"] is None # not passed: the pipe default engages
assert "guidance_schedule" not in call
def test_generate_ideogram_custom_guidance_nulls_schedule(fake_runtime, tmp_path):
# Any non-default request must broadcast the constant legally: guidance_scale set AND
# guidance_schedule explicitly nulled (the pipeline raises when both are set, and its default
# schedule is non-None).
backend = DiffusionBackend()
_load_ideogram(backend, tmp_path)
backend.generate(prompt = "a sloth", steps = 20, guidance = 5.0)
call = backend._state.pipe.last_kwargs
assert call["guidance_scale"] == 5.0
assert "guidance_schedule" in call and call["guidance_schedule"] is None
def _load_lumina(backend, tmp_path):
# Lumina 2 loads through the GENERIC pipeline path (standard diffusers layout);
# a local pipeline dir is enough here.
(tmp_path / "model_index.json").write_text("{}")
backend.load_pipeline(str(tmp_path), family_override = "lumina-2")
def test_generate_lumina2_passes_cfg_trunc_ratio(fake_runtime, tmp_path):
# The card recipe truncates the CFG double-forward to the first quarter of the
# trajectory; the pipeline default (1.0) applies it everywhere. The backend passes
# the constant card value on every lumina-2 generate.
backend = DiffusionBackend()
_load_lumina(backend, tmp_path)
backend.generate(prompt = "a sloth", steps = 50, guidance = 4.0)
call = backend._state.pipe.last_kwargs
assert call["cfg_trunc_ratio"] == 0.25
assert call["guidance_scale"] == 4.0
def test_generate_other_family_never_passes_cfg_trunc_ratio(fake_runtime, tmp_path):
# The kwarg is family-gated, not just signature-gated: another family whose pipeline
# happens to accept cfg_trunc_ratio must not inherit Lumina's recipe constant.
backend = DiffusionBackend()
(tmp_path / "model.gguf").write_bytes(b"weights")
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "base/repo",
family_override = "z-image",
)
backend.generate(prompt = "a sloth", steps = 9, guidance = 0.0)
call = backend._state.pipe.last_kwargs
assert call["cfg_trunc_ratio"] is None
def test_begin_load_rejects_concurrent(monkeypatch):
backend = DiffusionBackend()
# The worker resolves the base + downloads, both over the network; stub them
# so the test is offline.
monkeypatch.setattr("core.inference.diffusion._hf_base_model", lambda *a, **k: None)
monkeypatch.setattr(DiffusionBackend, "_prefetch_files", lambda self, *a, **k: None)
monkeypatch.setattr(
DiffusionBackend, "_estimate_download_bytes", staticmethod(lambda *a, **k: (0, []))
)
# Block the spawned worker so the load stays "in progress".
monkeypatch.setattr(
DiffusionBackend, "load_pipeline", lambda self, **k: __import__("time").sleep(0.2)
)
backend.begin_load("unsloth/Z-Image-Turbo-GGUF", gguf_filename = "z-image-turbo-Q4_K_S.gguf")
with pytest.raises(RuntimeError):
backend.begin_load("unsloth/Z-Image-Turbo-GGUF", gguf_filename = "z-image-turbo-Q4_K_S.gguf")
def test_unload_cancels_in_flight_load(fake_runtime):
# An unload (or arbiter eviction, which calls unload) while a load's worker is still
# resolving/downloading must cancel it: load_pipeline sees the bumped token and aborts, so the
# evicted load never resurrects a pipeline into VRAM.
backend = DiffusionBackend()
fam = detect_family("unsloth/Z-Image-Turbo-GGUF")
token = 7
backend._load_token = token
with pytest.raises(RuntimeError, match = "cancelled"):
# Simulate the worker reaching load_pipeline after unload bumped the token.
backend._load_token = token + 1
backend.load_pipeline(
"unsloth/Z-Image-Turbo-GGUF",
gguf_filename = "z-image-turbo-Q4_K_S.gguf",
base_repo = fam.base_repo,
_load_token = token,
)
def test_superseded_load_does_not_cancel_live_generation(fake_runtime):
# A superseded background load (token bumped by a newer load/unload) that finally reaches
# load_pipeline must bail WITHOUT signalling the current model's in-flight generation: the
# token check must run before the cancel is set, or a stale worker aborts an unrelated,
# still-live denoise.
import threading as _threading
backend = DiffusionBackend()
fam = detect_family("unsloth/Z-Image-Turbo-GGUF")
live_cancel = _threading.Event()
backend._active_generate_cancel = live_cancel # a generation from the CURRENT model
token = 11
backend._load_token = token + 1 # this load has already been superseded
with pytest.raises(RuntimeError, match = "cancelled"):
backend.load_pipeline(
"unsloth/Z-Image-Turbo-GGUF",
gguf_filename = "z-image-turbo-Q4_K_S.gguf",
base_repo = fam.base_repo,
_load_token = token,
)
assert not live_cancel.is_set() # the live generation was left untouched
def test_pick_dtype_bf16_only_on_ampere(fake_runtime, monkeypatch):
# BF16 only on Ampere+ (cc >= 8); pre-Ampere cards must fall back to FP16.
torch = sys.modules["torch"]
backend = DiffusionBackend()
monkeypatch.setattr(torch.cuda, "is_available", lambda: True, raising = False)
monkeypatch.setattr(torch.cuda, "get_device_capability", lambda: (8, 0), raising = False)
assert backend._pick_device_and_dtype() == ("cuda", torch.bfloat16)
monkeypatch.setattr(torch.cuda, "get_device_capability", lambda: (7, 5), raising = False)
assert backend._pick_device_and_dtype() == ("cuda", torch.float16)
def test_unload_sets_cancel_event(fake_runtime):
# unload signals an in-flight download (which runs without the lock) to abort.
backend = DiffusionBackend()
assert not backend._cancel_event.is_set()
backend.unload()
assert backend._cancel_event.is_set()
def test_prefetch_aborts_when_cancelled(tmp_path):
# A prefetch interrupted by unload (cancel event set) raises rather than
# downloading the whole base, so the load can be preempted mid-download.
backend = DiffusionBackend()
backend._cancel_event.set()
# Local gguf path so the transformer download is skipped; the base loop hits
# the cancel check on its first file (no network).
(tmp_path / "model.gguf").write_bytes(b"x")
with pytest.raises(RuntimeError, match = "Cancelled"):
backend._prefetch_files(
str(tmp_path),
"model.gguf",
"Tongyi-MAI/Z-Image-Turbo",
["vae/diffusion_pytorch_model.safetensors"],
None,
)
def test_prefetch_downloads_gguf_and_base(monkeypatch, tmp_path):
backend = DiffusionBackend()
calls: list = []
monkeypatch.setattr(
"utils.hf_xet_fallback.hf_hub_download_with_xet_fallback",
lambda repo, fn, tok, **k: (calls.append((repo, fn)), f"/cache/{fn}")[1],
)
# Hub repo: the GGUF transformer and each base file are fetched.
backend._prefetch_files(
"unsloth/Z-Image-Turbo-GGUF",
"model.gguf",
"base/repo",
["vae/x.safetensors", "text_encoder/y.safetensors"],
"hf_tok",
)
assert ("unsloth/Z-Image-Turbo-GGUF", "model.gguf") in calls
assert ("base/repo", "vae/x.safetensors") in calls
assert ("base/repo", "text_encoder/y.safetensors") in calls
# Local GGUF path: the transformer download is skipped, base still fetched.
calls.clear()
(tmp_path / "model.gguf").write_bytes(b"x")
backend._prefetch_files(str(tmp_path), "model.gguf", "base/repo", ["vae/x.safetensors"], None)
assert all(repo != str(tmp_path) for repo, _ in calls)
assert ("base/repo", "vae/x.safetensors") in calls
# fp16-incompatible guard + dtype promotion
def test_zimage_is_fp16_incompatible():
# Only Z-Image-class families carry the guard (their activations overflow fp16).
assert detect_family("unsloth/Z-Image-Turbo-GGUF").fp16_incompatible is True
assert detect_family("unsloth/Z-Image-GGUF").fp16_incompatible is True
assert detect_family("unsloth/Qwen-Image-2512-GGUF").fp16_incompatible is False
assert detect_family("unsloth/FLUX.1-schnell-GGUF").fp16_incompatible is False
assert detect_family("unsloth/FLUX.2-klein-4B-GGUF").fp16_incompatible is False
def test_resolve_compute_dtype_promotes_fp16_for_zimage(fake_runtime):
torch = sys.modules["torch"]
z = detect_family("unsloth/Z-Image-GGUF")
q = detect_family("unsloth/Qwen-Image-GGUF")
# Z-Image: fp16 -> fp32; bf16 / fp32 pass through unchanged.
assert _resolve_diffusion_compute_dtype(z, torch.float16) is torch.float32
assert _resolve_diffusion_compute_dtype(z, torch.bfloat16) is torch.bfloat16
assert _resolve_diffusion_compute_dtype(z, torch.float32) is torch.float32
# An fp16-compatible family (and None) keep fp16.
assert _resolve_diffusion_compute_dtype(q, torch.float16) is torch.float16
assert _resolve_diffusion_compute_dtype(None, torch.float16) is torch.float16
def test_load_promotes_fp16_to_fp32_for_zimage_only(fake_runtime, monkeypatch, tmp_path):
torch = sys.modules["torch"]
# Pre-Ampere CUDA -> the resolver picks fp16; the guard must promote Z-Image
# (and only Z-Image) to fp32 so it doesn't render a black image.
monkeypatch.setattr(torch.cuda, "is_available", lambda: True, raising = False)
monkeypatch.setattr(torch.cuda, "get_device_capability", lambda: (7, 5), raising = False)
(tmp_path / "m.gguf").write_bytes(b"x")
z = DiffusionBackend().load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image"
)
assert z["device"] == "cuda" and z["dtype"] == "float32"
# The promoted dtype reaches the transformer build (and thus the quant config).
assert str(_FakeTransformer.last["torch_dtype"]) == "torch.float32"
q = DiffusionBackend().load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "qwen-image"
)
assert q["dtype"] == "float16" # fp16-compatible family keeps fp16 on pre-Ampere
def test_bad_mode_strings_fail_before_eviction(fake_runtime):
# Every mode normalizer that can raise runs BEFORE the load evicts the previous
# pipeline, so a bad request never costs the user their working model.
backend = DiffusionBackend()
fam = detect_family("unsloth/Z-Image-GGUF")
backend._state = _LoadState(
pipe = object(),
family = fam,
repo_id = "r",
base_repo = "b",
device = "cpu",
dtype = "float32",
cpu_offload = False,
)
for kwargs in (
{"transformer_quant": "int7"},
{"speed_mode": "warp"},
{"attention_backend": "bogus"},
{"transformer_cache": "bogus"},
{"text_encoder_quant": "fp3"},
):
with pytest.raises(ValueError):
backend.load_pipeline("unsloth/Z-Image-GGUF", gguf_filename = "m.gguf", **kwargs)
assert backend._state is not None
# Lock split + mid-denoise cancellation
def test_generate_lock_split_keeps_status_and_unload_responsive(fake_runtime):
import threading
backend = DiffusionBackend()
started = threading.Event()
release = threading.Event()
class _BlockingPipe:
def __call__(self, **kwargs):
started.set()
release.wait(5)
return types.SimpleNamespace(images = [_FakeImage()])
fam = detect_family("unsloth/Z-Image-GGUF")
backend._state = _LoadState(
pipe = _BlockingPipe(),
family = fam,
repo_id = "r",
base_repo = "b",
device = "cpu",
dtype = "float32",
cpu_offload = False,
)
out: dict = {}
def _run():
try:
out["res"] = backend.generate(prompt = "p", steps = 4)
except Exception as exc: # noqa: BLE001
out["exc"] = exc
t = threading.Thread(target = _run)
t.start()
assert started.wait(5) # the denoise is in flight, holding only _generate_lock
# status() / generate_progress() must NOT block behind the denoise.
assert backend.status()["loaded"] is True
assert backend.generate_progress()["active"] is True
cancel_ref = backend._active_generate_cancel
assert cancel_ref is not None
# unload() signals THIS generation's cancel event, then waits for the denoise to exit before
# returning: callers treat its return as "VRAM is free" (the GPU arbiter hands the GPU to chat
# on it). Release the pipe once the cancel lands, standing in for a real pipeline's step
# callback.
releaser = threading.Thread(target = lambda: (cancel_ref.wait(5), release.set()))
releaser.start()
backend.unload()
releaser.join(5)
assert cancel_ref.is_set()
assert backend.status()["loaded"] is False
t.join(5)
# The cancelled generation raised rather than returning a now-evicted image, and
# it had already exited (deregistering its cancel) before unload() returned.
assert "exc" in out and "cancelled" in str(out["exc"]).lower()
assert backend._active_generate_cancel is None
def test_callback_cancellation_interrupts_denoise(fake_runtime):
import threading
backend = DiffusionBackend()
at_step0 = threading.Event()
resume = threading.Event()
class _SteppingPipe:
def __init__(self) -> None:
self._interrupt = False
self.steps_run = 0
def __call__(
self,
*,
callback_on_step_end = None,
num_inference_steps = 8,
**kwargs,
):
for i in range(num_inference_steps):
if self._interrupt: # diffusers' interrupt protocol
break
if callback_on_step_end is not None:
callback_on_step_end(self, i, 0.0, {})
self.steps_run = i + 1
if i == 0:
at_step0.set()
resume.wait(5)
return types.SimpleNamespace(images = [_FakeImage()])
pipe = _SteppingPipe()
fam = detect_family("unsloth/Z-Image-GGUF")
backend._state = _LoadState(
pipe = pipe,
family = fam,
repo_id = "r",
base_repo = "b",
device = "cpu",
dtype = "float32",
cpu_offload = False,
)
out: dict = {}
def _run():
try:
out["res"] = backend.generate(prompt = "p", steps = 8)
except Exception as exc: # noqa: BLE001
out["exc"] = exc
t = threading.Thread(target = _run)
t.start()
assert at_step0.wait(5) # step 0's callback ran with no cancel pending
# Simulate an eviction / superseding load signalling THIS generation's cancel.
assert backend._active_generate_cancel is not None
backend._active_generate_cancel.set()
resume.set()
t.join(5)
# The next step's callback saw the cancel, flipped pipe._interrupt, and the loop
# broke early, so the generation raised instead of returning a partial image.
assert pipe._interrupt is True
assert pipe.steps_run < 8
assert "exc" in out and "cancelled" in str(out["exc"]).lower()
def test_validate_load_request(tmp_path):
backend = DiffusionBackend()
# No filename + unsloth repo -> a full-pipeline load (allowed for unsloth/*).
assert backend.validate_load_request("unsloth/Z-Image-Turbo-unsloth-bnb-4bit").name == "z-image"
# No filename + non-unsloth repo -> a pipeline load, gated to unsloth/* -> rejected.
with pytest.raises(ValueError, match = "unsloth"):
backend.validate_load_request("some-org/Z-Image-bnb-4bit")
# An explicit gguf/single_file kind still requires a single-file name.
with pytest.raises(ValueError, match = "single-file"):
backend.validate_load_request("unsloth/Z-Image-Turbo-GGUF", model_kind = "gguf")
# A pipeline kind must NOT carry a single-file name.
with pytest.raises(ValueError, match = "pipeline"):
backend.validate_load_request(
"unsloth/Z-Image-Turbo-bnb-4bit", gguf_filename = "q.gguf", model_kind = "pipeline"
)
# A single-file safetensors load is also gated to unsloth/* repos.
with pytest.raises(ValueError, match = "unsloth"):
backend.validate_load_request("some-org/Z-Image", gguf_filename = "model.safetensors")
with pytest.raises(ValueError, match = "family"):
backend.validate_load_request("meta/Llama-3", gguf_filename = "q.gguf")
# A family-looking repo paired with a non-GGUF single-file name is rejected here, BEFORE the
# route evicts chat and hands over the GPU (else the background load would be the first to
# notice README.md is not a checkpoint).
with pytest.raises(ValueError, match = r"\.gguf"):
backend.validate_load_request("unsloth/Z-Image-Turbo-GGUF", gguf_filename = "README.md")
assert (
backend.validate_load_request("unsloth/Z-Image-Turbo-GGUF", gguf_filename = "q.gguf").name
== "z-image"
)
# A kind/extension mismatch fails fast here, before the route evicts chat + grabs the
# GPU only to fail in the background from_single_file path.
with pytest.raises(ValueError, match = ".gguf"):
backend.validate_load_request(
"unsloth/Z-Image-Turbo-GGUF", gguf_filename = "model.safetensors", model_kind = "gguf"
)
with pytest.raises(ValueError, match = "gguf"):
backend.validate_load_request(
"unsloth/Qwen-Image-2512-FP8", gguf_filename = "q.gguf", model_kind = "single_file"
)
# A remote "*-GGUF" repo loaded as a full pipeline (no single-file name) is a single-file GGUF
# repo, so from_pretrained finds no pipeline manifest and fails after chat is evicted; reject
# it here before the GPU handoff.
with pytest.raises(ValueError, match = "GGUF"):
backend.validate_load_request("unsloth/Z-Image-Turbo-GGUF", model_kind = "pipeline")
# A local path with a missing child fails here (before any GPU/network work).
with pytest.raises(FileNotFoundError):
backend.validate_load_request(
str(tmp_path), gguf_filename = "missing.gguf", family_override = "z-image"
)
(tmp_path / "m.gguf").write_bytes(b"x")
assert (
backend.validate_load_request(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image"
).name
== "z-image"
)
# A path-shaped repo_id that does not exist is rejected here (it would otherwise
# be treated as remote, evict chat, and only fail in the background load).
with pytest.raises(FileNotFoundError):
backend.validate_load_request(
"/tmp/unsloth-definitely-missing-model",
gguf_filename = "m.gguf",
family_override = "z-image",
)
def test_replacement_load_waits_for_inflight_generation(fake_runtime, tmp_path):
# A superseding load must signal the in-flight generation's cancel AND wait for it to release
# _generate_lock before allocating, so two pipelines never sit in VRAM at once (unlike
# unload(), which returns promptly without waiting).
import threading
backend = DiffusionBackend()
started = threading.Event()
release = threading.Event()
class _BlockingPipe:
def __call__(self, **kwargs):
started.set()
release.wait(5)
return types.SimpleNamespace(images = [_FakeImage()])
fam = detect_family("unsloth/Z-Image-GGUF")
backend._state = _LoadState(
pipe = _BlockingPipe(),
family = fam,
repo_id = "r",
base_repo = "b",
device = "cpu",
dtype = "float32",
cpu_offload = False,
)
gen_out: dict = {}
def _gen():
try:
backend.generate(prompt = "p", steps = 4)
except Exception as exc: # noqa: BLE001
gen_out["exc"] = exc
gt = threading.Thread(target = _gen)
gt.start()
assert started.wait(5) # generation in flight, holding _generate_lock
(tmp_path / "m.gguf").write_bytes(b"x")
load_done = threading.Event()
def _load():
backend.load_pipeline(str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image")
load_done.set()
lt = threading.Thread(target = _load)
lt.start()
# The load must NOT finish while the generation still holds _generate_lock; it
# has signalled the generation's cancel and is waiting to allocate.
assert not load_done.wait(0.5)
assert backend._active_generate_cancel is not None
assert backend._active_generate_cancel.is_set()
release.set() # the blocked denoise returns; generate() sees cancel and raises
gt.join(5)
assert load_done.wait(5) # only now does the replacement allocate
assert "exc" in gen_out and "cancelled" in str(gen_out["exc"]).lower()
assert backend.status()["loaded"] is True
assert backend.status()["repo_id"] == str(tmp_path)
# ── Phase 2A: memory policy wiring (load -> planner -> placement) ──────────────
def test_load_reports_memory_plan_fields_on_cpu(fake_runtime, tmp_path):
# The default stub resolves to a CPU target: no offload is possible, but VAE
# tiling is on (no separate device pool), and status carries the new fields.
(tmp_path / "m.gguf").write_bytes(b"weights")
backend = DiffusionBackend()
status = backend.load_pipeline(str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image")
assert status["offload_policy"] == "none"
assert status["cpu_offload"] is False
assert status["vae_tiling"] is True
assert status["memory_mode"] == "auto"
pipe = backend._state.pipe
assert pipe.moved_to == "cpu" and pipe.vae_tiled and pipe.vae_sliced
def _force_cuda_target(backend, monkeypatch):
"""Drive the loader down the CUDA (offload-capable) path under the stub."""
torch = sys.modules["torch"]
monkeypatch.setattr(backend, "_pick_device_and_dtype", lambda: ("cuda", torch.bfloat16))
def test_load_memory_mode_balanced_streams_or_falls_back(fake_runtime, tmp_path, monkeypatch):
# balanced requests streamed block-level (group) offload. Under the stub there's no real
# diffusers.hooks, so group can't engage and the applier falls back to whole-module offload,
# reporting the policy actually engaged (the real "group" path is GPU-verified in the bench).
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
status = backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", memory_mode = "balanced"
)
assert status["offload_policy"] in ("group", "model") and status["cpu_offload"] is True
assert status["memory_mode"] == "balanced"
assert backend._state.pipe.offloaded is True # model-offload fallback engaged
def test_load_memory_mode_low_vram_engages_model_offload(fake_runtime, tmp_path, monkeypatch):
# low_vram offloads every component (lowest VRAM); whole-module offload is the
# robust path and engages directly (no streaming, so no diffusers.hooks needed).
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
status = backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", memory_mode = "low_vram"
)
assert status["offload_policy"] == "model" and status["cpu_offload"] is True
pipe = backend._state.pipe
assert pipe.offloaded is True and pipe.moved_to is None # offload owns placement
def test_load_explicit_cpu_offload_engages_model_offload_on_cuda(
fake_runtime, tmp_path, monkeypatch
):
# cpu_offload=True with no mode: auto would stay resident (budget unknown under
# the stub), but the explicit flag forces whole-module offload.
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
status = backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", cpu_offload = True
)
assert status["offload_policy"] == "model" and status["cpu_offload"] is True
def test_load_speed_mode_gguf_auto_defaults_and_explicit(fake_runtime, tmp_path):
# No speed_mode on a GGUF model -> auto `default` (near-lossless, compile sits below the quant
# noise floor). compile only engages on CUDA, so on this CPU stub no optim engages, but the
# resolved mode is `default`.
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
status = backend.load_pipeline(str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image")
assert status["speed_mode"] == "default"
# An explicit "off" opts back into the bit-identical path (engages nothing).
status_off = backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", speed_mode = "off"
)
assert status_off["speed_mode"] == "off" and status_off["speed_optims"] == []
# An explicit speed_mode threads through to status (engaged optims are GPU-verified).
status2 = backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", speed_mode = "max"
)
assert status2["speed_mode"] == "max"
# Text-encoder quant defaults off (None); a requested mode threads through (the
# actual engagement is GPU-verified, since it needs real torch/torchao).
assert status2["text_encoder_quant"] is None
status3 = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
text_encoder_quant = "nvfp4",
)
# Under the CPU stub nvfp4 is unsupported, so it engages nothing -> None.
assert status3["text_encoder_quant"] is None
def test_load_fast_mode_stays_resident_on_cuda(fake_runtime, tmp_path, monkeypatch):
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
status = backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", memory_mode = "fast"
)
assert status["offload_policy"] == "none" and status["cpu_offload"] is False
assert backend._state.pipe.moved_to == "cuda"
# ── transformer quant (opt-in dense fast path) ────────────────────────────────
def _stub_dense_quant(monkeypatch, *, scheme = "fp8"):
"""Force the dense+quant branch hermetically: a supported dense source, a
from_pretrained on the fake transformer, and a quantizer that engages `scheme`.
Returns a dict recording the dense-loader / quantizer calls."""
from core.inference import diffusion as dmod
calls: dict = {"from_pretrained": 0, "quantize": 0, "quant_mode": None}
@classmethod
def _from_pretrained(cls, base, **kwargs):
calls["from_pretrained"] += 1
calls["fp_kwargs"] = {"base": base, **kwargs}
return object()
monkeypatch.setattr(_FakeTransformer, "from_pretrained", _from_pretrained, raising = False)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
# Resolve the scheme without the real GPU smoke probe, and configure no pre-quant
# checkpoint so the dense materialise+quantise branch is the one exercised.
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: scheme
)
monkeypatch.setattr(dmod, "resolve_prequant_source", lambda fam, scheme, **kw: None)
def _quantize(pipe, target, *, mode, **kw):
calls["quantize"] += 1
calls["quant_mode"] = mode
return scheme
monkeypatch.setattr(dmod, "quantize_transformer", _quantize)
return calls
def test_default_load_autos_dense_gate_and_falls_back(fake_runtime, tmp_path, monkeypatch):
# UNSET Dtype defaults to the hardware ladder: the dense gate IS consulted, and a
# device without dense support (this fake runtime) falls back to the GGUF build.
from core.inference import diffusion as dmod
consulted = {"n": 0}
def _supported(*a, **k):
consulted["n"] += 1
return False
monkeypatch.setattr(dmod, "dense_transformer_supported", _supported)
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
status = backend.load_pipeline(str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image")
assert consulted["n"] >= 1
assert status["transformer_quant"] is None
assert _FakeTransformer.last["path"] # GGUF from_single_file was used
def test_explicit_off_load_skips_dense_quant_path(fake_runtime, tmp_path, monkeypatch):
# An EXPLICIT "none" pins running the GGUF as-is: the dense gate is never even
# consulted (short-circuit), so the pinned-off contract cannot regress.
from core.inference import diffusion as dmod
monkeypatch.setattr(
dmod,
"dense_transformer_supported",
lambda *a, **k: pytest.fail("dense path must not run with an explicit off"),
)
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "none",
)
assert status["transformer_quant"] is None
assert _FakeTransformer.last["path"] # GGUF from_single_file was used
def test_speed_off_load_suppresses_auto_dtype_quant(fake_runtime, tmp_path, monkeypatch):
# An explicit Speed="off" (bit-exact) load with an UNSET dtype must stay GGUF-as-is: the auto
# dtype default must NOT promote it to a quantized + compiled build (silently breaking the
# bit-exact request). The dense gate must never be consulted.
from core.inference import diffusion as dmod
monkeypatch.setattr(
dmod,
"dense_transformer_supported",
lambda *a, **k: pytest.fail("dense path must not run under an explicit Speed=off"),
)
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
speed_mode = "off",
)
assert status["transformer_quant"] is None
assert status["speed_mode"] == "off"
assert _FakeTransformer.last["path"] # GGUF from_single_file was used, not a dense build
def test_speed_off_load_suppresses_auto_companion_quant(fake_runtime, tmp_path, monkeypatch):
# Mirror the DiT suppression for the companions: an explicit Speed="off" load with TE/VAE left at
# auto must keep them dense (mode "off"), not promote them to auto-quant and silently fp8/int8 the
# text encoder + VAE, which would break the bit-exact request. Unset speed still auto-quantises.
from core.inference import diffusion as dmod
te_modes: list = []
vae_modes: list = []
monkeypatch.setattr(
dmod, "quantize_text_encoders", lambda pipe, target, *, mode, **kw: te_modes.append(mode)
)
monkeypatch.setattr(
dmod, "quantize_vae", lambda pipe, target, *, mode, **kw: vae_modes.append(mode)
)
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image", speed_mode = "off"
)
assert te_modes == ["off"] and vae_modes == ["off"] # dense, not auto
backend.unload()
backend.load_pipeline(str(tmp_path), gguf_filename = "m.gguf", family_override = "z-image")
assert te_modes[-1] == "auto" and vae_modes[-1] == "auto" # promoted when speed is not off
def test_speed_off_load_suppresses_explicit_auto_companion_quant(
fake_runtime, tmp_path, monkeypatch
):
# auto is backend-owned, exactly like transformer_quant: an EXPLICIT text_encoder_quant/
# vae_quant="auto" must also go dense under Speed="off", not just an unset default. Otherwise a
# caller that sends auto + off would silently fp8/int8 the companions and break the bit-exact
# request. An explicit CONCRETE scheme still forces quant even under off.
from core.inference import diffusion as dmod
te_modes: list = []
vae_modes: list = []
monkeypatch.setattr(
dmod, "quantize_text_encoders", lambda pipe, target, *, mode, **kw: te_modes.append(mode)
)
monkeypatch.setattr(
dmod, "quantize_vae", lambda pipe, target, *, mode, **kw: vae_modes.append(mode)
)
(tmp_path / "m.gguf").write_bytes(b"x")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
speed_mode = "off",
text_encoder_quant = "auto",
vae_quant = "auto",
)
assert te_modes == ["off"] and vae_modes == ["off"] # explicit auto suppressed under off
backend.unload()
# An explicit concrete scheme is still honoured under off (only auto is backend-owned).
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
speed_mode = "off",
text_encoder_quant = "fp8",
)
assert te_modes[-1] == "fp8"
def test_transformer_quant_dense_path_engaged(fake_runtime, tmp_path, monkeypatch):
# transformer_quant + a CUDA resident plan -> load the DENSE transformer from the
# base repo, place it on the device, quantise it, and report the engaged scheme.
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
calls = _stub_dense_quant(monkeypatch, scheme = "fp8")
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
)
assert status["transformer_quant"] == "fp8"
# No speed_mode was given, but a quantized transformer is ~30x slower eager, so the
# backend promotes it to `default` (regional compile) instead of the dense `off`.
assert status["speed_mode"] == "default"
assert calls["from_pretrained"] == 1 and calls["quantize"] == 1
assert calls["quant_mode"] == "fp8"
assert calls["fp_kwargs"]["subfolder"] == "transformer" # dense transformer subfolder
# The GGUF single-file path was NOT used for the transformer.
assert _FakeTransformer.last == {}
# quantize ran on-device: the dense pipe was placed on cuda (before compile).
assert backend._state.pipe.moved_to == "cuda"
assert status["offload_policy"] == "none"
def test_transformer_quant_prequant_path_engaged(fake_runtime, tmp_path, monkeypatch):
# A configured pre-quant checkpoint -> load the already-quantized transformer directly;
# the dense from_pretrained and the on-device quantize_transformer are NOT used.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "fp8"
)
monkeypatch.setattr(dmod, "resolve_prequant_source", lambda fam, scheme, **kw: object())
prequant_obj = object()
loaded: dict = {"n": 0}
def _load_prequant(transformer_cls, base, source, **kw):
loaded["n"] += 1
loaded["scheme"] = kw.get("scheme")
return prequant_obj
monkeypatch.setattr(dmod, "load_prequantized_transformer", _load_prequant)
@classmethod
def _fp_fail(cls, *a, **k):
pytest.fail("dense from_pretrained must not run when a prequant checkpoint loads")
monkeypatch.setattr(_FakeTransformer, "from_pretrained", _fp_fail, raising = False)
monkeypatch.setattr(
dmod,
"quantize_transformer",
lambda *a, **k: pytest.fail("quantize_transformer must not run on the prequant path"),
)
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
transformer_prequant_path = str(tmp_path / "zimage_fp8.pt"),
)
assert status["transformer_quant"] == "fp8"
assert loaded["n"] == 1 and loaded["scheme"] == "fp8"
# The pre-quantized transformer object was assembled into the pipeline...
assert _FakePipeline.last.get("transformer") is prequant_obj
# ...and the GGUF single-file path was not used.
assert _FakeTransformer.last == {}
def test_transformer_quant_prequant_load_fails_falls_back_to_dense(
fake_runtime, tmp_path, monkeypatch
):
# A configured prequant source whose load returns None must fall back to the dense
# materialise+quantise path (not straight to GGUF), preserving the fast mode.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
calls = _stub_dense_quant(monkeypatch, scheme = "fp8")
# Override the no-prequant default: a source resolves, but its load fails.
monkeypatch.setattr(dmod, "resolve_prequant_source", lambda fam, scheme, **kw: object())
monkeypatch.setattr(dmod, "load_prequantized_transformer", lambda *a, **k: None)
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
)
assert status["transformer_quant"] == "fp8"
assert calls["from_pretrained"] == 1 and calls["quantize"] == 1 # dense path ran
assert _FakeTransformer.last == {} # GGUF not used
def test_transformer_quant_falls_back_to_gguf_on_failure(fake_runtime, tmp_path, monkeypatch):
# A dense/quant failure (here: quantize returns None -> unsupported) must fall back
# to the GGUF build, not error -- status reports no transformer_quant engaged.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
@classmethod
def _from_pretrained(cls, base, **kwargs):
return object()
monkeypatch.setattr(_FakeTransformer, "from_pretrained", _from_pretrained, raising = False)
monkeypatch.setattr(dmod, "quantize_transformer", lambda pipe, target, **kw: None)
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
)
assert status["loaded"] is True
assert status["transformer_quant"] is None # fell back
assert _FakeTransformer.last["path"] # GGUF from_single_file used
def test_transformer_quant_skipped_when_plan_offloads(fake_runtime, tmp_path, monkeypatch):
# The dense bf16 transformer only fits resident, so when the memory plan would offload (here
# low_vram) the fast path is skipped and GGUF loads instead -- the dense transformer is never
# loaded.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
@classmethod
def _fp_fail(cls, *a, **k):
pytest.fail("dense transformer must not load when the plan offloads")
monkeypatch.setattr(_FakeTransformer, "from_pretrained", _fp_fail, raising = False)
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
memory_mode = "low_vram",
)
assert status["transformer_quant"] is None
assert status["offload_policy"] == "model"
assert _FakeTransformer.last["path"] # GGUF path used
def test_dense_quant_skipped_when_dense_transformer_does_not_fit(
fake_runtime, tmp_path, monkeypatch
):
# The GGUF fits resident (plan `none`), but the DENSE bf16 transformer the fast path
# materializes does not. The fast path must be skipped up front (preflighted against the dense
# transformer, not the GGUF), and GGUF loads RESIDENT -- not evicted, OOMed, then offloaded.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
# A scheme resolves and there is no prequant, so the dense bf16 is materialized and the
# dense-fit re-check runs against a large (won't-fit) dense transformer.
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "fp8"
)
monkeypatch.setattr(dmod, "resolve_prequant_source", lambda fam, scheme, **kw: None)
monkeypatch.setattr(
DiffusionBackend,
"_dense_transformer_resident_bytes",
staticmethod(lambda base: 40 * 1024**3),
)
orig_plan = DiffusionBackend._plan_memory
def plan_wrap(
self,
*a,
transformer_resident_override_mib = None,
**k,
):
# GGUF budget fits (real plan -> none); the dense-transformer preflight does not.
if transformer_resident_override_mib is not None:
return types.SimpleNamespace(offload_policy = "model")
return orig_plan(self, *a, **k)
monkeypatch.setattr(DiffusionBackend, "_plan_memory", plan_wrap)
@classmethod
def _fp_fail(cls, *a, **k):
pytest.fail("dense transformer must not load when it won't fit resident")
monkeypatch.setattr(_FakeTransformer, "from_pretrained", _fp_fail, raising = False)
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
)
assert status["transformer_quant"] is None # dense quant skipped
assert status["offload_policy"] == "none" # GGUF loaded resident, not offloaded
assert _FakeTransformer.last["path"] # GGUF path used
def test_dense_quant_prequant_proceeds_but_forbids_dense_fallback(fake_runtime, tmp_path, monkeypatch):
# With a prequant checkpoint, the fast path loads the small quantized file, so a dense
# misfit must NOT decline the fast path -- but the dense re-check still runs to gate the
# in-loader fallback: if the prequant later fails, the loader must raise to GGUF instead of
# materialising the dense bf16 the plan never budgeted (allow_dense_fallback=False).
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "fp8"
)
# usable_ (not resolve_): the re-check site only honours a source the loader would
# actually accept, so the fake must present a USABLE one (e.g. a hosted repo).
monkeypatch.setattr(dmod, "usable_prequant_source", lambda fam, scheme, **kw: "prequant/path")
# Large dense shards cached: if the re-check ran, it would wrongly decline the fast path.
monkeypatch.setattr(
DiffusionBackend,
"_dense_transformer_resident_bytes",
staticmethod(lambda base: 999 * 1024**3),
)
dense_refit_ran = []
orig_plan = DiffusionBackend._plan_memory
def spy_plan(
self,
*a,
transformer_resident_override_mib = None,
**k,
):
if transformer_resident_override_mib is not None:
dense_refit_ran.append(True)
# GGUF budget fits (real plan -> none); the dense-transformer preflight does not.
return types.SimpleNamespace(offload_policy = "model")
return orig_plan(self, *a, **k)
monkeypatch.setattr(DiffusionBackend, "_plan_memory", spy_plan)
attempted = []
def fake_dense_load(self, *a, **k):
attempted.append(k.get("allow_dense_fallback"))
return None, None # fall through to GGUF; we only assert the path was reached
monkeypatch.setattr(DiffusionBackend, "_load_dense_quant_pipeline", fake_dense_load)
(tmp_path / "m.gguf").write_bytes(b"x")
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
)
assert dense_refit_ran == [True] # the re-check runs (it gates the fallback)...
assert attempted == [False] # ...fast path still attempted, dense fallback forbidden
def test_dense_quant_replan_retries_once_on_transient_free_undercount(
fake_runtime, tmp_path, monkeypatch
):
# A transient foreign allocation at snapshot time makes an empty card look full and the
# candidate replan declines resident -- but the candidate FITS total capacity, so the
# loader must retry the replan once with a fresh settled snapshot instead of silently
# falling back to GGUF-as-is (measured: FLUX.2-dev int8 cold load on an idle B200).
import dataclasses
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "int8"
)
monkeypatch.setattr(
dmod,
"resolve_dense_quant_candidate",
lambda **kw: types.SimpleNamespace(
transient_transformer_mib = 33_831, companions_mib = 46_157, prequant = True
),
)
replan_calls = []
orig_plan = DiffusionBackend._plan_memory
def spy_plan(self, *a, transformer_resident_override_mib = None, **k):
real = orig_plan(
self, *a, transformer_resident_override_mib = transformer_resident_override_mib, **k
)
if transformer_resident_override_mib is None:
# Initial GGUF plan: force offload so the candidate replan branch is entered.
return dataclasses.replace(real, offload_policy = "model")
replan_calls.append(True)
if len(replan_calls) == 1:
# First replan: the transient undercount. Required fits total capacity
# (90,228 <= 0.85 * (183,359 - 18,335)), so a retry must follow.
return types.SimpleNamespace(
offload_policy = "model",
estimates = {"resident_required_mib": 90_228, "safe_device_budget_mib": 40_000},
device_memory = types.SimpleNamespace(
total_mib = 183_359, memory_kind = "discrete_vram", free_mib = 60_000
),
reasons = ("companions exceed budget",),
)
# Retry: the transient cleared; resident.
return dataclasses.replace(real, offload_policy = "none")
monkeypatch.setattr(DiffusionBackend, "_plan_memory", spy_plan)
attempted = []
def fake_dense_load(self, *a, **k):
attempted.append(k.get("allow_dense_fallback"))
raise RuntimeError("test: stop after reaching the fast path")
monkeypatch.setattr(DiffusionBackend, "_load_dense_quant_pipeline", fake_dense_load)
(tmp_path / "m.gguf").write_bytes(b"x")
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "int8",
)
assert replan_calls == [True, True] # declined once, retried once
assert attempted == [False] # fast path attempted; prequant-sized plan forbids dense fallback
def test_dense_quant_replan_no_retry_when_capacity_truly_short(
fake_runtime, tmp_path, monkeypatch
):
# When the candidate does NOT fit total capacity, the decline is real: no retry.
import dataclasses
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "int8"
)
monkeypatch.setattr(
dmod,
"resolve_dense_quant_candidate",
lambda **kw: types.SimpleNamespace(
transient_transformer_mib = 33_831, companions_mib = 46_157, prequant = True
),
)
replan_calls = []
orig_plan = DiffusionBackend._plan_memory
def spy_plan(self, *a, transformer_resident_override_mib = None, **k):
real = orig_plan(
self, *a, transformer_resident_override_mib = transformer_resident_override_mib, **k
)
if transformer_resident_override_mib is None:
return dataclasses.replace(real, offload_policy = "model")
replan_calls.append(True)
return types.SimpleNamespace(
offload_policy = "model",
estimates = {"resident_required_mib": 150_000, "safe_device_budget_mib": 40_000},
device_memory = types.SimpleNamespace(
total_mib = 183_359, memory_kind = "discrete_vram", free_mib = 60_000
),
reasons = ("companions exceed budget",),
)
monkeypatch.setattr(DiffusionBackend, "_plan_memory", spy_plan)
(tmp_path / "m.gguf").write_bytes(b"x")
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "int8",
)
assert replan_calls == [True] # genuine capacity shortfall: declined without a retry
def _decline_dense_quant(backend, monkeypatch, tmp_path):
"""Configure the harness so the dense-quant fast path is declined for capacity
(mirrors test_dense_quant_replan_no_retry_when_capacity_truly_short)."""
import dataclasses
from core.inference import diffusion as dmod
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "int8"
)
monkeypatch.setattr(
dmod,
"resolve_dense_quant_candidate",
lambda **kw: types.SimpleNamespace(
transient_transformer_mib = 33_831, companions_mib = 46_157, prequant = False
),
)
orig_plan = DiffusionBackend._plan_memory
def spy_plan(self, *a, transformer_resident_override_mib = None, **k):
real = orig_plan(
self, *a, transformer_resident_override_mib = transformer_resident_override_mib, **k
)
if transformer_resident_override_mib is None:
return dataclasses.replace(real, offload_policy = "model")
return types.SimpleNamespace(
offload_policy = "model",
estimates = {"resident_required_mib": 150_000, "safe_device_budget_mib": 40_000},
device_memory = types.SimpleNamespace(
total_mib = 183_359, memory_kind = "discrete_vram", free_mib = 60_000
),
reasons = ("companions exceed budget",),
)
monkeypatch.setattr(DiffusionBackend, "_plan_memory", spy_plan)
(tmp_path / "m.gguf").write_bytes(b"x")
def test_declined_dense_with_baked_loras_fails_instead_of_silent_drop(
fake_runtime, tmp_path, monkeypatch
):
# transformer_quant + adapters, dense build declined for capacity: the GGUF fallback
# cannot bake the adapters, so completing it would silently generate WITHOUT the
# requested LoRAs behind an HTTP success. The load must fail with the recovery options.
backend = DiffusionBackend()
_decline_dense_quant(backend, monkeypatch, tmp_path)
with pytest.raises(RuntimeError, match = "LoRA adapters could not be applied"):
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "int8",
loras = [("adapter", 1.0)],
)
def test_declined_dense_without_loras_still_falls_back_to_gguf(
fake_runtime, tmp_path, monkeypatch
):
# The plain decline (no adapters requested) keeps the silent GGUF fallback: weight-0
# adapters count as "none" (an explicit disable is not a bake request).
backend = DiffusionBackend()
_decline_dense_quant(backend, monkeypatch, tmp_path)
result = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "int8",
loras = [("adapter", 0.0)],
)
assert result is not None
assert backend.status()["transformer_quant"] is None # GGUF-as-is fallback
class _BakePipe:
def __init__(self):
self.calls: list = []
def load_lora_weights(self, path, adapter_name = None):
self.calls.append(("load", path, adapter_name))
def set_adapters(self, names, adapter_weights = None):
self.calls.append(("set", tuple(names), tuple(adapter_weights)))
def test_dense_quant_lora_bake_attaches_before_quantize(fake_runtime, monkeypatch):
# A LoRA bake must (a) skip the prequant shortcut (adapters need the DENSE transformer),
# (b) attach the adapters BEFORE quantize_transformer (peft's post-quant torchao dispatch
# TypeErrors on a manually quantized module), and (c) mark the pipe as baked.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "int8"
)
prequant_consulted = []
monkeypatch.setattr(
dmod,
"resolve_prequant_source",
lambda *a, **k: prequant_consulted.append(True) or None,
)
order: list = []
class FakeTransformerCls:
@staticmethod
def from_pretrained(*a, **k):
order.append("dense_load")
return object()
pipe = _BakePipe()
monkeypatch.setattr(
DiffusionBackend, "_assemble_pipe", staticmethod(lambda *a, **k: pipe)
)
monkeypatch.setattr(
DiffusionBackend,
"_resolve_lora_set",
staticmethod(lambda specs, **k: (("sloth", "/adapters/sloth.safetensors", 0.8),)),
)
def fake_quantize(p, target, **k):
order.append("quantize")
assert any(c[0] == "load" for c in p.calls), "adapters must attach before quantize"
return "int8"
monkeypatch.setattr(dmod, "quantize_transformer", fake_quantize)
got_pipe, scheme = backend._load_dense_quant_pipeline(
FakeTransformerCls,
object,
"base/repo",
"cuda",
"bf16",
None,
types.SimpleNamespace(device = "cuda", dtype = "bf16"),
"int8",
fam = types.SimpleNamespace(name = "z-image"),
lora_specs = [("sloth", 0.8)],
)
assert scheme == "int8"
assert prequant_consulted == [] # prequant shortcut skipped for the bake
assert order == ["dense_load", "quantize"]
assert pipe.calls[0] == ("load", "/adapters/sloth.safetensors", "sloth")
assert pipe.calls[1] == ("set", ("sloth",), (0.8,))
assert pipe._unsloth_loras == (("sloth", "/adapters/sloth.safetensors", 0.8),)
assert pipe._unsloth_loras_baked is True
def _quant_lora_state(pipe, quant = "int8"):
return types.SimpleNamespace(
pipe = pipe,
transformer_quant = quant,
kind = "gguf",
family = types.SimpleNamespace(name = "z-image"),
hf_token = None,
speed_optims = ("compiled",),
)
def test_apply_loras_quant_unbaked_requires_reload(monkeypatch):
# A quantized pipe built WITHOUT adapters cannot take one at generation time (topology is
# frozen after quantize_ + compile): clean 400 telling the client to reload.
backend = DiffusionBackend()
pipe = _BakePipe()
with pytest.raises(ValueError, match = "Reload the model with the adapter selection"):
backend._apply_loras(
_quant_lora_state(pipe), [("sloth", 1.0)], threading.Event()
)
# ...but a no-adapter generation on the same pipe stays a plain no-op.
backend._apply_loras(_quant_lora_state(pipe), [], threading.Event())
assert pipe.calls == []
def test_apply_loras_quant_baked_matrix(monkeypatch):
# Baked pipe: same set -> no-op; weight-only change -> set_adapters (value-level, no
# topology change); empty -> all scales 0 (reproduces the quantized base); different
# adapter set -> reload error.
backend = DiffusionBackend()
monkeypatch.setattr(
DiffusionBackend,
"_resolve_lora_set",
staticmethod(
lambda specs, **k: tuple(
(i, f"/adapters/{i}.safetensors", w) for (i, w) in specs
)
),
)
def baked_pipe():
pipe = _BakePipe()
pipe._unsloth_loras = (("sloth", "/adapters/sloth.safetensors", 0.8),)
pipe._unsloth_loras_baked = True
return pipe
ev = threading.Event()
# same set: no-op
pipe = baked_pipe()
backend._apply_loras(_quant_lora_state(pipe), [("sloth", 0.8)], ev)
assert pipe.calls == []
# weight-only change: live set_adapters + marker update
pipe = baked_pipe()
backend._apply_loras(_quant_lora_state(pipe), [("sloth", 1.4)], ev)
assert pipe.calls == [("set", ("sloth",), (1.4,))]
assert pipe._unsloth_loras == (("sloth", "/adapters/sloth.safetensors", 1.4),)
# empty: scale everything to 0 (quantized base output), marker keeps paths
pipe = baked_pipe()
backend._apply_loras(_quant_lora_state(pipe), [], ev)
assert pipe.calls == [("set", ("sloth",), (0.0,))]
assert pipe._unsloth_loras == (("sloth", "/adapters/sloth.safetensors", 0.0),)
# empty again after zeroing: no further calls
backend._apply_loras(_quant_lora_state(pipe), [], ev)
assert len(pipe.calls) == 1
# different adapter set: topology change -> reload error
pipe = baked_pipe()
with pytest.raises(ValueError, match = "Reload the model with the new adapter selection"):
backend._apply_loras(_quant_lora_state(pipe), [("other", 1.0)], ev)
def test_assemble_pipe_routes_krea2_per_component(monkeypatch):
# krea's repo ships transformers-5.x configs and no top-level tokenizer files, so
# Pipeline.from_pretrained dies in the tokenizer (vocab_file = None). The quant fast
# path must assemble per-component via load_krea2_pipeline like every other krea load.
from core.inference import diffusion as dmod
calls: dict = {}
class Pipe:
def to(self, device):
calls["device"] = device
return self
def fake_loader(base, dtype, hf_token = None, transformer = None, text_encoder = None):
calls["base"] = base
calls["transformer"] = transformer
return Pipe()
monkeypatch.setattr(dmod, "load_krea2_pipeline", fake_loader)
class ExplodingPipeline:
@staticmethod
def from_pretrained(*a, **k):
raise AssertionError("krea-2 must not go through Pipeline.from_pretrained")
marker = object()
pipe = dmod.DiffusionBackend._assemble_pipe(
ExplodingPipeline,
"krea/Krea-2-Turbo",
marker,
"bf16",
None,
"cuda:0",
fam = types.SimpleNamespace(name = "krea-2"),
)
assert isinstance(pipe, Pipe)
assert calls == {"base": "krea/Krea-2-Turbo", "transformer": marker, "device": "cuda:0"}
def test_dense_quant_unusable_prequant_path_runs_dense_refit(fake_runtime, tmp_path, monkeypatch):
# A request-supplied transformer_prequant_path the loader refuses (missing, or outside
# UNSLOTH_ALLOW_LOCAL_PREQUANT_PATH) resolves to NO usable prequant source, so the
# dense-transformer fit re-check MUST run: with real device budgets it declines the fast path
# up front instead of evicting the resident pipeline and OOMing in the dense bf16 fallback.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: "fp8"
)
# The REAL usable_prequant_source refuses a non-allowlisted path (unit-tested in
# test_diffusion_prequant.py); returning None here pins that outcome at this site.
monkeypatch.setattr(dmod, "usable_prequant_source", lambda fam, scheme, **kw: None)
monkeypatch.setattr(
DiffusionBackend,
"_dense_transformer_resident_bytes",
staticmethod(lambda base: 999 * 1024**3),
)
dense_refit_ran = []
orig_plan = DiffusionBackend._plan_memory
def spy_plan(
self,
*a,
transformer_resident_override_mib = None,
**k,
):
if transformer_resident_override_mib is not None:
dense_refit_ran.append(True)
return orig_plan(self, *a, **k)
monkeypatch.setattr(DiffusionBackend, "_plan_memory", spy_plan)
monkeypatch.setattr(
DiffusionBackend, "_load_dense_quant_pipeline", lambda self, *a, **k: (None, None)
)
(tmp_path / "m.gguf").write_bytes(b"x")
backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
transformer_prequant_path = str(tmp_path / "not-allowlisted.pt"),
)
# Unusable path -> no prequant shortcut -> the dense fit re-check ran.
assert dense_refit_ran == [True]
assert backend.status()["loaded"] is True
def test_transformer_quant_unsupported_scheme_skips_dense_download(
fake_runtime, tmp_path, monkeypatch
):
# An explicit unsupported scheme (select_transformer_quant_scheme -> None) must fail the dense
# path BEFORE materialising the multi-GB dense transformer, then fall back to GGUF -- else the
# download runs under the load lock during finalization after the old model was evicted, only
# to fail at quantize.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
monkeypatch.setattr(dmod, "dense_transformer_supported", lambda target: True)
monkeypatch.setattr(
dmod, "select_transformer_quant_scheme", lambda target, mode, family = None: None
)
monkeypatch.setattr(dmod, "resolve_prequant_source", lambda fam, scheme, **kw: None)
@classmethod
def _fp_fail(cls, *a, **k):
pytest.fail("dense transformer must not download when the scheme is unsupported")
monkeypatch.setattr(_FakeTransformer, "from_pretrained", _fp_fail, raising = False)
(tmp_path / "m.gguf").write_bytes(b"x")
status = backend.load_pipeline(
str(tmp_path),
gguf_filename = "m.gguf",
family_override = "z-image",
transformer_quant = "fp8",
)
assert status["loaded"] is True
assert status["transformer_quant"] is None # fell back to GGUF
assert _FakeTransformer.last["path"] # GGUF from_single_file used
def test_base_file_downloaded_include_transformer_flag():
# Default: transformer/ shards are the GGUF's job, so they are excluded from
# the prefetch list; the dense transformer-quant path opts them back in.
from core.inference.diffusion import _base_file_downloaded
assert _base_file_downloaded("transformer/diffusion_pytorch_model-00001.safetensors") is False
assert (
_base_file_downloaded(
"transformer/diffusion_pytorch_model-00001.safetensors", include_transformer = True
)
is True
)
# The flag must not admit anything else that is normally excluded.
assert _base_file_downloaded("assets/teaser.png", include_transformer = True) is False
assert _base_file_downloaded("README.md", include_transformer = True) is False
def test_dense_quant_prefetch_capacity_gate(fake_runtime, monkeypatch):
# On a device that cannot hold even the candidate's post-quant resident set, the re-plan
# is certain to decline the dense path -- widening would fetch the multi-GB base
# transformer/ shards (measured: ~47 GB on a Qwen-Image GGUF load on a 24 GB card) only
# to run the GGUF as-is. The gate compares steady_total against TOTAL capacity (reserve +
# 0.85 margin), never the instantaneous free reading.
from core.inference import diffusion as dmod
from core.inference import diffusion_memory as dmem
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
fam = detect_family("unsloth/Qwen-Image-GGUF")
def candidate_with(steady):
return lambda **kw: types.SimpleNamespace(prequant = False, steady_total_mib = steady)
monkeypatch.setattr(
dmem,
"snapshot_device_memory",
lambda target: types.SimpleNamespace(
total_mib = 24_564, free_mib = 24_000, memory_kind = "discrete_vram"
),
)
# int8 qwen steady (~22 GB DiT + 17 GB companions = 39 GB) cannot fit a 24 GB card.
monkeypatch.setattr(dmod, "resolve_dense_quant_candidate", candidate_with(39_900))
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "int8"}) is False
# A candidate that fits total capacity still widens.
monkeypatch.setattr(dmod, "resolve_dense_quant_candidate", candidate_with(12_000))
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "int8"}) is True
# Unknown sizes keep the old behaviour (widen: the loader may still take the dense path).
monkeypatch.setattr(
dmod,
"resolve_dense_quant_candidate",
lambda **kw: types.SimpleNamespace(prequant = False),
)
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "int8"}) is True
def test_dense_quant_prefetch_needed_gates(fake_runtime, monkeypatch):
# The transformer/ prefetch widens exactly when load_pipeline takes the dense-quant path: it
# defers to resolve_dense_quant_candidate (quant requested + device supported + scheme
# resolvable + no prequant checkpoint + disk for the extra bf16 shards). An explicit
# Speed="off" (bit-exact) load never widens.
from core.inference import diffusion as dmod
backend = DiffusionBackend()
_force_cuda_target(backend, monkeypatch)
fam = detect_family("unsloth/Z-Image-Turbo-GGUF")
seen: list = []
def fake_candidate(
*,
fam,
target,
requested,
base_repo = None,
prequant_path = None,
force_dense = False,
logger = None,
):
seen.append(requested)
# A real (non-prequant) dense-quant candidate: scheme resolves AND disk fits, so the
# loader takes the dense build that needs the base repo's bf16 transformer/ shards.
return types.SimpleNamespace(prequant = False)
monkeypatch.setattr(dmod, "resolve_dense_quant_candidate", fake_candidate)
# Explicit fp8 -> widens; the resolved mode is threaded through to the candidate resolver.
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "fp8"}) is True
assert seen[-1] == "fp8"
# UNSET defaults to the hardware ladder (Dtype default-auto) -> widens, threading auto.
assert backend._dense_quant_prefetch_needed(fam, {}) is True
assert seen[-1] == "auto"
# A definite-offload memory policy forces load_pipeline onto offload regardless of the dense
# candidate's smaller footprint, so the dense build never runs and the widened prefetch would
# download base transformer/ shards the offloaded GGUF path never uses (disk-full there has no
# GGUF fallback). balanced / low_vram (and the legacy cpu_offload flag absent a memory_mode)
# must NOT widen, even though the candidate is dense-viable.
before = len(seen)
assert (
backend._dense_quant_prefetch_needed(
fam, {"transformer_quant": "fp8", "memory_mode": "balanced"}
)
is False
)
assert (
backend._dense_quant_prefetch_needed(
fam, {"transformer_quant": "fp8", "memory_mode": "low_vram"}
)
is False
)
assert (
backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "fp8", "cpu_offload": True})
is False
)
# The gate short-circuits BEFORE resolving the candidate (no wasted resolve).
assert len(seen) == before
# An explicit memory_mode still consulting the candidate: fast/auto can flip resident, so they
# widen when the candidate is dense-viable (memory_mode="fast" does not force offload).
assert (
backend._dense_quant_prefetch_needed(
fam, {"transformer_quant": "fp8", "memory_mode": "fast"}
)
is True
)
# A cpu_offload flag is overridden by an explicit resident memory_mode, so it still widens.
assert (
backend._dense_quant_prefetch_needed(
fam, {"transformer_quant": "fp8", "memory_mode": "fast", "cpu_offload": True}
)
is True
)
# An explicit off pins running the GGUF as-is -> never widen (mode resolves to None first).
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "none"}) is False
# An explicit Speed="off" (bit-exact) load suppresses the dense path -> never widen.
assert (
backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "fp8", "speed_mode": "off"})
is False
)
# A PREQUANT candidate loads the small pre-quantized checkpoint (+ config / companions), NOT
# the base repo's dense transformer/ shards, so the widened prefetch must NOT fire -- else it
# defeats the prequant savings and can hard-fail begin_load (no GGUF fallback) on a disk-full.
monkeypatch.setattr(
dmod, "resolve_dense_quant_candidate", lambda **kw: types.SimpleNamespace(prequant = True)
)
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "fp8"}) is False
# No viable candidate (unsupported scheme / no disk room) -> never widen. The disk guard here
# averts filling the cache volume and hard-failing the load instead of falling back to GGUF.
monkeypatch.setattr(dmod, "resolve_dense_quant_candidate", lambda **kw: None)
assert backend._dense_quant_prefetch_needed(fam, {"transformer_quant": "fp8"}) is False
def test_diffusion_status_response_carries_resolved():
# The backend records per-control auto-policy provenance (build_resolved_record) on
# state.resolved; the response model must DECLARE the field or Pydantic's extra='ignore' drops
# it, leaving that plumbing dead (never reaching a client).
from models.inference import DiffusionStatusResponse
rec = {"transformer_quant": {"value": "fp8", "source": "auto", "reason": "blackwell"}}
resp = DiffusionStatusResponse(loaded = True, resolved = rec)
# The typed field coerces the plain record into DiffusionResolvedControl objects; the
# serialized form must round-trip back to the record, proving the field is DECLARED and not
# dropped by Pydantic's extra='ignore'.
assert resp.model_dump()["resolved"] == rec
# Absent by default (nothing resolved / native engine).
assert DiffusionStatusResponse(loaded = False).resolved is None
def test_companion_cache_bytes_local_dir_excludes_transformer(tmp_path):
# A LOCAL diffusers base: sum the on-disk VAE / text-encoder weights so auto memory planning
# sees the resident companions, but exclude transformer/ (the GGUF supplies it) and non-weight
# files. A folded-to-zero companion could OOM a resident plan.
(tmp_path / "vae").mkdir()
(tmp_path / "vae" / "diffusion_pytorch_model.safetensors").write_bytes(b"x" * 100)
(tmp_path / "text_encoder").mkdir()
(tmp_path / "text_encoder" / "model.safetensors").write_bytes(b"y" * 50)
(tmp_path / "transformer").mkdir()
(tmp_path / "transformer" / "diffusion_pytorch_model.safetensors").write_bytes(b"z" * 9999)
(tmp_path / "model_index.json").write_bytes(b"{}") # non-weight file, ignored
total = DiffusionBackend._companion_cache_bytes(str(tmp_path))
assert total == 150 # vae + text_encoder only; transformer/ and json excluded
def test_plan_memory_dense_replan_does_not_double_count_prefetched_transformer(monkeypatch):
# Re-planning the dense transformer-quant candidate: the dense path prefetches the base repo's
# transformer/ shards into the SAME blob cache _companion_cache_bytes sums. If the re-plan read
# that cache it would count the transformer TWICE (as transformer_resident_override_mib and as
# a "companion") and force offload even when the quantised artifact fits resident. The re-plan
# must use the auto-policy's companion estimate. Here the cache is stubbed to the inflated
# value; the plan must still stay resident.
from core.inference import diffusion as dmod
from core.inference.diffusion_memory import OFFLOAD_NONE, DeviceMemory
backend = DiffusionBackend()
target = types.SimpleNamespace(device = "cuda", backend = "cuda", supports_model_cpu_offload = True)
# 40 GiB discrete card, 40000 MiB free: comfortably fits transformer + real
# companions + headroom, but NOT a second copy of the bf16 transformer.
monkeypatch.setattr(
dmod,
"settled_snapshot_device_memory",
lambda t: DeviceMemory("cuda", "cuda", "discrete_vram", 40000, 40960),
)
monkeypatch.setattr(dmod, "estimate_image_runtime_mib", lambda **kw: 4000)
# The cache is inflated by the prefetched bf16 transformer (~24000) on top of the
# ~8000 real companions; if the re-plan consulted it the plan would offload.
monkeypatch.setattr(
DiffusionBackend,
"_companion_cache_bytes",
staticmethod(lambda base: (8000 + 24000) * 1024 * 1024),
)
fam = types.SimpleNamespace(name = "z-image")
plan = backend._plan_memory(
target,
None,
"org/base",
fam,
None,
False,
kind = "gguf",
transformer_resident_override_mib = 12000, # int8 candidate transient (~half bf16)
companion_override_mib = 8000, # auto-policy text-encoder + VAE estimate
)
# 12000 + 8000 + 4000 + 2048 overhead = 26048 MiB, fits the ~36 GiB budget.
# A double-count (12000 + [8000+24000] + ...) would have exceeded it and offloaded.
assert plan.offload_policy == OFFLOAD_NONE
def test_reset_step_cache_helper_is_best_effort():
# Prefers the real diffusers CacheMixin hook (_reset_stateful_cache): on a genuine Flux /
# QwenImage transformer that is the reset entry point, and reset_stateful_hooks lives only on
# the HookRegistry (getattr on the transformer returns None), so the old lookup was a silent
# no-op that left stale FBCache residuals for the next generation.
calls = []
pipe = types.SimpleNamespace(
transformer = types.SimpleNamespace(_reset_stateful_cache = lambda: calls.append("real"))
)
DiffusionBackend._reset_step_cache(pipe)
assert calls == ["real"]
# _reset_stateful_cache wins when both are present.
calls.clear()
pipe = types.SimpleNamespace(
transformer = types.SimpleNamespace(
_reset_stateful_cache = lambda: calls.append("real"),
reset_stateful_hooks = lambda: calls.append("fallback"),
)
)
DiffusionBackend._reset_step_cache(pipe)
assert calls == ["real"]
# Falls back to reset_stateful_hooks for a transformer that exposes only that.
calls.clear()
pipe = types.SimpleNamespace(
transformer = types.SimpleNamespace(reset_stateful_hooks = lambda: calls.append("fallback"))
)
DiffusionBackend._reset_step_cache(pipe)
assert calls == ["fallback"]
# No transformer, or a transformer without either hook -> silent no-op (never raises).
DiffusionBackend._reset_step_cache(types.SimpleNamespace())
DiffusionBackend._reset_step_cache(types.SimpleNamespace(transformer = object()))
def test_generate_resets_step_cache_only_when_engaged(fake_runtime, tmp_path):
# FBCache residuals live on the resident transformer across generations, so each
# generate() must reset the stateful cache first -- but only when a cache is engaged.
(tmp_path / "model.gguf").write_bytes(b"weights")
backend = DiffusionBackend()
backend.load_pipeline(
str(tmp_path),
gguf_filename = "model.gguf",
base_repo = "base/repo",
family_override = "z-image",
)
resets = []
# Use the real diffusers CacheMixin entry point (_reset_stateful_cache); a genuine
# Flux/QwenImage transformer exposes this, not reset_stateful_hooks.
backend._state.pipe.transformer = types.SimpleNamespace(
_reset_stateful_cache = lambda: resets.append(True)
)
# No cache engaged (transformer_cache is None) -> reset must NOT run.
backend.generate(prompt = "a sloth")
assert resets == []
# Engage a cache; every subsequent generation resets the stateful cache first.
object.__setattr__(backend._state, "transformer_cache", "fbcache")
backend.generate(prompt = "a sloth")
backend.generate(prompt = "another sloth")
assert resets == [True, True]
def test_prefetch_returns_snapshot_dir_for_manifest(monkeypatch):
# The prefetched pipeline manifest's directory is the local snapshot root; a
# config-only base list (no manifest) returns None so the hub id stays in use.
backend = DiffusionBackend()
monkeypatch.setattr(
"utils.hf_xet_fallback.hf_hub_download_with_xet_fallback",
lambda repo, fn, tok, **k: f"/cache/snap/{fn}",
)
root = backend._prefetch_files(
"base/repo", None, "base/repo", ["model_index.json", "vae/x.safetensors"], None
)
assert root == "/cache/snap"
assert (
backend._prefetch_files("base/repo", None, "base/repo", ["vae/x.safetensors"], None) is None
)
def test_pipeline_load_uses_predownloaded_dir(fake_runtime, tmp_path):
# With a prefetched snapshot, from_pretrained must receive the local dir -- its own hub sweep
# would re-download the root packaged singles the scoped prefetch skips (24 GB per FLUX.1 repo).
backend = DiffusionBackend()
backend.load_pipeline(
"unsloth/Qwen-Image-2512-bnb-4bit",
model_kind = "pipeline",
_base_local_dir = str(tmp_path),
)
assert _FakePipeline.last["base"] == str(tmp_path)
backend.unload()
def test_unload_waits_for_in_flight_denoise_before_teardown():
# Regression: unload() must wait for a running denoise to exit (acquire _generate_lock) before
# _unload_locked() tears down process-wide state the denoise still depends on.
import threading
backend = DiffusionBackend()
denoise_active = {"v": False}
teardown_saw = [] # records denoise_active at the moment _unload_locked runs
cancel = threading.Event()
backend._active_generate_cancel = cancel
started = threading.Event()
finish = threading.Event()
# _generate_lock is the only lock a real denoise holds for its whole body.
def _denoise():
with backend._generate_lock:
denoise_active["v"] = True
started.set()
cancel.wait(2.0) # unload signals this
finish.wait(2.0) # the test lets us finish
denoise_active["v"] = False # about to release _generate_lock
def _fake_unload_locked():
teardown_saw.append(denoise_active["v"])
backend._unload_locked = _fake_unload_locked # instance attr shadows the method
d = threading.Thread(target = _denoise)
d.start()
assert started.wait(2.0) # denoise holds _generate_lock
unloaded = threading.Event()
def _unload():
backend.unload()
unloaded.set()
u = threading.Thread(target = _unload)
u.start()
assert cancel.wait(2.0) # unload has signalled the denoise and is now waiting on _generate_lock
# unload must NOT have torn down yet -- it is blocked on the denoise's _generate_lock.
assert teardown_saw == []
assert not unloaded.wait(0.3)
finish.set() # let the denoise release _generate_lock
d.join(2.0)
u.join(2.0)
assert unloaded.is_set()
# Teardown ran exactly once, and only AFTER the denoise had exited (denoise_active was False).
assert teardown_saw == [False]