Compare commits
1
Commits
main
...
tara-keyframes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6df4276ae9 |
@@ -48,8 +48,9 @@ def dense_backend_selection(override):
|
||||
|
||||
|
||||
def temporal_layout(native, refs, keyframes, video_index=1):
|
||||
if keyframes:
|
||||
raise ValueError('Native temporal mode cannot be combined with Add Guide, first-frame guides or history. Remove those guides.')
|
||||
# Add Guide keyframes (e.g. the previous shot's last frames as history) pack as 'cond' rows right after the text,
|
||||
# before the references, at the target's own timeline positions and never denoised. They stay as they are: no
|
||||
# temporal bias touches them, and the reference rows are located after them.
|
||||
required = ('position_ids', 'segments', 'seq_len', 'signature')
|
||||
if any(not hasattr(native, x) for x in required):
|
||||
raise RuntimeError('Unsupported H3 PackedLayout API; update ComfyUI.')
|
||||
@@ -59,8 +60,9 @@ def temporal_layout(native, refs, keyframes, video_index=1):
|
||||
target = torch.zeros_like(source)
|
||||
ta, tb, _ = next(s for s in native.segments if s[2] == 'video')
|
||||
target[ta:tb] = True
|
||||
# Native packing is text, each reference's optional audio then video, targets.
|
||||
# Native packing is text, keyframe cond rows, each reference's optional audio then video, targets.
|
||||
cursor = next(s[1] for s in native.segments if s[2] == 'text')
|
||||
cursor = max([cursor] + [s[1] for s in native.segments if s[2] in ('cond', 'cond_audio')])
|
||||
videos = 0
|
||||
for ref in refs:
|
||||
kind = ref['kind']
|
||||
|
||||
@@ -36,7 +36,24 @@ def test_wrong_video_index_and_temporal_mismatch_rejected():
|
||||
with pytest.raises(ValueError,match='Video 2'):node.temporal_layout(l,r,None,2)
|
||||
l,r=example(6)
|
||||
with pytest.raises(ValueError,match='identical temporal'):node.temporal_layout(l,r,None)
|
||||
with pytest.raises(ValueError,match='Add Guide'):node.temporal_layout(l,r,[{}])
|
||||
|
||||
def test_add_guide_history_keyframes_keep_reference_alignment():
|
||||
# The previous shot's last frames as an Add Guide history (cond rows after the text) must not shift the reference.
|
||||
l,refs=example();plain,src0,tgt0=node.temporal_layout(l,refs,None)
|
||||
kfs=[dict(resolved_frame_index=0,latent=torch.zeros(1,4,2,8,8))]
|
||||
k=CORE.PackedLayout(3,7,8,8,2,keyframes=kfs,refs=refs)
|
||||
aligned,src,tgt=node.temporal_layout(k,refs,kfs)
|
||||
cond=[s for s in k.segments if s[2]=='cond'];assert cond
|
||||
a,b,_=cond[0];n=b-a
|
||||
assert src.sum()==src0.sum() and tgt.sum()==tgt0.sum()
|
||||
assert not src[a:b].any() and not tgt[a:b].any()
|
||||
# Same rows as without history, shifted by the cond rows; same aligned positions for the reference and the target.
|
||||
assert torch.equal(src[b:],src0[a:]) and torch.equal(tgt[b:],tgt0[a:])
|
||||
torch.testing.assert_close(aligned.position_ids[src],plain.position_ids[src0],rtol=0,atol=1e-12)
|
||||
torch.testing.assert_close(aligned.position_ids[tgt],plain.position_ids[tgt0],rtol=0,atol=1e-12)
|
||||
# History rows sit on the target's first frames and are left untouched.
|
||||
torch.testing.assert_close(aligned.position_ids[a:b],k.position_ids[a:b],rtol=0,atol=0)
|
||||
assert aligned.position_ids[a,0]==aligned.position_ids[tgt][0,0]
|
||||
|
||||
def context():
|
||||
l,r=example();a,s,t=node.temporal_layout(l,r,None)
|
||||
|
||||
Reference in New Issue
Block a user