@@ -672,14 +672,6 @@ def _z_layout_to_qkvzba_kernel(
672672 tl .store (d_qkvzba_ptrs , dgate_val , mask = s_mask [:, None ])
673673
674674
675- @triton .autotune (
676- configs = _g_beta_autotune_configs (),
677- key = ["seq_len" , "num_v_heads" ],
678- # Each autotune trial atomic-adds partial sums into these accumulators.
679- # Without reset_to_zero the trials would stack on top of one another and
680- # produce values that are ``num_trials`` × the correct result.
681- reset_to_zero = ["d_A_log_ptr" , "d_dt_bias_ptr" ],
682- )
683675@triton .jit
684676def _g_beta_backward_kernel (
685677 qkvzba_ptr ,
@@ -721,8 +713,8 @@ def _g_beta_backward_kernel(
721713 d_A_log[h] = Σ_{b,s} d_g[b,s,h] * g[b,s,h]
722714
723715 ``d_alpha`` and ``d_beta_raw`` are written into the matching channel slices
724- of ``d_qkvzba``. ``d_A_log`` and ``d_dt_bias`` are reduced via per-element
725- atomic_add to fp32 buffers ; the caller casts those to the parameter dtype .
716+ of ``d_qkvzba``. Each program writes its parameter-gradient partial sums
717+ to a separate FP32 slot ; the caller reduces them in a fixed order .
726718 """
727719
728720 pid_b = tl .program_id (0 )
@@ -802,9 +794,10 @@ def _g_beta_backward_kernel(
802794 tl .store (d_alpha_ptrs , d_alpha .to (d_qkvzba_ptr .dtype .element_ty ), mask = mask )
803795 tl .store (d_beta_ptrs , d_beta_raw .to (d_qkvzba_ptr .dtype .element_ty ), mask = mask )
804796
805- # ----- Atomic-add (b, s) partials into per-head accumulators -----
806- tl .atomic_add (d_A_log_ptr + h_offs , d_A_log_partial , mask = h_mask )
807- tl .atomic_add (d_dt_bias_ptr + h_offs , d_dt_bias_partial , mask = h_mask )
797+ # ----- Store one partial per (batch, sequence block, head) -----
798+ partial_offset = (pid_b * tl .num_programs (1 ) + pid_s ) * num_v_heads + h_offs
799+ tl .store (d_A_log_ptr + partial_offset , d_A_log_partial , mask = h_mask )
800+ tl .store (d_dt_bias_ptr + partial_offset , d_dt_bias_partial , mask = h_mask )
808801
809802
810803# ---------------------------------------------------------------------------
@@ -996,25 +989,23 @@ def _triton_g_beta_backward(
996989
997990 device = qkvzba .device
998991
999- g_beta_grid = lambda meta : (
1000- batch ,
1001- triton .cdiv (seq_len , meta ["BLOCK_S" ]),
1002- triton .cdiv (num_value_heads , meta ["BLOCK_H" ]),
1003- )
992+ # Fixed tiles keep both the partial sums and their final reduction repeatable.
993+ block_s , block_h = 128 , 16
994+ sequence_blocks = triton .cdiv (seq_len , block_s )
995+ g_beta_grid = (batch , sequence_blocks , triton .cdiv (num_value_heads , block_h ))
1004996 with _launch_context (device , stream ):
1005- d_param_grads = torch .empty ((2 , num_value_heads ), dtype = torch .float32 , device = device )
1006- d_param_grads .zero_ ()
1007- d_A_log = d_param_grads [0 ]
1008- d_dt_bias = d_param_grads [1 ]
997+ d_param_grads = torch .empty (
998+ (2 , batch , sequence_blocks , num_value_heads ), dtype = torch .float32 , device = device
999+ )
10091000 _g_beta_backward_kernel [g_beta_grid ](
10101001 qkvzba ,
10111002 A_log ,
10121003 dt_bias ,
10131004 d_g ,
10141005 d_beta_out ,
10151006 d_qkvzba_out ,
1016- d_A_log ,
1017- d_dt_bias ,
1007+ d_param_grads [ 0 ] ,
1008+ d_param_grads [ 1 ] ,
10181009 seq_len ,
10191010 num_value_heads ,
10201011 beta_channel_offset ,
@@ -1028,8 +1019,13 @@ def _triton_g_beta_backward(
10281019 d_beta_out .stride (0 ),
10291020 d_beta_out .stride (1 ),
10301021 d_beta_out .stride (2 ),
1022+ BLOCK_S = block_s ,
1023+ BLOCK_H = block_h ,
1024+ num_warps = 4 ,
1025+ num_stages = 2 ,
10311026 )
1032- return d_qkvzba_out , d_A_log , d_dt_bias
1027+ d_param_grads = d_param_grads .sum (dim = (1 , 2 ))
1028+ return d_qkvzba_out , d_param_grads [0 ], d_param_grads [1 ]
10331029
10341030
10351031def _launch_context (device : torch .device , stream : Optional ["torch.cuda.Stream" ]):
0 commit comments