Fix CLIPSeg multi-prompt crash: missing padding/truncation on tokenizer call
Live rental run hit it immediately on 'detail_targets' with more than one
target: CLIPSegProcessor tokenizes each prompt to a different length, and
without padding=True torch can't stack them into a batch ('excessive
nesting... type list where int is expected'). Reproduced against the real
CIDAS/clipseg-rd64-refined model before and after the fix. Single-target
runs were unaffected (batch of 1 never needed padding), which is why the
earlier probe steps didn't catch it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c864f62480
commit
5727c39189
+6
-1
@@ -224,8 +224,13 @@ def _clipseg_heat(frames, prompts, debug=False):
|
||||
with torch.no_grad():
|
||||
for _, img in frames:
|
||||
pil = Image.fromarray((img.numpy() * 255.0).astype(np.uint8))
|
||||
# padding=True is mandatory once len(prompts) > 1: CLIPSeg's tokenizer
|
||||
# otherwise returns one variable-length id list per prompt and torch can't
|
||||
# stack them into a batch ("excessive nesting... type list where int is
|
||||
# expected"). truncation=True guards the rare very-long user-typed target.
|
||||
inputs = processor(
|
||||
text=list(prompts), images=[pil] * len(prompts), return_tensors="pt")
|
||||
text=list(prompts), images=[pil] * len(prompts), return_tensors="pt",
|
||||
padding=True, truncation=True)
|
||||
logits = model(**inputs).logits # [P, 352, 352] (or [352, 352] for one prompt)
|
||||
if logits.dim() == 2:
|
||||
logits = logits[None]
|
||||
|
||||
@@ -99,6 +99,41 @@ def test_find_tube_enforces_minimum_edge():
|
||||
assert (x1 - x0) >= detailing.MIN_TUBE_EDGE
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _clipseg_heat
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_clipseg_heat_passes_padding_and_truncation(monkeypatch):
|
||||
"""Regression: a multi-prompt call without padding=True crashes CLIPSeg's
|
||||
tokenizer ("excessive nesting... type list where int is expected") the moment
|
||||
detail_targets has more than one entry — caught live on a real rental run.
|
||||
truncation=True is the same call, cheap to require alongside it."""
|
||||
calls = []
|
||||
|
||||
class _FakeInputs(dict):
|
||||
def to(self, *a, **k):
|
||||
return self
|
||||
|
||||
class _FakeProcessor:
|
||||
def __call__(self, text, images, return_tensors, **kwargs):
|
||||
calls.append(kwargs)
|
||||
return _FakeInputs()
|
||||
|
||||
class _FakeModel:
|
||||
def __call__(self, **inputs):
|
||||
n = 2
|
||||
return types.SimpleNamespace(logits=torch.zeros(n, 8, 8))
|
||||
|
||||
def eval(self):
|
||||
return self
|
||||
|
||||
monkeypatch.setattr(detailing, "_get_clipseg", lambda: (_FakeProcessor(), _FakeModel()))
|
||||
frames = [(0, torch.zeros(16, 16, 3))]
|
||||
detailing._clipseg_heat(frames, ["hands", "feet"])
|
||||
assert calls and calls[0].get("padding") is True
|
||||
assert calls[0].get("truncation") is True
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# resolve_upsampler_name
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user