Skip to content

Commit 971cb75

Browse files
committed
Iteration 88/100: MLX-native ternary quantization implementation
1 parent e4a3457 commit 971cb75

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

src/quantization/mlx_quantizer.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# path: BitNet-mlx/src/quantization/mlx_quantizer.py
2+
#!/usr/bin/env python3
3+
"""
4+
MLX Quantizer
5+
6+
Production-grade MLX-native implementation of 1.58-bit ternary quantization.
7+
Supports post-training quantization and direct inference on Apple Silicon.
8+
"""
9+
10+
import logging
11+
from typing import Any, Dict, Optional
12+
13+
import mlx.core as mx
14+
15+
import numpy as np
16+
17+
from .ternary_pipeline import TernaryPipeline
18+
19+
logging.basicConfig(level=logging.INFO, format="[*] %(asctime)s - %(message)s")
20+
21+
22+
class MLXQuantizer:
23+
"""
24+
MLX-native 1.58-bit ternary quantizer.
25+
"""
26+
27+
def __init__(self, output_dim: int = 128):
28+
self.pipeline = TernaryPipeline(output_dim=output_dim)
29+
logging.info("MLXQuantizer initialized")
30+
31+
def quantize_weights(self, weights: mx.array) -> Dict[str, Any]:
32+
"""
33+
Quantize a weight matrix to ternary using the TDA pipeline.
34+
Returns ternary weights + metadata.
35+
"""
36+
# Convert to numpy for the analysis pipeline
37+
weights_np = np.array(weights)
38+
39+
result = self.pipeline.run(weights_np)
40+
41+
# Create ternary weights in MLX
42+
ternary_weights = mx.array(result["projection"]["ternary_weights"])
43+
44+
return {
45+
"ternary_weights": ternary_weights,
46+
"original_shape": weights.shape,
47+
"ternary_shape": ternary_weights.shape,
48+
"persistence_score": result["signature"]["persistence_score"],
49+
"sparsity": result["projection"].get("sparsity", 0.0),
50+
}
51+
52+
def quantize_linear_layer(self, weight: mx.array, bias: Optional[mx.array] = None) -> Dict[str, Any]:
53+
"""
54+
Quantize a full linear layer (weight + optional bias).
55+
"""
56+
q_weight = self.quantize_weights(weight)
57+
58+
result = {
59+
"weight": q_weight,
60+
"bias": bias,
61+
"is_quantized": True,
62+
}
63+
64+
if bias is not None:
65+
result["bias"] = bias # Bias usually kept in higher precision
66+
67+
return result
68+
69+
def create_quantized_linear(self, in_features: int, out_features: int) -> Dict[str, Any]:
70+
"""
71+
Create a new quantized linear layer with random init.
72+
"""
73+
weight = mx.random.normal((out_features, in_features))
74+
return self.quantize_linear_layer(weight)
75+
76+
def matmul_ternary(self, a: mx.array, ternary_weight: mx.array) -> mx.array:
77+
"""
78+
Efficient ternary matrix multiplication.
79+
In production this can be further optimized with custom Metal kernels.
80+
"""
81+
# Simple implementation - can be replaced with optimized kernel
82+
return mx.matmul(a, ternary_weight.T)

0 commit comments

Comments
 (0)