Conversation
When the uncached prompts are split into more than one batch, each chunk is already saved to the cache inside the loop. The save block after the if/else then ran again for every path and zipped all uncached prompts with `responses`, which at that point only holds the last chunk's responses. The first len(last_chunk) prompts were overwritten in the cache with other prompts' completions, so later cached runs returned the wrong answers. Move that save block into the single-batch branch so each path saves its responses exactly once. Add offline tests with a fake Anthropic batch call that check a fresh BatchInferenceAPI reads back each prompt's own completion, for both a single batch and chunk=2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When
BatchInferenceAPI.__call__splits the uncached prompts into more than one batch, the responses returned by that call are correct, but the cache gets corrupted: the firstlen(last_chunk)uncached prompts are saved with the last chunk's completions. Any later run that hits the cache silently returns another prompt's answer.It happens whenever the uncached prompts end up in more than one batch, e.g.
chunksmaller than the number of uncached prompts, more than 100k prompts / 250MB for Anthropic, or more than 50k prompts for OpenAI.Cause
The multi-chunk branch already saves each chunk inside its loop. The "Save responses to cache" block after the
if/elsethen ran again for both paths withzip(uncached_prompts, responses), and in the multi-chunk pathresponsesis the loop variable left over from the last chunk. This came in with #38 (Redis caching), which merged the tails of the two branches; before that, the single-batch branch had its own save and the multi-chunk branch returned early.Repro (no API calls)
On
main(library prints omitted):With this PR the cached run returns
['Say 0', 'Say 1', 'Say 2', 'Say 3'].Fix
Move the post-loop save back into the single-batch
elsebranch, so each path saves its responses exactly once. The multi-chunk path keeps its per-chunk save, which pairs each chunk's prompts with that chunk's responses. As a side effect the multi-chunk path no longer rewrites part of the cache a second time.Tests
New offline
tests/test_batch_api_cache.py(kept out of the slow, real-APItests/test_batch_api.py): a fake_anthropic_batch, then a freshBatchInferenceAPIhas to read every prompt's own completion back from the cache, forsingle_batchandtwo_chunks. Thetwo_chunkscase fails onmainas above; thesingle_batchcase guards the moved block.pytest tests/test_batch_api_cache.py: 2 passedpytest -n 6without API keys: the only failures are the same 8 key-requiring tests as onmainruff check .(0.9.0) andblack --check .(24.10.0): cleanCaches written by earlier multi-chunk runs may already contain wrong entries; those need to be cleared (or a new
seedused), this PR doesn't repair them.Separate from this, and not changed here: for non-Anthropic models
__call__never copiesmax_tokensintokwargs, so the OpenAI batch body getsmax_tokens: nulland the cache key'smax_tokensis alwaysNone. Fixing that changes cache keys, so I'd rather do it in its own PR if you want it.