ocr: resumption must respect the context window, and never extend a loop (v0.3.50)
Two defects that a throughput collapse on a live install made visible. With
surya_max_tokens raised to 12288, 262 resumption segments spent 1.6M generated
tokens in 80 minutes, 122 of them running the full cap dry, while 253 of those
262 ended in "came back repeating itself".
Resumption re-sends the text so far as INPUT, so the model's context window --
not the continuation budget -- is the real ceiling. The budget did not know
that: at a 12288-token cap, the third segment of a page asked for 12288 more on
top of ~28,500 already in a 32,768-token window and was rejected outright. The
page was then reported as one that could not be resumed AT ALL, discarding text
already paid for.
- surya_context_tokens, or 0 to read the server's own max_model_len from
/v1/models. Configuration wins: an operator may serve a shorter window than
the checkpoint advertises.
- Each segment asks for the smaller of the cap and the room left, measured
from what the server said the prompt cost (usage.prompt_tokens), not
guessed; the guess covers the first resumption only.
- Out of room stops, KEEPS what it has, and says so -- naming the fix that
helps, which is a SMALLER max_tokens, not a bigger budget.
- A refusal for length is not retried: the fallback resumption adds a user
turn, so it is longer than the request just refused.
- Not knowing the window changes nothing and guesses nothing.
The second defect: a reply that trips surya's repeat detector hit the cap
because it is LOOPING, not because the page is long. Resuming it can only
extend the loop, and surya re-runs the whole page anyway -- so one page on that
path cost four full generations. It is no longer resumed, and it is not marked
truncated either: that is surya's retry to make, and "truncated" would send the
caller looking for a bigger budget it cannot use.
A fixed token cap is also an accidental repetition circuit-breaker, which is
why raising it slowed the LOOPING pages by the ratio of the caps rather than
every page. Documented in docs/ocr.md with the window arithmetic (2048 -> ~13
segments, 12288 -> 2).
Tests: 8 new (window clamp, stop-one-segment-early, length refusal not
retried, unknown window, configuration over server, a cap below the 256-token
floor is never mistaken for a full window, a looping reply is not resumed, a
genuinely long page still is). 62 pass in the surya/blank-page suites; the
floor-versus-cap bug was caught by the existing 44.
Co-Authored-By:
Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PxYHWbCAjjjD7A1rhFKtaW
Showing
This diff is collapsed.
This diff is collapsed.
Please
register
or
sign in
to comment