| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| from torch import Tensor |
|
|
|
|
| class FastShiftConv1d_K3(nn.Module): |
| def __init__(self, dim: int): |
| super().__init__() |
| self.w0 = nn.Parameter(torch.ones(dim)) |
| self.w1 = nn.Parameter(torch.zeros(dim)) |
| self.w2 = nn.Parameter(torch.zeros(dim)) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x1 = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
| x2 = F.pad(x[:, :-2, :], (0, 0, 2, 0)) |
|
|
| return (x * self.w0.to(x.dtype)) + (x1 * self.w1.to(x.dtype)) + (x2 * self.w2.to(x.dtype)) |
|
|
|
|
| class FastShiftConv1d_K4(nn.Module): |
| def __init__(self, dim: int): |
| super().__init__() |
| self.w0 = nn.Parameter(torch.ones(dim)) |
| self.w1 = nn.Parameter(torch.zeros(dim)) |
| self.w2 = nn.Parameter(torch.zeros(dim)) |
| self.w3 = nn.Parameter(torch.zeros(dim)) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x1 = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
| x2 = F.pad(x[:, :-2, :], (0, 0, 2, 0)) |
| x3 = F.pad(x[:, :-3, :], (0, 0, 3, 0)) |
|
|
| return (x * self.w0.to(x.dtype)) + \ |
| (x1 * self.w1.to(x.dtype)) + \ |
| (x2 * self.w2.to(x.dtype)) + \ |
| (x3 * self.w3.to(x.dtype)) |
|
|
|
|
| class FastShiftConv1d_K2(nn.Module): |
| def __init__(self, dim: int): |
| super().__init__() |
| |
| self.w0 = nn.Parameter(torch.ones(dim)) |
| self.w1 = nn.Parameter(torch.zeros(dim)) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x1 = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
|
|
| return (x * self.w0.to(x.dtype)) + (x1 * self.w1.to(x.dtype)) |
|
|
|
|
| class RWKVTimeMix(nn.Module): |
| def __init__(self, dim: int): |
| super().__init__() |
| self.time_mix = nn.Parameter(torch.ones(dim, dtype=torch.float32)) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x_prev = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
| mix = self.time_mix.to(x.dtype) |
|
|
| return x * mix + x_prev * (1.0 - mix) |
|
|
|
|
| class SmearGate2(nn.Module): |
| def __init__(self, dim: int, gate_dim: int = 12): |
| super().__init__() |
| self.gate_dim = min(gate_dim, dim) |
| self.W_g = nn.Parameter(torch.zeros(self.gate_dim, dim)) |
| self.smear_lambda = nn.Parameter(torch.zeros(1)) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x_prev = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
| x_slice = x[..., :self.gate_dim] |
| g = torch.sigmoid(torch.matmul(x_slice, self.W_g.to(x.dtype))) |
|
|
| return x + self.smear_lambda * g * x_prev |
|
|
|
|
| class SmearGateLookback3(nn.Module): |
| def __init__(self, dim: int, gate_dim: int = 12): |
| super().__init__() |
| self.gate_dim = min(gate_dim, dim) |
|
|
| self.W_g = nn.Parameter(torch.zeros(self.gate_dim, dim * 3)) |
|
|
| self.smear_lambdas = nn.Parameter(torch.zeros(3)) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x_slice = x[..., :self.gate_dim] |
| g_all = torch.sigmoid(torch.matmul(x_slice, self.W_g.to(x.dtype))) |
|
|
| g1, g2, g3 = g_all.chunk(3, dim=-1) |
|
|
| x1 = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
| x2 = F.pad(x[:, :-2, :], (0, 0, 2, 0)) |
| x3 = F.pad(x[:, :-3, :], (0, 0, 3, 0)) |
|
|
| return x + (self.smear_lambdas[0] * g1 * x1) \ |
| + (self.smear_lambdas[1] * g2 * x2) \ |
| + (self.smear_lambdas[2] * g3 * x3) |
|
|
|
|
| class ModdedSmearGate(nn.Module): |
| def __init__(self, gate_dim: int = 12): |
| super().__init__() |
| self.gate_dim = gate_dim |
|
|
| self.smear_gate = nn.Linear(gate_dim, 1, bias=False) |
|
|
| with torch.no_grad(): |
| nn.init.zeros_(self.smear_gate.weight) |
|
|
| def forward(self, x: Tensor) -> Tensor: |
| x_prev = F.pad(x[:, :-1, :], (0, 0, 1, 0)) |
| x_slice = x[..., :self.gate_dim] |
|
|
| g = torch.sigmoid(self.smear_gate(x_slice)) |
| return x + g * (x_prev - x) |
|
|