Repository navigation
fix: KV-cache generation at batch size >= 2 (#164) - #187
Merged
Merged
Conversation
The exported graph ties position_ids' batch dim to input_ids'. Prefill passed position_ids [1, S] and decode [1, 1], and decode fed the [B] sampled tokens as [1, B]. Prefill now builds [B, S] positions, decode [B, 1] positions and a [B, 1] token input. Adds tests/test_kv_cache_batch.py: greedy KV-cache generation matches HF at B=1 and B=2 (GPU only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 23, 2026
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.
Background
With the KV cache on,
Optimus_Inference.generatecrashed for batch size >= 2 (#164). The torch.export graph ties the batch dim ofposition_idsto that ofinput_ids, but prefill passedposition_ids[1, S], decode passed [1, 1], and decode fed the [B] sampled tokens as [1, B] (unsqueeze(0)).Changes
opt_prime/opt_prime/schedule_infer.pyScheduleGeneration.prefill: defaultposition_idsarearange(S)expanded to [B, S] (docstring updated).opt_prime/opt_prime/schedule_infer.pyScheduleGeneration.decode_step:position_idsare [B, 1] (torch.full) instead of[[position]].opt_prime/opt_prime/inference.pydecode loop (was :1060): token input isnext_token.reshape(-1, 1)([B, 1]); replaces three lines ofunsqueeze(0)handling.opt_prime/tests/test_kv_cache_batch.py: tiny random Llama (sdpa), greedy, 5 new tokens, KV cache on, export path (dynamo_capture=True); output must equal HFgenerateexactly for B=1 and B=2. Skipped without CUDA.Verification
Environment: Python 3.10, torch 2.10.0+cu128, transformers 5.1.0, one A100 80GB (
CUDA_VISIBLE_DEVICES=1). Base: optimus-rm @253be20.1 failed, 1 passed. B=1 passes; B=2 fails in prefill withRuntimeError: The expanded size of the tensor (2) must match the existing size (4) at non-singleton dimension 1. Target sizes: [1, 2, 2, 6, 16].Target sizes: [1, 2, 2, 1, 16]), so the decodeposition_idschange is needed.2 passed.Full suite (
cd opt_prime && TORCH_DEVICE_BACKEND_AUTOLOAD=0 CUDA_VISIBLE_DEVICES=1 PYTHONPATH=$PWD python3 -m pytest -q tests):400 passed, 23 skipped, 135 subtests passed402 passed, 23 skipped, 135 subtests passedCompatibility and limits
position_idstoprefillmust now pass [B, S] for B >= 2 (the docstring said [1, S]); in-tree callers pass none.torch.zeros(1)) is untouched.arange(S)for every row, as before.Related Issue
Closes #164
🤖 Generated with Claude Code