Model reference · open weights
bge-m3-legal-ru-cocktail-40-60 is an open-weight embedding model from Roflmax. AxForge deploys and operates it for you on dedicated EU-owned hardware — with the licence handled where one is required.
Available as managed deployment — configured and operated for you on dedicated EU hardware, quoted per deployment.
What it is
| Released by | Roflmax |
|---|---|
| Type | Embedding models |
| Task | Embeddings |
| Parameters (lead) | 568M |
| Context | 8194 tokens |
| Runs with | sentence-transformers |
| Released | 2025-11-13 |
| Popularity | 803 downloads / month |
| Licence | Open weights |
About
🏆 Top-performing Russian legal document embedding model with 91.79% Recall@5
This model is created using LM-Cocktail weight interpolation technique, combining two state-of-the-art Russian legal embedding models:
Synergistic Effect: The cocktail model outperforms both parent models through optimal weight combination!
| Metric | Score | Rank |
|---|---|---|
| Recall@1 | 76.66% | #1 |
| Recall@5 | 91.79% | 🥇 #1 |
| Recall@10 | 94.85% | #1 |
| Dataset | Recall@1 | Recall@5 | Recall@10 | Description |
|---|---|---|---|---|
| court_law | 66.01% | 86.47% | 91.08% | Court decisions and rulings |
| other_law | 90.44% | 95.80% | 96.97% | Federal laws and codes |
| reg_law | 75.52% | 93.09% | 96.49% | Regional legislation |
| Average | 76.66% | 91.79% | 94.85% | Across all domains |
| Model | Recall@5 | Improvement |
|---|---|---|
| Cocktail 40/60 (this model) | 91.79% | Baseline |
| bge-m3-russian-legal | 91.43% | +0.36% |
| bge-m3-legal-ru-updata | 91.28% | +0.51% |
The cocktail demonstrates synergistic effect - it outperforms both parent models!
pip install -U sentence-transformers
from sentence_transformers import SentenceTransformer
# Load the model
model = SentenceTransformer("Roflmax/bge-m3-legal-ru-cocktail-40-60")
model.max_seq_length = 512 # Optimized for speed
# Example: Semantic search in legal documents
query = "Какое наказание предусмотрено за управление транспортным средством в состоянии опьянения?"
documents = [
"Статья 264.1 УК РФ. Нарушение правил дорожного движения лицом, подвергнутым административному наказанию...",
"КоАП РФ Статья 12.8. Управление транспортным средством водителем, находящимся в состоянии опьянения...",
"Статья 228 УК РФ. Незаконные приобретение, хранение, перевозка, изготовление..."
]
# Encode
query_embedding = model.encode(query, normalize_embeddings=True)
doc_embeddings = model.encode(documents, normalize_embeddings=True)
# Calculate similarity
from sklearn.metrics.pairwise import cosine_similarity
similarities = cosine_similarity([query_embedding], doc_embeddings)[0]
# Get top results
top_indices = similarities.argsort()[::-1]
for idx in top_indices:
print(f"Score: {similarities[idx]:.4f} | {documents[idx][:100]}...")
from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer("Roflmax/bge-m3-legal-ru-cocktail-40-60")
model.max_seq_length = 512
# Batch encode documents
documents = [
"Первый документ...",
"Второй документ...",
# ... more documents
]
# Process in batches for efficiency
embeddings = model.encode(
documents,
batch_size=32,
normalize_embeddings=True,
show_progress_bar=True
)
print(f"Generated {len(embeddings)} embeddings of dimension {embeddings.shape[1]}")
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("Roflmax/bge-m3-legal-ru-cocktail-40-60")
# Your corpus
corpus = [
"Документ 1: содержание...",
"Документ 2: содержание...",
# ... more documents
]
# Encode corpus once
corpus_embeddings = model.encode(corpus, convert_to_tensor=True, normalize_embeddings=True)
# Query
query = "Ваш поисковый запрос"
query_embedding = model.encode(query, convert_to_tensor=True, normalize_embeddings=True)
# Search
hits = util.semantic_search(query_embedding, corpus_embeddings, top_k=5)[0]
# Display results
for hit in hits:
print(f"Score: {hit['score']:.4f} | {corpus[hit['corpus_id']][:100]}...")
Unlike some BGE models, this model does NOT require query/passage prefixes. Simply encode your text directly:
# ✅ Correct - no prefix needed
embedding = model.encode("Ваш текст")
# ❌ Not needed
embedding = model.encode("Represent this sentence for searching relevant passages: Ваш текст")
The model is optimized for 512 tokens:
For longer documents, consider chunking:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("Roflmax/bge-m3-legal-ru-cocktail-40-60")
model.max_seq_length = 512
# Split long document into chunks
def chunk_text(text, max_length=2000):
# Simple character-based chunking
return [text[i:i+max_length] for i in range(0, len(text), max_length)]
long_document = "Очень длинный документ..."
chunks = chunk_text(long_document)
chunk_embeddings = model.encode(chunks, normalize_embeddings=True)
# Use average embedding for the whole document
import numpy as np
document_embedding = np.mean(chunk_embeddings, axFrom the published model card. Full card on the HuggingFace links in the sidebar.
Using it via the API
Once AxForge deploys bge-m3-legal-ru-cocktail-40-60 for you, it answers on the OpenAI-compatible API — the same base URL and keys as every other model. (bge-m3-legal-ru-cocktail-40-60 below is illustrative; you get the exact model name on deployment.)
$ curl -sS https://api.axforge.ai/v1/embeddings \
-H "Authorization: Bearer $AXFORGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"bge-m3-legal-ru-cocktail-40-60","input":"text to embed"}'
Create an account — your API key is available in the console. 3M free tokens every 30 days with every new account.