The SwiGLU variant introduced in https://arxiv.org/pdf/2002.05202 is simply "divine benevolence" and the implementation on Flash-Attention just works out of the box https://github.com/Dao-AILab/flash-attention/tree/main Comparing the the implementation: import torch swiglu_fwd_codestring = """ template <typename T> T swiglu_fwd(T x, T y) { return float(x) * float(y) / (1.0f + ::exp(-float(x))); } """ swiglu_bwd_codestring = """ template <typename T> T swiglu_bwd(T x, T y, T g, T& dx, T& dy) { float x_sigmoid = 1.0f / (1.0f + ::exp(-float(x))); dx = x_sigmoid * (1 + float(x) * (1.0f - x_sigmoid)) * float(g) * float(y); dy = float(x) * x_sigmoid * float(g); } """ swiglu_fwd = torch.cuda.jiterator._create_jit_fn(swiglu_fwd_codestring) swiglu_bwd = torch.cuda.jiterator._create_multi_output_jit_fn(swiglu_bwd_codestring, num_outputs=2) class SwiGLUFunction(torch.autograd.Function): @staticmethod def forward(ctx, x, y): ctx.save_for_backward(x, y) return swiglu_fwd(x, y) @staticmethod def backward(ctx, dout): x, y = ctx.saved_tensors return swiglu_bwd(x, y, dout) swiglu = SwiGLUFunction.apply swiglu(torch.tensor(1.0).to('cuda'), torch.tensor(0.5).to('cuda')) and import torch.nn.functional as F swiglu_torch = lambda x, y: F.silu(x) * y swiglu_torch(torch.tensor(1.0).to('cuda'), torch.tensor(0.5).to('cuda')) They both give the same output: tensor(0.3655, device='cuda:0') The paper description, the input to the activation is a single x tensor, but both the implementation is taking x and y, what does the y corresponds to when we only have the x tensor as in the input in the formula? Is that x = W1.x and y=W2.x? Continue reading...