faxenoff's picture
Model card: R2 (gte-modernbert distill) + reranker section
a2f1eb6 verified
|
Raw
History Blame Contribute Delete
8.66 kB
---
license: mit
language:
- code
- multilingual
tags:
- code
- code-search
- code-retrieval
- embeddings
- feature-extraction
- sentence-similarity
- knowledge-distillation
pipeline_tag: feature-extraction
base_model:
- Alibaba-NLP/gte-modernbert-base
datasets:
- Fsoft-AIC/the-vault-function
- unicamp-dl/mmarco
- sentence-transformers/all-nli
- sentence-transformers/gooaq
- jinaai/negation-dataset
---
# code-daemon-embed-v1
A small, fast **code-embedding model** for semantic code search and code retrieval. It maps short code
units β€” function and method bodies, signatures, docstrings β€” and short natural-language queries into a
shared **768-dim** vector space.
It is **specialized for short code, not long documents**: the maximum sequence is **128 tokens**,
trading long-context capability for high throughput and strong quality on short units.
- **768-dim** embeddings, **Matryoshka (MRL)** β€” truncatable to **512 / 256** dims with graceful decay.
- **~54.5M params** β€” XLM-RoBERTa architecture, **4 layers / 768 hidden**, a **code-oriented 32k SentencePiece vocab**.
- **Mean pooling fused into the graph** β€” the output is already pooled (`[batch, 768]`); just **L2-normalize**.
- Trained at sequence length **128** (length buckets s / m / l = seq **40 / 64 / 128**).
## Where it's good β€” and where it isn't
Measured on CoIR (NDCG@10, full corpora). Use it for:
**Strong:**
- **Code β†’ related code** β€” finding similar or duplicate implementations (its best relative area).
- **Natural-language β†’ code** β€” docstring or description β†’ function (strongest on Python).
- **Short question β†’ code** β€” "how / where does X…".
- **NL β†’ SQL** and **NL instruction β†’ code**.
**Weak / out of scope:**
- **Long documents** β€” hard 128-token cap; longer inputs are truncated. This is not a long-context retriever.
- **Noisy / ambiguous NL→code** (hard, under-specified queries) — mid quality.
- **General English prose** (medical / financial / news) β€” the code-specialized 32k vocab trades
general-text coverage for code. Multilingual text works as a fallback, not a specialty.
Embed **queries and documents the same way** β€” no instruction prefix. For smaller indexes, truncate to
**256** or **512** dims (MRL) before normalizing.
## How it was made
Knowledge-distilled (embedding regression) from **[`Alibaba-NLP/gte-modernbert-base`](https://huggingface.co/Alibaba-NLP/gte-modernbert-base)**
(Apache-2.0, ~150M, a strong general + code retriever on a ModernBERT backbone). The student is a fresh,
shallow-wide XLM-R encoder trained from scratch on the teacher's passage embeddings over a ~30M-sample
code + text corpus, with a custom 32k code-oriented SentencePiece vocabulary (syntax + identifier lexicon
rather than prose). The shallow-wide 4-layer / 768-hidden shape keeps inference cheap while distilling at
the teacher's full 768-dim width.
## Built for speed
- **Short context by design** β€” max **128 tokens**, no long-document path, so the engines avoid a wide
dynamic shape range.
- **Rectangular TensorRT profiles** β€” each length bucket is a *fixed* shape (min == opt == max), one
optimal kernel set per bucket: **s** = batch 64 Γ— seq 40 Β· **m** = batch 128 Γ— seq 64 Β·
**l** = batch 256 Γ— seq 128.
- **INT8 (W8A16)** weights; **mean-pool + projection + L2-norm fused into the graph** (one pass β†’ `[B, 768]`).
## Usage (standalone ONNX)
The FP32 `model.onnx` is bundled. Tokenize with the bundled `sentencepiece.bpe.model`, run, and the
pooled `[B, 768]` output is already produced β€” just L2-normalize:
```python
import onnxruntime as ort, sentencepiece as spm, numpy as np
sp = spm.SentencePieceProcessor(model_file="sentencepiece.bpe.model") # pad=0 unk=1 bos=2 eos=3
sess = ort.InferenceSession("model.onnx", providers=["CPUExecutionProvider"])
def embed(texts, max_len=128, mrl_dim=768):
ids = [[2, *sp.encode(t)[: max_len - 2], 3] for t in texts] # bos … eos
L = max(len(x) for x in ids)
inp = np.array([x + [0] * (L - len(x)) for x in ids], dtype=np.int64) # pad=0
mask = (inp != 0).astype(np.int64)
out = sess.run(None, {"input_ids": inp, "attention_mask": mask})[0] # already mean-pooled [B,768]
out = out[:, :mrl_dim] # MRL truncation (768/512/256)
return out / np.linalg.norm(out, axis=1, keepdims=True)
```
## What's in this repo β€” ready-to-run compiled engines
Pre-compiled engines, named per **runtime Γ— GPU arch Γ— OS Γ— length-bucket** β€” pick the one matching your
runtime and hardware; no compilation needed.
- **TensorRT** `*.engine` β€” NVIDIA, INT8 W8A16:
`code-daemon-embed-v1-{s,m,l}_{win_x64,linux_x64}_trt_sm_{86,89,120}.engine`
(sm_86 β‰ˆ RTX 30xx / A-series Β· sm_89 β‰ˆ RTX 40xx / L4 Β· sm_120 β‰ˆ RTX 50xx).
- **TVM** `*_tvm_vulkan.{dll,so}` β€” Vulkan fallback for non-TRT / older NVIDIA & other GPUs, per bucket.
- **OpenVINO** `*.xml` + `*.bin` β€” Intel **CPU / iGPU / NPU**, per bucket.
- **Metal** `*_tvm_metal.*` β€” Apple Silicon (macOS), per bucket.
- **Tokenizer** β€” `sentencepiece.bpe.model` (specials at pad=0 / unk=1 / bos=2 / eos=3, byte-fallback) +
`tokenizer_config.json`.
- **ONNX source** β€” `model.onnx` (+ `model.onnx.data`) FP32 and `model_int8qdt.onnx` (INT8 W8A16).
## Evaluation β€” CoIR (NDCG@10, full corpora)
Retrieval quality on the CoIR tasks that match this model's design (short code + retrieval). Four of
CoIR's ten tasks β€” code↔code translation, multi-turn dialogue, long problem-statements β€” exceed the
128-token / retrieval scope and are not shown.
| CoIR task | NDCG@10 | Pattern |
|---|--:|---|
| codesearchnet (6-lang avg) | **73.17** | docstring / NL β†’ code |
| stackoverflow-qa | 62.70 | short question β†’ code |
| synthetic-text2sql | 61.32 | NL β†’ SQL |
| codesearchnet-ccr (6-lang avg) | **57.30** | code β†’ related code |
| codefeedback-st | 56.38 | NL instruction β†’ code |
| cosqa | 35.51 | NL question β†’ code (noisy / hard) |
| **Average** | **57.73** | |
Per language — codesearchnet (NL→code): python **88.82**, java 75.78, php 73.71, go 73.49, ruby 64.10, js 63.09.
Per language — codesearchnet-ccr (code→code): ruby **65.67**, java 62.87, js 61.05, python 55.88, go 51.53, php 46.77.
**Binary (1-bit sign) vectors** retain **94.4%** of the float NDCG before any rescore β€” the embeddings
are clean by sign, so a Hamming (XOR + popcount) index over 1-bit codes gives a ~32Γ— memory / search win
at a small quality cost.
> For scale, the 1.5B-parameter `bge-code-v1` scores 81.77 on full CoIR β€” this is a **54.5M** model
> (27Γ— smaller) tuned for short-code retrieval.
## Performance (embeddings / sec)
| Backend | Hardware | Throughput |
|---|---|--:|
| TensorRT INT8 | NVIDIA RTX 5060 (sm_120) | **~24,000 emb/s** |
| OpenVINO INT4 | Intel iGPU (Xe2, Lunar Lake) | ~580 emb/s |
| OpenVINO INT4 | Intel NPU (NPU4) | ~574 emb/s |
| OpenVINO INT8 | Intel CPU (Core Ultra) | ~375 emb/s |
| OpenVINO β€” **all 3 in parallel** | iGPU + NPU + CPU concurrently | ~1,290 emb/s |
The combined OpenVINO figure is genuine concurrent multi-device execution β€” three workers (iGPU, NPU,
CPU) embed different batches at the same time and the throughputs add up. This is **not** OpenVINO's
`AUTO` mode (which picks a single device per inference). Measured on a Core Ultra (Lunar Lake) laptop;
the TensorRT figure is on the bucketed batch path.
## License & training data
Released under the **MIT license**.
The teacher (`Alibaba-NLP/gte-modernbert-base`) is Apache-2.0, and the XLM-R architecture is MIT. As is
standard practice for distilled embedding models, the **weights are released under MIT**. For
transparency, the training corpus the teacher embedded includes:
| Dataset | License note |
|---|---|
| `Fsoft-AIC/the-vault-function` (code) | dataset MIT; underlying code has mixed upstream provenance |
| `unicamp-dl/mmarco` (EN/RU retrieval) | **MS MARCO-derived β†’ non-commercial research terms** |
| `sentence-transformers/all-nli` | SNLI (CC BY-SA 4.0) + MultiNLI |
| `sentence-transformers/gooaq` | Apache-2.0 |
| `jinaai/negation-dataset` | see source repo |
⚠️ If your use requires strict training-data-license compliance, note that **mMARCO derives from
MS MARCO (non-commercial)**. Whether a distilled model inherits dataset-use terms is legally unsettled;
this is **not legal advice**. A data-clean variant can be retrained without the mMARCO splits if needed.
## Attribution
Distilled from **[Alibaba-NLP/gte-modernbert-base](https://huggingface.co/Alibaba-NLP/gte-modernbert-base)** (Apache-2.0). Backbone: XLM-RoBERTa (MIT).