Skip to content

Commit 1ae9653

Browse files
committed
change attention dir and add ring-attem docs
1 parent 986a9e7 commit 1ae9653

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

fastvideo/attention/AGENTS.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ Backend registry + selector wrapping FlashAttn / SageAttn / SageAttn3 / SDPA / V
1010
attention/
1111
├── __init__.py # Exports DistributedAttention, LocalAttention, get_attn_backend
1212
├── layer.py # DistributedAttention, DistributedAttention_VSA, LocalAttention
13+
├── ring_attention.py # RingAttention: owns every Ring/USP-specific decision (see below)
1314
├── selector.py # get_attn_backend (cached) + _component_attention_backend_scope
15+
├── ring/ # Vendored Ring FlashAttention kernel (ring_flash_attn_func)
1416
├── backends/
1517
│ ├── abstract.py # AttentionBackend / AttentionMetadata / AttentionMetadataBuilder
1618
│ ├── flash_attn.py # FA2/FA3
@@ -97,6 +99,35 @@ config. Thread the request alongside that tuple, one model family at a time —
9799
Wan, LTX-2 and Kandinsky5 first, since those carry per-role requests — and the
98100
scope goes away when the last family lands. Do not build on it.
99101

102+
## Ring Attention / USP Ownership Boundary
103+
104+
Ring Attention (and its Ring+Ulysses/USP hybrid) is a second delegate on
105+
`DistributedAttention`, with the same shape as `self.attn_impl`:
106+
107+
- `DistributedAttention` reads only `get_ring_size()`, and only to fail loudly
108+
if a subclass overrides `forward()` wholesale (e.g. `DistributedAttention_VSA`)
109+
without wiring in the Ring dispatch. Everything else about Ring — reading
110+
the process-wide topology, the Ulysses-within-ring all-to-all, Ring-local
111+
RoPE slicing, construction-time validation, and the direct call into the
112+
vendored Ring FlashAttention kernel (bypassing `self.attn_impl` /
113+
`AttentionBackend` entirely, since Ring picks *which* backend runs per
114+
shard rather than being one) — lives in `RingAttention`
115+
(`ring_attention.py`). `DistributedAttention.forward()` dispatches to
116+
`self._ring_attention.forward(...)` when Ring is enabled, exactly the way
117+
it dispatches to `self.attn_impl.forward(...)` otherwise.
118+
- The Ring x Ulysses topology itself (deriving ring/ulysses sizes from
119+
`sp_size`, the pure-Ring / pure-Ulysses degenerate cases, building the 2D
120+
mesh of subgroups) is policy owned by `fastvideo/distributed/usp_topology.py`,
121+
not `parallel_state.py`. `parallel_state.py` calls
122+
`build_usp_topology()` once from `initialize_model_parallel()` and stores
123+
the resulting `USPTopology`, then hands out thin accessors
124+
(`get_ring_group()`, `get_ulysses_group()`, `get_ring_rank()`, ...) the same
125+
way it does for `_TP`/`_SP`/`_DP` — it stays a process-group registry, not a
126+
sequence-parallel policy module.
127+
128+
A new Ring/USP-specific decision belongs in `RingAttention` or
129+
`usp_topology.py`, not back in `layer.py` or `parallel_state.py`.
130+
100131
## Adding a Backend
101132

102133
1. Subclass `AttentionBackend` in `backends/<name>.py`.

0 commit comments

Comments
 (0)