AI-assisted coordination disclosure: This proposal was developed with AI assistance after three days of implementation, testing, benchmarking, and human review in our Cohere Arabic batch-inference project. I am opening this issue first to follow the repository's agentic-contribution policy and will wait for maintainer approval before opening a PR.
Summary
CohereAsrDecoder.forward() currently applies its encoder-to-decoder projection on every autoregressive decoder call. During cached generation, each decoder layer stores its encoder K/V states after prefill, so later steps do not consume the projected encoder values; they only need source-shape and mask metadata.
Would you accept a scoped Cohere ASR change that applies the projection only while at least one cross-attention cache layer is uninitialized?
Proposed behavior
- Preserve the current projection for training, direct forwards,
use_cache=False, fresh caches, and partially initialized caches.
- Once every
EncoderDecoderCache.is_updated[layer_idx] is true, skip the shared projection.
- Use the cached first-layer K tensor as zero-copy mask metadata so source length and projected/KV dtype remain consistent under mixed precision.
- Add no public API and no mutable module-level memoization.
This uses the existing cache lifecycle, so independent calls, beam cache reordering, external encoder_outputs, compilation, and device maps do not share retained state.
Evidence
On the current tiny test model, five generated tokens invoke decoder.proj five times today. All cross-attention layers report initialized immediately after prefill. With deliberately different encoder/decoder widths (24 -> 16), skipping the projection on a cached step was bit-exact (max_abs_diff=0.0).
Our production implementation has used equivalent one-projection-per-decode behavior in AliOsm/cohere-transcribe-arabic-batch-inference.
Matched 500-clip ablation (RTX 3060 12 GB, BF16, batch 24, 5,032.699 seconds Arabic audio, max_new_tokens=445):
| Configuration |
Wall |
Generation |
Outputs changed |
| Stock repeated projection |
61.208 s |
38.677 s |
baseline |
| One projection per decode |
59.603 s |
37.034 s |
0 / 500 |
| Single-run change |
-2.62% |
-4.25% |
none |
This table is a matched single-run production observation of the deployed wrapper, not a claim of statistically stable speedup. The proposed PR will include repeated measurements of the exact upstream diff.
Validation plan
Add targeted projection-call-count tests for greedy and beam generation, cache-disabled and partial-cache coverage, external encoder outputs, padded eager/SDPA parity, mixed precision, compilation, and training gradients. Run the complete Cohere ASR model suite plus repository consistency checks.
I searched open and closed issues/PRs before filing and found no existing implementation. The open Cohere ASR PRs associated with #46894 address an unrelated training-loss bug. #47271 only cites this optimization's production result.
cc @eustlb @Cyrilvallez
AI-assisted coordination disclosure: This proposal was developed with AI assistance after three days of implementation, testing, benchmarking, and human review in our Cohere Arabic batch-inference project. I am opening this issue first to follow the repository's agentic-contribution policy and will wait for maintainer approval before opening a PR.
Summary
CohereAsrDecoder.forward()currently applies its encoder-to-decoder projection on every autoregressive decoder call. During cached generation, each decoder layer stores its encoder K/V states after prefill, so later steps do not consume the projected encoder values; they only need source-shape and mask metadata.Would you accept a scoped Cohere ASR change that applies the projection only while at least one cross-attention cache layer is uninitialized?
Proposed behavior
use_cache=False, fresh caches, and partially initialized caches.EncoderDecoderCache.is_updated[layer_idx]is true, skip the shared projection.This uses the existing cache lifecycle, so independent calls, beam cache reordering, external
encoder_outputs, compilation, and device maps do not share retained state.Evidence
On the current tiny test model, five generated tokens invoke
decoder.projfive times today. All cross-attention layers report initialized immediately after prefill. With deliberately different encoder/decoder widths (24 -> 16), skipping the projection on a cached step was bit-exact (max_abs_diff=0.0).Our production implementation has used equivalent one-projection-per-decode behavior in AliOsm/cohere-transcribe-arabic-batch-inference.
Matched 500-clip ablation (RTX 3060 12 GB, BF16, batch 24, 5,032.699 seconds Arabic audio,
max_new_tokens=445):This table is a matched single-run production observation of the deployed wrapper, not a claim of statistically stable speedup. The proposed PR will include repeated measurements of the exact upstream diff.
Validation plan
Add targeted projection-call-count tests for greedy and beam generation, cache-disabled and partial-cache coverage, external encoder outputs, padded eager/SDPA parity, mixed precision, compilation, and training gradients. Run the complete Cohere ASR model suite plus repository consistency checks.
I searched open and closed issues/PRs before filing and found no existing implementation. The open Cohere ASR PRs associated with #46894 address an unrelated training-loss bug. #47271 only cites this optimization's production result.
cc @eustlb @Cyrilvallez