Files
olivv-cs-ComfyUI-FunPack/tests/test_companion_conditioning.py
T
digital-garbageandClaude Opus 5 8e3c707c81 fix(sampler): a wired reference conditioning is not a second scene
The Chain Sampler reads one conditioning entry per SCENE
(scene_conditionings = positive[:max_scenes]). When Studio stopped discarding
the entries past the first of a wired CONDITIONING — the fix for a reference
surviving while the prompt did not — those entries reached the sampler
untagged, and the r2v reference block was counted as a scene of its own. The
run sampled the shot twice, which from outside is "the model ran a second pass
for no reason".

Studio tags every pass-through entry as a companion; the sampler excludes
companions when counting scenes and hands them to every scene instead, so they
still reach the model. Both halves of the original bug stay fixed: nothing is
dropped, and nothing is mistaken for a scene.

Also fixes the liked-conditioning blend, which was the last payload path still
doing a raw lerp: _v2_shape_compatible ignores sequence length by design, so a
direction learned at 586 positions met a 494-position prompt, threw, and took
the whole pull toward what the user rated well with it. Routed through
_v2_payload_like like every other payload.

Adds stage timers for the nine learning steps the first pass did not cover —
55% of a 26.9s run was accounted for, and the rest was unnamed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 14:06:52 +03:00

64 lines
2.3 KiB
Python

"""A wired r2v conditioning is several entries describing ONE generation, not several scenes.
The Chain Sampler reads one conditioning entry per SCENE. When Studio stopped discarding the
entries past the first of a wired CONDITIONING — the fix for "the right face speaking invented
syllables" — those entries started arriving at the sampler untagged, and it counted the
reference block as a second scene. From outside that looks like the model sampling the shot
twice for no reason anyone asked for.
"""
import sys
import pytest
import torch
sys.path.insert(0, ".")
@pytest.fixture
def chain():
from samplers import FunPackLTXAVSceneChainSampler
return FunPackLTXAVSceneChainSampler
def _entry(companion=False, text="scene"):
meta = {"funpack_scene_text": text}
if companion:
meta["funpack_companion_conditioning"] = True
return [torch.zeros(1, 4, 8), meta]
def test_a_tagged_entry_is_a_companion(chain):
assert chain._is_companion_conditioning(_entry(companion=True)) is True
def test_an_ordinary_entry_is_a_scene(chain):
assert chain._is_companion_conditioning(_entry()) is False
@pytest.mark.parametrize("junk", [None, [], [torch.zeros(1)], "text", 7, [torch.zeros(1), None]])
def test_a_malformed_entry_is_not_mistaken_for_a_companion(chain, junk):
"""Guessing wrong here drops a real scene, so anything unreadable counts as a scene."""
assert chain._is_companion_conditioning(junk) is False
def test_companions_do_not_add_scenes(chain):
"""The regression itself: one scene plus one reference companion is ONE scene."""
positive = [_entry(), _entry(companion=True)]
scenes = [c for c in positive if not chain._is_companion_conditioning(c)]
assert len(scenes) == 1
def test_real_scenes_still_count(chain):
positive = [_entry(text="a"), _entry(text="b"), _entry(companion=True)]
scenes = [c for c in positive if not chain._is_companion_conditioning(c)]
assert len(scenes) == 2
def test_studio_tags_what_it_passes_through():
"""Studio is what applies the tag; without it the sampler cannot tell the two apart."""
import inspect
from conditioning import FunPackVideoRefinerV2
src = inspect.getsource(FunPackVideoRefinerV2.refine_v2)
assert 'meta_copy["funpack_companion_conditioning"] = True' in src