[Perf][B300] Add a group-parallel Taylor-moment scan for Based attention
Problem
BasedLinearAttention is a public layer whose default mode="parallel" path calls parallel_based. The default feature geometry is K=16, 12 heads, and V=64 for a hidden size of 768.
The current kernels in fla/ops/based/parallel.py recompute every causal prefix in forward and dQ backward, and every causal suffix in dK/dV backward. The resulting work is quadratic in sequence length. The repository's fused_chunk_based implementation already demonstrates the exact zero-, first-, and second-order Taylor moments needed to evaluate the same polynomial attention in linear work, but its sequence-serial grid exposes only 24 long-running CTAs for the default B1/H12/K16/V64 shape. That leaves a long-context concurrency problem on a 148-SM B300.
This issue is a performance hypothesis. No speedup is claimed until the profile, correctness, resource, operator, and public-layer gates below pass.
Proposed Scope
Add an exact-SM103, dense, long-context path inside parallel_based that uses the existing Taylor algebra with a group-parallel scan schedule:
- Split the sequence into deterministic coarse groups. The initial proof compares 512- and 1024-token groups at K=16; only measured profitable choices may be retained.
- Compute one additive FP32 summary per
(batch, head, group, value tile), containing the zero-, first-, and second-order denominator and numerator moments.
- Run an exclusive prefix scan over the small group-summary axis, tiled across independent state dimensions.
- Replay each group from its scanned prefix and emit its local causal outputs. The added group grid supplies long-context CTA parallelism without materializing token-by-token states.
- Use the analogous reverse group summaries, exclusive reverse scan, and group-local replay for dQ/dK/dV.
The public signature, score 1 + s + 0.5 * s^2, scale, normalization epsilon, dtype, accumulation policy, and gradients must stay unchanged. The current kernel remains the exact fallback for non-SM103 devices, short sequences, K other than 16, unsupported dtypes/layouts, and any measured losing bucket.
Do not change fla/layers/based.py, fla/ops/based/naive.py, ReBased, generic linear-attention code, cache/state behavior, public APIs, or mathematical semantics. Do not turn this into a generic scan framework or autotuning project.
Memory Bound
The FP32 group-prefix buffer is bounded by:
B * H * NG * (1 + K + K^2) * (1 + V) * 4 bytes.
For B1/H12/T8192/K16/V64 with 512-token groups this is about 13 MiB. Backward may use an equivalently bounded transient reverse buffer. No O(T^2) allocation and no per-token K^2 * V state are allowed.
Fixture-First Correctness Contract
The current tests/ops/test_based.py does not provide a usable oracle: it constructs obsolete head-first public inputs, and its output/gradient assertions are guarded by dtype == torch.float32 even though its parametrized cases are FP16. Before any production edit:
- Make one fixture-only commit that corrects public input layout, transposes only around the head-first naive reference, and actually checks output plus dQ/dK/dV.
- Cover FP16, BF16, and a small FP32 control; K=8/16/32; V=60/64/100/128; T=63/111/257/1024; H=1/4/12; normalization on/off; default and unit scale; non-power-of-two tails; and supported noncontiguous inputs.
- Add a small
BasedLinearAttention(mode="parallel") oracle using the shipped scale=1 behavior and the same projected q/k/v weights. Do not use or repair the pre-existing forward_reference semantic mismatch in this performance issue.
- Establish all dtype-specific tolerances against untouched production, record the fixture commit as
BENCH_BASE, then freeze the test, reference, seeds, inputs, dtypes, numeric flags, and tolerances for the complete optimization loop.
Allocator NaN poisoning remains enabled. If untouched production fails the corrected fixture deterministically, stop and record no-go; do not repair semantics or relax the oracle in this issue.
Promotion requires the complete frozen tests/ops/test_based.py, all tests returned by scripts/find_dependent_tests.py, changed-file lint/header/syntax checks, int64 pointer/grid arithmetic review, and the repository block-pointer ban. Dense is the applicable layout; parallel_based has no varlen/state/cache API.
Profile-First and Staged Proof
On untouched B300 production, profile both the direct operator and public BasedLinearAttention(hidden_size=768, feature_dim=16, num_heads=12, mode="parallel") at B1/H12/K16/V64/T4096 and T8192.
Stop before production work unless the Based kernels are at least 30% of public-layer CUDA time at a representative long endpoint and the measured Amdahl bound can support at least a 10% layer gain.
The first production proof is forward-only at B1/H12/K16/V64/T4096:
- Compile and time the complete summary + scan + apply sequence, including workspace allocation.
- Require at least 1.30x over the current forward kernel before implementing backward.
- Stop on frozen-oracle failure, compile/resource failure, workspace above the analytic bound, local-memory spill or occupancy collapse, or a stage sum that misses the proof threshold.
Only after this proof passes may the reverse summaries/scan/local backward be implemented. Correctness-green representative performance shortfalls use at most two reviewer-approved bounded depth iterations, with all original gates unchanged.
Representative Benchmarks
Add one isolated parallel_based OpConfig in benchmarks/ops/registry.py in the fixture commit. It may add only this operator and its shapes; it must not change runner behavior, generic registry schema, input-distribution infrastructure, or absorb work from upstream PR fla-org#1144.
Primary BF16 and FP16 shapes:
- B1/H12/K16/V64, T=128/256/2048/4096/8192/16384
- B1/H12/K16/V128, T=4096/8192
- B4/H12/K16/V64, T=2048/4096
- H4 and T=4097 controls
Use the repository-native commands with the immutable fixture commit as the comparison base:
python -m benchmarks.ops.verify --op parallel_based --base <BENCH_BASE> --modes fwd fwdbwd
python -m benchmarks.ops.run --op parallel_based --base <BENCH_BASE> --modes fwd fwdbwd --json <artifact>
Measure the public Based layer separately with an ignored deterministic harness at B1/B4 and T=2048/4096/8192. The repository has no Based pretrained model, so the public layer is the integration endpoint and no model-level claim should be made.
Compare baseline and candidate in the same isolated B300 allocation with identical inputs, environment, warmup, clocks, and repetitions. Use at least three alternating complete runs and report every retained row with median and p20/p80. NCU full/source reports must compare the current kernels against the sum of all new stages, including DRAM/L2 traffic, tensor-pipe utilization, achieved occupancy, active/eligible warps, registers, spills, waves, and source stalls.
Acceptance Gates
- Frozen output and all-gradient correctness passes without tolerance, reference, precision, or numeric-flag changes.
- Direct default B1/H12/K16/V64 reaches at least 1.50x forward and 1.30x forward+backward at both T4096 and T8192.
- Equal-weight geomean over retained long T=2048/4096/8192/16384 and V64/V128 shapes is at least 1.30x in both modes.
- Public Based layer forward+backward reaches at least 1.10x at T4096 and T8192 and at least 1.05x geomean over T2048/4096/8192.
- No retained target or fallback median regresses more than 3%; short T128/256 fallback remains within 2% noise.
- Measured workspace matches the analytic bound, and NCU attributes the result to eliminated quadratic prefix/suffix work plus useful group concurrency without material spill or skipped work.
If these gates require a one-off shape lookup, changed semantics/precision, broader architecture or module scope, or a benchmark-only result, record no-go rather than widening the issue.
Expected Files
fla/ops/based/parallel.py
tests/ops/test_based.py in the fixture-only commit, then frozen
benchmarks/ops/registry.py for one isolated repository-native operator registration
Upstream PR fla-org#1144 currently edits generic registry input-profile plumbing but does not add Based coverage or touch the production/test files above. Treat this as a mechanical rebase risk: if it lands, rebase the isolated registration onto its schema and rerun the frozen gates; do not overwrite or incorporate its distribution changes.
Duplicate Audit
As of the baseline audit, no open upstream PR or issue and no fork issue implements group-parallel Based Taylor moments or touches fla/ops/based/parallel.py / tests/ops/test_based.py. Open issues fla-org#117, fla-org#229, and fla-org#411 concern generic autotuning, chunk API unification, and different blockwise masking semantics respectively. Existing fused_chunk_based supplies mathematical precedent but not this long-context group-parallel schedule.
Baseline: upstream/main@27967b970eaaf982a6960abf6cba8add9c34c7cc.
[Perf][B300] Add a group-parallel Taylor-moment scan for Based attention
Problem
BasedLinearAttentionis a public layer whose defaultmode="parallel"path callsparallel_based. The default feature geometry isK=16, 12 heads, andV=64for a hidden size of 768.The current kernels in
fla/ops/based/parallel.pyrecompute every causal prefix in forward and dQ backward, and every causal suffix in dK/dV backward. The resulting work is quadratic in sequence length. The repository'sfused_chunk_basedimplementation already demonstrates the exact zero-, first-, and second-order Taylor moments needed to evaluate the same polynomial attention in linear work, but its sequence-serial grid exposes only 24 long-running CTAs for the default B1/H12/K16/V64 shape. That leaves a long-context concurrency problem on a 148-SM B300.This issue is a performance hypothesis. No speedup is claimed until the profile, correctness, resource, operator, and public-layer gates below pass.
Proposed Scope
Add an exact-SM103, dense, long-context path inside
parallel_basedthat uses the existing Taylor algebra with a group-parallel scan schedule:(batch, head, group, value tile), containing the zero-, first-, and second-order denominator and numerator moments.The public signature, score
1 + s + 0.5 * s^2, scale, normalization epsilon, dtype, accumulation policy, and gradients must stay unchanged. The current kernel remains the exact fallback for non-SM103 devices, short sequences, K other than 16, unsupported dtypes/layouts, and any measured losing bucket.Do not change
fla/layers/based.py,fla/ops/based/naive.py, ReBased, generic linear-attention code, cache/state behavior, public APIs, or mathematical semantics. Do not turn this into a generic scan framework or autotuning project.Memory Bound
The FP32 group-prefix buffer is bounded by:
B * H * NG * (1 + K + K^2) * (1 + V) * 4bytes.For B1/H12/T8192/K16/V64 with 512-token groups this is about 13 MiB. Backward may use an equivalently bounded transient reverse buffer. No
O(T^2)allocation and no per-tokenK^2 * Vstate are allowed.Fixture-First Correctness Contract
The current
tests/ops/test_based.pydoes not provide a usable oracle: it constructs obsolete head-first public inputs, and its output/gradient assertions are guarded bydtype == torch.float32even though its parametrized cases are FP16. Before any production edit:BasedLinearAttention(mode="parallel")oracle using the shippedscale=1behavior and the same projected q/k/v weights. Do not use or repair the pre-existingforward_referencesemantic mismatch in this performance issue.BENCH_BASE, then freeze the test, reference, seeds, inputs, dtypes, numeric flags, and tolerances for the complete optimization loop.Allocator NaN poisoning remains enabled. If untouched production fails the corrected fixture deterministically, stop and record no-go; do not repair semantics or relax the oracle in this issue.
Promotion requires the complete frozen
tests/ops/test_based.py, all tests returned byscripts/find_dependent_tests.py, changed-file lint/header/syntax checks, int64 pointer/grid arithmetic review, and the repository block-pointer ban. Dense is the applicable layout;parallel_basedhas no varlen/state/cache API.Profile-First and Staged Proof
On untouched B300 production, profile both the direct operator and public
BasedLinearAttention(hidden_size=768, feature_dim=16, num_heads=12, mode="parallel")at B1/H12/K16/V64/T4096 and T8192.Stop before production work unless the Based kernels are at least 30% of public-layer CUDA time at a representative long endpoint and the measured Amdahl bound can support at least a 10% layer gain.
The first production proof is forward-only at B1/H12/K16/V64/T4096:
Only after this proof passes may the reverse summaries/scan/local backward be implemented. Correctness-green representative performance shortfalls use at most two reviewer-approved bounded depth iterations, with all original gates unchanged.
Representative Benchmarks
Add one isolated
parallel_basedOpConfiginbenchmarks/ops/registry.pyin the fixture commit. It may add only this operator and its shapes; it must not change runner behavior, generic registry schema, input-distribution infrastructure, or absorb work from upstream PR fla-org#1144.Primary BF16 and FP16 shapes:
Use the repository-native commands with the immutable fixture commit as the comparison base:
Measure the public Based layer separately with an ignored deterministic harness at B1/B4 and T=2048/4096/8192. The repository has no Based pretrained model, so the public layer is the integration endpoint and no model-level claim should be made.
Compare baseline and candidate in the same isolated B300 allocation with identical inputs, environment, warmup, clocks, and repetitions. Use at least three alternating complete runs and report every retained row with median and p20/p80. NCU full/source reports must compare the current kernels against the sum of all new stages, including DRAM/L2 traffic, tensor-pipe utilization, achieved occupancy, active/eligible warps, registers, spills, waves, and source stalls.
Acceptance Gates
If these gates require a one-off shape lookup, changed semantics/precision, broader architecture or module scope, or a benchmark-only result, record no-go rather than widening the issue.
Expected Files
fla/ops/based/parallel.pytests/ops/test_based.pyin the fixture-only commit, then frozenbenchmarks/ops/registry.pyfor one isolated repository-native operator registrationUpstream PR fla-org#1144 currently edits generic registry input-profile plumbing but does not add Based coverage or touch the production/test files above. Treat this as a mechanical rebase risk: if it lands, rebase the isolated registration onto its schema and rerun the frozen gates; do not overwrite or incorporate its distribution changes.
Duplicate Audit
As of the baseline audit, no open upstream PR or issue and no fork issue implements group-parallel Based Taylor moments or touches
fla/ops/based/parallel.py/tests/ops/test_based.py. Open issues fla-org#117, fla-org#229, and fla-org#411 concern generic autotuning, chunk API unification, and different blockwise masking semantics respectively. Existingfused_chunk_basedsupplies mathematical precedent but not this long-context group-parallel schedule.Baseline:
upstream/main@27967b970eaaf982a6960abf6cba8add9c34c7cc.