1
stars
60
commits
1
repos using this model
1
linked in READMEs
Jul 18, 2026
updated
Standard dense retrieval models score query–passage pairs using a single semantic similarity signal, giving users no control over what "relevant" means beyond keyword choice. Promptriever (Weller et al., 2024) introduced per-instance natural language instructions that dynamically redefine relevance — a capability previously limited to generative LLMs.
ru-Promptriever extends this paradigm to Russian:
| Model | Parameters | Link |
|---|---|---|
| ru-Promptriever-4B | 4B | this model |
| ru-Promptriever-4B-pretrained | 4B | link |
| ru-Promptriever-4B-ru-only | 4B | link |
| ru-Promptriever-1.7B | 1.7B | link |
| ru-Promptriever-0.6B | 0.6B | link |
This is the final, best-performing model in the ru-Promptriever family. Starting from ru-Promptriever-4B-pretrained, it was further fine-tuned on a balanced multilingual mix of:
Under the current harmonized evaluation protocol, this model obtains 17.28 p-MRR on mFollowIR-RU while matching Promptriever-8B's retrieval quality at half the parameter count.
Russian split of mFollowIR — multilingual instruction-following retrieval using TREC NeuCLIR narratives as instructions.
p-MRR (Pairwise Mean Reciprocal Rank, ×100) is the primary instruction-following metric — higher means the model correctly adjusts rankings when instructions change. nDCG@20 measures standard retrieval quality.
| Model | nDCG@20 | p-MRR |
|---|---|---|
| ru-Promptriever-4B (this model) | 0.5350 | +17.28 |
| Promptriever Llama-3.1-8B | 0.5348 | +12.43 |
Both models were rerun on the official MTEB 2.10.5 candidate pools with their native preprocessing. The paired nDCG@20 difference is +0.0003 (95% CI [−0.047, +0.049], p=0.991). The p-MRR difference is numerically positive but not statistically significant (95% CI [−1.36, +11.57], p=0.156). These results support higher observed instruction sensitivity without an established retrieval-quality loss, not proven overall superiority.
| Benchmark | Retrieval metric | Instruction metric |
|---|---|---|
| InstructIR | 0.9425 nDCG@10 | 0.7193 Robustness@10 |
| FollowIR Robust04 | 0.3301 MAP@1000 | +14.11 p-MRR |
| FollowIR Core17 | 0.3596 MAP@1000 | +12.85 p-MRR |
| FollowIR News21 | 0.4827 nDCG@5 | +6.58 p-MRR |
| FollowIR macro | — | +11.18 p-MRR |
| RuBQ | 0.6996 nDCG@10 | — |
| SciFact | 0.7338 nDCG@10 | — |
| NFCorpus | 0.3277 nDCG@10 | — |
These values use the repository's selected step-300 adapter and the corrected MTEB 2.10.5 protocol. FollowIR retrieval columns use the original-instruction qrels; legacy published retrieval values from older FollowIR implementations are not directly comparable.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch.nn.functional as F
model_name = "Vladimirlv/ru-promptriever-qwen3-4b"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.bfloat16,
device_map="auto",
)
model.eval()
def encode(texts: list[str], max_length: int = 512) -> torch.Tensor:
"""Encode texts using last-token (EOS) pooling."""
inputs = tokenizer(
texts,
padding=True,
truncation=True,
max_length=max_length,
return_tensors="pt",
).to(model.device)
with torch.no_grad():
# Bypass lm_head to get post-norm hidden states
original_lm_head = model.lm_head
model.lm_head = torch.nn.Identity()
outputs = model(**inputs, use_cache=False, return_dict=True)
model.lm_head = original_lm_head
# EOS pooling: take embedding at last non-padding token
seq_len = inputs["attention_mask"].sum(dim=1) - 1
embeddings = outputs.logits[torch.arange(len(texts)), seq_len]
return F.normalize(embeddings, p=2, dim=1)
query = "Когда была основана Москва?"
passages = [
"Москва была основана в 1147 году князем Юрием Долгоруким.",
"Санкт-Петербург был основан Петром I в 1703 году.",
]
q_emb = encode([query])
p_emb = encode(passages)
scores = (q_emb @ p_emb.T).squeeze()
print(scores) # tensor([0.82, 0.61])
# Append the instruction directly to the query (same format as training)
instruction = "Найди документ, в котором упоминается конкретная дата основания города."
instructed_query = f"{query} {instruction}"
q_emb = encode([instructed_query])
p_emb = encode(passages)
scores = (q_emb @ p_emb.T).squeeze()
# The model adjusts rankings based on the instruction
This model is not compatible with sentence-transformers out of the box due to the custom EOS pooling. Use the snippet above directly with transformers.
| Property | Value |
|---|---|
| Base model | ru-Promptriever-4B-pretrained (continued training) |
| Architecture | CausalLM bi-encoder (EOS pooling) |
| Fine-tuning method | LoRA (rank-32, α=64, all linear layers) |
| Training data | ~65k mixed rows (Russian real + Russian synthetic + English synthetic) |
| Effective batch size | 128 (8 per device × 4 accum × 4 GPUs) |
| Loss | InfoNCE contrastive (temperature=0.01) |
| Learning rate | 5e-5 |
| Epochs | 1 |
| Max query length | 512 tokens |
| Max passage length | 256 tokens |
This model was trained in two stages:
Stage 1 — Pretraining (ru-Promptriever-4B-pretrained): LoRA fine-tuning of Qwen3-4B on ~500k synthetic instruction-augmented Russian retrieval triples from ru-promptriever-dataset, built on top of mMARCO-ru.
Stage 2 — Continued training (this model): further LoRA fine-tuning on a balanced multilingual mix of ~65k rows:
Key properties:
This model is released under CC BY-NC 4.0 (Creative Commons Attribution–NonCommercial 4.0 International).
The non-commercial restriction is inherited from the upstream MS MARCO license (Microsoft Research License — non-commercial use only), which governs the training corpus.
If you use this model, please cite the original Promptriever paper:
@article{weller2024promptriever,
title = {Promptriever: Instruction-Trained Retrievers Can Be Prompted Like Language Models},
author = {Weller, Orion and Van Durme, Benjamin and Lawrie, Dawn and
Paranjape, Ashwin and Zhang, Yuhao and Hessel, Jack},
journal = {arXiv preprint arXiv:2409.11136},
year = {2024}
}
60 commits
1
stars
60
commits
1
repos using this model
1
linked in READMEs
Jul 18, 2026
updated
Standard dense retrieval models score query–passage pairs using a single semantic similarity signal, giving users no control over what "relevant" means beyond keyword choice. Promptriever (Weller et al., 2024) introduced per-instance natural language instructions that dynamically redefine relevance — a capability previously limited to generative LLMs.
ru-Promptriever extends this paradigm to Russian:
| Model | Parameters | Link |
|---|---|---|
| ru-Promptriever-4B | 4B | this model |
| ru-Promptriever-4B-pretrained | 4B | link |
| ru-Promptriever-4B-ru-only | 4B | link |
| ru-Promptriever-1.7B | 1.7B | link |
| ru-Promptriever-0.6B | 0.6B | link |
This is the final, best-performing model in the ru-Promptriever family. Starting from ru-Promptriever-4B-pretrained, it was further fine-tuned on a balanced multilingual mix of:
Under the current harmonized evaluation protocol, this model obtains 17.28 p-MRR on mFollowIR-RU while matching Promptriever-8B's retrieval quality at half the parameter count.
Russian split of mFollowIR — multilingual instruction-following retrieval using TREC NeuCLIR narratives as instructions.
p-MRR (Pairwise Mean Reciprocal Rank, ×100) is the primary instruction-following metric — higher means the model correctly adjusts rankings when instructions change. nDCG@20 measures standard retrieval quality.
| Model | nDCG@20 | p-MRR |
|---|---|---|
| ru-Promptriever-4B (this model) | 0.5350 | +17.28 |
| Promptriever Llama-3.1-8B | 0.5348 | +12.43 |
Both models were rerun on the official MTEB 2.10.5 candidate pools with their native preprocessing. The paired nDCG@20 difference is +0.0003 (95% CI [−0.047, +0.049], p=0.991). The p-MRR difference is numerically positive but not statistically significant (95% CI [−1.36, +11.57], p=0.156). These results support higher observed instruction sensitivity without an established retrieval-quality loss, not proven overall superiority.
| Benchmark | Retrieval metric | Instruction metric |
|---|---|---|
| InstructIR | 0.9425 nDCG@10 | 0.7193 Robustness@10 |
| FollowIR Robust04 | 0.3301 MAP@1000 | +14.11 p-MRR |
| FollowIR Core17 | 0.3596 MAP@1000 | +12.85 p-MRR |
| FollowIR News21 | 0.4827 nDCG@5 | +6.58 p-MRR |
| FollowIR macro | — | +11.18 p-MRR |
| RuBQ | 0.6996 nDCG@10 | — |
| SciFact | 0.7338 nDCG@10 | — |
| NFCorpus | 0.3277 nDCG@10 | — |
These values use the repository's selected step-300 adapter and the corrected MTEB 2.10.5 protocol. FollowIR retrieval columns use the original-instruction qrels; legacy published retrieval values from older FollowIR implementations are not directly comparable.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch.nn.functional as F
model_name = "Vladimirlv/ru-promptriever-qwen3-4b"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.bfloat16,
device_map="auto",
)
model.eval()
def encode(texts: list[str], max_length: int = 512) -> torch.Tensor:
"""Encode texts using last-token (EOS) pooling."""
inputs = tokenizer(
texts,
padding=True,
truncation=True,
max_length=max_length,
return_tensors="pt",
).to(model.device)
with torch.no_grad():
# Bypass lm_head to get post-norm hidden states
original_lm_head = model.lm_head
model.lm_head = torch.nn.Identity()
outputs = model(**inputs, use_cache=False, return_dict=True)
model.lm_head = original_lm_head
# EOS pooling: take embedding at last non-padding token
seq_len = inputs["attention_mask"].sum(dim=1) - 1
embeddings = outputs.logits[torch.arange(len(texts)), seq_len]
return F.normalize(embeddings, p=2, dim=1)
query = "Когда была основана Москва?"
passages = [
"Москва была основана в 1147 году князем Юрием Долгоруким.",
"Санкт-Петербург был основан Петром I в 1703 году.",
]
q_emb = encode([query])
p_emb = encode(passages)
scores = (q_emb @ p_emb.T).squeeze()
print(scores) # tensor([0.82, 0.61])
# Append the instruction directly to the query (same format as training)
instruction = "Найди документ, в котором упоминается конкретная дата основания города."
instructed_query = f"{query} {instruction}"
q_emb = encode([instructed_query])
p_emb = encode(passages)
scores = (q_emb @ p_emb.T).squeeze()
# The model adjusts rankings based on the instruction
This model is not compatible with sentence-transformers out of the box due to the custom EOS pooling. Use the snippet above directly with transformers.
| Property | Value |
|---|---|
| Base model | ru-Promptriever-4B-pretrained (continued training) |
| Architecture | CausalLM bi-encoder (EOS pooling) |
| Fine-tuning method | LoRA (rank-32, α=64, all linear layers) |
| Training data | ~65k mixed rows (Russian real + Russian synthetic + English synthetic) |
| Effective batch size | 128 (8 per device × 4 accum × 4 GPUs) |
| Loss | InfoNCE contrastive (temperature=0.01) |
| Learning rate | 5e-5 |
| Epochs | 1 |
| Max query length | 512 tokens |
| Max passage length | 256 tokens |
This model was trained in two stages:
Stage 1 — Pretraining (ru-Promptriever-4B-pretrained): LoRA fine-tuning of Qwen3-4B on ~500k synthetic instruction-augmented Russian retrieval triples from ru-promptriever-dataset, built on top of mMARCO-ru.
Stage 2 — Continued training (this model): further LoRA fine-tuning on a balanced multilingual mix of ~65k rows:
Key properties:
This model is released under CC BY-NC 4.0 (Creative Commons Attribution–NonCommercial 4.0 International).
The non-commercial restriction is inherited from the upstream MS MARCO license (Microsoft Research License — non-commercial use only), which governs the training corpus.
If you use this model, please cite the original Promptriever paper:
@article{weller2024promptriever,
title = {Promptriever: Instruction-Trained Retrievers Can Be Prompted Like Language Models},
author = {Weller, Orion and Van Durme, Benjamin and Lawrie, Dawn and
Paranjape, Ashwin and Zhang, Yuhao and Hessel, Jack},
journal = {arXiv preprint arXiv:2409.11136},
year = {2024}
}
60 commits