Feature Extraction
sentence-transformers
Safetensors
Chinese
English
minimind
text-embedding
chinese
qwen3-embedding
matryoshka
Instructions to use Muzian/minimind-embedding-dense with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- sentence-transformers
How to use Muzian/minimind-embedding-dense with sentence-transformers:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("Muzian/minimind-embedding-dense") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium." ] embeddings = model.encode(sentences) similarities = model.similarity(embeddings, embeddings) print(similarities.shape) # [3, 3] - Notebooks
- Google Colab
- Kaggle
| language: | |
| - zh | |
| - en | |
| license: apache-2.0 | |
| library_name: sentence-transformers | |
| tags: | |
| - text-embedding | |
| - sentence-transformers | |
| - feature-extraction | |
| - chinese | |
| - minimind | |
| - qwen3-embedding | |
| - matryoshka | |
| base_model: jingyaogong/minimind-3 | |
| pipeline_tag: feature-extraction | |
| <div align="center"> | |
| <img src="./images/banner.png" alt="MiniMind-Embedding" width="100%"> | |
| </div> | |
| # MiniMind-Embedding-Dense | |
| <div align="center"> | |
|  | |
|  | |
|  | |
|  | |
| </div> | |
| A text embedding model built on the [MiniMind-3](https://huggingface.co/jingyaogong/minimind-3-pytorch) small language model (64M params), with the training pipeline fully aligned with [Qwen3-Embedding](https://arxiv.org/abs/2506.05176). Part of the [minimind-embedding](https://github.com/muzian666/minimind-embedding) project. | |
| ## π Introduction | |
| This model turns the 64M MiniMind-3 causal language model into a text encoder using three key techniques: | |
| ### 1. Last-Token Pooling | |
| > π‘ *Think of a sentence as a queue of people. The last person (EOS) has "heard" everyone before them through causal attention, so they alone can summarize the whole sentence.* | |
| <div align="center"> | |
|  | |
| </div> | |
| Instead of BERT-style bidirectional attention + mean pooling, we keep **causal (unidirectional) attention** and take the hidden state at the appended EOS token. The last token aggregates information from all preceding tokens via causal attention, naturally serving as a sentence summary. This maximizes reuse of pretrained weights. | |
| ### 2. InfoNCE + False-Negative Masking | |
| > π‘ *Contrastive learning is like a "find your friend" game: push the correct match closer, push strangers further away. But what if a "stranger" is actually your friend (false negative)? We detect and mask them!* | |
| <div align="center"> | |
|  | |
| </div> | |
| The core loss is InfoNCE (contrastive). Qwen3-Embedding adds a **false-negative mask**: if a candidate negative is *more* similar to the query than the positive (beyond margin=0.1), it's likely a false negative and gets masked out. | |
| <div align="center"> | |
|  | |
| </div> | |
| ### 3. Matryoshka Representation Learning (MRL) | |
| > π‘ *Like Russian nesting dolls β the big doll (768-dim) contains smaller dolls (512/256/128/64-dim), each fully functional at its size.* | |
| <div align="center"> | |
|  | |
| </div> | |
| Trained so the vector works at any truncated dimension. Use 64-dim for fast coarse retrieval, 768-dim for precise re-ranking. | |
| ## ποΈ Model Details | |
| | Item | Value | | |
| |------|-------| | |
| | Architecture | MiniMind-3 (causal decoder-only Transformer) | | |
| | Parameters | 64M | | |
| | Hidden size | 768 | | |
| | Layers | 8 | | |
| | Attention heads | 8 (query) / 4 (KV, GQA) | | |
| | Vocab size | 6400 | | |
| | Embedding output dim | 768 (MRL: truncatable to 512/256/128/64) | | |
| | Max sequence length | 8192 (backbone supports 32768) | | |
| | Pooling | last-token | | |
| | Features | L2-normalized; MRL multi-dim | | |
| ## π Training Details (3 Stages) | |
| | Stage | Data | Loss | Steps | Final Loss | Status | | |
| |-------|------|------|-------|------------|--------| | |
| | **1. Weakly-supervised** | T2Ranking triplets (90k) | Standard InfoNCE | 1,413 | 0.43 | β Done | | |
| | **2. Supervised** | T2Ranking-15 (340k, 15 hard negs) | InfoNCE + false-neg mask + MRL | 63,768 (3 epochs) | 0.72 | β Done | | |
| | **3. Model merging** | Last 5 Stage-2 checkpoints | SLERP | β | β | β Done | | |
| <div align="center"> | |
|  | |
| *Stage 1 (left): 1.16β0.43. Stage 2 (right): 1.47β0.72, 3 epochs with epoch boundaries marked.* | |
| </div> | |
| | Hyperparameter | Value | | |
| |----------------|-------| | |
| | Temperature Ο | 0.02 | | |
| | False-neg margin | 0.1 | | |
| | Hard negatives | 7 per query | | |
| | Batch size | 16 | | |
| | Learning rate | 1e-5 (Stage 2), 2e-4 (Stage 1) | | |
| | MRL dims | [768, 512, 256, 128, 64] | | |
| ## π Evaluation | |
| <div align="center"> | |
|  | |
| </div> | |
| | Task | Samples | Score | | |
| |------|---------|:-----:| | |
| | ATEC | 20,000 | 0.265 | | |
| | BQ | 10,000 | 0.379 | | |
| | LCQMC | 12,500 | 0.631 | | |
| | STSB | 1,361 | 0.637 | | |
| | **Average** | | **0.478** | | |
| <div align="center"> | |
|  | |
| </div> | |
| | Model | Params | C-MTEB STS | | |
| |-------|--------|:----------:| | |
| | **This model** | **64M** | **0.478** | | |
| | BGE-small-zh | 24M | ~0.60 | | |
| | BGE-large-zh | 326M | ~0.66 | | |
| | Qwen3-Embedding-0.6B | 600M | ~0.66 | | |
| > **Honest note**: scores are bounded by the small vocab (6400) and limited Stage-1 data (90k vs Qwen3's 150M). The value is the **complete, reproducible** Qwen3-Embedding pipeline. | |
| ## π Usage | |
| ### sentence-transformers | |
| ```python | |
| from sentence_transformers import SentenceTransformer | |
| from sentence_transformers.util import cos_sim | |
| model = SentenceTransformer("Muzian/minimind-embedding-dense") | |
| documents = ["倩空εθθ²ζ―ε δΈΊι³ε ζ£ε°γ", "ηΊ’η§θηεζ³ζ―..."] | |
| doc_embs = model.encode(documents, normalize_embeddings=True) | |
| queries = ["倩空为δ»δΉζ―θθ²η"] | |
| query_embs = model.encode(queries, prompt_name="query", normalize_embeddings=True) | |
| scores = cos_sim(query_embs, doc_embs) | |
| ``` | |
| ### Matryoshka (truncate dimensions) | |
| ```python | |
| # Use only first 256 dims (smaller index, faster search) | |
| emb_256 = embedding[:, :256] | |
| emb_256 = F.normalize(emb_256, p=2, dim=1) | |
| ``` | |
| ## β οΈ Limitations | |
| 1. **Small vocabulary (6400)** β weak Chinese compression, primary bottleneck | |
| 2. **Limited Stage-1 data** (90k vs Qwen3's 150M) β scaling is the top improvement direction | |
| 3. SLERP merging shows minimal gain on small models (Stage2 β Stage3) | |
| ## π Acknowledgements | |
| - Base: [MiniMind](https://github.com/jingyaogong/minimind) by @jingyaogong | |
| - Route: [Qwen3-Embedding](https://arxiv.org/abs/2506.05176) | |
| - Data: [T2Ranking](https://huggingface.co/datasets/THUIR/T2Ranking) | |
| - Eval: [MTEB](https://github.com/embeddings-benchmark/mteb) | |
| ## π License | |
| Apache 2.0 | |