New Feature: Enabling Speculative Decoding with Batch Size > 1 (If draft and target model share tokenizer)#42655
Conversation
- Add batch speculative decoding functionality for batch_size > 1 - Update candidate generator to handle batch processing - Enhance generation utils with batch speculative decoding support - Add cache utilities for batch speculative decoding - Update tests for batch speculative decoding
4bf1fb8 to
800012c
Compare
|
Hi! Thanks! |
|
@YanivDorGalron hey! Thanks for the PR It is a nice-to-have feature for sure. We have been delaying it since an implementation would be complicated unless we can use a I will definitely take a closer look around this week |
| padding_mask = cache_input_ids[:, :-1] == pad_token_id | ||
| past_key_values.compress_and_repad_cache(padding_mask) | ||
| # 1. Filter out current padding and repad to minimum length. | ||
| next_input_ids_clean = [row[row != pad_token_id] for row in next_input_ids] |
zucchini-nlp
left a comment
There was a problem hiding this comment.
Hey again, sorry for the delay
I get the idea behind and I think it is in a good direction. I liked that we don't pad infinitely and the next input ids are re-padded back. Though the cache logic look more involved as we need to basically re-create a new padded cache each time. I personally prefer to not have more code in cache_utils. Since it is creating new cache from an old, we can separate it out to a helper fn
Given the complexities of the feature and since it wasn't being requested much recently, I suggest us to move it to hub via remote code. Here is more info on custom generate. We can add it in transformers-community org and communicate to users. If the feature gets traction and interest from community, we will consider adding it in core library.
That will help us to make sure that the feature is shipped fast bypassing the review cycle, we can get feedback from community fast. Also it helps to not put maintenance burden for a rarely-used feature. LMK if that sounds good to you and I can help with making a custom generate repo
|
Thanks for your response, that sounds great. If you can create a repo under Looking forward to it! |
|
@YanivDorGalron sure, what is you HF handle? |
|
My HF handle is
|
|
I will ask @ArthurZucker to add, just noticed I am not admin 😄 Most maintainer are now in winter vacations so feel free in the meantime experiment with a repo under your own profile/org. |
|
Relevant paper using unpad-append-repad for batch speculative decoding: https://arxiv.org/pdf/2510.22876 The code is open sourced. May I ask what's the current progress for this PR? |
Hey @WindChimeRan, we have decided to move this code to a custom generate which we will publish on the hub. |
@YanivDorGalron Sure! I'm glad to help! |
What does this PR do?
Many discussions focused on speculative decoding with 'batch_size > 1' (#26875, #29769, #32165, #32189), but none were fully implemented. This PR does that.
Summary of Changes: Enable Batched Speculative Decoding
Until now, invoking
generate()with anassistant_modelraised aValueErrorifbatch_size > 1. This update modifies the codebase to support batched speculative decoding.Key Features & Limitations
batch_size > 1for standard speculative decoding.batch_size = 1and will still raise aValueErrorif used with a batch.Technical Implementation Details
Supporting batches requires dealing with "ragged tensors", where different sequences in a batch accept a different number of speculative tokens, leading to misalignment in tensor shapes and KV caches. The implementation addresses this via the following mechanisms:
1. Assistant Cache Alignment
align_cachefunction was implemented incandidate_generator.py. It identify which parts of the old cache match the new inputs and removing the irrelevant keys and values from the cache. This ensures the assistant's cache correctly reflects the accepted tokens.2. Repadding Inputs and Main Model Cache
3. Vectorized Verification & Sampling
cumsumoperations to identify the index of the first mismatch for every item in the batch simultaneously._speculative_samplinghas been updated to calculate acceptance probabilities (4. Dynamic Heuristics (
update_candidate_strategy)num_assistant_tokens) now aggregates statistics across the batch (e.g., using the average number of matches) to determine if the draft model step size should increase or decrease.Note on
max_new_tokensWhen using speculative decoding with
batch_size > 1, the behavior regardingmax_new_tokensrequires nuance. Because the generation loop serves the entire batch, the process continues until one items satisfy the stopping criteria. However, due to the repadding and varying acceptance rates, other items in the batch may effectively stop generating before reaching the globalmax_new_tokenslimit.Batch Size = 3: Assistant vs Standard Decoding
WITHOUT assistant_model: 9.2215 seconds
WITH assistant_model: 7.4744 seconds
I look forward to your response and comments to ensure this can be included in the next version.