Embeddings-модели: какую выбрать для RAG
Собрали RAG-пайплайн, подключили векторную базу, а поиск всё равно находит не те куски документов — знакомая ситуация. Чаще всего дело не в чанкинге и не в промпте, а в модели эмбеддингов: она определяет, насколько «умно» система понимает смысл текста, и ошибка на этом уровне не лечится тюнингом промпта. Разберём, как выбрать модель осознанно, а не по первой ссылке в документации.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое эмбеддинг простыми словами
Эмбеддинг — это число-вектор, который отражает смысл текста. Модель эмбеддингов берёт кусок текста (предложение, абзац, вопрос) и превращает его в массив из нескольких сотен или тысяч чисел с плавающей точкой. Тексты с похожим смыслом дают вектора, которые лежат «рядом» друг с другом в этом многомерном пространстве — их можно сравнить математически, например через косинусное сходство.
Именно на этом строится RAG: вы превращаете в вектора все куски своей базы знаний, кладёте их в векторную БД, а когда приходит вопрос пользователя — превращаете вопрос в вектор той же моделью и ищете ближайшие по смыслу куски. Дальше эти куски отдаются языковой модели как контекст для ответа.
Важно понимать: эмбеддинг не хранит текст — он хранит только «геометрическое» представление его смысла, конкретное для той модели, которая его создала. Это ключевое ограничение, к которому мы ещё вернёмся.
Размерность вектора и что она стоит вам в хранилище
Размерность — это длина вектора, то есть сколько чисел в нём содержится. У разных моделей она разная: где-то 384, где-то 768, где-то 1024 или больше. Чем выше размерность, тем детальнее модель в теории может закодировать смысл — но и тем больше места он займёт в векторной БД и тем дольше будет считаться поиск.
Это не абстрактная величина — она напрямую превращается в мегабайты и гигабайты на диске. Прикидка по объёму для одного вектора в float32:
| Размерность | Байт на 1 вектор | ~1 млн векторов |
|---|---|---|
| 384 | 1536 байт | ~1.5 ГБ |
| 768 | 3072 байт | ~3 ГБ |
| 1024 | 4096 байт | ~4 ГБ |
| 1536 | 6144 байт | ~6 ГБ |
Это без учёта индексов (HNSW и подобные добавляют накладные расходы), метаданных и оверхеда самой БД — по факту цифры на диске будут выше. Если у вас база из десятков тысяч документов, разница между 384 и 1536 измерениями может быть не критична. Если счёт идёт на миллионы чанков — она превращается в разницу между «влезаем в RAM недорогого сервера» и «нужен отдельный сервер под векторную БД». Многие современные модели поддерживают усечение вектора (Matryoshka-представление) — можно взять только первые N чисел вектора и получить компромисс между качеством и размером, но эту возможность стоит проверять в документации конкретной модели, а не считать её универсальной.
Практический вывод: не берите модель «на вырост» с максимальной размерностью, если не уверены, что она вам нужна. Начните с расчёта — сколько у вас документов, сколько чанков они дадут, сколько это займёт места при разных размерностях — и уже от этого отталкивайтесь. Как прикинуть память под векторную БД под свою нагрузку, разбирали в статье про расчёт RAM для Qdrant.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть QdrantРусский язык: проверяйте, а не верьте описанию
Здесь начинается самое неприятное место в выборе модели. Большинство сильных открытых эмбеддинг-моделей обучены преимущественно на английском тексте, и на карточке модели в Hugging Face может быть написано «multilingual» — но это не гарантия одинакового качества на русском.
На практике встречаются модели, которые:
- нормально работают с русским текстом, но заметно хуже, чем с английским, на технических и специфичных терминах;
- путают близкие по написанию, но разные по смыслу русские слова из-за особенностей токенизации;
- дают неплохие эмбеддинги для отдельных предложений, но хуже справляются с длинными абзацами на русском.
Честный совет: не берите модель в продакшен только потому, что в описании написано «поддерживает 100+ языков». Возьмите 20-30 реальных пар «вопрос — релевантный кусок текста» из своей предметной области на русском языке, прогоните через кандидатов и вручную посмотрите, действительно ли релевантные куски оказываются ближе по косинусному сходству, чем нерелевантные. Это займёт час, а сэкономит недели разбора «почему RAG плохо ищет».
Из открытых семейств, ориентированных на многоязычность включая русский, стоит присматриваться к моделям линейки E5 (в частности мультиязычных вариантах) и BGE — но конкретную версию и её актуальный рейтинг на момент выбора обязательно сверяйте на лидерборде MTEB (Massive Text Embedding Benchmark) сами: рейтинги меняются, новые модели выходят регулярно, и то, что было топом полгода назад, может уже не быть таковым.
Локальный запуск через открытые модели vs эмбеддинги через API
Здесь два принципиально разных пути, и выбор влияет на архитектуру всего RAG-пайплайна.
Локальный запуск через открытые модели. Библиотека sentence-transformers — стандартный инструмент для запуска таких моделей на своём сервере. В общем виде это выглядит так:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("название-модели-с-huggingface")
vectors = model.encode([
"Первый кусок документа",
"Второй кусок документа",
])
print(vectors.shape) # (2, размерность_модели)
Плюсы: данные не покидают ваш сервер (критично, если работаете с конфиденциальными документами), нет платы за каждый запрос, нет зависимости от доступности внешнего API и от блокировок. Минусы: нужен сервер с достаточным CPU или GPU под инференс, вы сами отвечаете за апдейты модели и версий библиотек, для больших объёмов текста расчёт эмбеддингов может быть медленнее, чем через оптимизированный облачный API. Считать эмбеддинги можно и без видеокарты — см. отдельный разбор как считать эмбеддинги на CPU без GPU.
Эмбеддинги через API. Отправляете текст в облачный сервис, получаете вектор в ответ. Плюсы: не нужно думать про инфраструктуру под саму модель, обычно стабильно высокое качество, простая интеграция. Минусы: ваш текст (в том числе потенциально чувствительные документы) уходит на сторонний сервер, есть стоимость за объём запросов, есть зависимость от доступности сервиса и от сети — из России доступ к некоторым API идёт нестабильно, и для этого нужен либо VPN, либо сервер за рубежом как точка выхода.
Если решаете пойти по пути API, но нужен стабильный выход за рубеж — вариант поднять точку доступа на своём сервере в США или Великобритании и слать запросы через неё, не завязываясь на VPN на каждой машине.
Практическое правило выбора: если данные чувствительные, нагрузка предсказуемая и есть время на настройку — локальный запуск обычно выгоднее в долгосрочной перспективе. Если нужно быстро запустить прототип и объём запросов небольшой — API проще для старта.
Главное правило: одна модель для индексации и для поиска
Это не рекомендация, а жёсткое требование к архитектуре RAG. Модель, которой вы превращаете документы в вектора при индексации, и модель, которой вы превращаете запрос пользователя в вектор при поиске, обязаны быть одной и той же моделью — той же версии, с теми же параметрами.
Причина в том, что каждая модель создаёт своё собственное «пространство смыслов». Вектор из одной модели и вектор из другой модели не сопоставимы между собой, даже если у них одинаковая размерность — координаты в этих пространствах означают разные вещи. Сравнение векторов от разных моделей — это не «немного менее точный» поиск, это фактически случайные числа: релевантность результатов будет близка к нулю, и отладить проблему бывает не так просто, потому что ошибок и исключений нигде не будет — просто тихо будет плохо искать.
Эта ловушка особенно легко возникает при смене модели: вы решили перейти на более новую или более компактную модель эмбеддингов, поменяли код инференса — но забыли переиндексировать уже существующую базу в векторной БД. Старые вектора остались от старой модели, новые запросы кодируются новой — и поиск начинает деградировать без явной причины. Правило простое: при любой смене модели эмбеддингов нужна полная переиндексация всей базы, без исключений. Держите версию модели явно зафиксированной в конфиге проекта, а не «последнюю доступную», чтобы случайный апдейт зависимости не сломал согласованность.
Как выбрать модель — практический чек-лист
Соберём критерии в последовательность действий:
- Определите объём данных. Сколько документов, сколько получится чанков после разбиения — это задаёт допустимую размерность вектора.
- Проверьте качество на своём русском тексте. Не доверяйте описанию модели — прогоните тестовый набор запросов из своей предметной области.
- Решите про локально или через API. Отталкивайтесь от чувствительности данных, предсказуемости нагрузки и доступности сети из России.
- Проверьте лимит длины входного текста модели. У каждой модели есть максимальное число токенов на один фрагмент — если ваши чанки длиннее, текст будет обрезан незаметно для вас.
- Зафиксируйте версию модели в конфигурации и не меняйте её без осознанной переиндексации всей базы.
- Проверьте совместимость с векторной БД. Например, при развёртывании Qdrant на своём сервере размерность коллекции задаётся один раз при создании и должна точно совпадать с размерностью выбранной модели.
Если весь пайплайн RAG вы ещё не собирали, весь путь целиком — от загрузки документов до ответа с цитированием источника — описан в статье как поднять RAG по своим документам на сервере.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть QdrantОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Можно ли использовать разные модели эмбеддингов для разных языков в одной базе?
Технически можно завести отдельные коллекции под разные языки с разными моделями, но проще и надёжнее использовать одну мультиязычную модель для всей базы — это исключает путаницу при маршрутизации запросов.
Что будет, если сменить модель эмбеддингов и не переиндексировать базу?
Поиск начнёт возвращать нерелевантные результаты без явных ошибок в логах, потому что старые и новые вектора лежат в несопоставимых пространствах. Решение одно — полная переиндексация.
Нужен ли GPU для расчёта эмбеддингов?
Не обязательно. Для умеренных объёмов и компактных моделей CPU справляется приемлемо по времени; GPU ускоряет процесс в первую очередь при постоянной массовой индексации больших объёмов текста.
Как понять, что модель плохо работает с русским, если внешне выдаёт вектора без ошибок?
Только проверкой на своих данных: возьмите реальные пары «вопрос — правильный ответ» и сравните, действительно ли релевантный кусок оказывается ближе по сходству, чем случайный.
Стоит ли брать модель с максимальной размерностью «про запас»?
Обычно нет — это лишняя нагрузка на хранилище и на скорость поиска без гарантированного выигрыша в качестве, особенно если качество на русском у более крупной модели не проверено отдельно.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.