|
|
| import pytest |
| import torch |
| import torch.nn.functional as F |
|
|
| from fla.modules.activations import logsigmoid, sigmoid, swiglu, swiglu_linear, swish |
| from fla.utils import assert_close, device |
|
|
|
|
| @pytest.mark.parametrize( |
| ('B', 'T', 'D', 'compile'), |
| [ |
| (1, 1, 64, False), |
| (2, 500, 128, False), |
| (2, 512, 128, True), |
| (3, 2048, 1200, True), |
| ], |
| ) |
| def test_sigmoid(B: int, T: int, D: int, compile: bool): |
| torch.manual_seed(42) |
| x = torch.randn(B, T, D, device=device, requires_grad=True) |
| y_ref = torch.sigmoid(x) |
| y_tri = sigmoid(x) if not compile else torch.compile(sigmoid)(x) |
|
|
| g = torch.randn_like(y_ref) |
| dx_ref = torch.autograd.grad(y_ref, x, g)[0] |
| dx_tri = torch.autograd.grad(y_tri, x, g)[0] |
|
|
| assert_close('sigmoid fwd', y_ref, y_tri, 1e-3) |
| assert_close('sigmoid bwd', dx_ref, dx_tri, 1e-3) |
|
|
|
|
| @pytest.mark.parametrize( |
| ('B', 'T', 'D', 'temperature', 'compile'), |
| [ |
| (1, 1, 64, 1.0, False), |
| (2, 500, 128, 0.5, False), |
| (2, 512, 128, 0.5, True), |
| (3, 2048, 1200, 2.0, True), |
| ], |
| ) |
| def test_logsigmoid(B: int, T: int, D: int, temperature: float, compile: bool): |
| torch.manual_seed(42) |
| x = torch.randn(B, T, D, device=device, requires_grad=True) |
| y_ref = F.logsigmoid(x) / temperature |
| y_tri = logsigmoid(x, temperature) if not compile else torch.compile(logsigmoid)(x, temperature) |
|
|
| g = torch.randn_like(y_ref) |
| dx_ref = torch.autograd.grad(y_ref, x, g)[0] |
| dx_tri = torch.autograd.grad(y_tri, x, g)[0] |
|
|
| assert_close('logsigmoid fwd', y_ref, y_tri, 1e-3) |
| assert_close('logsigmoid bwd', dx_ref, dx_tri, 1e-3) |
|
|
|
|
| @pytest.mark.parametrize( |
| ('B', 'T', 'D', 'compile'), |
| [ |
| (1, 1, 64, True), |
| (2, 500, 128, True), |
| (2, 512, 128, False), |
| (3, 2048, 1200, False), |
| ], |
| ) |
| def test_swish(B: int, T: int, D: int, compile: bool): |
| torch.manual_seed(42) |
| x = torch.randn(B, T, D, device=device, requires_grad=True) |
| y_ref = F.silu(x) |
| y_tri = swish(x) if not compile else torch.compile(swish)(x) |
|
|
| g = torch.randn_like(y_ref) |
| dx_ref = torch.autograd.grad(y_ref, x, g)[0] |
| dx_tri = torch.autograd.grad(y_tri, x, g)[0] |
|
|
| assert_close('swish fwd', y_ref, y_tri, 1e-3) |
| assert_close('swish bwd', dx_ref, dx_tri, 1e-3) |
|
|
|
|
| @pytest.mark.parametrize( |
| ('B', 'T', 'D', 'compile'), |
| [ |
| (1, 1, 64, True), |
| (2, 500, 128, True), |
| (2, 512, 128, False), |
| (3, 2048, 1200, False), |
| ], |
| ) |
| def test_swiglu(B: int, T: int, D: int, compile: bool): |
| torch.manual_seed(42) |
| x = torch.randn(B, T, D, device=device, requires_grad=True) |
| y = torch.randn(B, T, D, device=device, requires_grad=True) |
|
|
| y_ref = F.silu(x) * y |
| y_tri = swiglu(x, y) if not compile else torch.compile(swiglu)(x, y) |
|
|
| g = torch.randn_like(y_ref) |
| dx_ref, dy_ref = torch.autograd.grad(y_ref, (x, y), g) |
| dx_tri, dy_tri = torch.autograd.grad(y_tri, (x, y), g) |
|
|
| assert_close('swiglu fwd', y_ref, y_tri, 1e-3) |
| assert_close('swiglu dx', dx_ref, dx_tri, 1e-3) |
| assert_close('swiglu dy', dy_ref, dy_tri, 1e-3) |
|
|
|
|
| @pytest.mark.parametrize( |
| ('B', 'T', 'D', 'O', 'compile'), |
| [ |
| (2, 512, 128, 256, True), |
| (1, 1, 64, 32, False), |
| (2, 500, 128, 64, True), |
| (3, 2048, 1200, 600, False), |
| ], |
| ) |
| def test_swiglu_linear(B: int, T: int, D: int, O: int, compile: bool): |
| torch.manual_seed(42) |
| x = torch.randn(B, T, D, device=device, requires_grad=True) |
| y = torch.randn(B, T, D, device=device, requires_grad=True) |
| w = torch.randn(O, D, device=device, requires_grad=True) |
| b = torch.randn(O, device=device, requires_grad=True) |
|
|
| z_ref = F.silu(x) * y |
| out_ref = F.linear(z_ref, w, b) |
| out_tri = swiglu_linear(x, y, w, b) if not compile else torch.compile(swiglu_linear)(x, y, w, b) |
|
|
| g = torch.randn_like(out_ref) |
| dx_ref, dy_ref, dw_ref, db_ref = torch.autograd.grad(out_ref, (x, y, w, b), g) |
| dx_tri, dy_tri, dw_tri, db_tri = torch.autograd.grad(out_tri, (x, y, w, b), g) |
|
|
| assert_close('swiglu_linear out', out_ref, out_tri, 1e-3) |
| assert_close('swiglu_linear dx', dx_ref, dx_tri, 1e-3) |
| assert_close('swiglu_linear dy', dy_ref, dy_tri, 1e-3) |
| assert_close('swiglu_linear dw', dw_ref, dw_tri, 1e-3) |
| assert_close('swiglu_linear db', db_ref, db_tri, 1e-3) |
|
|