{"article":{"slug":"model2vec-v0-10-0","title":"Model2Vec v0.10.0","subtitle":null,"summary":"Release notes for Model2Vec 0.10.0: major training-side improvements to the fast static embeddings library, with links to the PyPI release and what changed for practitioners.","content_type":"changelog","language":"en","canonical_url":"https://minish.ai/blog/2026-10-12-model2vec-0100/","author":{"name":"Minish","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Minish","url":"https://minish.ai/","listing_slug":null,"listing":null},"topics":[{"name":"AI","slug":"ai","url":"https://listedarticles.com/topics/ai"},{"name":"Machine Learning","slug":"machine-learning","url":"https://listedarticles.com/topics/machine-learning"},{"name":"Open Source","slug":"open-source","url":"https://listedarticles.com/topics/open-source"},{"name":"Developer Tools","slug":"developer-tools","url":"https://listedarticles.com/topics/developer-tools"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":929,"reading_minutes":4,"published_at":"2026-10-12T00:00:00.000Z","added_at":"2026-10-14T02:17:13.559Z","updated_at":"2026-10-14T02:17:13.559Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/model2vec-v0-10-0","markdown_url":"https://listedarticles.com/articles/model2vec-v0-10-0.md","example":false,"citation":"Minish, Minish. \"Model2Vec v0.10.0.\" 12 Oct 2026. https://minish.ai/blog/2026-10-12-model2vec-0100/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://minish.ai/blog/2026-10-12-model2vec-0100/"},"body_markdown":"# Model2Vec v0.10.0\n\nMost of this release is about training. It adds a pair-similarity trainer, lets `fit` take Hugging Face `datasets` columns directly, and adds focal loss, token dropout and faster training. It also adds a public ONNX export API that can export classifier and regressor pipelines, and fixes a number of tokenization and padding bugs.\n\n## ⚠️ Breaking changes\n\n- `StaticModel.tokenize` no longer takes`max_length` . Truncation now follows the model’s`max_length` property, which has a new setter (#356, #363).\n- `encode_as_sequence` ignores the model’s`max_length` . It only truncates if you pass`max_length` to the call yourself (#363).\n- The ONNX export script has been replaced by a function. `scripts/export_to_onnx.py` is gone, so use`model2vec.onnx.export_model_to_onnx(model, save_path, ...)` instead (#347).\n- Trainable models no longer use a pad token. The `pad_token` argument of`from_pretrained` and`from_static_model` and the`pad_id` constructor argument have been removed (#390).\n- Token weights in trainable models are no longer passed through a sigmoid. They’re trained directly and start at 1 (#371). Training code that reads `model.w` directly will see different values.\n- `freeze_weights` now defaults to`None` . With`None` , a model that has token weights trains them, and a model without token weights takes the unweighted mean of its token embeddings. Previously, a model without weights always learned new ones. To keep that behavior, pass`freeze_weights=False` (#390).\n- Dependency changes:\n  - `huggingface-hub>=1.0.0` is now a core dependency (#345).\n  - The `distill` extra no longer needs`scikit-learn` , because PCA is now implemented in NumPy (#344). It now requires`skeletoken>=0.6.0,<0.7.0` .\n  - The `train` extra now requires`datasets>=4.0.0` (#387).\n  - The `onnx` extra now includes`onnxruntime` ,`onnxscript` and`skeletoken` (#347).\n\n## ✨ New features\n\n### Training\n\n- **Pair similarity:**`StaticModelForPairSimilarity` is a new trainer that embeds related pairs of texts close together, such as queries and their documents (#372). It’s trained with an InfoNCE loss over in-batch negatives, and its`temperature` argument defaults to`0.05` (#381). With`n_layers=0` , pair and similarity models have no head, so`to_static_model` returns exactly the trained embeddings (#383).\n- **Hugging Face datasets:**`fit` accepts dataset columns such as`dataset[\"text\"]` directly. Data is read and tokenized per batch, so the dataset isn’t loaded into memory. Without an explicit validation set, the held-out split is capped at 10,000 rows, and single-label classification splits are stratified (#387).\n- **Focal loss:**`StaticModelForClassification.fit(..., focal_gamma=...)` down-weights texts the model already classifies confidently. It supports single-label and multi-label classification and can be combined with`class_weight` . The default,`0.0` , is plain (binary) cross-entropy (#391).\n- **Token dropout:**`fit(..., token_dropout=...)` randomly drops a fraction of the tokens of each training text. A non-empty text always keeps at least one token. It’s available for all trainers, and for pair similarity it applies to both texts of a pair (#373, #393).\n- **Faster training:** training was reworked (#387, #390). The classification example in the training README now trains in 31 seconds instead of 81, and reaches 92% accuracy instead of 91%.\n- **Explicit arguments:**`from_pretrained` and`from_static_model` on every trainable class now list and document their arguments (`max_length` ,`n_layers` ,`hidden_dim` ,`out_dim` ,`freeze` ,`normalize` ,`freeze_weights` ). You no longer have to pass them blindly through`**kwargs` (#388, #389).\n- **More metrics in the progress bar:** classifiers now show extra metrics, such as accuracy, in the training progress bar (#384).\n\n### ONNX\n\n- Classifier and regressor pipelines can be exported to ONNX with their heads included (#346).\n- Exports now include a model card, and `source_model_name` records which model was exported (#349).\n\n### Inference and loading\n\n- **Faster encoding:** parallel encoding now uses threads, and int8 models are cast to float32 before encoding (#367).\n- `StaticModel` has a`max_length` property with a setter. ONNX export respects it too (#356).\n- Hub downloads only fetch model2vec files and the README, so the rest of a repository is skipped (#370, #392).\n- Download progress bars are now silenced (#345).\n\n## 🐛 Bug fixes\n\n- Padding and tokenization:\n  - Padding is turned off during distillation, inference and training, so texts are no longer padded to the longest text in a chunk (#376, #379).\n  - Unknown tokens are dropped during training and inference, matching how `StaticModel` tokenizes (#359).\n  - The unk token is fixed for Unigram tokenizers (#354), and added tokens get correct start-of-word handling (#351).\n- Training:\n  - Texts without any tokens no longer cause NaN gradients (#380).\n  - The trainer now restores the best checkpoint, not the last one (#352).\n  - The trainer’s `max_length` no longer depends on the static model’s tokenizer truncation (#374).\n  - `random_seed` now also controls the train/validation split. Before, the split always used the default seed (#396).\n- Loading:\n  - `subfolder` is now respected when downloading from the Hub, and a cached model is only reused if it actually contains a valid model (#392).\n  - The `token` argument is now passed through when a pipeline loads its encoder (#362).\n- ONNX:\n  - Export correctly ignores the unk token (#353).\n  - Vocabulary-quantized models are exported with their token mapping and weights (#364).\n- Other:\n  - Distillation now guards against duplicate tokens, and added tokens are normalized (#350).\n  - Fixed a float16 norm underflow (#369).\n\n## 📚 Docs and maintenance\n\n- The training docs were rewritten to cover every trainer, focal loss and token dropout. The training benchmark was also rerun on 26 datasets, with fastText and a fully fine-tuned MiniLM as new baselines (#397).\n- The tutorial notebooks were removed (#394).\n- Added contribution guidelines (#386), updated the main README (#361), fixed the classifier docstring (#366), and added a Greptile acknowledgement (#377).\n- Added a new integration test (#355). Loader return types now use `T` (#357), and some encoding code was refactored to remove duplication (#365).","body_html":"<h1 id=\"model2vec-v0-10-0\">Model2Vec v0.10.0</h1>\n<p>Most of this release is about training. It adds a pair-similarity trainer, lets <code>fit</code> take Hugging Face <code>datasets</code> columns directly, and adds focal loss, token dropout and faster training. It also adds a public ONNX export API that can export classifier and regressor pipelines, and fixes a number of tokenization and padding bugs.</p>\n<h2 id=\"breaking-changes\">⚠️ Breaking changes</h2>\n<ul><li><code>StaticModel.tokenize</code> no longer takes<code>max_length</code> . Truncation now follows the model’s<code>max_length</code> property, which has a new setter (#356, #363).</li><li><code>encode_as_sequence</code> ignores the model’s<code>max_length</code> . It only truncates if you pass<code>max_length</code> to the call yourself (#363).</li><li>The ONNX export script has been replaced by a function. <code>scripts/export_to_onnx.py</code> is gone, so use<code>model2vec.onnx.export_model_to_onnx(model, save_path, ...)</code> instead (#347).</li><li>Trainable models no longer use a pad token. The <code>pad_token</code> argument of<code>from_pretrained</code> and<code>from_static_model</code> and the<code>pad_id</code> constructor argument have been removed (#390).</li><li>Token weights in trainable models are no longer passed through a sigmoid. They’re trained directly and start at 1 (#371). Training code that reads <code>model.w</code> directly will see different values.</li><li><code>freeze_weights</code> now defaults to<code>None</code> . With<code>None</code> , a model that has token weights trains them, and a model without token weights takes the unweighted mean of its token embeddings. Previously, a model without weights always learned new ones. To keep that behavior, pass<code>freeze_weights=False</code> (#390).</li><li>Dependency changes:<ul><li><code>huggingface-hub&gt;=1.0.0</code> is now a core dependency (#345).</li><li>The <code>distill</code> extra no longer needs<code>scikit-learn</code> , because PCA is now implemented in NumPy (#344). It now requires<code>skeletoken&gt;=0.6.0,&lt;0.7.0</code> .</li><li>The <code>train</code> extra now requires<code>datasets&gt;=4.0.0</code> (#387).</li><li>The <code>onnx</code> extra now includes<code>onnxruntime</code> ,<code>onnxscript</code> and<code>skeletoken</code> (#347).</li></ul></li></ul>\n<h2 id=\"new-features\">✨ New features</h2>\n<h3 id=\"training\">Training</h3>\n<ul><li><strong>Pair similarity:</strong><code>StaticModelForPairSimilarity</code> is a new trainer that embeds related pairs of texts close together, such as queries and their documents (#372). It’s trained with an InfoNCE loss over in-batch negatives, and its<code>temperature</code> argument defaults to<code>0.05</code> (#381). With<code>n_layers=0</code> , pair and similarity models have no head, so<code>to_static_model</code> returns exactly the trained embeddings (#383).</li><li><strong>Hugging Face datasets:</strong><code>fit</code> accepts dataset columns such as<code>dataset[&quot;text&quot;]</code> directly. Data is read and tokenized per batch, so the dataset isn’t loaded into memory. Without an explicit validation set, the held-out split is capped at 10,000 rows, and single-label classification splits are stratified (#387).</li><li><strong>Focal loss:</strong><code>StaticModelForClassification.fit(..., focal_gamma=...)</code> down-weights texts the model already classifies confidently. It supports single-label and multi-label classification and can be combined with<code>class_weight</code> . The default,<code>0.0</code> , is plain (binary) cross-entropy (#391).</li><li><strong>Token dropout:</strong><code>fit(..., token_dropout=...)</code> randomly drops a fraction of the tokens of each training text. A non-empty text always keeps at least one token. It’s available for all trainers, and for pair similarity it applies to both texts of a pair (#373, #393).</li><li><strong>Faster training:</strong> training was reworked (#387, #390). The classification example in the training README now trains in 31 seconds instead of 81, and reaches 92% accuracy instead of 91%.</li><li><strong>Explicit arguments:</strong><code>from_pretrained</code> and<code>from_static_model</code> on every trainable class now list and document their arguments (<code>max_length</code> ,<code>n_layers</code> ,<code>hidden_dim</code> ,<code>out_dim</code> ,<code>freeze</code> ,<code>normalize</code> ,<code>freeze_weights</code> ). You no longer have to pass them blindly through<code>**kwargs</code> (#388, #389).</li><li><strong>More metrics in the progress bar:</strong> classifiers now show extra metrics, such as accuracy, in the training progress bar (#384).</li></ul>\n<h3 id=\"onnx\">ONNX</h3>\n<ul><li>Classifier and regressor pipelines can be exported to ONNX with their heads included (#346).</li><li>Exports now include a model card, and <code>source_model_name</code> records which model was exported (#349).</li></ul>\n<h3 id=\"inference-and-loading\">Inference and loading</h3>\n<ul><li><strong>Faster encoding:</strong> parallel encoding now uses threads, and int8 models are cast to float32 before encoding (#367).</li><li><code>StaticModel</code> has a<code>max_length</code> property with a setter. ONNX export respects it too (#356).</li><li>Hub downloads only fetch model2vec files and the README, so the rest of a repository is skipped (#370, #392).</li><li>Download progress bars are now silenced (#345).</li></ul>\n<h2 id=\"bug-fixes\">🐛 Bug fixes</h2>\n<ul><li>Padding and tokenization:<ul><li>Padding is turned off during distillation, inference and training, so texts are no longer padded to the longest text in a chunk (#376, #379).</li><li>Unknown tokens are dropped during training and inference, matching how <code>StaticModel</code> tokenizes (#359).</li><li>The unk token is fixed for Unigram tokenizers (#354), and added tokens get correct start-of-word handling (#351).</li></ul></li><li>Training:<ul><li>Texts without any tokens no longer cause NaN gradients (#380).</li><li>The trainer now restores the best checkpoint, not the last one (#352).</li><li>The trainer’s <code>max_length</code> no longer depends on the static model’s tokenizer truncation (#374).</li><li><code>random_seed</code> now also controls the train/validation split. Before, the split always used the default seed (#396).</li></ul></li><li>Loading:<ul><li><code>subfolder</code> is now respected when downloading from the Hub, and a cached model is only reused if it actually contains a valid model (#392).</li><li>The <code>token</code> argument is now passed through when a pipeline loads its encoder (#362).</li></ul></li><li>ONNX:<ul><li>Export correctly ignores the unk token (#353).</li><li>Vocabulary-quantized models are exported with their token mapping and weights (#364).</li></ul></li><li>Other:<ul><li>Distillation now guards against duplicate tokens, and added tokens are normalized (#350).</li><li>Fixed a float16 norm underflow (#369).</li></ul></li></ul>\n<h2 id=\"docs-and-maintenance\">📚 Docs and maintenance</h2>\n<ul><li>The training docs were rewritten to cover every trainer, focal loss and token dropout. The training benchmark was also rerun on 26 datasets, with fastText and a fully fine-tuned MiniLM as new baselines (#397).</li><li>The tutorial notebooks were removed (#394).</li><li>Added contribution guidelines (#386), updated the main README (#361), fixed the classifier docstring (#366), and added a Greptile acknowledgement (#377).</li><li>Added a new integration test (#355). Loader return types now use <code>T</code> (#357), and some encoding code was refactored to remove duplication (#365).</li></ul>","headings":[{"level":1,"text":"Model2Vec v0.10.0","id":"model2vec-v0-10-0"},{"level":2,"text":"⚠️ Breaking changes","id":"breaking-changes"},{"level":2,"text":"✨ New features","id":"new-features"},{"level":3,"text":"Training","id":"training"},{"level":3,"text":"ONNX","id":"onnx"},{"level":3,"text":"Inference and loading","id":"inference-and-loading"},{"level":2,"text":"🐛 Bug fixes","id":"bug-fixes"},{"level":2,"text":"📚 Docs and maintenance","id":"docs-and-maintenance"}]}}