Fix/adjust diffusion lifecycle + UI for PR #5754
- unload_model now takes _load_lock so it cannot race with an in-flight load_model and have the load thread overwrite cleared state after unload returned is_loaded=false. - Move stable-diffusion-xl out of _FAMILIES into _FULL_REPO_FAMILIES. SDXL uses a UNet (no transformer GGUF path is wired); listing it in the GGUF families panel was misleading. SDXL full-repo loads still work via family_override='stable-diffusion-xl'. - Result gallery now uses h-auto + object-contain so portrait / landscape outputs render at their true aspect ratio instead of being cropped into a square thumbnail.
This commit is contained in:
parent
669964f52c
commit
d6f2a238aa
2 changed files with 40 additions and 22 deletions
|
|
@ -115,15 +115,25 @@ _FAMILIES: tuple[DiffusionFamily, ...] = (
|
|||
base_repo = "stabilityai/stable-diffusion-3-medium-diffusers",
|
||||
aliases = ("sd3-medium", "stable-diffusion-3-medium", "sd3.5"),
|
||||
),
|
||||
# SDXL: full diffusers path only (no GGUF). SDXL uses a UNet (not a
|
||||
# transformer) and wiring UNet2DConditionModel.from_single_file +
|
||||
# GGUF is a separate code path the rest of this module does not
|
||||
# exercise. The family is intentionally NOT in _FAMILIES so the
|
||||
# frontend status panel does not advertise GGUF support we do not
|
||||
# implement; callers wanting SDXL full repos can still do so by
|
||||
# passing the diffusers repo with no gguf_filename and
|
||||
# family_override = "stable-diffusion-xl" via the route, which uses
|
||||
# the lookup in _FULL_REPO_FAMILIES.
|
||||
)
|
||||
|
||||
|
||||
# Families available via family_override on the routes layer when the
|
||||
# user is loading a full diffusers checkpoint (no GGUF). Kept separate
|
||||
# from _FAMILIES so the GGUF-only status panel does not over-advertise.
|
||||
_FULL_REPO_FAMILIES: tuple[DiffusionFamily, ...] = (
|
||||
DiffusionFamily(
|
||||
name = "stable-diffusion-xl",
|
||||
pipeline_class = "StableDiffusionXLPipeline",
|
||||
# SDXL uses a UNet, not a transformer. Loading SDXL GGUFs would
|
||||
# require UNet2DConditionModel.from_single_file + GGUF, which is
|
||||
# not the same code path as the FLUX / Qwen-Image transformers
|
||||
# this PR ships. Until that path is wired and smoke-tested,
|
||||
# treat SDXL as full-repo-only and surface a clear error when a
|
||||
# user tries to pass gguf_filename for it.
|
||||
transformer_class = "",
|
||||
base_repo = "stabilityai/stable-diffusion-xl-base-1.0",
|
||||
aliases = ("sdxl",),
|
||||
|
|
@ -137,13 +147,14 @@ def detect_family(
|
|||
"""Return the diffusion family matching ``repo_id``.
|
||||
|
||||
Matching is substring-based and case-insensitive. ``override_family``
|
||||
bypasses substring matching and looks up by ``DiffusionFamily.name``.
|
||||
Returns ``None`` when no family applies so callers can surface a clear
|
||||
"unsupported model" error rather than guessing wrong.
|
||||
bypasses substring matching and looks up by ``DiffusionFamily.name``
|
||||
or (when explicitly asked) by ``_FULL_REPO_FAMILIES.name``.
|
||||
Returns ``None`` when no family applies so callers can surface a
|
||||
clear "unsupported model" error rather than guessing wrong.
|
||||
"""
|
||||
if override_family:
|
||||
wanted = override_family.strip().lower()
|
||||
for fam in _FAMILIES:
|
||||
for fam in _FAMILIES + _FULL_REPO_FAMILIES:
|
||||
if fam.name == wanted:
|
||||
return fam
|
||||
return None
|
||||
|
|
@ -395,17 +406,21 @@ class DiffusionBackend:
|
|||
self._loading = False
|
||||
|
||||
def unload_model(self) -> dict[str, Any]:
|
||||
with self._lock:
|
||||
old = self._pipe
|
||||
self._pipe = None
|
||||
self._family = None
|
||||
self._repo_id = None
|
||||
self._gguf_path = None
|
||||
self._base_repo = None
|
||||
self._device = None
|
||||
self._dtype = None
|
||||
self._loaded_at = None
|
||||
_release(old)
|
||||
# Take the load lock too so unload cannot race with an in-flight
|
||||
# load_model and have the load thread overwrite the cleared state
|
||||
# after we already returned {"is_loaded": false}.
|
||||
with self._load_lock:
|
||||
with self._lock:
|
||||
old = self._pipe
|
||||
self._pipe = None
|
||||
self._family = None
|
||||
self._repo_id = None
|
||||
self._gguf_path = None
|
||||
self._base_repo = None
|
||||
self._device = None
|
||||
self._dtype = None
|
||||
self._loaded_at = None
|
||||
_release(old)
|
||||
return {"is_loaded": False}
|
||||
|
||||
# ── generation ────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -458,7 +458,10 @@ export function ImagesPage() {
|
|||
<img
|
||||
src={`data:${r.image_mime};base64,${r.image_b64}`}
|
||||
alt={`Generated image ${idx + 1}`}
|
||||
className="aspect-square w-full rounded-md border border-border object-cover"
|
||||
// h-auto + object-contain so portrait / landscape
|
||||
// outputs render at their true aspect ratio instead
|
||||
// of being cropped into a square thumbnail.
|
||||
className="h-auto w-full rounded-md border border-border object-contain"
|
||||
data-testid="diffusion-result-image"
|
||||
/>
|
||||
<figcaption className="text-xs text-muted-foreground">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue