Key the auto step-cache on the pipe's default strength when the request omits it

The auto FBCache policy keyed on the full step count whenever strength was omitted, but the
loader only passes the strength kwarg when it is set, so an img2img/inpaint pipe then runs its
OWN signature default (< 1, e.g. FluxImg2ImgPipeline's 0.6). FBCache would engage on the full
28 steps while the pipe actually denoises ~16, degrading the image on exactly the short
trajectory the policy exists to keep uncached. Thread the pipe's signature default into the
policy via a new effective_request_strength helper (unit-tested), so the effective denoise count
matches what the pipe runs.
This commit is contained in:
Daniel Han 2026-07-06 14:49:47 +00:00
commit b6b507c48b
3 changed files with 52 additions and 8 deletions

View file

@ -180,6 +180,7 @@ from core.inference.diffusion_cache import ( # noqa: E402
FBCACHE_MIN_STEPS,
TC_AUTO,
effective_denoise_steps,
effective_request_strength,
maybe_toggle_step_cache,
)
@ -200,6 +201,25 @@ def test_effective_steps_low_strength_shrinks_below_the_bar():
assert eff < FBCACHE_MIN_STEPS
def test_effective_request_strength_uses_pipe_default_when_omitted():
import inspect
# txt2img (no init image) or a pipe without the strength kwarg -> full trajectory (None).
assert effective_request_strength(None, False, True, 0.6) is None
assert effective_request_strength(0.5, True, False, None) is None
# img2img with an explicit strength -> that value.
assert effective_request_strength(0.2, True, True, 0.6) == 0.2
# img2img with an OMITTED strength -> the pipe's own signature default (< 1), so the auto
# policy keys on the real (short) trajectory, not the full step count. This is the fix:
# int(28 * 0.6) = 16 real steps, not 28.
s = effective_request_strength(None, True, True, 0.6)
assert s == 0.6
assert effective_denoise_steps(28, s) == 16
# A non-numeric signature default (inspect.Parameter.empty) falls back to the full count.
assert effective_request_strength(None, True, True, inspect.Parameter.empty) is None
assert effective_request_strength(None, True, True, None) is None
def test_effective_steps_matches_diffusers_get_timesteps():
# Mirror diffusers exactly: it denoises init_timestep = min(int(num_inference_steps *
# strength), num_inference_steps) steps (the product is floored, not rounded).