Spaces:
Runtime error
Runtime error
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |
| # All rights reserved. | |
| # | |
| # This source code is licensed under the license found in the | |
| # LICENSE file in the root directory of this source tree. | |
| import torch | |
| import torch.nn as nn | |
| from torch import Tensor | |
| from typing import Union, Callable | |
| class CustomGLU(nn.Module): | |
| """Custom Gated Linear Unit activation. | |
| Applies a modified gated linear unit :math:`a * f(b)` where :math:`a` is the first half | |
| of the input matrices, :math:`b` is the second half, and :math:`f` is a provided activation | |
| function (i.e. sigmoid, swish, etc.). | |
| Args: | |
| activation (nn.Module): The custom activation to apply in the Gated Linear Unit | |
| dim (int): the dimension on which to split the input. Default: -1 | |
| Shape: | |
| - Input: :math:`(\ast_1, N, \ast_2)` where `*` means, any number of additional | |
| dimensions | |
| - Output: :math:`(\ast_1, M, \ast_2)` where :math:`M=N/2` | |
| Examples:: | |
| >>> m = CustomGLU(nn.Sigmoid()) | |
| >>> input = torch.randn(4, 2) | |
| >>> output = m(input) | |
| """ | |
| def __init__(self, activation: nn.Module, dim: int = -1): | |
| super(CustomGLU, self).__init__() | |
| self.dim = dim | |
| self.activation = activation | |
| def forward(self, x: Tensor): | |
| assert x.shape[self.dim] % 2 == 0 # M = N / 2 | |
| a, b = torch.chunk(x, 2, dim=self.dim) | |
| return a * self.activation(b) | |
| class SwiGLU(CustomGLU): | |
| """SiLU Gated Linear Unit activation. | |
| Applies SiLU Gated Linear Unit :math:`a * SiLU(b)` where :math:`a` is | |
| the first half of the input matrices, :math:`b` is the second half. | |
| Args: | |
| dim (int): the dimension on which to split the input. Default: -1 | |
| """ | |
| def __init__(self, dim: int = -1): | |
| super(SwiGLU, self).__init__(nn.SiLU(), dim) | |
| class GeGLU(CustomGLU): | |
| """GeLU Gated Linear Unit activation. | |
| Applies GeLU Gated Linear Unit :math:`a * GELU(b)` where :math:`a` is | |
| the first half of the input matrices, :math:`b` is the second half. | |
| Args: | |
| dim (int): the dimension on which to split the input. Default: -1 | |
| """ | |
| def __init__(self, dim: int = -1): | |
| super(GeGLU, self).__init__(nn.GELU(), dim) | |
| class ReGLU(CustomGLU): | |
| """ReLU Gated Linear Unit activation. | |
| Applies ReLU Gated Linear Unit :math:`a * ReLU(b)` where :math:`a` is | |
| the first half of the input matrices, :math:`b` is the second half. | |
| Args: | |
| dim (int): the dimension on which to split the input. Default: -1 | |
| """ | |
| def __init__(self, dim: int = -1): | |
| super(ReGLU, self).__init__(nn.ReLU(), dim) | |
| def get_activation_fn( | |
| activation: Union[str, Callable[[Tensor], Tensor]] | |
| ) -> Union[str, Callable[[Tensor], Tensor]]: | |
| """Helper function to map an activation string to the activation class. | |
| If the supplied activation is not a string that is recognized, the activation is passed back. | |
| Args: | |
| activation (Union[str, Callable[[Tensor], Tensor]]): Activation to check | |
| """ | |
| if isinstance(activation, str): | |
| if activation == "reglu": | |
| return ReGLU() | |
| elif activation == "geglu": | |
| return GeGLU() | |
| elif activation == "swiglu": | |
| return SwiGLU() | |
| return activation | |