Say what actually failed, and tell the model how to use the thing
Two problems, both found by looking rather than by guessing. ComfyUI writes its history entry in task_done and nowhere else, so the entry appearing IS "finished" -- but it sets completed=e.success, which means an out-of-memory, a cancelled job and a broken node all stay completed:false for ever. await_images waited on that flag. So every failure sat for the full 600s timeout and then reported a timeout, when ComfyUI had known within one second and written down the node, the exception type and the message. Proved by causing both against the real instance: an OOM now raises in 1.0s and an interrupt in 4.0s, each naming the node. The terminal condition is a record with a status, and status.messages is read for the last execution_error or execution_interrupted. OutOfMemory and Interrupted are their own classes because they are the two failures with an obvious next move: the first tells the model to retry at a named smaller size -- worked out from what it actually asked for, since "use a lower resolution" against a request that was already 512x512 is advice nobody can follow -- or with a lighter checkpoint; the second says somebody pressed stop, so do not simply start again. Everything else gets the reason and no advice, because a model told to try again after a broken workflow tries the identical thing. The OOM message is cut to its first sentence. The rest is allocator advice -- PYTORCH_CUDA_ALLOC_CONF, fragmentation notes -- addressed to whoever runs the box and meaningless to a model, in a tool result that is already a failure. Second: the parameters were described in the register of a reference table, and "cfg: prompt adherence, default 8" tells a model nothing it can act on. Measured on a 4B model, same request, same everything else: with the old wording it sent prompt and template and nothing more -- so 512x512 on an SDXL checkpoint, which is exactly the duplicated-limbs failure the width description now warns about. With descriptions that say what each value does to the picture and when to move it, the same model sent a portrait 1024x1536 and a deliberate sampler. ~3KB of schema per request in a chat that can draw, and the difference between having ten parameters and having one. docs/image-generation-instructions.md is the long version for the admin instructions box, for models that need more than the harness can afford to carry on every request in every chat. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1983,6 +1983,42 @@ compaction off. It is biased hard towards KEEP on purpose: a reviewer that
|
||||
retries on taste spends the GPU four times and usually ends up back at the first
|
||||
image.
|
||||
|
||||
**A failed generation is `completed: false` for ever, so waiting on that flag
|
||||
hangs the reply.** ComfyUI writes its history entry in `task_done` and nowhere
|
||||
else, so the entry appearing *is* "finished" — but it sets `completed=e.success`,
|
||||
which means an out-of-memory, a cancelled job and a broken node all stay
|
||||
incomplete permanently. The first version waited on the flag, so every failure
|
||||
sat for the full 600s timeout and then reported a timeout, when ComfyUI had known
|
||||
within one second and written down exactly what happened. The terminal condition
|
||||
is now *a record with a status*, and `status.messages` is read for the last
|
||||
`execution_error` or `execution_interrupted` in it, which carries the node and
|
||||
the exception.
|
||||
|
||||
Two failures get their own class because they have an obvious next move.
|
||||
`OutOfMemory` — matched on `exception_type`, not on the message, which is a
|
||||
paragraph of allocator advice addressed to whoever runs the box — makes the tool
|
||||
tell the model to retry at a named smaller size (worked out from what it actually
|
||||
asked for, because "use a lower resolution" against a request that was already
|
||||
512x512 is advice nobody can follow) or with a lighter checkpoint. `Interrupted`
|
||||
is not a fault at all: somebody pressed stop, and the model is told not to simply
|
||||
start it again. **Everything else gets the reason and no advice** — a model told
|
||||
to "try again" after a broken workflow tries the identical thing, and a
|
||||
suggestion invented for a failure nobody understands is a guess wearing the
|
||||
application's authority.
|
||||
|
||||
**A tool's parameter descriptions are instructions, and terse ones are why a
|
||||
model sends only the prompt.** "cfg: prompt adherence, default 8" tells a model
|
||||
nothing it can act on. Measured against a 4B model on the same request: with the
|
||||
terse descriptions it sent `prompt` and `template` and nothing else — meaning
|
||||
512x512 defaults on an SDXL checkpoint, which is precisely the duplicated-limbs
|
||||
failure the width description now warns about. With descriptions that say what
|
||||
each value *does to the picture* and when to move it, the same model sent a
|
||||
portrait 1024x1536 and a deliberate sampler. It costs ~3KB of schema per request
|
||||
in a chat that can draw, and it is the difference between having ten parameters
|
||||
and having one. `docs/image-generation-instructions.md` is the long version, to
|
||||
paste into the admin instructions box for models that need more than the harness
|
||||
can afford to carry.
|
||||
|
||||
**Preserve VRAM unloads the chat's own connection and nothing else.**
|
||||
`Connection.unload_url` is a column because the memory being freed belongs to one
|
||||
machine: a local llama-swap answers `GET /unload`, and a box on the network has
|
||||
|
||||
Reference in New Issue
Block a user