Актриса Милла Йовович и разработчик Бен Сигман создали open-source систему памяти для ИИ на базе Claude. MemPalace показал идеальный результат на стандартном бенчмарке — и он полно…
База знаний
BAAI/bge-m3 — мультиязычная embedding-модель для self-hosted RAG
Open-source embedding-модель от BAAI для поиска, RAG и семантического сравнения текстов. Контекст 8192 токена, 100+ языков, MIT-лицензия, работает на CPU. Разбор возможностей, сравнение с альтернативами и эталонная сборка сервера на FastAPI.
Если вы собираете свой RAG и ищете открытую embedding-модель, которая хорошо работает и с русским, и с английским, да ещё и тянет длинные документы — с большой вероятностью вам нужна именно BAAI/bge-m3. Это мой дефолтный выбор для self-hosted сценариев, и в этом справочнике я собрал всё, что стоит знать, прежде чем ставить её на свой сервер.
Что это вообще такое
BGE-M3 (BAAI General Embedding — M3) — embedding-модель от Beijing Academy of Artificial Intelligence, опубликованная в начале 2024 года. М3 в названии — это три «мульти», которыми она отличается от предыдущих поколений:
- Multi-Linguality — больше 100 языков, включая русский, и что важно — сильный cross-lingual: запрос на русском находит релевантный фрагмент на английском и наоборот.
- Multi-Functionality — dense, sparse и multi-vector retrieval внутри одной модели. Не надо держать несколько.
- Multi-Granularity — контекст до 8192 токенов. Можно эмбеддить не «кусочки», а целые статьи.
Под капотом — XLM-RoBERTa-large, дообученная на больших объёмах парных и триплетных данных. На момент релиза модель была одной из лучших открытых на бенчмарке MIRACL (мультиязычный retrieval), и с тех пор её так и не скинули с пьедестала для двуязычных задач.
Ключевые характеристики
| Параметр | Значение |
| Разработчик | BAAI (Beijing Academy of Artificial Intelligence) |
| Лицензия | MIT — коммерческое использование без ограничений |
| Архитектура | XLM-RoBERTa-large, дообученная |
| Размер весов | ~2.27 ГБ |
| RAM при инференсе | ~0.9–1.2 ГБ |
| Размерность dense-вектора | 1024 |
| Максимальный контекст | 8192 токена |
| Языки | 100+, включая русский, английский, китайский |
| Типы retrieval | Dense, Sparse (lexical), Multi-vector (ColBERT-style) |
| Скорость на CPU (Ryzen 5 3600) | ~120 мс на чанк |
Три режима работы в одной модели
Главная фишка M3 — одна и та же модель даёт три разных типа представлений. Можно брать по одному, можно комбинировать в гибридный поиск.
| Режим | Что выдаёт | Когда использовать |
| Dense | Один вектор 1024 на текст | Классический семантический поиск, обычный RAG |
| Sparse / Lexical | Веса токенов (как BM25, но обученные) | Когда важны точные совпадения терминов, имён, кодов |
| Multi-vector (ColBERT) | Отдельный вектор на каждый токен | Ре-ранжирование top-N для максимальной точности |
Когда BGE-M3 — правильный выбор
- Двуязычные и мультиязычные базы знаний, где надо искать по-русски по английским документам (и наоборот).
- Длинные чанки и документы — всё, что не лезет в 512 токенов у старых моделей вроде
e5-largeилиmultilingual-MiniLM. - Self-hosted сценарии, где важна предсказуемая стоимость и нет желания зависеть от внешнего API.
- Гибридный поиск — когда хочется из одной модели получать и dense, и lexical.
- Коммерческие проекты — MIT-лицензия снимает вопросы, в отличие от
jina-v3с её CC-BY-NC.
Когда лучше взять что-то другое
- Чисто английские задачи с максимальными требованиями к качеству.
text-embedding-3-largeот OpenAI, Voyage-3, Cohere Embed v3 часто выигрывают. - Нужна минимальная задержка на коротких запросах без GPU. Маленькие модели вроде
bge-small-enилиgte-smallдают 10–30 мс против 120 мс у M3. - Критична экономия на векторной БД. 1024 измерения против 384 у малых моделей — это в 2,6 раза больше места.
- Эмбеддинги для кода. Берите специализированные модели (
jina-embeddings-v2-code,voyage-code-2).
Сравнение с альтернативами
| Модель | Контекст | Мультиязычность | Лицензия | Размерность |
| BAAI/bge-m3 | 8192 | 100+ языков, сильная | MIT | 1024 |
| intfloat/multilingual-e5-large | 512 | 100 языков | MIT | 1024 |
| jina-embeddings-v3 | 8192 | 89 языков | CC-BY-NC-4.0 (non-commercial) | 1024 |
| OpenAI text-embedding-3-large | 8191 | Хорошая, без фокуса на RU | Проприетарная, только API | 3072 (truncatable) |
| Cohere embed-multilingual-v3 | 512 | 100+ языков | Проприетарная, только API | 1024 |
Поднимаем на своём сервере
Минимальные требования
- CPU: любой современный x86_64. В примерах ниже — Ryzen 5 3600.
- RAM: от 4 ГБ свободной. Сама модель ~1 ГБ, остальное уходит на батчи и overhead.
- Диск: ~3 ГБ под веса и зависимости.
- Python 3.10+.
- GPU не обязателен. Но если он есть — инференс ускоряется в 10–30 раз.
Ставим зависимости
python3 -m venv .venv
source .venv/bin/activate
pip install -U FlagEmbedding fastapi uvicorn pydanticFlagEmbedding — официальная библиотека от BAAI. В ней уже собраны оптимальные пресеты для всех трёх режимов, не надо ничего угадывать.
Эталонный FastAPI-сервер (OpenAI-compatible)
Рабочий пример: кладёте в один файл server.py, запускаете, получаете embedding-сервис с API в формате OpenAI /v1/embeddings. Это значит, что вы можете вставить его как drop-in replacement в LiteLLM, LangChain, LlamaIndex — ничего не переписывая.
# server.py — OpenAI-compatible embeddings server на BGE-M3
from fastapi import FastAPI
from pydantic import BaseModel
from FlagEmbedding import BGEM3FlagModel
from typing import List, Union
import time, uuid
# use_fp16=False на CPU; на GPU ставьте True для 2x ускорения
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=False)
app = FastAPI()
class EmbeddingRequest(BaseModel):
input: Union[str, List[str]]
model: str = "bge-m3"
@app.post("/v1/embeddings")
def embeddings(req: EmbeddingRequest):
texts = [req.input] if isinstance(req.input, str) else req.input
# dense-вектор — основной режим для RAG
vectors = model.encode(texts, batch_size=8, max_length=8192)['dense_vecs']
return {
"object": "list",
"model": req.model,
"data": [
{"object": "embedding", "index": i, "embedding": v.tolist()}
for i, v in enumerate(vectors)
],
"usage": {"prompt_tokens": 0, "total_tokens": 0},
}
@app.get("/health")
def health():
return {"status": "ok", "model": "BAAI/bge-m3"}Запуск:
uvicorn server:app --host 127.0.0.1 --port 8080Systemd-юнит для автозапуска
# /etc/systemd/system/bge-m3.service
[Unit]
Description=BGE-M3 Embeddings Server
After=network.target
[Service]
Type=simple
User=embeddings
WorkingDirectory=/opt/bge-m3
Environment="PATH=/opt/bge-m3/.venv/bin"
ExecStart=/opt/bge-m3/.venv/bin/uvicorn server:app --host 127.0.0.1 --port 8080
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetАктивация:
sudo systemctl daemon-reload
sudo systemctl enable --now bge-m3
sudo systemctl status bge-m3127.0.0.1 или на интерфейс Tailscale, а не на 0.0.0.0. Авторизации у модели из коробки нет. Открытый порт в интернет — это приглашение чужим ботам молотить ваш CPU за ваш же счёт.Проверяем, что всё живо
curl -X POST http://127.0.0.1:8080/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"input": ["Привет, мир", "Hello, world"], "model": "bge-m3"}' | jq '.data | length'
# ожидаемо: 2Чтобы проверить cross-lingual качество на глаз, посчитайте cosine similarity между русской и английской версией одной и той же фразы. Для нормальных переводов должно быть 0.85+. Если получаете 0,70 или ниже — где-то накосячили: не тот pooling, обрезан контекст, неправильно собран батч.
Практические сценарии
RAG по двуязычной базе знаний
- Индексируете документы на русском и английском одной моделью.
- Запрос может быть на любом языке — релевантный фрагмент найдётся независимо от языка источника.
- Работает из коробки, без отдельного переводчика в пайплайне.
Гибридный поиск dense + sparse
- Dense ловит синонимы и переформулировки.
- Sparse ловит точные термины, имена, артикулы, номера версий.
- Финальный скор — взвешенная сумма, обычно
0.7 × dense + 0.3 × sparse. Веса стоит подкрутить под свой корпус.
Семантический дедуп
- Эмбеддите входящие сообщения, тикеты или карточки.
- Порог cosine > 0.92 — почти наверняка дубль.
- 0.80–0.92 — похожая тема, кандидат на объединение, но лучше глазами.
Кластеризация идей и заметок
- Эмбеддите все заметки, прогоняете через UMAP + HDBSCAN.
- Получаете тематические группы без заранее заданных категорий. Удобно для «а что у меня вообще в голове творится».
Типичные ошибки и как их чинить
| Симптом | Причина | Решение |
| Низкая cross-lingual similarity (<0.75) | Обрезка контекста по 512 токенам, неправильный pooling | Явно указать max_length=8192, использовать dense_vecs из FlagEmbedding |
| OOM на больших батчах | batch_size слишком большой для RAM | Снизить до 4–8 на CPU, 16–32 на GPU |
| Первый запрос — 30+ секунд | Cold start: загрузка весов и прогрев | Прогревать модель фиктивным запросом при старте сервиса |
| Ошибка 422 в LiteLLM | Ответ не соответствует ожидаемой схеме | Отдавать ровно OpenAI-формат: {object, model, data: [{embedding, index}], usage} |
| Медленно на CPU (500+ мс) | Нет AVX2, старый NumPy, включён fp16 на CPU | Проверить lscpu, обновить numpy и torch, убрать use_fp16=True |
use_fp16=True на CPU не ускоряет инференс, а замедляет его в 2–3 раза. Флаг имеет смысл только на GPU с tensor cores. На CPU — строго False.Антипаттерны
- ❌ Эмбеддить весь документ целиком. Даже при контексте 8192 качество retrieval проседает. Режьте на чанки по 500–1500 токенов с overlap.
- ❌ Выставлять сервис в публичный интернет без auth. Бесплатный compute для чужих ботов за вашу электричество — сомнительное удовольствие.
- ❌ Мешать эмбеддинги от разных моделей в одном индексе. Векторы несопоставимы. Поиск сломается тихо и незаметно — это худший вариант.
- ❌ Считать cosine similarity до нормализации. FlagEmbedding возвращает уже нормализованные векторы, но если собираете руками — нормализуйте, иначе скор будет искажён.
- ❌ Игнорировать prompt-инструкции для запросов. Для retrieval-режима BGE рекомендует префикс к query — посмотрите карточку модели на HuggingFace.
Полезные ссылки
- Модель на HuggingFace: huggingface.co/BAAI/bge-m3
- Репозиторий FlagEmbedding: github.com/FlagOpen/FlagEmbedding
- Статья на arXiv (2402.03216): arxiv.org/abs/2402.03216
- Бенчмарк MIRACL: github.com/project-miracl/miracl
- Лидерборд MTEB: huggingface.co/spaces/mteb/leaderboard
По теме
- Статья: Как я собрал автоматический контур консультаций из Notion, Яндекс 360 и Kinescope
- Блог: yandex-office для OpenClaw — один скилл для всего Яндекс 360, от которого не хочется сбежать
- База знаний: OpenAI Codex — облачный coding-агент для параллельной разработки
Если собираете свой RAG-контур и прикидываете, какую embedding-модель ставить под двуязычную базу знаний — давайте обсудим, что лучше подойдёт под вашу нагрузку и инфраструктуру.