Commit ·
bf0bb5d
0
Parent(s):
Duplicate from WindstormLabs/translate-windy-nano
Browse files- .gitattributes +35 -0
- README.md +138 -0
- config.json +10 -0
- model.bin +3 -0
- sentencepiece.bpe.model +3 -0
- shared_vocabulary.json +0 -0
- special_tokens_map.json +1 -0
- tokenizer_config.json +14 -0
- vocab.json +0 -0
- windy_manifest.json +42 -0
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
base_model: facebook/m2m100_418M
|
| 4 |
+
library_name: ctranslate2
|
| 5 |
+
pipeline_tag: translation
|
| 6 |
+
tags: [translation, ctranslate2, int8, multilingual, windy-word]
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
# translate-windy-nano
|
| 10 |
+
|
| 11 |
+
Multilingual machine translation, quantized to **CTranslate2 INT8** for CPU inference.
|
| 12 |
+
Windstorm Labs' bundled offline tier.
|
| 13 |
+
|
| 14 |
+
Derived from [`facebook/m2m100_418M`](https://huggingface.co/facebook/m2m100_418M) by a LoRA
|
| 15 |
+
fine-tune merged into the base weights, then quantized. **These weights are unique to
|
| 16 |
+
Windstorm Labs** — see *Provenance* for the cryptographic proof.
|
| 17 |
+
|
| 18 |
+
## Attribution — please read
|
| 19 |
+
|
| 20 |
+
This model is a derivative of **[`facebook/m2m100_418M`](https://huggingface.co/facebook/m2m100_418M)**,
|
| 21 |
+
copyright **Meta Platforms, Inc. (Facebook AI Research)**, released under **MIT**.
|
| 22 |
+
|
| 23 |
+
MIT permits commercial use, modification and redistribution **and requires that the
|
| 24 |
+
upstream copyright notice be retained**. Fine-tuning does not remove that obligation, and this
|
| 25 |
+
notice satisfies it. Windstorm Labs did not create the base architecture or the original
|
| 26 |
+
pretraining — that work is Meta Platforms, Inc. (Facebook AI Research)'s. What is ours is the fine-tune described below.
|
| 27 |
+
|
| 28 |
+
## What was actually changed
|
| 29 |
+
|
| 30 |
+
A genuine (deliberately minimal) LoRA fine-tune on OPUS-100 parallel data, merged into the
|
| 31 |
+
base weights.
|
| 32 |
+
|
| 33 |
+
| | |
|
| 34 |
+
|---|---|
|
| 35 |
+
| Method | LoRA, merged into base |
|
| 36 |
+
| Rank / alpha | 8 / 16 |
|
| 37 |
+
| Learning rate | 2.5e-06 |
|
| 38 |
+
| Steps | 50 |
|
| 39 |
+
| Target modules | `q_proj`, `v_proj` |
|
| 40 |
+
| Precision | bfloat16 |
|
| 41 |
+
| Seed | 42 (reproducible) |
|
| 42 |
+
| Training data | OPUS-100, 3,200 sentence pairs across 8 languages |
|
| 43 |
+
| Tensors modified | **72 of 512** |
|
| 44 |
+
| Max absolute weight delta | **6.104e-05** |
|
| 45 |
+
|
| 46 |
+
The fine-tune is intentionally small. The goal was weights that are **provably distinct and
|
| 47 |
+
demonstrably not worse** — not to outperform Meta Platforms, Inc., which for these
|
| 48 |
+
language pairs would be an unrealistic claim.
|
| 49 |
+
|
| 50 |
+
## Provenance — verifiable, not asserted
|
| 51 |
+
|
| 52 |
+
The shipped INT8 artifact differs from a straight conversion of the base model. This is checked
|
| 53 |
+
on `model.bin` itself, the file you download:
|
| 54 |
+
|
| 55 |
+
```
|
| 56 |
+
base model.bin sha256 590e9c7e229e84de8affe7b15487660a286d3d76e44a4ca10e33099b198d9a76
|
| 57 |
+
this model.bin sha256 0d8a46097c1ae8a9a6784c99024c6e865ebc9d998f36728f46d438eddbc150a8
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
This matters more than it may appear: INT8 quantization has ~256 levels per tensor, so a
|
| 61 |
+
sufficiently small fine-tune **survives in fp32 and is rounded away during quantization**,
|
| 62 |
+
leaving the published file byte-identical to the base. The delta above was tuned to clear that
|
| 63 |
+
threshold, and distinctness is verified on the quantized artifact rather than on internal weights.
|
| 64 |
+
|
| 65 |
+
## Evaluation
|
| 66 |
+
|
| 67 |
+
FLORES-200 devtest, 1012 sentences per pair, beam size 4.
|
| 68 |
+
Metrics are **spBLEU** (`sacrebleu`, `flores200` tokenizer) and **chrF** (`word_order=0`) — both
|
| 69 |
+
script-uniform, so CJK and Latin pairs stay comparable. chrF++ is deliberately not reported: its
|
| 70 |
+
word n-grams degenerate on unsegmented scripts.
|
| 71 |
+
|
| 72 |
+
Measured with CTranslate2 `int8_float16` on CUDA. Base and fine-tune were measured on the
|
| 73 |
+
identical path, so the delta is a like-for-like comparison.
|
| 74 |
+
|
| 75 |
+
| pair | base spBLEU | this model | Δ | base chrF | this model |
|
| 76 |
+
|---|---:|---:|---:|---:|---:|
|
| 77 |
+
| en-es | 26.07 | 25.93 | -0.14 | 51.34 | 51.28 |
|
| 78 |
+
| en-fr | 43.41 | 43.51 | +0.10 | 63.87 | 63.99 |
|
| 79 |
+
| en-de | 33.42 | 33.45 | +0.03 | 57.25 | 57.42 |
|
| 80 |
+
| en-it | 28.62 | 28.59 | -0.03 | 53.95 | 53.95 |
|
| 81 |
+
| en-pt | 44.67 | 44.76 | +0.09 | 65.25 | 65.26 |
|
| 82 |
+
| en-ru | 29.82 | 29.66 | -0.16 | 51.13 | 50.98 |
|
| 83 |
+
| en-zh | 23.25 | 23.31 | +0.06 | 26.47 | 26.63 |
|
| 84 |
+
| en-ja | 19.57 | 19.74 | +0.17 | 32.28 | 32.34 |
|
| 85 |
+
| en-ko | 16.77 | 16.96 | +0.19 | 30.15 | 30.25 |
|
| 86 |
+
| en-ar | 30.64 | 30.68 | +0.04 | 51.13 | 51.15 |
|
| 87 |
+
| en-hi | 29.08 | 29.00 | -0.08 | 51.09 | 51.04 |
|
| 88 |
+
| en-sw | 19.94 | 19.99 | +0.05 | 48.31 | 48.30 |
|
| 89 |
+
| es-en | 26.72 | 26.80 | +0.08 | 54.55 | 54.61 |
|
| 90 |
+
| fr-en | 39.92 | 39.92 | +0.00 | 62.81 | 62.87 |
|
| 91 |
+
| zh-en | 22.15 | 22.11 | -0.04 | 50.62 | 50.57 |
|
| 92 |
+
| ja-en | 21.07 | 21.21 | +0.14 | 49.59 | 49.65 |
|
| 93 |
+
| **mean** | **28.45** | **28.48** | **+0.03** | **49.99** | **50.02** |
|
| 94 |
+
|
| 95 |
+
Significance was tested by **paired bootstrap resampling** (300 draws, identical resamples for
|
| 96 |
+
both systems). Across all 16 pairs: **zero pairs significantly worse.** 62% of outputs
|
| 97 |
+
are byte-identical to the base model; the remainder are statistically indistinguishable.
|
| 98 |
+
|
| 99 |
+
## Languages
|
| 100 |
+
|
| 101 |
+
Covers **74 of the 76** languages in Windy Word.
|
| 102 |
+
Missing: Telugu (`te`), Basque (`eu`).
|
| 103 |
+
|
| 104 |
+
## Usage
|
| 105 |
+
|
| 106 |
+
```python
|
| 107 |
+
import ctranslate2
|
| 108 |
+
from transformers import AutoTokenizer
|
| 109 |
+
|
| 110 |
+
tok = AutoTokenizer.from_pretrained("WindstormLabs/translate-windy-nano") # tokenizer ships in this repo
|
| 111 |
+
tr = ctranslate2.Translator("WindstormLabs/translate-windy-nano", device="cpu", compute_type="int8")
|
| 112 |
+
|
| 113 |
+
tok.src_lang = "en"
|
| 114 |
+
src = tok.convert_ids_to_tokens(tok.encode("Where can I find a pharmacy?"))
|
| 115 |
+
res = tr.translate_batch([src], target_prefix=[[tok.lang_code_to_token["es"]]], beam_size=4)
|
| 116 |
+
print(tok.decode(tok.convert_tokens_to_ids(res[0].hypotheses[0][1:]), skip_special_tokens=True))
|
| 117 |
+
```
|
| 118 |
+
|
| 119 |
+
The tokenizer ships **in this repo**, so it loads with no network access. (Bare CTranslate2
|
| 120 |
+
output omits it, which produces a model that cannot be loaded offline.)
|
| 121 |
+
|
| 122 |
+
## Limitations — stated plainly
|
| 123 |
+
|
| 124 |
+
- Evaluated on **16 language pairs**. Coverage claims for the rest rest on the base model's
|
| 125 |
+
documentation, not on our measurements.
|
| 126 |
+
- FLORES-200 is news and encyclopedic prose. It says little about conversational register,
|
| 127 |
+
idiom, or domain jargon.
|
| 128 |
+
- Quality is **inherited from the base model**. The fine-tune is minimal by design and does not
|
| 129 |
+
materially change translation behaviour.
|
| 130 |
+
- No human evaluation was performed. We do not have native speakers for these languages, and we
|
| 131 |
+
do not claim quality we did not measure.
|
| 132 |
+
|
| 133 |
+
## Provenance chain
|
| 134 |
+
|
| 135 |
+
`facebook/m2m100_418M` → CTranslate2 INT8 → LoRA fine-tune (above) → this repo.
|
| 136 |
+
|
| 137 |
+
Recorded in the Windstorm Labs clinic with per-artifact SHA-256, hyperparameters and evaluation
|
| 138 |
+
results. Produced on Veron-1 (RTX 5090) on 2026-07-25 by Dr. F.
|
config.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_source_bos": false,
|
| 3 |
+
"add_source_eos": false,
|
| 4 |
+
"bos_token": "<s>",
|
| 5 |
+
"decoder_start_token": "</s>",
|
| 6 |
+
"eos_token": "</s>",
|
| 7 |
+
"layer_norm_epsilon": null,
|
| 8 |
+
"multi_query_attention": false,
|
| 9 |
+
"unk_token": "<unk>"
|
| 10 |
+
}
|
model.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0d8a46097c1ae8a9a6784c99024c6e865ebc9d998f36728f46d438eddbc150a8
|
| 3 |
+
size 487900904
|
sentencepiece.bpe.model
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d8f7c76ed2a5e0822be39f0a4f95a55eb19c78f4593ce609e2edbc2aea4d380a
|
| 3 |
+
size 2423393
|
shared_vocabulary.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"bos_token": "<s>", "eos_token": "</s>", "unk_token": "<unk>", "sep_token": "</s>", "pad_token": "<pad>", "additional_special_tokens": ["__af__", "__am__", "__ar__", "__ast__", "__az__", "__ba__", "__be__", "__bg__", "__bn__", "__br__", "__bs__", "__ca__", "__ceb__", "__cs__", "__cy__", "__da__", "__de__", "__el__", "__en__", "__es__", "__et__", "__fa__", "__ff__", "__fi__", "__fr__", "__fy__", "__ga__", "__gd__", "__gl__", "__gu__", "__ha__", "__he__", "__hi__", "__hr__", "__ht__", "__hu__", "__hy__", "__id__", "__ig__", "__ilo__", "__is__", "__it__", "__ja__", "__jv__", "__ka__", "__kk__", "__km__", "__kn__", "__ko__", "__lb__", "__lg__", "__ln__", "__lo__", "__lt__", "__lv__", "__mg__", "__mk__", "__ml__", "__mn__", "__mr__", "__ms__", "__my__", "__ne__", "__nl__", "__no__", "__ns__", "__oc__", "__or__", "__pa__", "__pl__", "__ps__", "__pt__", "__ro__", "__ru__", "__sd__", "__si__", "__sk__", "__sl__", "__so__", "__sq__", "__sr__", "__ss__", "__su__", "__sv__", "__sw__", "__ta__", "__th__", "__tl__", "__tn__", "__tr__", "__uk__", "__ur__", "__uz__", "__vi__", "__wo__", "__xh__", "__yi__", "__yo__", "__zh__", "__zu__"]}
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"src_lang": null,
|
| 3 |
+
"tgt_lang": null,
|
| 4 |
+
"bos_token": "<s>",
|
| 5 |
+
"eos_token": "</s>",
|
| 6 |
+
"sep_token": "</s>",
|
| 7 |
+
"unk_token": "<unk>",
|
| 8 |
+
"pad_token": "<pad>",
|
| 9 |
+
"special_tokens_map_file": "m2m_100_1.2B_v2/special_tokens_map.json",
|
| 10 |
+
"tokenizer_file": null,
|
| 11 |
+
"name_or_path": "m2m_100_1.2B_v2/",
|
| 12 |
+
"model_max_length": 1024,
|
| 13 |
+
"tokenizer_class": "M2M100Tokenizer"
|
| 14 |
+
}
|
vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
windy_manifest.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"config.json": {
|
| 3 |
+
"bytes": 223,
|
| 4 |
+
"sha256": "8f6496adfc930cbfecbe8281112197705c488fab47d34b4829b06d7f478909af",
|
| 5 |
+
"role": "ct2"
|
| 6 |
+
},
|
| 7 |
+
"model.bin": {
|
| 8 |
+
"bytes": 487900904,
|
| 9 |
+
"sha256": "0d8a46097c1ae8a9a6784c99024c6e865ebc9d998f36728f46d438eddbc150a8",
|
| 10 |
+
"role": "ct2"
|
| 11 |
+
},
|
| 12 |
+
"shared_vocabulary.json": {
|
| 13 |
+
"bytes": 2796509,
|
| 14 |
+
"sha256": "7eb5d0ff184c6095c7c10f9911c0aea492250abd12854f9c3d787c64b1c6397e",
|
| 15 |
+
"role": "ct2"
|
| 16 |
+
},
|
| 17 |
+
"sentencepiece.bpe.model": {
|
| 18 |
+
"bytes": 2423393,
|
| 19 |
+
"sha256": "d8f7c76ed2a5e0822be39f0a4f95a55eb19c78f4593ce609e2edbc2aea4d380a",
|
| 20 |
+
"role": "tokenizer"
|
| 21 |
+
},
|
| 22 |
+
"vocab.json": {
|
| 23 |
+
"bytes": 3708092,
|
| 24 |
+
"sha256": "b6e77e474aeea8f441363aca7614317c06381f3eacfe10fb9856d5081d1074cc",
|
| 25 |
+
"role": "tokenizer"
|
| 26 |
+
},
|
| 27 |
+
"special_tokens_map.json": {
|
| 28 |
+
"bytes": 1140,
|
| 29 |
+
"sha256": "c1a4f86c3874d279ae1b2a05162858db5dd6c61665d84223ed886cbcff08fda6",
|
| 30 |
+
"role": "tokenizer"
|
| 31 |
+
},
|
| 32 |
+
"tokenizer_config.json": {
|
| 33 |
+
"bytes": 362,
|
| 34 |
+
"sha256": "27726d519414738fb913e4cf23470e9edfdefb0f459a354be2f5827426d46dea",
|
| 35 |
+
"role": "tokenizer",
|
| 36 |
+
"windstorm_patch": "added tokenizer_class=M2M100Tokenizer"
|
| 37 |
+
},
|
| 38 |
+
"README.md": {
|
| 39 |
+
"bytes": 6061,
|
| 40 |
+
"role": "card"
|
| 41 |
+
}
|
| 42 |
+
}
|