fix: a prompt change was reported as "nothing changed"

The run fingerprint captured only scalar arguments, and the prompt
arrives as conditioning tensors — so two runs of completely different
text compared as a repeatability check, and the resulting structure drop
(0.44-0.93) read as "generation is not reproducible here" when one row
in the same batch showed a bit-identical pair (structure 1.000, detail
x1.000, edge +0.000), proving it demonstrably is.

Fingerprint now includes a conditioning stand-in: per-entry shape + mean
+ std, which differs between any two real prompts and costs two
reductions on a tensor already resident. The row says "prompt/scenes
changed" and refuses to call the pair a noise-floor reading.
This commit is contained in:
digital-garbage
2026-09-04 18:18:41 +03:00
parent be5579f1f9
commit 8a670fdf60
3 changed files with 36 additions and 2 deletions
+9 -2
View File
@@ -412,6 +412,9 @@
// so the seed decides. Different seeds = two different generations and the comparison
// never was an A/B (a reference pins the subject, not the sample). Same seed = the
// change moved the shot rather than its detail, which is a RESULT, not a bad setup.
if (r.changed && r.changed.conditioning) {
return "the prompt or scenes changed — a different generation, not an A/B";
}
const onlySeed = r.changed && !Object.keys(r.changed).filter((k) => k !== "seed").length;
if (onlySeed && r.same_seed) {
// Nothing differed at all: this is the instrument's noise floor for this setup.
@@ -450,10 +453,14 @@
return r.same_seed ? "nothing changed — repeatability check"
: "only the seed changed — a different sample";
}
return keys.slice(0, 3).map((k) => {
const rest = keys.filter((k) => k !== "conditioning");
const promptMoved = keys.includes("conditioning") ? "prompt/scenes changed" : null;
const parts = rest.slice(0, 3).map((k) => {
const show = (v) => (v === "" || v == null ? "—" : String(v));
return `${k}: ${show(ch[k][0])} → ${show(ch[k][1])}`;
}).join(" · ") + (keys.length > 3 ? ` · +${keys.length - 3} more` : "");
});
if (promptMoved) parts.unshift(promptMoved);
return parts.join(" · ") + (rest.length > 3 ? ` · +${rest.length - 3} more` : "");
}
function detailProbeRows(key) {
+15
View File
@@ -7274,6 +7274,21 @@ class FunPackLTXAVSceneChainSampler:
# name list would go stale the first time a widget is added.
_run_settings = {k: v for k, v in locals().items()
if isinstance(v, (bool, int, float, str)) and k != "self"}
# The prompt is NOT a scalar -- it arrives as conditioning tensors -- so scalars
# alone report "nothing changed" across two runs of completely different text, and a
# repeatability check that is really a prompt change reads as "generation is not
# reproducible". Cheap stand-in: per-entry shape + mean + std, which differs between
# any two real prompts and costs two reductions on an already-resident tensor.
try:
_fp = []
for _e in (positive or [])[:8]:
_t = _e[0] if isinstance(_e, (list, tuple)) and _e else _e
if isinstance(_t, torch.Tensor) and _t.numel():
_f = _t.detach().float()
_fp.append(f"{tuple(_t.shape)}:{float(_f.mean()):.5g}:{float(_f.std()):.5g}")
_run_settings["conditioning"] = "|".join(_fp)
except Exception: # noqa: BLE001
pass # a fingerprint is a label, never a reason to fail a generation
self._is_h3 = self._set_stream_axes(model)
if self._is_h3:
# H3's rating-driven mechanisms are h3_phrase_emphasis (Studio), h3_repr_steering,
+12
View File
@@ -338,3 +338,15 @@ def test_no_settings_at_all_is_an_empty_diff_not_a_crash():
dp.record("k", _edged())
row = dp.record("k", _edged())
assert row["changed"] == {}
def test_a_prompt_change_is_reported_and_not_treated_as_a_repeatability_check():
"""The prompt is not a scalar -- it arrives as conditioning -- so scalars alone called two
runs of different text "nothing changed", and the resulting structure drop read as
"generation is not reproducible" rather than "you changed the prompt"."""
base = {"seed": 1, "cfg": 1.0, "conditioning": "(1,9,4096):0.01:0.5"}
dp.record("k", _edged(seed=0), seed=1, settings=base)
row = dp.record("k", _edged(seed=1), seed=1,
settings={**base, "conditioning": "(1,12,4096):0.03:0.7"})
assert "conditioning" in row["changed"]
assert row["same_seed"] is True # same seed, but NOT the same generation