base_IIXIV / fla /ops /mesa_net /decoding_one_step.py
mainline777's picture
Duplicate from silx-ai/Quasar-Preview
41865df
Raw
History Blame Contribute Delete
4.96 kB
# Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
import torch
import triton
import triton.language as tl
from fla.ops.utils.op import exp
from fla.utils import input_guard
@triton.jit
def mesa_net_decoding_one_step_kernel(
q,
k,
v,
g,
o,
lamb,
beta,
prev_h_kk,
prev_h_kv,
curr_h_kk,
curr_h_kv,
B: tl.constexpr,
H: tl.constexpr,
K: tl.constexpr,
V: tl.constexpr,
BK: tl.constexpr,
BV: tl.constexpr,
MAX_CG_STEP: tl.constexpr,
):
i_nh = tl.program_id(0)
i_h = i_nh % H
o_k = tl.arange(0, BK)
o_v = tl.arange(0, BV)
p_q = q + i_nh * K + o_k
p_k = k + i_nh * K + o_k
p_v = v + i_nh * V + o_v
p_beta = beta + i_nh
p_g = g + i_nh
p_lamb = lamb + i_h * K + o_k
b_g = exp(tl.load(p_g).to(tl.float32))
b_beta = tl.load(p_beta).to(tl.float32)
mask_k = o_k < K
mask_v = o_v < V
mask_kk = mask_k[:, None] & mask_k[None, :]
mask_kv = mask_k[:, None] & mask_v[None, :]
b_k = tl.load(p_k, mask=mask_k, other=0).to(tl.float32)
b_v = tl.load(p_v, mask=mask_v, other=0).to(tl.float32)
b_q = tl.load(p_q, mask=mask_k, other=0).to(tl.float32)
b_lamb = tl.load(p_lamb, mask=mask_k, other=0).to(tl.float32)
p_hkk_prev = prev_h_kk + i_nh * K * K + o_k[:, None] * K + o_k[None, :]
b_h_kk = tl.load(p_hkk_prev, mask=mask_kk, other=0).to(tl.float32)
b_h_kk = b_h_kk * b_g + (b_k * b_beta)[:, None] * b_k[None, :]
p_hkk_curr = curr_h_kk + i_nh * K * K + o_k[:, None] * K + o_k[None, :]
tl.store(p_hkk_curr, b_h_kk.to(p_hkk_curr.dtype.element_ty), mask=mask_kk)
p_hkv_prev = prev_h_kv + i_nh * K * V + o_k[:, None] * V + o_v[None, :]
b_h_kv = tl.load(p_hkv_prev, mask=mask_kv, other=0).to(tl.float32)
b_h_kv = b_h_kv * b_g + (b_k * b_beta)[:, None] * b_v[None, :]
p_hkv_curr = curr_h_kv + i_nh * K * V + o_k[:, None] * V + o_v[None, :]
tl.store(p_hkv_curr, b_h_kv.to(p_hkv_curr.dtype.element_ty), mask=mask_kv)
diag_mask = tl.arange(0, BK)[:, None] == tl.arange(0, BK)[None, :]
diag_mask = diag_mask & mask_kk
b_h_kk_diag = tl.sum(tl.where(diag_mask, b_h_kk, 0.0), axis=1)
b_x = b_q / (b_h_kk_diag + b_lamb + 1e-5)
b_Hx = tl.sum(b_h_kk * b_x[:, None], axis=0)
b_r = b_q - b_Hx - b_lamb * b_x
b_p = tl.zeros([BK], dtype=tl.float32)
b_p += b_r
delta_old = tl.sum(b_r * b_r)
for i_iter in range(MAX_CG_STEP):
b_Ap = tl.sum(b_h_kk * b_p[:, None], axis=0) + b_lamb * b_p
pAp = tl.sum(b_p * b_Ap)
alpha = delta_old / (pAp + 1e-5)
b_x = b_x + alpha * b_p
b_r = b_r - alpha * b_Ap
delta_new = tl.sum(b_r * b_r)
beta_cg = delta_new / (delta_old + 1e-5)
b_p = b_r + beta_cg * b_p
delta_old = delta_new
b_o = tl.sum(b_h_kv * b_x[:, None], axis=0)
p_o = o + i_nh * V + o_v
tl.store(p_o, b_o.to(p_o.dtype.element_ty), mask=mask_v)
@input_guard
def mesa_net_decoding_one_step(
q: torch.Tensor,
k: torch.Tensor,
v: torch.Tensor,
g: torch.Tensor,
lamb: torch.Tensor,
beta: torch.Tensor,
prev_h_kk: torch.Tensor,
prev_h_kv: torch.Tensor,
max_CG_iteration: int = 30,
):
"""
Triton implementation of Mesa Net CG one step
Args:
q (torch.Tensor):
query tensor [B, H, K]
k (torch.Tensor):
key tensor [B, H, K]
v (torch.Tensor):
value tensor [B, H, V]
g (torch.Tensor):
gate tensor [B, H]
lamb (torch.Tensor):
lambda tensor [H, K]
beta (torch.Tensor):
beta tensor [B, H]
prev_h_kk (torch.Tensor):
previous hidden state KK [B, H, K, K]
prev_h_kv (torch.Tensor):
previous hidden state KV [B, H, K, V]
max_CG_iteration (int):
maximum CG iterations
Returns:
o (torch.Tensor):
output tensor [B, H, V]
h_kk_new (torch.Tensor):
updated hidden state KK [B, H, K, K]
h_kv_new (torch.Tensor):
updated hidden state KV [B, H, K, V]
"""
B, H, K, V = *q.shape, v.shape[-1]
o = torch.empty((B, H, V), dtype=q.dtype, device=q.device)
curr_h_kk = torch.empty_like(prev_h_kk)
curr_h_kv = torch.empty_like(prev_h_kv)
BK = max(triton.next_power_of_2(K), 16)
BV = max(triton.next_power_of_2(V), 16)
assert BK <= 128 and BV <= 128, "BK and BV must be less than or equal to 128"
grid = (B * H,)
mesa_net_decoding_one_step_kernel[grid](
q=q,
k=k,
v=v,
g=g,
o=o,
lamb=lamb,
beta=beta,
prev_h_kk=prev_h_kk,
prev_h_kv=prev_h_kv,
curr_h_kk=curr_h_kk,
curr_h_kv=curr_h_kv,
B=B,
H=H,
K=K,
V=V,
BK=BK,
BV=BV,
MAX_CG_STEP=max_CG_iteration,
num_warps=4 if BK <= 64 else 8,
)
return o, curr_h_kk, curr_h_kv