Bonsai-27b-MLX-UltraFastUnStable / optimized_runtime.py
VertexAIco's picture
Release extreme 48-block-pruned experimental edition with benchmark and quality warnings
7ae0b4d verified
Raw History Blame Contribute Delete
16.2 kB
"""Text-only loader for the Bonsai 2 MLX pack.
This keeps the language model numerically identical to the pack's bundled loader,
but does not instantiate or evaluate the 0.92 GB vision tower for text-only use.
"""
from __future__ import annotations
import json
import math
import os
import sys
from pathlib import Path
import mlx.core as mx
import mlx.nn as nn
from mlx_lm.models.qwen3_5 import TextModel, TextModelArgs
from mlx_lm.models.activations import swiglu
from mlx_lm.models.base import scaled_dot_product_attention
def _touch_placeholder_cache(cache):
"""Give pruned-layer ArraysCache entries serializable, inert state."""
if cache is not None and cache[0] is None:
cache[0] = mx.zeros((1,), dtype=mx.uint8)
cache[1] = mx.zeros((1,), dtype=mx.uint8)
class SkippedDecoderLayer(nn.Module):
"""Identity replacement used only by the explicitly enabled Turbo mode."""
def __init__(self, is_linear, scale=1.0):
super().__init__()
self.original_is_linear = is_linear
# Identity layers need only a harmless cache placeholder. ArraysCache
# tolerates an empty state; KVCache.state assumes allocated keys.
self.is_linear = True
self.scale = float(scale)
def __call__(self, x, mask=None, cache=None):
_touch_placeholder_cache(cache)
return x if self.scale == 1.0 else x * self.scale
class AffineSkippedDecoderLayer(nn.Module):
"""Cheap calibrated diagonal approximation for an omitted decoder block."""
def __init__(self, is_linear, scale, bias):
super().__init__()
self.original_is_linear = is_linear
self.is_linear = True
self.scale = scale
self.bias = bias
def __call__(self, x, mask=None, cache=None):
_touch_placeholder_cache(cache)
return x * self.scale + self.bias
class SkippedMLP(nn.Module):
"""Zero residual used to omit only a decoder block's MLP branch."""
def __call__(self, x):
return mx.zeros_like(x)
class AffineSkippedMLP(nn.Module):
"""Calibrated diagonal approximation of an MLP residual branch."""
def __init__(self, scale, bias):
super().__init__()
self.scale = scale
self.bias = bias
def __call__(self, x):
return x * self.scale + self.bias
class FusedDecodeProjection(nn.Module):
"""Fuse sibling ternary GEMVs only when autoregressive decode benefits."""
def __init__(self, projections, fwht):
super().__init__()
first = projections[0]
if any(
projection.block != first.block or projection.signs is not first.signs
for projection in projections[1:]
):
raise ValueError("Cannot fuse projections with different transforms")
self.weight = mx.concatenate([p.weight for p in projections], axis=0)
self.scales = mx.concatenate([p.scales for p in projections], axis=0)
self.biases = mx.concatenate([p.biases for p in projections], axis=0)
self.signs = first.signs
self.block = first.block
sizes = [projection.weight.shape[0] for projection in projections]
self.boundaries = [sum(sizes[: index + 1]) for index in range(len(sizes) - 1)]
self.slices = []
start = 0
for size in sizes:
self.slices.append(slice(start, start + size))
start += size
self._fwht = fwht
def _matmul(self, x, weight, scales, biases):
return mx.quantized_matmul(
x,
weight,
scales,
biases,
transpose=True,
group_size=128,
bits=2,
)
def __call__(self, x):
x = self._fwht(x, self.block, self.signs)
# One wide GEMV is faster during autoregressive decode. For prompt
# batches, two narrower QMMs are slightly faster on Apple M4.
if math.prod(x.shape[:-1]) == 1:
combined = self._matmul(x, self.weight, self.scales, self.biases)
return tuple(mx.split(combined, self.boundaries, axis=-1))
else:
return tuple(
self._matmul(
x,
self.weight[section],
self.scales[section],
self.biases[section],
)
for section in self.slices
)
class FusedDecodeMLP(nn.Module):
def __init__(self, projection, down):
super().__init__()
self.projection = projection
self.down_proj = down
def __call__(self, x):
gate, up = self.projection(x)
return self.down_proj(swiglu(gate, up))
class FusedDecodeAttention(nn.Module):
def __init__(self, attention, projection):
super().__init__()
self.projection = projection
self.num_key_value_heads = attention.num_key_value_heads
self.num_attention_heads = attention.num_attention_heads
self.head_dim = attention.head_dim
self.scale = attention.scale
self.q_norm = attention.q_norm
self.k_norm = attention.k_norm
self.rope = attention.rope
self.o_proj = attention.o_proj
def __call__(self, x, mask=None, cache=None):
batch, length, _ = x.shape
q_proj_output, keys, values = self.projection(x)
queries, gate = mx.split(
q_proj_output.reshape(batch, length, self.num_attention_heads, -1),
2,
axis=-1,
)
gate = gate.reshape(batch, length, -1)
queries = self.q_norm(queries).transpose(0, 2, 1, 3)
keys = self.k_norm(
keys.reshape(batch, length, self.num_key_value_heads, -1)
).transpose(0, 2, 1, 3)
values = values.reshape(
batch, length, self.num_key_value_heads, -1
).transpose(0, 2, 1, 3)
if cache is not None:
queries = self.rope(queries, offset=cache.offset)
keys = self.rope(keys, offset=cache.offset)
keys, values = cache.update_and_fetch(keys, values)
else:
queries = self.rope(queries)
keys = self.rope(keys)
output = scaled_dot_product_attention(
queries, keys, values, cache=cache, scale=self.scale, mask=mask
)
output = output.transpose(0, 2, 1, 3).reshape(batch, length, -1)
return self.o_proj(output * mx.sigmoid(gate))
def load_text_model(directory: str | Path):
directory = Path(directory)
config = json.loads((directory / "config.json").read_text())
if config.get("schema_version") != 2:
raise ValueError(f"Unsupported schema version: {config.get('schema_version')!r}")
if config.get("model_type") != "prism_hadamard_qwen35":
raise ValueError(f"Unsupported model type: {config.get('model_type')!r}")
runtime = directory / "runtime"
sys.path.insert(0, str(runtime))
from runtime import Packed, fwht
model = TextModel(TextModelArgs.from_dict(config["text_config"]))
all_weights = mx.load(str(directory / "model.safetensors"))
prefix = "language_model."
layout = config.get("optimized_weight_layout", {})
share_signs = layout.get("sign_sharing") == "by_input_width"
Packed.share_fwht_activations = bool(layout.get("shared_fwht_activations", False))
seen = set()
for record in config["modules"]:
path = record["path"]
if path in seen:
raise ValueError(f"Duplicate packed module: {path}")
seen.add(path)
if record["dtype"] != "float16":
raise ValueError(f"Unsupported activation dtype at {path}")
parts = path.split(".")
parent = model
for part in parts[:-1]:
parent = parent[int(part)] if part.isdigit() else getattr(parent, part)
key = prefix + path
arrays = [all_weights[key + "." + suffix] for suffix in ("weight", "scales", "biases")]
block = record["block"]
if block and block not in (512, 1024, 2048, 4096):
raise ValueError(f"Unsupported Hadamard block size at {path}: {block}")
signs = all_weights.get(key + ".signs")
if block and signs is None:
raise ValueError(f"Missing Hadamard signs at {path}")
if signs is not None and not mx.all((signs == 1) | (signs == -1)).item():
raise ValueError(f"Invalid Hadamard signs at {path}")
setattr(
parent,
parts[-1],
Packed(arrays, block, signs, record["embedding"], mx.float16),
)
text_weights = [
(name[len(prefix) :], value)
for name, value in all_weights.items()
if name.startswith(prefix)
]
model.load_weights(text_weights, strict=True)
del text_weights
# The checkpoint contains 402 sign tensors but only three unique, byte-identical
# payloads (one for each input width). Point modules with the same width at one
# canonical array after load_weights has assigned the checkpoint parameters.
# This is an exact representation change: ternary weights, scales, biases, and
# every sign value remain untouched.
if share_signs:
canonical_signs = {}
for record in config["modules"]:
if not record["block"]:
continue
parent = model
parts = record["path"].split(".")
for part in parts:
parent = parent[int(part)] if part.isdigit() else getattr(parent, part)
signs = parent.signs
key = (tuple(signs.shape), signs.dtype)
canonical = canonical_signs.get(key)
if canonical is None:
canonical_signs[key] = signs
else:
parent.signs = canonical
expected = layout.get("unique_sign_payloads")
if expected is not None and len(canonical_signs) != expected:
raise ValueError(
f"Expected {expected} canonical sign tensors, found {len(canonical_signs)}"
)
fuse_decode = os.environ.get("BONSAI_FUSE_DECODE") == "1" or bool(
layout.get("fused_decode_projections", False)
)
if fuse_decode:
for layer_index, layer in enumerate(model.model.layers):
old_mlp = layer.mlp
gate, up = old_mlp.gate_proj, old_mlp.up_proj
projection = FusedDecodeProjection((gate, up), fwht)
fused = FusedDecodeMLP(projection, old_mlp.down_proj)
# Materialize one layer at a time and release its old gate/up arrays,
# keeping peak memory bounded while the checkpoint is memory-mapped.
mx.eval(projection.weight, projection.scales, projection.biases)
layer.mlp = fused
stem = f"{prefix}model.layers.{layer_index}.mlp."
for projection in ("gate_proj", "up_proj"):
for suffix in ("weight", "scales", "biases", "signs"):
all_weights.pop(stem + projection + "." + suffix, None)
if not layer.is_linear:
old_attention = layer.self_attn
qkv = FusedDecodeProjection(
(
old_attention.q_proj,
old_attention.k_proj,
old_attention.v_proj,
),
fwht,
)
mx.eval(qkv.weight, qkv.scales, qkv.biases)
layer.self_attn = FusedDecodeAttention(old_attention, qkv)
stem = f"{prefix}model.layers.{layer_index}.self_attn."
for projection_name in ("q_proj", "k_proj", "v_proj"):
for suffix in ("weight", "scales", "biases", "signs"):
all_weights.pop(
stem + projection_name + "." + suffix, None
)
profile_name = os.environ.get("BONSAI_PROFILE", "").strip()
profile = {}
if profile_name:
profiles = config.get("optimized_runtime_profiles", {})
if profile_name not in profiles:
raise ValueError(f"Unknown BONSAI_PROFILE value: {profile_name!r}")
profile = profiles[profile_name]
profile_layers = profile.get("skip_layers", [])
skip_text = ",".join(str(index) for index in profile_layers)
config["active_runtime_profile"] = profile_name
else:
skip_text = os.environ.get("BONSAI_SKIP_LAYERS", "").strip()
if skip_text:
skip_layers = sorted({int(value) for value in skip_text.split(",")})
adapter_path = os.environ.get("BONSAI_SKIP_ADAPTERS", "").strip()
if not adapter_path and profile.get("skip_adapters"):
adapter_path = str(directory / profile["skip_adapters"])
skip_adapters = mx.load(adapter_path) if adapter_path else {}
scale_text = os.environ.get("BONSAI_SKIP_SCALES", "").strip()
skip_scales = {}
if scale_text:
for item in scale_text.split(","):
index_text, scale_value = item.split(":", 1)
skip_scales[int(index_text)] = float(scale_value)
if any(index < 0 or index >= len(model.model.layers) for index in skip_layers):
raise ValueError(f"Invalid BONSAI_SKIP_LAYERS value: {skip_text!r}")
# Layers 0 and 3 own the reference SSM/attention caches used to build
# masks for the whole stack and therefore cannot be identity-pruned.
if {0, model.model.fa_idx} & set(skip_layers):
raise ValueError("Turbo mode cannot skip the reference cache layers")
for index in skip_layers:
old_layer = model.model.layers[index]
scale_key = f"layers.{index}.scale"
bias_key = f"layers.{index}.bias"
if adapter_path:
if scale_key not in skip_adapters or bias_key not in skip_adapters:
raise ValueError(f"Missing affine adapter for skipped layer {index}")
model.model.layers[index] = AffineSkippedDecoderLayer(
old_layer.is_linear,
skip_adapters[scale_key],
skip_adapters[bias_key],
)
else:
model.model.layers[index] = SkippedDecoderLayer(
old_layer.is_linear, skip_scales.get(index, 1.0)
)
config["active_runtime_skip_layers"] = skip_layers
if adapter_path:
config["active_runtime_skip_adapters"] = adapter_path
if skip_scales:
config["active_runtime_skip_scales"] = skip_scales
skip_mlp_text = os.environ.get("BONSAI_SKIP_MLP_LAYERS", "").strip()
if not skip_mlp_text and profile.get("skip_mlp_layers"):
skip_mlp_text = ",".join(str(index) for index in profile["skip_mlp_layers"])
if skip_mlp_text:
skip_mlp_layers = sorted({int(value) for value in skip_mlp_text.split(",")})
mlp_adapter_path = os.environ.get("BONSAI_SKIP_MLP_ADAPTERS", "").strip()
mlp_adapters = mx.load(mlp_adapter_path) if mlp_adapter_path else {}
if any(index < 0 or index >= len(model.model.layers) for index in skip_mlp_layers):
raise ValueError(f"Invalid BONSAI_SKIP_MLP_LAYERS value: {skip_mlp_text!r}")
active_full_skips = set(config.get("active_runtime_skip_layers", []))
if active_full_skips & set(skip_mlp_layers):
raise ValueError("A layer cannot be both fully skipped and MLP-skipped")
for index in skip_mlp_layers:
scale_key = f"mlp_layers.{index}.scale"
bias_key = f"mlp_layers.{index}.bias"
if mlp_adapter_path:
if scale_key not in mlp_adapters or bias_key not in mlp_adapters:
raise ValueError(f"Missing affine MLP adapter for layer {index}")
model.model.layers[index].mlp = AffineSkippedMLP(
mlp_adapters[scale_key], mlp_adapters[bias_key]
)
else:
model.model.layers[index].mlp = SkippedMLP()
config["active_runtime_skip_mlp_layers"] = skip_mlp_layers
if mlp_adapter_path:
config["active_runtime_skip_mlp_adapters"] = mlp_adapter_path
model.eval()
mx.eval(model.parameters())
return model, config