Give the 720p HunyuanVideo repack its own family and free offload hooks on cancel
The trusted-repo allowlist admitted the 720p t2v repack while the only Hunyuan family entry carried 480p presets, so a 720p load silently defaulted to 832x480. It now resolves a dedicated entry whose repo-id alias outranks the generic token (same guider config, verified: both repos ship guidance 6.0). A scheduler-wrapped cancel unwinds pipe call by exception and skips the pipeline's end-of-call maybe_free_model_hooks, leaving onloaded offload modules on the GPU until the next request; generate() now frees them before surfacing the cancelled sentinel.
This commit is contained in:
parent
3e6604d6b4
commit
b96820a0d2
4 changed files with 59 additions and 0 deletions
|
|
@ -1238,6 +1238,17 @@ class VideoBackend:
|
|||
with torch.inference_mode(), progress_ctx:
|
||||
output = pipe(**kwargs)
|
||||
except _VideoGenerationCancelled:
|
||||
# This cancel unwinds pipe.__call__ by exception (the scheduler
|
||||
# wrapper has no cooperative _interrupt), skipping the pipeline's
|
||||
# end-of-call maybe_free_model_hooks(); under model/group offload
|
||||
# the currently-onloaded modules would otherwise stay on the GPU
|
||||
# until the next request touches them.
|
||||
free_hooks = getattr(pipe, "maybe_free_model_hooks", None)
|
||||
if callable(free_hooks):
|
||||
try:
|
||||
free_hooks()
|
||||
except Exception: # noqa: BLE001 -- cleanup is best-effort
|
||||
pass
|
||||
raise RuntimeError(VIDEO_CANCELLED_MSG) from None
|
||||
if cancel.is_set():
|
||||
raise RuntimeError(VIDEO_CANCELLED_MSG)
|
||||
|
|
|
|||
|
|
@ -237,6 +237,30 @@ _FAMILIES: tuple[VideoFamily, ...] = (
|
|||
# VAE (4.7 -> 2.4); the Qwen2.5-VL TE is stored bf16 (14.0) plus ByT5 0.8.
|
||||
bf16_components_gb = (16.6, 14.8, 2.4),
|
||||
),
|
||||
# The 720p t2v repack: same architecture, pipeline quirks, guider config
|
||||
# (guidance 6.0) and shard footprint as the 480p entry above; only the
|
||||
# trained resolution class differs. Kept as its OWN family so a 720p load
|
||||
# defaults to 720p-class sizes instead of silently rendering at 832x480.
|
||||
# The repo-id alias is the full path segment, so it out-lengths (and thus
|
||||
# outranks) the generic "hunyuanvideo-1.5" token for this repo only.
|
||||
VideoFamily(
|
||||
name = "hunyuanvideo-1.5-720p",
|
||||
pipeline_class = "HunyuanVideo15Pipeline",
|
||||
transformer_class = "HunyuanVideo15Transformer3DModel",
|
||||
base_repo = "hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v",
|
||||
aliases = ("hunyuanvideo-1.5-diffusers-720p_t2v", "hv15-720p"),
|
||||
has_audio = False,
|
||||
guidance_via_guider = True,
|
||||
default_steps = 50,
|
||||
default_guidance = 6.0,
|
||||
default_num_frames = 121,
|
||||
default_fps = 24,
|
||||
frame_step = 4,
|
||||
resolution_multiple = 16,
|
||||
# 720p-class presets: landscape, vertical, square (all /16).
|
||||
resolution_presets = ((1280, 720), (720, 1280), (960, 960)),
|
||||
bf16_components_gb = (16.6, 14.8, 2.4),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -303,6 +303,10 @@ class _FakeHV15Pipe:
|
|||
self.components = {"transformer": self.transformer, "vae": self.vae}
|
||||
self.moved_to = None
|
||||
self.last_kwargs = None
|
||||
self.hooks_freed = 0
|
||||
|
||||
def maybe_free_model_hooks(self):
|
||||
self.hooks_freed += 1
|
||||
|
||||
def to(self, device):
|
||||
self.moved_to = device
|
||||
|
|
@ -718,6 +722,10 @@ def test_hv15_cancel_unwinds_scheduler_loop(fake_runtime):
|
|||
assert pipe.scheduler.calls == 1
|
||||
# The wrapper must restore scheduler.step even on the exception path.
|
||||
assert pipe.scheduler.step.__func__ is _FakeHV15Scheduler.step
|
||||
# The exception unwound pipe.__call__ before its own end-of-call cleanup, so
|
||||
# generate() must have freed the offload hooks itself (VRAM would otherwise
|
||||
# stay onloaded until the next request).
|
||||
assert pipe.hooks_freed == 1
|
||||
|
||||
|
||||
def test_singleton():
|
||||
|
|
@ -1129,3 +1137,18 @@ def test_base_download_files_ltx23_keeps_only_shared_components():
|
|||
assert not any(
|
||||
n.startswith(("vae/", "connectors/", "latent_upsampler/", "transformer/")) for n in names
|
||||
)
|
||||
|
||||
|
||||
def test_hv15_720p_repo_gets_720p_family_defaults():
|
||||
# The 720p repack is trusted, but it must resolve its OWN family entry: the
|
||||
# generic hunyuanvideo-1.5 entry would default generation to 832x480.
|
||||
from core.inference.video_families import detect_video_family
|
||||
|
||||
fam = detect_video_family("hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v")
|
||||
assert fam is not None and fam.name == "hunyuanvideo-1.5-720p"
|
||||
assert fam.resolution_presets[0] == (1280, 720)
|
||||
assert fam.base_repo.endswith("720p_t2v")
|
||||
# The 480p repo keeps the original entry.
|
||||
fam480 = detect_video_family("hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-480p_t2v")
|
||||
assert fam480 is not None and fam480.name == "hunyuanvideo-1.5"
|
||||
assert fam480.resolution_presets[0] == (832, 480)
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ def test_supported_names():
|
|||
"wan2.2-ti2v-5b",
|
||||
"wan2.2-t2v-a14b",
|
||||
"hunyuanvideo-1.5",
|
||||
"hunyuanvideo-1.5-720p",
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue