Feature Extraction
Transformers
ONNX
Basque
bert
basque
euskara
int8
int4
quantized
text-embeddings-inference
Instructions to use itzune/berteus-onnx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use itzune/berteus-onnx with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="itzune/berteus-onnx")# Load model directly from transformers import AutoTokenizer, AutoModel tokenizer = AutoTokenizer.from_pretrained("itzune/berteus-onnx") model = AutoModel.from_pretrained("itzune/berteus-onnx", device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 11,100 Bytes
144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc ce9153a 144edcc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | ---
language: eu
library_name: transformers
license: apache-2.0
base_model: ixa-ehu/berteus-base-cased
tags:
- onnx
- bert
- basque
- euskara
- feature-extraction
- int8
- int4
- quantized
inference: false
---
# BERTeus ONNX (int8 + int4 quantized)
> β οΈ **This is an unofficial community conversion.** This is not the original BERTeus repository.
> The original model was created by **Rodrigo Agerri, IΓ±aki San Vicente, Jon Ander Campos, Ander Barrena, Xabier Saralegi, Aitor Soroa, and Eneko Agirre** at the [IXA NLP Group](https://ixa.eus/) (University of the Basque Country, UPV/EHU).
>
> π **Original model:** [`ixa-ehu/berteus-base-cased`](https://huggingface.co/ixa-ehu/berteus-base-cased)
>
> π **Paper:** [Give your Text Representation Models some Love: the Case for Basque](https://arxiv.org/abs/2004.00033) (LREC 2020)
---
## What is this?
This repository provides **ONNX-quantized** versions of [BERTeus](https://huggingface.co/ixa-ehu/berteus-base-cased), a monolingual BERT model pre-trained on Basque (Euskara). Two quantization levels are available:
- **int8** (`model_quantized.onnx`, 119 MB) β dynamic int8 quantization
- **int4** (`model_q4.onnx`, 85 MB) β weight-only int4 (MatMul) + int8 (embeddings)
Both enable efficient inference in:
- **JavaScript / TypeScript** via [`@huggingface/transformers`](https://github.com/huggingface/transformers.js) (Transformers.js) β runs in the browser via WebAssembly
- **Python** via [`optimum`](https://github.com/huggingface/optimum) with ONNX Runtime
- Any runtime that supports the ONNX format
### Why use this instead of the original?
| | Original (`ixa-ehu/berteus-base-cased`) | This repo (`itzune/berteus-onnx`) |
|---|---|---|
| Format | PyTorch / Safetensors | **ONNX (int8 or int4 quantized)** |
| Size | ~470 MB | **85 MB** (int4) or 119 MB (int8) + 74 MB (embeddings) |
| Python (PyTorch) | β
| β |
| Python (ONNX Runtime) | β | β
|
| Browser (WASM) | β | β
via Transformers.js |
| Speed (CPU) | Baseline | **~2β4Γ faster** (quantized + ONNX Runtime) |
The original PyTorch model remains the best choice for training, fine-tuning, or GPU inference. Use this ONNX version when you need **browser deployment, small download size, or fast CPU inference**.
### int4 vs int8 β which should I use?
| | int4 (`model_q4.onnx`) | int8 (`model_quantized.onnx`) |
|---|---|---|
| File size | **85 MB** | 119 MB |
| Transformers.js `dtype` | `'q4'` | `'q8'` |
| Quality (benchmark) | **+110 net** (85.5% accuracy) | +105 net (85.0% accuracy) |
| Ranking agreement vs fp32 | 96.7% | 96.7% |
| Mean score diff vs fp32 | 0.011 | 0.013 |
| Browser load time | ~2.8s | ~3.1s |
**Recommendation:** Use **int4** (`dtype: 'q4'`) for browser deployment β it is smaller, faster to load, and produces equivalent or better quality on the re-ranking benchmark. Use int8 if you need maximum backward compatibility with older Transformers.js versions.
---
## Model details
| Property | Value |
|---|---|
| Architecture | BERT (encoder only, `BertModel`) |
| Parameters | ~110M (encoder) + ~39M (embeddings) |
| Hidden size | 768 |
| Layers | 12 |
| Attention heads | 12 |
| Vocab size | 50,099 |
| Max sequence length | 512 |
| Training corpus | 224.6M tokens (Basque news + Wikipedia) |
| Quantization | int4 (weight-only, MatMul) + int8 (embeddings), or int8 (dynamic) |
**Note:** The original BERTeus checkpoint was saved as `BertModel` (encoder only) β it does **not** include the masked LM (MLM) prediction head. This means `BertForMaskedLM` will produce random MLM outputs. For masked LM tasks, use the static word embeddings approach described below, or fine-tune an MLM head on the original model.
### Quantization details
**int4** (`model_q4.onnx`): Two-step quantization using ONNX Runtime's `MatMulNBitsQuantizer`:
1. Encoder MatMul ops β int4 (weight-only, block_size=128, asymmetric) via `MatMulNBits` operator
2. Embedding Gather ops β int8 (QDQ: `DequantizeLinear`) via dynamic quantization
This approach keeps the embedding table in int8 (not int4) to avoid `GatherBlockQuantized`, which is not implemented on the WASM backend. The `MatMulNBits` operator IS supported on WASM in Transformers.js v3+.
**int8** (`model_quantized.onnx`): Standard dynamic int8 quantization using `MatMulInteger` + `DynamicQuantizeLinear` operators.
---
## Files
| File | Size | Description |
|---|---|---|
| `onnx/model_q4.onnx` | 85 MB | **int4 quantized** ONNX model (recommended for browser) |
| `onnx/model_quantized.onnx` | 119 MB | int8 quantized ONNX model |
| `word_embeddings_f16.bin` | 74 MB | Word embedding matrix (50,099 Γ 768) in float16 |
| `config.json` | 578 B | Model configuration |
| `tokenizer.json` | 1.2 MB | Fast tokenizer (Transformers.js compatible) |
| `tokenizer_config.json` | 1.3 KB | Tokenizer configuration |
| `special_tokens_map.json` | 125 B | Special tokens mapping |
| `vocab.txt` | 413 KB | WordPiece vocabulary |
| `embedding_meta.json` | 187 B | Embedding matrix metadata (vocab size, token IDs) |
### Why a separate embedding file?
The ONNX model outputs contextual hidden states, but the **static word embedding matrix** (the input embedding layer) is useful for tasks like lexical similarity and candidate scoring. We extract it as a separate float16 binary file (74 MB) to avoid loading the full model when only embeddings are needed.
---
## Usage
### Python (ONNX Runtime via Optimum)
```python
from optimum.onnxruntime import ORTModelForFeatureExtraction
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("itzune/berteus-onnx")
model = ORTModelForFeatureExtraction.from_pretrained("itzune/berteus-onnx")
inputs = tokenizer("Euskara munduko hizkuntzarik ederrena da.", return_tensors="pt")
outputs = model(**inputs)
# Contextual embeddings: [1, seq_len, 768]
hidden_states = outputs.last_hidden_state
```
### JavaScript / Browser (Transformers.js)
**int4 (recommended β smaller, faster):**
```javascript
import { AutoModel, AutoTokenizer, env } from '@huggingface/transformers';
const model = await AutoModel.from_pretrained('itzune/berteus-onnx', {
dtype: 'q4', // int4 quantization β 85 MB
device: 'wasm',
});
const tokenizer = await AutoTokenizer.from_pretrained('itzune/berteus-onnx');
const inputs = tokenizer('Euskara mundiko hizkuntzarik ederrena da.', {
truncation: true,
max_length: 512,
padding: false,
});
const outputs = await model(inputs);
// outputs.last_hidden_state.data β Float32Array of shape [1, seq_len, 768]
```
**int8 (alternative β slightly larger):**
```javascript
const model = await AutoModel.from_pretrained('itzune/berteus-onnx', {
dtype: 'q8', // int8 quantization β 119 MB
device: 'wasm',
});
```
### Using the embedding matrix (lexical similarity)
```python
import numpy as np
import struct
# Load float16 embeddings
with open("word_embeddings_f16.bin", "rb") as f:
raw = np.frombuffer(f.read(), dtype=np.float16)
embeddings = raw.reshape(50099, 768).astype(np.float32)
# Get embedding for a token ID
token_id = tokenizer.convert_tokens_to_ids("euskara")
word_embedding = embeddings[token_id] # 768-dim vector
```
```javascript
// Browser: load and convert float16 β float32
const response = await fetch('word_embeddings_f16.bin');
const buffer = await response.arrayBuffer();
const uint16 = new Uint16Array(buffer);
const float32 = new Float32Array(uint16.length);
// Convert each float16 β float32 (bit manipulation, see source)
```
---
## Use cases
### β
What this model is good for
| Use case | How |
|---|---|
| **Contextual embeddings** | Run the encoder, extract `last_hidden_state` for any token |
| **Sentence embeddings** | Mean-pool the `last_hidden_state` across tokens |
| **Lexical similarity** | Compare static word embeddings (from the `.bin` file) |
| **Candidate re-ranking** | Mask a position, compare `[MASK]` hidden state against candidate embeddings (cosine similarity) |
| **Feature extraction** | Feed hidden states to a downstream classifier (NER, POS, sentiment) |
| **Text classification** | Use `[CLS]` token output as a sentence representation |
### β What this model cannot do
| Limitation | Why |
|---|---|
| **Masked LM fill-in-the-blank** | The checkpoint has no MLM head (`cls` weights missing). Use the embedding similarity approach instead. |
| **Text generation** | BERT is encoder-only, not a generative model. |
| **Fine-tuning** | ONNX is an inference format. Fine-tune the [original PyTorch model](https://huggingface.co/ixa-ehu/berteus-base-cased) instead. |
### Masked embedding similarity (no MLM head needed)
Since the checkpoint lacks an MLM head, the recommended approach for "which word fits here?" tasks is:
1. Replace the target position with `[MASK]` (token ID 4)
2. Run the BERT encoder on the full sentence (bidirectional context)
3. Extract the `[MASK]` position's hidden state (768-dim)
4. For each candidate word, compute its static embedding (mean of subword piece embeddings)
5. Score by cosine similarity between the `[MASK]` hidden state and the candidate embedding
This is based on the lexical substitution approach from Paetzold & Specia (2017) and works well for spell-checker candidate re-ranking.
---
## Performance
### int4 vs int8 vs fp32 (933-case spell-correction re-ranking benchmark)
| Model | Size | Best weight | Accuracy | Net improvement | Mean score diff vs fp32 |
|---|---|---|---|---|---|
| PyTorch fp32 | 496 MB | w=12 | 84.2% | +99 | β |
| ONNX int8 | 119 MB | w=15 | 85.0% | +105 | 0.013 |
| **ONNX int4** | **85 MB** | **w=18** | **85.5%** | **+110** | **0.011** |
Both quantized variants slightly outperform fp32 PyTorch on this benchmark β quantization noise occasionally helps break ties in the re-ranking task. The int4 model is the best overall: smallest, fastest, and highest accuracy.
### Browser validation (30-case subset, Transformers.js WASM)
| Variant | Model load | T2 accuracy | Match Python ranking | Mean score diff |
|---|---|---|---|---|
| int4 (`q4`) | 2.8s | 80.0% | 96.7% | 0.011 |
| int8 (`q8`) | 3.1s | 73.3% | 96.7% | 0.013 |
The float16 embedding matrix has negligible precision loss compared to float32.
---
## Citation
If you use this model, please cite the **original** BERTeus paper:
```bibtex
@inproceedings{agerri2020give,
title = {Give your Text Representation Models some Love: the Case for Basque},
author = {Rodrigo Agerri and IΓ±aki San Vicente and Jon Ander Campos and Ander Barrena and Xabier Saralegi and Aitor Soroa and Eneko Agirre},
booktitle = {Proceedings of the 12th International Conference on Language Resources and Evaluation (LREC)},
year = {2020}
}
```
---
## License
The original BERTeus model is released under the Apache 2.0 license. This ONNX conversion is provided under the same license.
## Acknowledgements
All credit for the BERTeus model goes to the [IXA NLP Group](https://ixa.eus/) at the University of the Basque Country (UPV/EHU). This repository is merely a format conversion for deployment convenience.
|