Skip to content

Avoid repeated Cohere ASR encoder projection during cached generation #47272

Description

@AliOsm

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions