Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

## 📖 Introduction

ZeroModels is a collection of pretrained models built entirely in Keras 3. It spans a broad range of tasks, including image classification, object detection, segmentation, monocular depth estimation, feature extraction, vision-language modeling (VLMs), speech recognition, speech-aware language modeling, text encoding and masked language modeling, large language models (LLMs), text-to-text encoder-decoder modeling, multimodal vision-language generation, text-to-image diffusion, and more.
ZeroModels is a collection of pretrained models built entirely in Keras 3. It spans a broad range of tasks, including image classification, object detection, segmentation, monocular depth estimation, feature extraction, vision-language modeling (VLMs), speech recognition, speech-aware language modeling, text encoding and masked language modeling, sentence embeddings, large language models (LLMs), text-to-text encoder-decoder modeling, multimodal vision-language generation, text-to-image diffusion, and more.

## ⚡ Installation

Expand All @@ -40,6 +40,28 @@ Classification backbones share a single [documentation page](https://imvision12.
Documentation sources are also available in [`docs/`](docs/).


## 💬 Sentence Transformers Models (sentence_transformers)

All 13 checkpoints below have pre-converted Keras weights under the `zeromodels` Hugging Face organization. Use `ZMSentenceTransformer` and `ZMSentenceTransformerTokenizer` from `zeromodels.sentence_transformers` for sentence similarity, semantic search, or clustering.

| 🏷️ Model Name | 📜 Reference Paper | 📦 Source of Weights |
|---------------|-------------------|---------------------|
| [all-mpnet-base-v2](https://huggingface.co/zeromodels/all-mpnet-base-v2) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [multi-qa-mpnet-base-dot-v1](https://huggingface.co/zeromodels/multi-qa-mpnet-base-dot-v1) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [all-distilroberta-v1](https://huggingface.co/zeromodels/all-distilroberta-v1) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [all-MiniLM-L12-v2](https://huggingface.co/zeromodels/all-MiniLM-L12-v2) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [multi-qa-distilbert-cos-v1](https://huggingface.co/zeromodels/multi-qa-distilbert-cos-v1) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [all-MiniLM-L6-v2](https://huggingface.co/zeromodels/all-MiniLM-L6-v2) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [multi-qa-MiniLM-L6-cos-v1](https://huggingface.co/zeromodels/multi-qa-MiniLM-L6-cos-v1) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [paraphrase-multilingual-mpnet-base-v2](https://huggingface.co/zeromodels/paraphrase-multilingual-mpnet-base-v2) | [Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation](https://arxiv.org/abs/2004.09813) | `sentence-transformers` |
| [paraphrase-albert-small-v2](https://huggingface.co/zeromodels/paraphrase-albert-small-v2) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [paraphrase-multilingual-MiniLM-L12-v2](https://huggingface.co/zeromodels/paraphrase-multilingual-MiniLM-L12-v2) | [Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation](https://arxiv.org/abs/2004.09813) | `sentence-transformers` |
| [paraphrase-MiniLM-L3-v2](https://huggingface.co/zeromodels/paraphrase-MiniLM-L3-v2) | [Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks](https://arxiv.org/abs/1908.10084) | `sentence-transformers` |
| [distiluse-base-multilingual-cased-v1](https://huggingface.co/zeromodels/distiluse-base-multilingual-cased-v1) | [Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation](https://arxiv.org/abs/2004.09813) | `sentence-transformers` |
| [distiluse-base-multilingual-cased-v2](https://huggingface.co/zeromodels/distiluse-base-multilingual-cased-v2) | [Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation](https://arxiv.org/abs/2004.09813) | `sentence-transformers` |

<br>

## 📑 Models

### 📝 Text Models
Expand Down Expand Up @@ -295,6 +317,7 @@ This project leverages [timm](https://github.com/huggingface/pytorch-image-model
- The [Transformers](https://github.com/huggingface/transformers) library for its robust tools for loading and adapting pretrained models
- The [pytorch-image-models (timm)](https://github.com/huggingface/pytorch-image-models) project for pioneering many computer vision model implementations
- The [Diffusers](https://github.com/huggingface/diffusers) library, the reference the diffusion models are converted from and verified against
- The [Sentence Transformers](https://github.com/huggingface/sentence-transformers) project for its sentence-embedding checkpoints and preprocessing recipes
- All contributors to the original papers and architectures implemented in this library

## Citing
Expand Down
23 changes: 23 additions & 0 deletions docs/auto.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ fine-tune of the same architecture loads exactly like the official weights.
inspect, so pass it to the concrete class instead
(`ResNetImageClassify.from_weights("resnet50_a1_in1k")`).

## Sentence Transformer models

All 13 ZeroModels-hosted Sentence Transformer checkpoints use
`model_type: "sentence_transformer"`. The Auto loaders resolve them to
`ZMSentenceTransformer` and `ZMSentenceTransformerTokenizer`:

```python
from zeromodels import AutoZModel, AutoZMTokenizer

repo = "zeromodels/all-MiniLM-L6-v2"
model = AutoZModel.from_weights(repo) # -> ZMSentenceTransformer
tokenizer = AutoZMTokenizer.from_weights(repo) # -> ZMSentenceTransformerTokenizer
embeddings = model.encode(["A cat on a mat.", "A dog on a mat."], tokenizer=tokenizer)
print(embeddings.shape) # (2, 384)
```

Here `AutoZModel` loads the complete sentence-embedding stack, including its
pooling, optional Dense projection, and normalization—not just the text encoder.
The tokenizer preserves the checkpoint's own preprocessing recipe. See
[Sentence Transformer](sentence_transformer.md) for the concrete API. Original
upstream `hf:sentence-transformers/...` configs describe their backbone type;
use the concrete classes to load their sentence-embedding recipe.

## Task classes

### Pipeline components
Expand Down
7 changes: 7 additions & 0 deletions docs/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ Encoders for embeddings and masked language modelling, and decoder LLMs, dense a
- [RoBERTa](roberta.md)
- [XLM-RoBERTa](xlm_roberta.md)

## Sentence Transformer models

Dense text embeddings with checkpoint-specific pooling and normalization.

- [All 13 Sentence Transformer checkpoints](sentence_transformers.md)
- [Sentence Transformer API and usage](sentence_transformer.md)

## Vision models

Detection, segmentation, monocular depth, and self-supervised backbones.
Expand Down
3 changes: 2 additions & 1 deletion docs/mpnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ See also [bert.md](bert.md), [roberta.md](roberta.md), [modernbert.md](modernber
[electra.md](electra.md).

MPNet is also the backbone of `sentence-transformers/all-mpnet-base-v2`, one of the most
widely used sentence-embedding models.
widely used sentence-embedding models — see [sentence_transformer.md](sentence_transformer.md)
for the separate embedding API.

## Variants

Expand Down
167 changes: 167 additions & 0 deletions docs/sentence_transformer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Sentence Transformer

<div class="kf-note kf-note--weights">
<b>Weights:</b> Pre-converted Keras weights for all 13 checkpoints are hosted under the
<a href="https://huggingface.co/zeromodels">zeromodels organization</a>. Load one with
<code>from_weights("zeromodels/all-MiniLM-L6-v2")</code>; no conversion is needed.
Original <code>sentence-transformers</code> checkpoints can also be converted on the fly
with the <code>hf:</code> prefix, e.g.
<code>from_weights("hf:sentence-transformers/all-MiniLM-L6-v2")</code>.
The backbone and embedding recipe are read from the checkpoint metadata.
</div>

ZeroModels loads 13 original dense sentence-embedding checkpoints. See the
[Sentence Transformer models](sentence_transformers.md) page for the available
ZeroModels-hosted checkpoint IDs and Hub links.
It builds a Keras 3 encoder and applies the checkpoint's declared pooling,
optional Dense projection, and optional L2 normalization. Parity has been
verified on the Keras Torch backend; TensorFlow and JAX parity have not yet
been checked for all 13 checkpoints.

The public API is `zeromodels.sentence_transformers`, separate from the upstream
`sentence_transformers` reference library. The former `zeromodels.st_models`
and `zeromodels.models.sentence_transformer` paths remain compatibility aliases
for existing code and saved metadata; new examples and exports use the new namespace.
Use `ZMSentenceTransformer` and `ZMSentenceTransformerTokenizer`; the former
`SentenceTransformer`, `SentenceTransformerModel`, and `SentenceTransformerTokenizer`
names remain compatibility aliases.

## Usage

```python
import os

os.environ["KERAS_BACKEND"] = "torch" # or "jax" / "tensorflow"

from zeromodels.sentence_transformers import (
ZMSentenceTransformer,
ZMSentenceTransformerTokenizer,
)

repo = "zeromodels/all-MiniLM-L6-v2"
model = ZMSentenceTransformer.from_weights(repo)
tokenizer = ZMSentenceTransformerTokenizer.from_weights(repo)

embeddings = model.encode(
["A man is eating food.", "A man is eating pasta."],
tokenizer=tokenizer,
)
print(embeddings.shape) # (2, 384)
print(model.similarity(embeddings[:1], embeddings[1:]))
```

`model(tokenizer(texts))` returns `embeddings` and `token_embeddings` tensors.
`encode()` batches raw strings and returns a NumPy array. Use the same repo for
the model and tokenizer. `model.similarity()` uses the checkpoint's declared
cosine or dot-product scoring function.

## Auto loading

The same ZeroModels-hosted repositories work with the Auto API:

```python
from zeromodels import AutoZModel, AutoZMTokenizer

repo = "zeromodels/all-MiniLM-L6-v2"
model = AutoZModel.from_weights(repo) # ZMSentenceTransformer
tokenizer = AutoZMTokenizer.from_weights(repo) # ZMSentenceTransformerTokenizer
```

Detection uses `model_type: "sentence_transformer"` in `zm_config.json`, so this
works for all 13 hosted checkpoints and compatible fine-tunes. The model's full
embedding recipe and the tokenizer's checkpoint-specific settings are preserved.

## Tokenizer preprocessing metadata

Each checkpoint uses its own `tokenizer.json` for the vocabulary, normalization,
token splitting, and special-token insertion. Optional `zm_preprocessor.json`
records the surrounding official configuration in two separate blocks:

```json
{
"library_name": "zeromodels",
"preprocessor_module": "zeromodels.sentence_transformers",
"preprocessor_class": "ZMSentenceTransformerTokenizer",
"tokenizer_file": "tokenizer.json",
"backbone_type": "bert",
"tokenizer_config": {
"do_lower_case": true,
"model_max_length": 512,
"cls_token": "[CLS]",
"sep_token": "[SEP]",
"pad_token": "[PAD]"
},
"sentence_transformer_config": {
"max_seq_length": 256,
"do_lower_case": false
}
}
```

This abbreviated example represents `all-MiniLM-L6-v2`. The tokenizer's own
lowercasing is already encoded in `tokenizer.json`; the Sentence Transformers
flag requests an additional normalization step only when true. The effective
sequence limit is 256, including special tokens. Padding and truncation sides
come from `tokenizer_config`, defaulting to right; batches pad to their longest
sequence and pairs use longest-first truncation.

Both metadata and tokenizer assets load from one resolved Hub commit, available
as `tokenizer.source_revision`. Pass `revision=` to select a particular snapshot.
An explicit `max_seq_len=` overrides the stored limit. Legacy repos without
`zm_preprocessor.json` continue to read the backbone and sequence limit from
`zm_config.json`, including its nested `text_config` form.

`write_zm_preprocessor(directory, tokenizer, variant)` exports a portable recipe
referencing `tokenizer.json` in the same repo, rather than a local cache path.
New exports set both `model_module` in `zm_config.json` and `preprocessor_module`
in `zm_preprocessor.json` to `zeromodels.sentence_transformers`.
Text preprocessing uses the `tokenizers` library; `transformers` is not needed
to load these converted checkpoints.

## Original Sentence Transformers checkpoints

To load directly from an original Sentence Transformers repo instead, use the
`hf:` prefix for both components and pass the model's resolved revision to the
tokenizer:

```python
upstream = "hf:sentence-transformers/all-MiniLM-L6-v2"
model = ZMSentenceTransformer.from_weights(upstream)
tokenizer = ZMSentenceTransformerTokenizer.from_weights(
upstream, revision=model.source_revision
)
```

An explicit commit SHA can be supplied as `revision=` to pin the upstream
snapshot.

`AutoZMTextEmbed` resolves ZeroModels `sentence_transformer` configs to the
`SentenceTransformerTextEmbed` task view. For upstream `hf:` repos, load the
concrete class as shown above: their root `model_type` describes the backbone,
not the sentence-embedding task.

Unsupported upstream module types, combinations, or pooling modes raise a
`ValueError` rather than silently changing the embedding recipe. Cross-encoders,
sparse encoders, and multi-vector encoders are separate tasks and are not
supported by this model.

## Parity check

The optional `sentence-transformers` dependency is needed only for comparison
against the original implementation. After the Usage example above, compare
the published ZeroModels weights with the matching original checkpoint:

```python
import numpy as np
from sentence_transformers import SentenceTransformer as ReferenceSentenceTransformer

texts = ["A man is eating food.", "A man is eating pasta."]
reference = ReferenceSentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
expected = reference.encode(texts, normalize_embeddings=False)
actual = model.encode(texts, tokenizer=tokenizer)
print("Maximum absolute difference:", np.max(np.abs(actual - expected)))
```

Use matching checkpoint names from the models table, compare in float32, and
record Hub commit SHAs for reproducible results. This downloads original
weights for comparison; it does not convert or publish a new checkpoint.
49 changes: 49 additions & 0 deletions docs/sentence_transformers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Sentence Transformer models

ZeroModels provides 13 converted dense sentence-embedding checkpoints. Each
checkpoint combines a text encoder with its original pooling, optional Dense
projection, and optional L2 normalization. Load them through the
[`zeromodels.sentence_transformers` API](sentence_transformer.md); no conversion is needed
for the ZeroModels-hosted weights.

| Checkpoint | Backbone | Embedding recipe | Dimensions |
|---|---|---|---:|
| [`all-mpnet-base-v2`](https://huggingface.co/zeromodels/all-mpnet-base-v2) | MPNet | Mean pooling → L2 normalization | 768 |
| [`multi-qa-mpnet-base-dot-v1`](https://huggingface.co/zeromodels/multi-qa-mpnet-base-dot-v1) | MPNet | CLS pooling; dot-product similarity | 768 |
| [`all-distilroberta-v1`](https://huggingface.co/zeromodels/all-distilroberta-v1) | RoBERTa | Mean pooling → L2 normalization | 768 |
| [`all-MiniLM-L12-v2`](https://huggingface.co/zeromodels/all-MiniLM-L12-v2) | BERT | Mean pooling → L2 normalization | 384 |
| [`multi-qa-distilbert-cos-v1`](https://huggingface.co/zeromodels/multi-qa-distilbert-cos-v1) | DistilBERT | Mean pooling → L2 normalization | 768 |
| [`all-MiniLM-L6-v2`](https://huggingface.co/zeromodels/all-MiniLM-L6-v2) | BERT | Mean pooling → L2 normalization | 384 |
| [`multi-qa-MiniLM-L6-cos-v1`](https://huggingface.co/zeromodels/multi-qa-MiniLM-L6-cos-v1) | BERT | Mean pooling → L2 normalization | 384 |
| [`paraphrase-multilingual-mpnet-base-v2`](https://huggingface.co/zeromodels/paraphrase-multilingual-mpnet-base-v2) | XLM-RoBERTa | Mean pooling | 768 |
| [`paraphrase-albert-small-v2`](https://huggingface.co/zeromodels/paraphrase-albert-small-v2) | ALBERT | Mean pooling | 768 |
| [`paraphrase-multilingual-MiniLM-L12-v2`](https://huggingface.co/zeromodels/paraphrase-multilingual-MiniLM-L12-v2) | BERT | Mean pooling | 384 |
| [`paraphrase-MiniLM-L3-v2`](https://huggingface.co/zeromodels/paraphrase-MiniLM-L3-v2) | BERT | Mean pooling | 384 |
| [`distiluse-base-multilingual-cased-v1`](https://huggingface.co/zeromodels/distiluse-base-multilingual-cased-v1) | DistilBERT | Mean pooling → Tanh Dense | 512 |
| [`distiluse-base-multilingual-cased-v2`](https://huggingface.co/zeromodels/distiluse-base-multilingual-cased-v2) | DistilBERT | Mean pooling → Tanh Dense | 512 |

The `paraphrase-multilingual-mpnet-base-v2` name is historical; the checkpoint
actually uses an XLM-RoBERTa backbone.

## Quick start

```python
import os

os.environ["KERAS_BACKEND"] = "torch" # or "jax" / "tensorflow"

from zeromodels.sentence_transformers import (
ZMSentenceTransformer,
ZMSentenceTransformerTokenizer,
)

repo = "zeromodels/all-MiniLM-L6-v2"
model = ZMSentenceTransformer.from_weights(repo)
tokenizer = ZMSentenceTransformerTokenizer.from_weights(repo)

embeddings = model.encode(["A cat on a mat.", "A dog on a mat."], tokenizer=tokenizer)
print(embeddings.shape) # (2, 384)
```

See [Sentence Transformer](sentence_transformer.md) for the complete API,
upstream `hf:` loading, similarity scoring, and parity-check instructions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ version = { attr = "zeromodels.__version__" }
source = ["zeromodels", "tests"]
omit = [
"zeromodels/models/*/convert_*.py",
"zeromodels/sentence_transformers/convert_*.py",
]

[tool.coverage.report]
Expand Down
Loading
Loading