⚡️ Speed up method BeamSearchDecoder.update by 80% - #2
Open
codeflash-ai[bot] wants to merge 1 commit into
Open
Conversation
Thank you for providing a detailed line profiler report. Most of the CPU time is spent in these "hot spots". - `logprobs[idx].topk(self.beam_size + 1)` (and the nested for loop), - `new_logprob = (sum_logprobs[idx] + logprob).item()` - `sequence = tuple(prefix + [token.item()])` Additional issues. - There is heavy repeated Python looping (instead of batched tensor operations). - Inefficient construction of sequences (list concatenation and then tuple conversion). - Dictionary sorting and key construction is slow. To speed up this beam search decoder, we need to **vectorize** as much of the candidate computation as possible, avoid repeated `.item()` and `tolist()` calls in Python, and batch candidate tracking. Below is a rewritten version that. - **Vectorizes the candidate logprob and topk computations**, - Avoids Python loops for sequence reconstruction as much as possible, - Avoids list/tuple concatenations where possible, - Processes all beams for all audios in batches, not in innermost Python loops, - Keeps finished sequences in the same data structure, but more efficiently. **Key changes:** - Use a single batch `log_softmax` and `topk` for all beams (removes one for-loop entirely). - Batch build the new tokens by "expanding" and appending new candidates with tensor operations. - Use efficient slicing and flattening for candidate management. - Dict-based operations (scoring, finished-completed check) done only per audio, not per candidate. - Eliminated redundant `.tolist()` and `.item()` (now done only when absolutely necessary, e.g., for Python dict key creation). - Reduced the conversion of tensor-to-list-to-tuple in the inner loops. The largest gain is from removing the innermost for-loops and vectorizing the probability+token expansion for all beams in all audios. This should give a significant improvement. --- If you want even more, you can use `NamedTuple` or hashable array types for sequences and more vectorized pruning of finished sequences, but that will require a more thorough refactoring of the API and outside code assumptions. **Let me know if you want deeper C++/Cython-level or further functional refactors!**
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.
📄 80% (0.80x) speedup for
BeamSearchDecoder.updateinwhisper/decoding.py⏱️ Runtime :
214 milliseconds→119 milliseconds(best of56runs)📝 Explanation and details
Thank you for providing a detailed line profiler report. Most of the CPU time is spent in these "hot spots".
logprobs[idx].topk(self.beam_size + 1)(and the nested for loop),new_logprob = (sum_logprobs[idx] + logprob).item()sequence = tuple(prefix + [token.item()])Additional issues.
To speed up this beam search decoder, we need to vectorize as much of the candidate computation as possible, avoid repeated
.item()andtolist()calls in Python, and batch candidate tracking.Below is a rewritten version that.
Key changes:
log_softmaxandtopkfor all beams (removes one for-loop entirely)..tolist()and.item()(now done only when absolutely necessary, e.g., for Python dict key creation).The largest gain is from removing the innermost for-loops and vectorizing the probability+token expansion for all beams in all audios.
This should give a significant improvement.
If you want even more, you can use
NamedTupleor hashable array types for sequences and more vectorized pruning of finished sequences, but that will require a more thorough refactoring of the API and outside code assumptions.Let me know if you want deeper C++/Cython-level or further functional refactors!
✅ Correctness verification report:
🌀 Generated Regression Tests Details
To edit these changes
git checkout codeflash/optimize-BeamSearchDecoder.update-mayrurbjand push.