Files

72 lines
3.6 KiB
Python

import pytest
import torch
@pytest.fixture(autouse=True)
def _needs_comfy(comfyui):
"""Imports comfy."""
def _load(tiny, **v):
from comfy.patcher_extension import WrappersMP
from modules.sampling.modifiers.nodes import FunUILoadModifiers
patched, status = FunUILoadModifiers.execute(
tiny.patcher, {"sharpness": {"enabled": True, **v}}).result
wrap = [w for ws in patched.wrappers[WrappersMP.APPLY_MODEL].values() for w in ws][-1]
return patched, wrap, status
def _to(i, steps=4):
s = torch.linspace(1.0, 0.0, steps + 1)
return {"sample_sigmas": s, "sigmas": s[i:i + 1]}
def test_off_installs_nothing(tiny_h3):
from comfy.patcher_extension import WrappersMP
from modules.sampling.modifiers.nodes import FunUILoadModifiers
patched, _ = FunUILoadModifiers.execute(tiny_h3.patcher, {"sharpness": {"enabled": False}}).result
assert not patched.wrappers.get(WrappersMP.APPLY_MODEL)
def test_a_plain_latent_is_pushed_away_from_the_previous_prediction_in_the_last_part_only(tiny_h3):
_p, wrap, status = _load(tiny_h3, amount=0.5, last_part=0.5)
assert "sharpness" in status
x = torch.randn(1, 4, 3, 8, 8)
outs = [x * f for f in (0.9, 0.5, 0.2, 0.1)]
ts = torch.linspace(1.0, 0.0, 5)
got = [wrap(lambda *a, o=outs[i], **kw: o, x, ts[i:i + 1], None, None, None, _to(i)) for i in range(4)]
assert torch.equal(got[0], outs[0]) and torch.equal(got[1], outs[1]) # outside the last half
kept = list(got) # the boost is measured against the sharpened answer before
for i in (2, 3):
assert torch.allclose(got[i], outs[i] + 0.25 * (outs[i] - kept[i - 1]), atol=1e-5)
def test_a_packed_model_is_edited_on_its_answer_including_the_last_step_and_never_the_sound(tiny_h3):
from conftest import packed_av, unpacked
_p, wrap, _ = _load(tiny_h3, amount=1.0, last_part=1.0)
x0, shapes = packed_av(torch.randn(1, 4, 3, 8, 8), torch.randn(1, 8, 5))
answers = [x0 * f for f in (0.9, 0.5, 0.2, 0.1)]
ts = torch.linspace(1.0, 0.0, 5)
got = [wrap(lambda *a, o=answers[i], **k: o, x0, ts[i:i + 1], None, None, None, _to(i), latent_shapes=shapes)
for i in range(4)]
assert torch.equal(got[0], answers[0]) # nothing to compare on step 0
for i in (1, 3):
assert not torch.allclose(unpacked(got[i], shapes)[0], unpacked(answers[i], shapes)[0])
assert torch.equal(unpacked(got[i], shapes)[1], unpacked(answers[i], shapes)[1]) # sound untouched
def test_a_hand_over_to_a_bigger_picture_is_never_compared_with_the_smaller_one_before_it(tiny_h3):
"""Two stages: the step index counts the whole schedule, and the first call at the full size has nothing of its
own size to compare with, so it is not sharpened against the first stage's smaller answer."""
_p, wrap, _ = _load(tiny_h3, amount=1.0, last_part=1.0)
ts = torch.linspace(1.0, 0.0, 5)
small = torch.randn(1, 4, 3, 4, 4)
big = torch.randn(1, 4, 3, 8, 8)
first = wrap(lambda *a, **k: small, small, ts[0:1], None, None, None, _to(0))
second = wrap(lambda *a, **k: small * 0.5, small, ts[1:2], None, None, None, _to(1))
assert torch.equal(first, small) and not torch.equal(second, small * 0.5) # same size: compared
handed = wrap(lambda *a, **k: big, big, ts[2:3], None, None, None, _to(2))
assert torch.equal(handed, big) # new size: left as the model said
after = wrap(lambda *a, **k: big * 0.5, big, ts[3:4], None, None, None, _to(3))
assert not torch.equal(after, big * 0.5) # and sharpening goes on in stage 2