From c88ab10a5ce27aa6e3d3b1372f4bdd67f9e03cf6 Mon Sep 17 00:00:00 2001 From: Daniel Han-Chen Date: Sat, 2 Mar 2024 18:28:39 +1100 Subject: [PATCH] Approx gelu --- unsloth/kernels/geglu.py | 44 ++++++++++++++++++++++++++++++++++++---- unsloth/models/gemma.py | 2 +- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/unsloth/kernels/geglu.py b/unsloth/kernels/geglu.py index 7001b8ff0a..eccc316284 100644 --- a/unsloth/kernels/geglu.py +++ b/unsloth/kernels/geglu.py @@ -19,7 +19,7 @@ from .utils import calculate_settings @triton.jit -def _forward_kernel(e, g, h, n_elements, BLOCK_SIZE : tl.constexpr,): +def _exact_forward_kernel(e, g, h, n_elements, BLOCK_SIZE : tl.constexpr,): block_idx = tl.program_id(0) offsets = block_idx*BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) mask = offsets < n_elements @@ -43,13 +43,13 @@ def geglu_forward_kernel(gate, up): n_elements = gate.numel() out = torch.empty((batch, seq_len, hd), dtype = gate.dtype, device = "cuda") grid = lambda meta: (triton.cdiv(n_elements, meta['BLOCK_SIZE']),) - _forward_kernel[grid](gate, up, out, n_elements, BLOCK_SIZE = 1024,) + _exact_forward_kernel[grid](gate, up, out, n_elements, BLOCK_SIZE = 1024,) return out pass @triton.jit -def _backward_kernel(DW, e, g, n_elements, BLOCK_SIZE : tl.constexpr,): +def _exact_backward_kernel(DW, e, g, n_elements, BLOCK_SIZE : tl.constexpr,): """ f = 1/2 * e * (1 + erf(1/sqrt(2) * e)) h = f * up @@ -99,6 +99,42 @@ def geglu_backward_kernel(DW, e, g): batch_seq_len, hd = e.shape n_elements = e.numel() grid = lambda meta: (triton.cdiv(n_elements, meta['BLOCK_SIZE']),) - _backward_kernel[grid](DW, e, g, n_elements, BLOCK_SIZE = 1024,) + _exact_backward_kernel[grid](DW, e, g, n_elements, BLOCK_SIZE = 1024,) return DW, e, g pass + + +@triton.jit +def _approx_forward_kernel(e, g, h, n_elements, BLOCK_SIZE : tl.constexpr,): + block_idx = tl.program_id(0) + offsets = block_idx*BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) + mask = offsets < n_elements + + # f = 1/2 * e * (1 + tanh( sqrt(2/pi) * (x + 0.044715 * x^3 ) )) + # f = 1/2 * e * (1 + tanh( sqrt(2/pi) * x * (1 + 0.044715 * x^2 ) )) + # h = f * up + s = 0.7978845608028654 # math.sqrt(2 / math.pi) + + e_row = tl.load(e + offsets, mask = mask, other = 0).to(tl.float32) + g_row = tl.load(g + offsets, mask = mask, other = 0)#.to(tl.float32) + + f_row = 0.5 * e_row * ( + tl.math.tanh(s * e_row * (1.0 + 0.044715 * e_row * e_row)) \ + + 1.0 + ) + f_row = f_row.to(g_row.dtype) # Exact copy from HF + h_row = f_row * g_row + + # Store h + tl.store(h + offsets, h_row, mask = mask) +pass + + +def geglu_approx_forward_kernel(gate, up): + batch, seq_len, hd = gate.shape + n_elements = gate.numel() + out = torch.empty((batch, seq_len, hd), dtype = gate.dtype, device = "cuda") + grid = lambda meta: (triton.cdiv(n_elements, meta['BLOCK_SIZE']),) + _approx_forward_kernel[grid](gate, up, out, n_elements, BLOCK_SIZE = 1024,) + return out +pass diff --git a/unsloth/models/gemma.py b/unsloth/models/gemma.py index d6c06edc9f..97da833c12 100644 --- a/unsloth/models/gemma.py +++ b/unsloth/models/gemma.py @@ -48,7 +48,7 @@ def fast_geglu_inference(self, X): gate = fast_linear_forward(self.gate_proj, X, out = temp[0]) up = fast_linear_forward(self. up_proj, X, out = temp[1]) - gate = torch.nn.functional.gelu(gate) + gate = torch.nn.functional.gelu(gate, approximate = "tanh") gate *= up # X = self.down_proj(gate)