amonshano's picture
Add Echo-Memory codebase used for this run (CC BY 4.0, JD Echo Team) (part 4)
c335050 verified
Raw
History Blame Contribute Delete
2.27 kB
import pytest
import torch
import torch.nn as nn
import torch.nn.functional as F
from fla.modules import FusedLinearCrossEntropyLoss
from fla.modules.l2warp import l2_warp as standalone_l2_warp
from fla.utils import assert_close, device, is_intel_alchemist
@pytest.mark.parametrize("dtype", [torch.float32, torch.bfloat16])
@pytest.mark.parametrize("B", [4, 8])
@pytest.mark.parametrize("T", [1024])
@pytest.mark.parametrize("H", [256])
@pytest.mark.parametrize("V", [2000])
@pytest.mark.parametrize("l2_penalty_factor", [1e-4, 1])
@pytest.mark.skipif(
is_intel_alchemist is True,
reason="Intel Triton Failure",
)
def test_fused_linear_cross_entropy_l2_warp(
B: int,
T: int,
H: int,
V: int,
l2_penalty_factor: float,
dtype: torch.dtype,
):
torch.manual_seed(42)
lm_head = nn.Linear(H, V, bias=True, device=device, dtype=dtype)
x = torch.randn(B, T, H, device=device, dtype=dtype, requires_grad=True)
labels = torch.randint(0, V, (B, T), device=device)
ignore_index = -100
shift_labels = torch.cat((labels[..., 1:], torch.full_like(labels[:, :1], ignore_index)), 1)
ref_criterion = nn.CrossEntropyLoss()
ref_logits = F.linear(x.view(-1, H), lm_head.weight, lm_head.bias)
ref_loss_ce = ref_criterion(ref_logits.view(B * T, V), shift_labels.view(-1))
ref_loss = standalone_l2_warp(ref_loss_ce, ref_logits.view(B, T, V), l2_penalty_factor)
ref_loss.backward()
ref_x_grad = x.grad.clone()
ref_w_grad = lm_head.weight.grad.clone()
ref_b_grad = lm_head.bias.grad.clone()
x.grad = None
lm_head.zero_grad()
fused_criterion = FusedLinearCrossEntropyLoss(
l2_penalty_factor=l2_penalty_factor,
use_l2warp=True, # Make sure to enable it
)
fused_loss = fused_criterion(x, shift_labels, lm_head.weight, lm_head.bias)
fused_loss.backward()
fused_x_grad = x.grad.clone()
fused_w_grad = lm_head.weight.grad.clone()
fused_b_grad = lm_head.bias.grad.clone()
ratio = 4e-3 if dtype == torch.bfloat16 else 1e-3
assert_close("Loss", ref_loss, fused_loss, ratio)
assert_close("dx", ref_x_grad, fused_x_grad, ratio)
assert_close("dw", ref_w_grad, fused_w_grad, ratio)
assert_close("db", ref_b_grad, fused_b_grad, ratio)