minuscule
A Latin-script vocabulary prune of
bert-base-multilingual-cased-ner-hrl.
Specifically of
Xenova/bert-base-multilingual-cased-ner-hrl,
the int8 ONNX export of
Davlan/bert-base-multilingual-cased-ner-hrl, stripped
of the vocabulary a Latin-script deployment can never tokenize.
178.5 MB → 139.6 MB (−21.8%), with identical output for the languages it
still covers. No encoder weight was touched and nothing was re-quantized. This
is a packaging change, not a distillation — there is no accuracy trade to
evaluate.
Why it works
bert-base-multilingual-cased carries a 119,547-token vocabulary spanning 104
languages. At 768 dimensions that embedding table is ~92 MB of the 178 MB
file — more than half the model, and every user downloads all of it. If you
ship Latin-script languages, the Cyrillic, CJK, Arabic, Hangul, Hebrew,
Devanagari, Greek, Armenian and Thai rows are downloaded by everyone and
gathered by no one.
Removing them is exact rather than approximate, for two reasons:
- The embedding is per-tensor quantized — a scalar scale and zero-point
shared by the whole tensor — and is read by a plain
Gather. Selecting a
subset of rows preserves both the int8 values and their dequantization. No
weight is re-quantized and nothing drifts.
- WordPiece is longest-match over the available pieces. Only pieces
unreachable from a kept script were removed, so segmentation of Latin text is
unchanged too.
Vocabulary: 119,547 → 68,875 tokens (57.6% kept).
Verification
Not asserted — measured. Both models were run over the same 77 documents —
synthetic contracts, financial statements and medical records across 7
languages — comparing raw logits rather than entity lists, because entity
lists can agree by luck:
| |
|---|
| documents | 77 |
| entities compared | 2,219 |
| segmentation differences | 0 |
| entity differences | 0 |
| max abs. logit delta | 0.0000000000 |
The comparison is over raw logits and fails on any nonzero difference.
Two limits worth stating plainly. The corpus covers 7 of the 8 kept
languages — Latvian is not represented in it, and while the argument above
applies to Latvian exactly as it does to the rest, it has not been measured
there. And the documents are synthetic: they are shaped like real contracts and
records rather than drawn from them.
So: verify on your own corpus before shipping. The guarantee is exact for
kept scripts, but "kept" depends on which scripts you selected, and a corpus
containing a dropped script will (correctly) diverge.
⚠️ Latin script only
Text in a dropped script is not supported — it degrades to [UNK], not to
"slightly worse". Relative to the original model:
- Kept: German, English, Spanish, French, Italian, Latvian, Dutch,
Portuguese — and any other Latin-script language the base model handled.
- Removed: Arabic and Chinese, which the original supports and this
model does not.
If you need those, use
Xenova/bert-base-multilingual-cased-ner-hrl
— it is the model this one is built from, unchanged apart from the vocabulary.
The same technique keeps whichever scripts you do ship: retaining kana and
ideographs alongside Latin lands at ~151 MB, still 27 MB under the original.
Labels
PER, ORG, LOC, DATE — unchanged from the base model, as B-/I- tags.
Usage (transformers.js)
1import { pipeline } from "@huggingface/transformers";
2
3const ner = await pipeline(
4 "token-classification",
5 "promptshield/minuscule",
6 { dtype: "q8" },
7);
8
9await ner("Le contrat a été signé par Jean-Baptiste Lefèvre à Bordeaux.", {
10 aggregation_strategy: "simple",
11});
It also loads in onnxruntime directly — it is a standard BERT token-classification
graph with input_ids, attention_mask and token_type_ids.
Provenance and licence
All credit for the model itself belongs to David Adelani (Davlan) for the
fine-tune, to the Google Research team for the base model, and to
Joshua Lochner (Xenova) for the ONNX export and int8 quantization this repo
is built directly on. We changed the vocabulary and nothing else.
The upstream card declares no training datasets; if your use has data-provenance
requirements, check with the original authors rather than relying on this card.
Who made this and why
Built for
promptShield, an offline document
anonymizer. Its web app runs detection
entirely in the browser — no document
ever leaves the device — so the model is a first-visit download, and 39 MB of
unreachable vocabulary was 39 MB charged to every visitor.
Published because the technique generalises: the embedding table is over half of
most multilingual encoders, and almost every deployment ships a fraction of the
104 languages.