Skip to content

Commit aa58996

Browse files
[Pytorch][Attention][CP][CI] Make 3221 changes robust (#3438)
* Support no-load-balance THD with FlashAttention FlashAttention 2 backward needs zeroed gradient outputs for deterministic grouped-query attention in this path. Permit unpadded FlashAttention backends because inter-sequence padding requires no backend-specific handling, and align the autograd return arity with the forward inputs. Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Clarify no-load-balance backend constraints Document why FA2 initializes backward gradient buffers and why inter-sequence padding remains limited to FusedAttention. This makes the supported backend matrix explicit without changing behavior. Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> * Add no-load-balance FlashAttention regression coverage Reuse the focused CP test across supported FlashAttention generations and force FA2 from L1 in a fresh process. Backend controls are read at import time, so a separate invocation covers deterministic FA2 GQA backward without adding runner plumbing. Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> * Use backend selection for FlashAttention CP test Query the existing backend selector for the exact THD context-parallel configuration instead of duplicating architecture and version gates in pytest. This keeps capability decisions in one place while allowing version-forced test invocations to exercise production selection logic. Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> * Clarify forced FA2 regression coverage Document why the focused deterministic case runs in a fresh process and how the version flags force FA2, while the full runs retain normal backend selection. Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> * Rely on existing L1 attention runs The general context-parallel test is already collected by both L1 attention invocations. Since this suite selects FA2, a separate forced deterministic invocation duplicates coverage without exercising a distinct path. Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> --------- Signed-off-by: Sudhakar Singh <sudhakars@nvidia.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent ace1873 commit aa58996

2 files changed

Lines changed: 29 additions & 12 deletions

File tree

‎tests/pytorch/attention/test_attention_with_cp.py‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -739,12 +739,22 @@ def test_cp_with_fused_attention_no_load_balance(cp_pool):
739739
)
740740

741741

742-
@pytest.mark.skipif(
743-
get_device_compute_capability() != (9, 0) or not FlashAttentionUtils.v3_is_installed,
744-
reason="FlashAttention 3 requires sm90 and an installed FA3 package.",
745-
)
746-
def test_cp_with_flash_attention_3_no_load_balance(cp_pool):
747-
"""Check the supported unpadded FlashAttention 3 path."""
742+
def test_cp_with_flash_attention_no_load_balance(cp_pool):
743+
"""Check the supported unpadded FlashAttention path."""
744+
config = copy.deepcopy(model_configs_flash_attn["cp_2_0"])
745+
config.context_parallel = True
746+
config.cp_comm_type = "all_gather"
747+
config.attn_mask_type = "padding_causal"
748+
available_backends, _, _ = get_available_attention_backends(
749+
config,
750+
qkv_dtype=torch.bfloat16,
751+
qkv_layout="thd_thd_thd",
752+
pad_between_seqs=False,
753+
is_training=True,
754+
deterministic=_deterministic,
755+
)
756+
if not available_backends[0]:
757+
pytest.skip("FlashAttention is unavailable.")
748758
_submit(
749759
cp_pool(2),
750760
dtype="bf16",

‎transformer_engine/pytorch/attention/dot_product_attention/context_parallel.py‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4184,6 +4184,13 @@ def backward(ctx, dout, *_args):
41844184
fa_backward_kwargs["deterministic"] = ctx.deterministic
41854185
if fa_utils.v2_6_0_plus:
41864186
fa_backward_kwargs["softcap"] = 0.0
4187+
if (
4188+
ctx.qkv_format == "thd"
4189+
and ctx.load_balancing_strategy is CPLoadBalancingStrategy.NO_LOAD_BALANCE
4190+
):
4191+
# FA2 GQA backward accumulates into expanded K/V gradient buffers.
4192+
# Initialize them before accumulation in this partitioning path.
4193+
fa_backward_kwargs["zero_tensors"] = True
41874194

41884195
local_seq_chunk_ids = (
41894196
[rank]
@@ -4563,6 +4570,7 @@ def backward(ctx, dout, *_args):
45634570
None,
45644571
None,
45654572
None,
4573+
None,
45664574
)
45674575

45684576

@@ -5452,7 +5460,7 @@ def attn_forward_func_with_cp(
54525460
assigns one contiguous physical-buffer chunk to each rank and uses one attention
54535461
step per rank. Logical sequences remain isolated by ``cu_seqlens``. This strategy
54545462
requires THD, all-gather, causal self-attention without a sliding window, and
5455-
FusedAttention, or FlashAttention 3 with ``pad_between_seqs=False``. Input producers
5463+
FusedAttention, or FlashAttention with ``pad_between_seqs=False``. Input producers
54565464
must use the same strategy when partitioning inputs with
54575465
:func:`get_batch_on_this_cp_rank` or :func:`get_thd_partitioned_indices`.
54585466
@@ -5540,12 +5548,11 @@ def attn_forward_func_with_cp(
55405548
assert (
55415549
cp_comm_type == "all_gather"
55425550
), "No-load-balance THD partitioning requires cp_comm_type='all_gather'."
5551+
# Backend selection is handled by the caller. FlashAttention does not yet
5552+
# support inter-sequence padding with this partitioning strategy.
55435553
assert (
5544-
use_fused_attention or use_flash_attn_3
5545-
), "No-load-balance THD partitioning requires FusedAttention or FlashAttention 3."
5546-
assert not (
5547-
use_flash_attn_3 and pad_between_seqs
5548-
), "No-load-balance THD partitioning with FlashAttention 3 does not support padding yet."
5554+
not pad_between_seqs or use_fused_attention
5555+
), "No-load-balance THD partitioning only supports padding with FusedAttention."
55495556
assert "causal" in attn_mask_type and window_size == (
55505557
-1,
55515558
0,

0 commit comments

Comments
 (0)