[Python] How to implement SwiGLU activation? Why does SwiGLU takes in two tensors?

Discussão em 'Python' iniciado por Stack, Outubro 2, 2024.

  1. Stack

    Stack Membro Participativo

    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,

    [​IMG]

    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...

Compartilhe esta Página