huggingface/transformers · error · RuntimeError
Once the sliding window size has been reached, `DynamicSlidi
Error message
Once the sliding window size has been reached, `DynamicSlidingWindowLayer` can only be cropped by passing a negative int, to specify how many tokens to remove
What it means
Raised by DynamicSlidingWindowLayer.crop when the sliding window is full and tokens_to_remove is strictly positive. In the pre-window regime crop(n) means 'keep n tokens' (standard DynamicCache semantics); once the window is full that meaning is invalid — removal is specified with a negative count. The full-cache branch only accepts tokens_to_remove <= 0 (0 compacts to the minimal working size, negative values drop that many tokens).
Source
Thrown at src/transformers/cache_utils.py:298
"""Return the maximum cache shape of the cache"""
return self.sliding_window
@deprecate_kwarg("max_length", new_name="tokens_to_remove", version="5.18")
def crop(self, tokens_to_remove: int) -> None:
"""
Remove `tokens_to_remove` tokens from the current cache layer. This will also restrict the size of the cached states back to their
minimal working size, i.e. `sliding_window - 1` if they reached the sliding window length. This means that `crop(0)` will not
necessarily always be a no-op, as it may still remove useless states (i.e. states that are not needed for the next `forward`).
"""
# If we are beyond the sliding window, we need to be more careful
if self.get_seq_length() >= self.sliding_window:
if not self.record_past:
raise RuntimeError(
"`crop` was called, but the current layer does not track past states, and the sliding window size was already "
"reached. Call `activate_past_recording` before `crop` to be able to rollback the cache."
)
if tokens_to_remove > 0:
raise RuntimeError(
"Once the sliding window size has been reached, `DynamicSlidingWindowLayer` can only be cropped by passing a "
"negative int, to specify how many tokens to remove"
)
# In this case, simply restrict the size back to sliding window without cropping
if tokens_to_remove == 0:
self.keys = self.keys[:, :, -self.sliding_window + 1 :, :]
self.values = self.values[:, :, -self.sliding_window + 1 :, :]
# In this case, we crop and restrict the size back to the sliding window if still larger
else:
tokens_to_remove = abs(tokens_to_remove)
self.keys = self.keys[:, :, -self.sliding_window + 1 - tokens_to_remove : -tokens_to_remove, :]
self.values = self.values[:, :, -self.sliding_window + 1 - tokens_to_remove : -tokens_to_remove, :]
self.cumulative_length = self.cumulative_length - tokens_to_remove
# If we did not reach the sliding window, we can do the same as for a full attention layer
else:
super().crop(tokens_to_remove)
self.cumulative_length = self.keys.shape[-2]View on GitHub (pinned to a597f97485)
Solutions
- Once the window is full, pass a negative count: cache.crop(-n) removes n tokens
- Use cache.crop(0) to compact back to the minimal working size (sliding_window - 1 tokens) without removing anything
- Branch on cache.get_seq_length() >= layer.sliding_window to choose the sign convention
Example fix
# before (window already full) cache.crop(5) # positive -> RuntimeError # after cache.crop(-5) # remove 5 tokens cache.crop(0) # or just compact to minimal working size
Defensive patterns
Strategy: validation
Validate before calling
if cache.get_seq_length() >= layer_sliding_window:
to_remove = -num_tokens_to_drop # negative in the full-window regime
else:
to_remove = keep_length # pre-window: crop-to-length semantics
cache.crop(to_remove) Prevention
- Learn the two crop regimes: pre-window crop(n) keeps n tokens; full-window crop(-n) drops n
- Branch on get_seq_length() vs sliding_window before calling crop
- Prefer cache.crop(0) for compaction after the window fills
When it happens
Trigger: Calling cache.crop(k) with k > 0 after the layer's sequence length has reached sliding_window — e.g. generate() internals or user code applying prefill-style crop semantics (crop(past_length - keep_length)) to an already-full sliding layer.
Common situations: Porting manual cache-management code written for DynamicCache to a sliding-window DynamicCache; beam-search / assisted-decoding helpers that call crop with positive keep-lengths; version upgrades where the crop contract changed to support sliding windows.
Related errors
- `crop` was called, but the current layer does not track past
- `crop` was called, but the current layer does not track past
- `QuantizedCache` is only supported for models with only full
- Invalid `cache_implementation` ({}). Choose one of: {}
- Passing both `cache_implementation` (used to initialize cert
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/ce3eb4c0cad95bd3.
Report an issue: GitHub.