Instructions to use sahilchachra/Laya-Multilingual-MXFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use sahilchachra/Laya-Multilingual-MXFP4 with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir Laya-Multilingual-MXFP4 sahilchachra/Laya-Multilingual-MXFP4
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
Laya-Multilingual-MXFP4
This is the Multilingual encoder backbone of convaiinnovations/laya (mmBERT-base (100+ languages), 322M params, 768 hidden size, 22 layers, 1024 token context), quantized to MXFP4 for MLX on Apple Silicon.
What's included -- and what's not
Laya is not a plain encoder: it is mmBERT-base (100+ languages) (this repo) plus a small
from-scratch decision head (a 2-layer torch.nn.TransformerEncoder, an
option-marker scorer, and an act/escalate head) defined in Laya's own
rl_common.py, trained separately with RL (RLCD). Only the shared bidirectional
encoder backbone is quantized and published here -- the decision head is a
tiny (~15M param) uncompiled torch module that gains nothing from MLX
quantization, and porting it to MLX would not make Laya's laya.load(...) /
RLAgent API usable anyway (that API expects a torch model directory as-is).
To use Laya's actual decision-making API, keep using the upstream
convaiinnovations/laya repo. This repo is for people who want the ModernBERT/mmBERT
encoder only (e.g. as a quantized general-purpose feature extractor, or to
build a custom MLX head on top) at a fraction of the memory footprint.
- Size on disk: ~163 MB
- Architecture:
ModernBertModel(via mlx-embeddings) - Quantized with:
mlx-embeddings(nn.quantize(..., mode="mxfp4"), group size 32)
Other quantizations
Use with mlx-embeddings
pip install mlx-embeddings
import mlx.core as mx
import mlx.nn as nn
from safetensors import safe_open
from transformers import AutoTokenizer
from mlx_embeddings.models.modernbert import ModelArgs, ModernBertModel
import json
mlx_dir = "sahilchachra/Laya-Multilingual-MXFP4" # or a local snapshot_download() path
with open(f"{mlx_dir}/config.json") as f:
cfg = json.load(f)
args = ModelArgs(model_type=cfg["model_type"], vocab_size=cfg["vocab_size"], hidden_size=cfg["hidden_size"],
num_hidden_layers=cfg["num_hidden_layers"], intermediate_size=cfg["intermediate_size"],
num_attention_heads=cfg["num_attention_heads"], max_position_embeddings=cfg.get("max_position_embeddings"),
norm_eps=cfg.get("layer_norm_eps", 1e-5), attention_bias=cfg.get("attention_bias", False),
global_attn_every_n_layers=cfg.get("global_attn_every_n_layers", 3), local_attention=cfg.get("local_attention", 128))
rp = cfg.get("rope_parameters")
if rp:
args.global_rope_theta = rp["full_attention"]["rope_theta"]
args.local_rope_theta = rp["sliding_attention"]["rope_theta"]
model = ModernBertModel(args)
weights = {}
with safe_open(f"{mlx_dir}/model.safetensors", framework="numpy") as f:
for k in f.keys():
weights[k] = mx.array(f.get_tensor(k))
qcfg = cfg["quantization"]
nn.quantize(model, group_size=qcfg["group_size"], bits=qcfg["bits"], mode=qcfg["mode"],
class_predicate=lambda p, m: hasattr(m, "to_quantized") and f"{p}.scales" in weights)
model.load_weights(list(weights.items()), strict=True)
mx.eval(model.parameters())
tok = AutoTokenizer.from_pretrained(mlx_dir)
enc = tok("The quick brown fox jumps over the lazy dog.", return_tensors="np")
out = model(mx.array(enc["input_ids"]), attention_mask=mx.array(enc["attention_mask"]))
print(out["last_hidden_state"].shape)
Verification
Verified against the bf16/fp32 torch reference (answerdotai/ModernBERT-large /
mmBERT-base weights loaded via the original rl_common.build_model) in two stages:
1. Port correctness (unquantized). The unquantized MLX encoder's last_hidden_state
was compared directly to the torch reference on held-out text: max abs diff 0.045,
mean abs diff 0.0025 (hidden states have mean abs magnitude ~0.63) -- confirms the
mlx-embeddings ModernBERT port itself is numerically correct, independent of
quantization.
2. End-to-end decision quality (quantized). The MLX-quantized encoder's
last_hidden_state was fed into Laya's original, unmodified torch decision head
(same weights, loaded from model.safetensors) and compared against the full torch
reference pipeline, on real choice / score / noul-type questions (moderation and
sentiment-style prompts):
| Metric | MXFP4 | MXFP8 |
|---|---|---|
| Encoder hidden-state mean abs diff vs fp32 | 0.287 | 0.218 |
| Decision-head logit max abs diff | 1.157 | 0.806 |
| Top-1 answer mismatches (out of 3 test questions) | 0/3 | 0/3 |
Honest caveat: this is a small (322M), LayerNorm-heavy encoder, not an LLM --
it is noticeably more sensitive to block quantization than modern decoder-only models.
Hidden-state drift from MXFP4/MXFP8 is meaningfully larger in relative terms (35-45%
mean abs perturbation) than typical MXFP4 LLM quantization (~1-5%), and one of three
test questions (a typed-decisions MXFP8 score question with two closely-scored
options) flipped its top-1 answer. Top-1 answers matched in 5/6 checkpoint x mode
combinations, but if you need calibrated, tie-breaking-sensitive decisions, prefer the
original bf16/fp32 encoder or treat quantized confidence scores as directional only,
not exact.
LM Studio
Not applicable. Laya is a non-autoregressive encoder + custom scoring head, not a
chat/completion model -- there is no generate() path or chat template, so LM Studio
(which only runs chat/completion-style models) cannot load or serve this repo.
- Downloads last month
- 65
Quantized
Model tree for sahilchachra/Laya-Multilingual-MXFP4
Base model
convaiinnovations/laya