-
Notifications
You must be signed in to change notification settings - Fork 592
[GDN] Add exp2 support across chunk kernels for improved performance #791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
8b287d5
0a745db
b16630c
d03a419
28abbab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |
| from fla.ops.gated_delta_rule.chunk_fwd import chunk_gated_delta_rule_fwd_intra | ||
| from fla.ops.gated_delta_rule.wy_fast import prepare_wy_repr_bwd, recompute_w_u_fwd | ||
| from fla.ops.utils import chunk_local_cumsum | ||
| from fla.ops.utils.constant import RCP_LN2 | ||
| from fla.ops.utils.index import prepare_chunk_indices | ||
| from fla.utils import autocast_custom_bwd, autocast_custom_fwd, input_guard | ||
|
|
||
|
|
@@ -33,9 +34,16 @@ def chunk_gated_delta_rule_fwd( | |
| cu_seqlens: torch.LongTensor | None = None, | ||
| cp_context: FLACPContext | None = None, | ||
| chunk_indices: torch.LongTensor | None = None, | ||
| use_exp2: bool = True, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| transpose_state_layout: bool = False, | ||
| ): | ||
| g = chunk_local_cumsum(g, chunk_size=64, cu_seqlens=cu_seqlens, chunk_indices=chunk_indices) | ||
| g = chunk_local_cumsum( | ||
| g, | ||
| chunk_size=64, | ||
| scale=RCP_LN2 if use_exp2 else None, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| ) | ||
| # obtain WY representation. u is actually the new v. | ||
| # fused kkt + solve_tril + recompute_w_u | ||
| w, u, A = chunk_gated_delta_rule_fwd_intra( | ||
|
|
@@ -45,6 +53,7 @@ def chunk_gated_delta_rule_fwd( | |
| beta=beta, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| ) | ||
|
|
||
| if cp_context is not None: | ||
|
|
@@ -56,6 +65,7 @@ def chunk_gated_delta_rule_fwd( | |
| cu_seqlens=cu_seqlens, | ||
| initial_state=initial_state, | ||
| context=cp_context, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
|
|
||
|
|
@@ -68,6 +78,7 @@ def chunk_gated_delta_rule_fwd( | |
| output_final_state=output_final_state, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
|
|
||
|
|
@@ -83,6 +94,7 @@ def chunk_gated_delta_rule_fwd( | |
| scale=scale, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
| return g, o, A, final_state, initial_state | ||
|
|
@@ -102,6 +114,7 @@ def chunk_gated_delta_rule_bwd( | |
| cu_seqlens: torch.LongTensor | None = None, | ||
| cp_context: FLACPContext | None = None, | ||
| chunk_indices: torch.LongTensor | None = None, | ||
| use_exp2: bool = True, | ||
| transpose_state_layout: bool = False, | ||
| ): | ||
| w, u = recompute_w_u_fwd( | ||
|
|
@@ -112,6 +125,7 @@ def chunk_gated_delta_rule_bwd( | |
| g=g, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| ) | ||
|
|
||
| if cp_context is not None: | ||
|
|
@@ -126,6 +140,7 @@ def chunk_gated_delta_rule_bwd( | |
| output_final_state=False, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
| dv = chunk_bwd_dv_local( | ||
|
|
@@ -136,6 +151,7 @@ def chunk_gated_delta_rule_bwd( | |
| scale=scale, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| ) | ||
|
|
||
| if cp_context is not None: | ||
|
|
@@ -153,6 +169,7 @@ def chunk_gated_delta_rule_bwd( | |
| dht=dht, | ||
| initial_state=initial_state, | ||
| context=cp_context, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
|
|
||
|
|
@@ -168,6 +185,7 @@ def chunk_gated_delta_rule_bwd( | |
| scale=scale, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
| dq, dk, dw, dg = chunk_bwd_dqkwg( | ||
|
|
@@ -183,6 +201,7 @@ def chunk_gated_delta_rule_bwd( | |
| scale=scale, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| transpose_state_layout=transpose_state_layout, | ||
| ) | ||
| dk2, dv, db, dg2 = prepare_wy_repr_bwd( | ||
|
|
@@ -195,6 +214,7 @@ def chunk_gated_delta_rule_bwd( | |
| du=dv, | ||
| cu_seqlens=cu_seqlens, | ||
| chunk_indices=chunk_indices, | ||
| use_exp2=use_exp2, | ||
| ) | ||
| dk.add_(dk2) | ||
| dg.add_(dg2) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scale
g_gammabefore theexp2branches.The
USE_Gpath can stay equivalent becausefla/ops/gated_delta_rule/chunk.pynow pre-scales cumulativegbyRCP_LN2before it reaches this file.g_gammais generated locally here, though, so the newexp2(...)branches are still consuming raw natural-log decays. Withuse_exp2=True, everyUSE_G_GAMMApath here changes the operator in both forward and backward.💡 Suggested fix
+from fla.ops.utils.constant import RCP_LN2 from fla.ops.utils import prepare_chunk_indices from fla.ops.utils.op import exp, exp2if USE_G_GAMMA: b_gamma = tl.load(g_gamma + i_h) b_g = b_gamma * (tl.arange(0, BT) + 1) + if USE_EXP2: + b_g = b_g * RCP_LN2if USE_G_GAMMA: b_gamma = tl.load(g_gamma + i_h) b_g = b_gamma * (tl.arange(0, BT) + 1) b_g_last = b_gamma * min(BT, T - i_t * BT) + if USE_EXP2: + b_g = b_g * RCP_LN2 + b_g_last = b_g_last * RCP_LN2Apply the same normalization in each kernel here that materializes
b_g/b_g_lastfromg_gamma.Also applies to: 311-319, 421-427, 512-516
🤖 Prompt for AI Agents