Вибір та налаштування Embedding-моделі для RAG
Embedding-модель — один із найбільш критичних компонентів RAG-системи. Якість пошуку напрямую залежить від того, наскільки добре модель представляє тексти у векторному просторі. Зміна embedding-моделі може дати більший приріст recall, ніж оптимізація чункінгу або параметрів пошуку.
Категорії embedding-моделей
Проприєтарні API-моделі:
-
text-embedding-3-large(OpenAI, dim=3072): найкраща якість на більшості бенчмарків MTEB -
text-embedding-3-small(OpenAI, dim=1536): гарний баланс ціни та якості -
embed-v3(Cohere): сильна на задачах пошуку, підтримує параметр input_type
Відкриті моделі (self-hosted):
-
BAAI/bge-m3(dim=1024): багатомовна, підтримує dense+sparse+colbert -
BAAI/bge-large-en-v1.5(dim=1024): найкраща для англійської -
intfloat/multilingual-e5-large(dim=1024): добре працює на українській -
nomic-ai/nomic-embed-text-v1.5(dim=768): матрьошка (пропорційні розмірності)
MTEB бенчмарк: порівняння моделей
На задачах Retrieval (BEIR benchmark, усереднений nDCG@10):
| Модель | NDCG@10 (BEIR avg) | Dim | Макс. токени | Тип |
|---|---|---|---|---|
| text-embedding-3-large | 54.9 | 3072 | 8191 | API |
| text-embedding-3-small | 51.7 | 1536 | 8191 | API |
| cohere embed-v3 | 55.0 | 1024 | 512 | API |
| BAAI/bge-m3 | 54.0 | 1024 | 8192 | Open |
| intfloat/e5-mistral-7b | 56.9 | 4096 | 32768 | Open |
| nomic-embed-text-v1.5 | 53.5 | 768 | 8192 | Open |
Для українськомовних задач картина інша — рекомендуємо тестувати на власному домені.
Налаштування Cohere Embed v3 з input_type
Cohere embed-v3 вимагає вказання input_type — це важливо для пошуку:
import cohere
co = cohere.Client(api_key="...")
def embed_documents(texts: list[str]) -> list[list[float]]:
"""Для індексації документів"""
response = co.embed(
texts=texts,
model="embed-multilingual-v3.0",
input_type="search_document", # Для документів під час індексації
)
return response.embeddings
def embed_query(query: str) -> list[float]:
"""Для пошукового запиту"""
response = co.embed(
texts=[query],
model="embed-multilingual-v3.0",
input_type="search_query", # Асиметрична модель — різні типи
)
return response.embeddings[0]
Використання правильного input_type підвищує recall на 8–15% — модель навчена на asymmetric retrieval.
Self-hosted BGE-M3
BGE-M3 — найбільш універсальна open-source модель: підтримує dense, sparse (SPLADE) та ColBERT-стиль multi-vector retrieval з однієї моделі:
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel(
"BAAI/bge-m3",
use_fp16=True, # Економія памяті
device="cuda",
)
# Dense embeddings (для стандартного ANN пошуку)
dense_embeddings = model.encode(
texts,
batch_size=32,
max_length=8192,
return_dense=True,
return_sparse=False,
return_colbert_vecs=False,
)["dense_vecs"]
# Sparse embeddings (для BM25-подібного пошуку)
sparse_embeddings = model.encode(
texts,
return_dense=False,
return_sparse=True,
)["lexical_weights"] # dict {token: weight}
# Hybrid retrieval score
def compute_bge_m3_score(query_dense, doc_dense, query_sparse, doc_sparse,
alpha=0.5) -> float:
dense_score = np.dot(query_dense, doc_dense)
sparse_score = sum(
query_sparse.get(token, 0) * doc_sparse.get(token, 0)
for token in query_sparse
)
return alpha * dense_score + (1 - alpha) * sparse_score
Вибір розмірності: Matryoshka Embeddings
Nomic Embed та низка інших моделей підтримують матрьошкові embeddings — можна використовувати перші N вимірів без перенавчання:
from openai import OpenAI
client = OpenAI()
# text-embedding-3-large зі зменшеною розмірністю
# 3072 → 1536 без переіндексації (офіційно підтримується OpenAI)
response = client.embeddings.create(
model="text-embedding-3-large",
input=texts,
dimensions=1536, # Зменшуємо розмірність
)
Це дозволяє знизити вимоги до RAM векторної БД в 2× при незначній (2–5%) втраті якості.
Практичний вибір embedding-моделі
Якщо дані конфіденційні / on-premise: BGE-M3 або E5-mistral-7b (self-hosted).
Якщо потрібна найкраща українська мова: тестуємо BGE-M3, multilingual-e5-large та text-embedding-3-large на своєму домені. Універсального переможця немає.
Якщо мінімальна latency: text-embedding-3-small (API) або nomic-embed-text-v1.5 (small, self-hosted).
Якщо потрібен hybrid sparse+dense без двох моделей: BGE-M3 — єдина open-source модель з нативною підтримкою обох режимів.
Оцінка на своєму домені
from ragas import evaluate
from ragas.metrics import context_recall, context_precision
# Тестування двох моделей на вашому датасеті
for model_name in ["text-embedding-3-small", "text-embedding-3-large"]:
retriever = build_retriever(model_name)
scores = evaluate(test_dataset, metrics=[context_recall, context_precision],
retriever=retriever)
print(f"{model_name}: recall={scores['context_recall']:.3f}, "
f"precision={scores['context_precision']:.3f}")
Терміни
- Налаштування embedding моделі та індексація: 2–5 днів
- Порівняльне тестування 2–3 моделей: 3–5 днів
- Всього: 1–2 тижні







