VeOmni Fused Attention Interface#
VeOmni registers sequence-parallel FlashAttention and FlexAttention adapters in
Transformers’ ALL_ATTENTION_FUNCTIONS registry. Models continue to select an
attention implementation through config._attn_implementation; VeOmni’s
registered names all enter one model-facing facade and then dispatch to a
backend-specific adapter.
Configuration#
The ops configuration selects FlexAttention only after the model has been integrated with the Transformers attention and mask registries. Changing this value alone does not make an arbitrary model FlexAttention-compatible:
model:
ops_implementation:
attn_implementation: flex_attention
The model must call the attention implementation selected by
config._attn_implementation and must supply a native BlockMask whose
predicate preserves all model-specific visibility rules. A model that
hard-codes SDPA/FlashAttention, constructs only dense masks, or bypasses
Transformers’ mask registry needs model-level patchgen adaptation first.
With MODELING_BACKEND=veomni, OpsImplementationConfig rewrites this public
value to veomni_flex_attention_with_sp. Flash values are rewritten in the
same way:
Public value |
VeOmni registry name |
|---|---|
|
|
|
|
|
|
|
|
The native Transformers flex_attention registry entry is left unchanged.
Only the VeOmni-specific name routes through VeOmni’s SP-aware facade.
Dispatch and backend adapters#
The model-facing call path is:
ALL_ATTENTION_FUNCTIONS[config._attn_implementation]
-> fused_attention_forward(...)
-> flash_attention_forward(...)
-> flex_attention_forward(...)
The facade resolves only VeOmni’s private dispatch table; it does not look the
name up in ALL_ATTENTION_FUNCTIONS again. This avoids recursive dispatch and
keeps the Flash and Flex adapters independently testable.
The backend compute functions are replaceable module-level slots:
attention.flash._flash_attention_forward, defaulting to Transformers’_flash_attention_forward;attention.flex._flex_attention_forward, defaulting to Transformers’flex_attention_forward.
All three public callables use the Transformers attention-forward convention.
Q/K/V inputs use [batch, heads, sequence, head_dim]; the returned attention
output uses [batch, sequence, heads, head_dim].
FlexAttention mask contract#
flex_attention_forward requires a native
torch.nn.attention.flex_attention.BlockMask. The model owns visibility
semantics and BlockMask construction; the generic op does not convert a dense
mask or construct model-specific visibility rules.
Transformers models may pass sliding_window metadata alongside a native
BlockMask whose predicate already encodes the window. The adapter accepts but
does not use that integer metadata to reconstruct or alter visibility; the
supplied BlockMask remains the sole mask authority. Calls without a native
BlockMask are rejected. Dropout and remaining kernel validation are delegated
to the pinned Transformers/PyTorch FlexAttention adapter.
Integrating a new patchgen model#
Before enabling attn_implementation: flex_attention for a new model:
Inspect the pinned Transformers modeling source. Its attention layer must dispatch through
ALL_ATTENTION_FUNCTIONSusingconfig._attn_implementation, and its mask preparation must select the matching builder fromALL_MASK_ATTENTION_FUNCTIONS. Add narrow patchgen overrides when either path is hard-coded.Preserve the model’s complete visibility contract in a native
BlockMask. Full attention, sliding windows, bidirectional regions, packed-sample boundaries, prefix rules, and cache offsets remain model-owned semantics; the generic VeOmni FlexAttention adapter does not recreate them.If VeOmni packing or Ulysses changes the mask inputs, replace the relevant Transformers mask-helper imports in the patchgen config and pass the required metadata through the generated model forward. Packed boundaries must be prepared before model forward from full, unsliced sequence metadata; do not recompute them inside attention layers after SP slicing. Self- attention may use one boundary vector for both query and key visibility, while asymmetric attention must forward every Q/K boundary input its mask helper requires. Do not edit the generated modeling file directly.
Register the generated class in
MODELING_REGISTRYunder the exact configmodel_type. If the integration adds a custom config or processor, register those inMODEL_CONFIG_REGISTRYandMODEL_PROCESSOR_REGISTRYas well. Import the model package fromveomni.models.transformersso every module-level registration runs at import time.Regenerate with
patchgen ... --diff -v, review the generated output, runpatchgen --check, and add model-level tests for registry routing, native BlockMask type/visibility, forward/backward parity, packing, and Ulysses where supported.
Gemma 3 is the concrete reference in this repository. Its patchgen config
replaces the upstream causal/sliding mask-helper imports with VeOmni wrappers
and overrides Gemma3TextModel.forward so cu_seq_lens_q reaches mask
construction. Gemma 3 uses self-attention, so that one packed-boundary vector
defines both query and key sample membership. The resulting full/sliding
BlockMask objects still come from the model’s native visibility rules; only
after that adaptation does the flex_attention ops setting select the VeOmni
backend.
See Modeling Code Generation for the complete patchgen generation and drift-check workflow.
Ulysses sequence parallelism#
When Ulysses is active, both backend adapters use the same transport helpers:
exchange local-sequence/global-head Q/K/V into full-sequence/local-head tensors;
execute the selected attention backend;
exchange the output back to local-sequence/global-head layout.
The helpers preserve the existing FlashAttention GQA/KV-head repeat behavior.
FlexAttention additionally restores its log-sum-exp tensor and slices a global
one-dimensional s_aux tensor to the rank-local query heads.
FlexAttention with Ulysses currently requires a head-broadcast BlockMask
(BlockMask.shape[1] == 1). Local head indices restart at zero on every rank;
a head-specific BlockMask would require rank-aware block slicing and global
head-index rebasing. The adapter rejects such a mask instead of silently
applying the wrong head visibility.
Pass skip_ulysses=True for a submodule that must execute independently of the
active Ulysses group.
Scope#
This interface consumes model-provided masks and transports attention tensors. It does not define model-specific masking, data preprocessing, trainer scheduling, or FSDP policy.