Skip to content

Commit 7523ef0

Browse files
committed
feat: Add refined BitNet 1.58 ternary kernels + Metal target + CUDA stubs for ecosystem integration
1 parent 76af05d commit 7523ef0

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/kernels/cuda_kernels.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# path: src/kernels/cuda_kernels.py
2+
3+
def cuda_ternary_matmul(input, ternary_weight, scale):
4+
raise NotImplementedError("CUDA ternary matmul not implemented")
5+
6+
def cuda_abs_mean_quantize(weight, eps=1e-8):
7+
raise NotImplementedError("CUDA quantization not implemented")

src/kernels/metal_kernels.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# path: src/kernels/metal_kernels.py
2+
3+
import mlx.core as mx
4+
5+
6+
def ternary_matmul_metal(input: mx.array, ternary_weight: mx.array, scale: mx.array) -> mx.array:
7+
"""
8+
Target for custom MLX Metal ternary matmul kernel.
9+
"""
10+
w = ternary_weight.astype(input.dtype) * scale
11+
return mx.matmul(input, w.T)

src/kernels/ternary_kernels.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# path: src/kernels/ternary_kernels.py
2+
3+
import mlx.core as mx
4+
from typing import Tuple
5+
6+
7+
def abs_mean_quantize(weight: mx.array, eps: float = 1e-8) -> Tuple[mx.array, mx.array]:
8+
"""BitNet 1.58 AbsMean quantization to ternary {-1, 0, +1}."""
9+
scale = mx.mean(mx.abs(weight), axis=1, keepdims=True) + eps
10+
scaled = weight / scale
11+
ternary = mx.where(scaled > 0.5, 1.0,
12+
mx.where(scaled < -0.5, -1.0, 0.0))
13+
return ternary.astype(mx.int8), scale
14+
15+
16+
def ternary_matmul(input: mx.array, ternary_weight: mx.array, scale: mx.array) -> mx.array:
17+
"""Optimized ternary matmul for BitNet 1.58."""
18+
w = ternary_weight.astype(input.dtype) * scale
19+
return mx.matmul(input, w.T)
20+
21+
22+
class BitNetLinear:
23+
"""BitNet 1.58 style linear layer."""
24+
def __init__(self, in_features: int, out_features: int, bias: bool = False):
25+
self.in_features = in_features
26+
self.out_features = out_features
27+
weight = mx.random.normal((out_features, in_features)) * 0.02
28+
self.ternary_weight, self.scale = abs_mean_quantize(weight)
29+
self.bias = mx.zeros((out_features,)) if bias else None
30+
31+
def __call__(self, x: mx.array) -> mx.array:
32+
out = ternary_matmul(x, self.ternary_weight, self.scale)
33+
if self.bias is not None:
34+
out = out + self.bias
35+
return out

0 commit comments

Comments
 (0)