Skip to content

Emit bias-aware external-KV (TensorScatter + nonpad_kv_seqlen) attention for float-bias decoders #366

Description

@titaiwangms

Problem

Decoders that require a float additive attention bias — Gemma-4's bidirectional vision-block overlay, and sliding-window / custom-mask models — cannot use com.microsoft.GroupQueryAttention (it accepts only causal/local masking, not an arbitrary attention_bias). mobius therefore emits them with the standard ONNX Attention op, is_causal=0, over an internal dynamic past/present KV cache. With a bias present this routes ORT to the internal-cache MEA path, which the kernel's own source note calls ~15-30% slower than contrib GQA's in-place decode. Today these models give up the decode fast-path entirely.

ORT supports a faster alternative on the SAME standard Attention op: the opset-24 external KV cache (nonpad_kv_seqlen + TensorScatter). On the MEA path it combines additive bias + GQA + external cache and reaches near-contrib-GQA performance — letting a single standard-Attention graph carry the bias during prefill AND hit a near-GQA decode (Flash is precluded by any bias, so MEA-external ≈ GQA is the ceiling).

Mobius-side deliverable (this issue — contract-independent, ORT-testable now)

mobius already emits the maskless external-KV static-cache graph (sibling work #345) and already builds the causal+sliding+Gemma-4 block-overlay bias (create_attention_bias). This issue wires the two together:

  • Thread an optional float bias into the shared static-cache Attention path (_apply_attention), pairing bias-present with is_causal=0 (maskless is_causal=1 stays the default).
  • Add an external-cache bias builder producing a (B,1,S_q,max_seq) additive bias keyed on absolute query positions with KV validity slot < nonpad_kv_seqlen, reusing the proven causal/sliding/block-overlay/padding logic.
  • Flag-gated (MOBIUS_STATIC_CACHE_BIAS, default off).
  • An ORT manual-feed parity test (CPU MEA, no genai, no Flash) vs a dense-attention reference for a prefill chunk and a decode step.
    The bias geometry is a pure function of model semantics + cache layout — independent of how the runtime drives it — so this slice is safe to land before the genai consumer exists.

Acceptance criteria

  • Shared static-cache Attention path honours an optional float bias with is_causal=0; maskless default unchanged.
  • create_static_cache_attention_bias emits the (B,1,S_q,max_seq), slot<nonpad bias (causal + sliding + block-overlay + padding).
  • ORT-level parity test passes on CPU (MEA) for prefill + decode vs a dense reference; matches HF Gemma-4 single-layer attention.
  • Flag-gated, default off; no shipped model's emission changes when off.

Explicitly out of scope (separate follow-ups)

Re-emitting Gemma-4's own decoder task/model on the static path, genai_config.json wiring, single-graph vs prefill/decode-split packaging, and e2e generation/decode profiling.

Relationships

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions