61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
"""Phase 8 component test: /api/reload-loras hot-swap.
|
|
|
|
Verifies that ``VideoEngine.load_loras`` can be called again after startup
|
|
and the idle clip is regenerated to reflect the new style.
|
|
|
|
This test is the 'real model' version of test_07's reload endpoint stub.
|
|
|
|
Run:
|
|
docker compose exec voice-chat python -m tests.component.test_08_lora_reload
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
|
|
from server.video import LoRASpec, VideoConfig, VideoEngine
|
|
from tests.component._common import ensure_sample_avatar, get_logger, write_bytes
|
|
|
|
log = get_logger("test_08")
|
|
|
|
|
|
def run():
|
|
avatar_path = ensure_sample_avatar()
|
|
cfg = VideoConfig.from_dict({"enabled": True, "mode": "reflective"})
|
|
engine = VideoEngine(cfg)
|
|
engine.load_models()
|
|
|
|
# Initial state: no LoRAs
|
|
engine.set_avatar(avatar_path)
|
|
idle_a = engine.get_idle_clip()
|
|
assert idle_a is not None
|
|
hash_a = hashlib.sha256(idle_a).hexdigest()
|
|
write_bytes("phase8_idle_noloras.mp4", idle_a)
|
|
log.info("idle (no LoRAs) sha256=%s", hash_a[:16])
|
|
|
|
# Hot-reload with a distill LoRA
|
|
specs = [
|
|
LoRASpec(
|
|
path="lightx2v/Wan2.2-Distill-Loras:"
|
|
"wan2.2_i2v_A14b_high_noise_lora_rank64_lightx2v_4step.safetensors",
|
|
weight=1.0,
|
|
target="high_noise",
|
|
name="distill-hi",
|
|
),
|
|
]
|
|
engine.load_loras(specs)
|
|
engine.set_avatar(avatar_path)
|
|
idle_b = engine.get_idle_clip()
|
|
assert idle_b is not None
|
|
hash_b = hashlib.sha256(idle_b).hexdigest()
|
|
write_bytes("phase8_idle_withlora.mp4", idle_b)
|
|
log.info("idle (with LoRA) sha256=%s", hash_b[:16])
|
|
|
|
if hash_a != hash_b:
|
|
log.info("PASS: idle clip changed after LoRA reload")
|
|
else:
|
|
log.warning("clips identical — LoRA may not be applied; eyeball _out/*.mp4")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|