惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
G
Google Developers Blog
量子位
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
阮一峰的网络日志
阮一峰的网络日志
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
B
Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Proofpoint News Feed
美团技术团队
V
Visual Studio Blog
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Fortinet All Blogs
博客园 - Franky
The Register - Security
The Register - Security
O
OpenAI News
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
罗磊的独立博客
博客园 - 叶小钗
博客园 - 聂微东
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
SecWiki News
SecWiki News
T
Tor Project blog
月光博客
月光博客
S
Secure Thoughts
博客园 - 【当耐特】
Help Net Security
Help Net Security
D
Docker
Recent Announcements
Recent Announcements
GbyAI
GbyAI
B
Blog RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Blog of Author Tim Ferriss
Webroot Blog
Webroot Blog
V
Vulnerabilities – Threatpost
Forbes - Security
Forbes - Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Hacker News: Ask HN
Hacker News: Ask HN
Cyberwarzone
Cyberwarzone
宝玉的分享
宝玉的分享
Cisco Talos Blog
Cisco Talos Blog
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Retrieval в 2026: как RAG переехал с энкодеров на LLM (и что с этим делать в своём проекте)
Софья Кузьмина · 2026-06-20 · via Все публикации подряд на Хабре

Средний

8 мин

78

Если вы строили RAG в 2023, ваш стек выглядел плюс-минус одинаково. BERT-семейство (BGE, e5) для семантики, BM25 для буквальных совпадений, cross-encoder для реранкинга, какой-нибудь Qdrant сверху. Этим жили два года, и многие до сих пор так живут.

Но если посмотреть, кто реально гоняется в продакшене у команд, которые ушли вперёд, ландшафт другой. Энкодеров там почти нет. Эмбеддит файнтюненная LLM. Реранкер — тоже LLM. Инференс на SGLang, а не на ONNX. И вся обвязка перестроилась под это.

Эта статья про то, что поменялось и как переиспользовать этот стек у себя. Особенно если вы работаете в узком домене, где готовых датасетов нет.

Что было: классический стек и его потолок

Дефолтный retrieval делал три вещи. Энкодер берёт текст, прогоняет через bidirectional трансформер, собирает информацию в один вектор — через [CLS] токен или усреднение. Этот вектор кладётся в векторную базу, по нему ищется ближайший сосед по косинусу. Параллельно работает BM25 для точных совпадений по словам — нужен, потому что эмбеддер плохо ищет коды, артикулы, номера законов. Сверху cross-encoder переранжирует топ-K и отдаёт пользователю.

Где этот стек упёрся:

Узкие домены он не вытягивает. Если BGE на претрейне не видел юридический корпус, вы не дотянете его до приличного качества простым bge-large вместо bge-base.

Длинный контекст — до свидания. Большинство энкодеров живёт в районе 512 токенов, чуть больше у Jina и Nomic. Поэтому появился весь зоопарк chunking-стратегий в LangChain.

Инструкции под задачу нельзя задать на лету. Хотите retrieval — учите модель под retrieval, под классификацию — учите отдельно.

Инференс-стек умер. ONNX Runtime поддерживается номинально, flash attention туда так и не завезли, prefix caching нет. Сообщество перешло на vLLM и SGLang под декодеры, а энкодерам ничего не досталось.

Логичный ход — не чинить энкодеры, а взять то, во что вкладываются все, и приспособить под эмбеддинг.

Главный сдвиг: декодер становится эмбеддером

Идея кажется странной. Декодер обучен предсказывать следующий токен, у него causal mask — каждый токен видит только себя и предшественников. Усреднять по токенам бессмысленно: первый токен ничего не знает о предложении.

Решение: пулят последний токен. Конкретно — <eos>. Он «видел» всю последовательность и собирает в себе её смысл. На этом трюке стоит большинство современных эмбеддеров.

Базовая статья тут — LLM2Vec (McGill, 2024). Авторы показали рецепт из трёх шагов: включить bidirectional attention, дообучить через masked next-token prediction, добить unsupervised contrastive learning по схеме SimCSE. Уже на этом этапе модель обгоняет энкодеры сопоставимого размера. Дальше — supervised contrastive с инструкциями и hard negatives.

Что даёт переезд на декодерную архитектуру:

Гигантский pretrain в наследство. В энкодеры заливали десятки миллиардов токенов. В современные декодеры — триллионы. Эта разница видна в качестве эмбеддингов.

Понимание инструкций. В промпт можно положить описание задачи: «Найди документ, отвечающий на вопрос». Та же модель переключается между retrieval, классификацией и кластеризацией без переобучения.

Длинный контекст из коробки. Qwen3-Embedding держит 32k токенов. Можно класть параграф целиком, не дробить.

Весь декодерный тулинг. Flash attention, KV-cache, prefix caching, vLLM, SGLang. Всё это работает.

NV-Embed добавил важный нюанс к рецепту: вместо тупого <eos> они используют latent attention pooling — отдельный обучаемый слой, который собирает информацию со всех токенов. На MTEB это даёт +1–2 пункта стабильно.

Сравнение пулинга: энкодер агрегирует через CLS или mean, декодер берёт последний токен (EOS)

Сравнение пулинга: энкодер агрегирует через CLS или mean, декодер берёт последний токен (EOS)

Современные модели

Что брать сегодня, если хочется decoder-based эмбеддер с HuggingFace:

Модель

Размер

Контекст

MTEB

Особенности

Qwen3-Embedding-0.6B

0.6B

32k

~64

MRL (матрёшка), 100+ языков

Qwen3-Embedding-4B

4B

32k

~68

Тот же тренировочный пайплайн

Qwen3-Embedding-8B

8B

32k

70.58

№1 в multilingual MTEB на момент релиза

NV-Embed-v2

7B

32k

72.31

Latent attention pooling, на Mistral

E5-Mistral-7B-instruct

7B

32k

~66

Первая массовая instruction-модель

Qwen3-Embedding из коробки умеет Matryoshka Representation Learning: один и тот же эмбеддинг можно усечь до 256 / 512 / 1024 размерности без переобучения, и качество просядет мягко, а не катастрофически. На практике это значит, что один индекс гоняется с разной точностью на разных стадиях пайплайна.

Под русский язык из коробки никто не идеален. У Qwen3 покрытие неплохое, но если домен специфичный, файнтюнить всё равно придётся.

Что делать, если в вашем домене нет датасетов

Тут самое интересное и больное. Раньше переход на новый эмбеддер в узкий домен — нефтянка, юриспруденция, бухгалтерия, медицина — упирался в один и тот же вопрос: где взять данные. Готовых датасетов нет, на HuggingFace их никто не выкладывает, собрать вручную — это месяцы работы команды разметчиков. На этом этапе многие проекты буксовали.

Декодерный эмбеддер этот блок снимает не до конца, но сильно ослабляет. Сразу с нескольких сторон.

Знания уже внутри модели. Декодерный претрейн на 15 триллионах токенов включает огромные куски Common Crawl, GitHub, arXiv, юридические корпуса, медицинские форумы, технические PDF. Модель уже видела термины своего домена, даже если он узкий. Файнтюнить нужно ранжирование пар «запрос → документ» в вашей конкретной задаче. Сам язык модель и так знает. Это на порядок дешевле.

Инструкции вместо обучения. В промпт можно положить:

Instruct: Найди в корпусе нормативных документов раздел, 
описывающий требования к промышленной безопасности 
на нефтеперерабатывающих установках.
Query: {запрос пользователя}

И та же модель без файнтюна работает на этом домене лучше, потому что инструкция переводит её в нужный режим. Это бесплатный буст качества на 3–5 пунктов recall.

Синтетическая разметка той же LLM. Логика такая: у вас есть документы. Их обычно много. Запросов к ним нет, потому что либо продукт ещё не запущен, либо логи слишком скудные.

Берёте декодерную LLM (можно ту же, что эмбеддит, можно сильнее — Qwen3-32B, Llama, что угодно с API) и просите её сгенерировать запросы к каждому документу:

Документ: {текст документа}

Сгенерируй 5 вопросов, которые мог бы задать инженер, 
ищущий именно этот документ. Вопросы должны быть разной 
формулировки: формальные, разговорные, с аббревиатурами, 
с опечатками.

На выходе — десятки тысяч пар (query, positive_doc) бесплатно. Качество не идеальное, но для дообучения эмбеддера хватает. Дальше синтетику фильтруют: прогоняют через эмбеддер до файнтюна, смотрят, какие пары он уже правильно ранжирует (выкидывают как слишком лёгкие), какие катастрофически путает (выкидывают как шум).

Пайплайн дообучения эмбеддера без размеченного датасета: LLM генерирует синтетические запросы к корпусу, baseline-эмбеддер фильтрует пары, hard negatives майнятся positive-aware методом, итог — LoRA-файнтюн

Пайплайн дообучения эмбеддера без размеченного датасета: LLM генерирует синтетические запросы к корпусу, baseline-эмбеддер фильтрует пары, hard negatives майнятся positive-aware методом, итог — LoRA-файнтюн

Hard negatives без разметки. Подход из NV-Retriever (2024). Берёте базовый эмбеддер, для каждого запроса достаёте топ-100 документов. Те, что близки к позитиву, но не он, — кандидаты в hard negatives. Дальше фильтруете positive-aware: если скор кандидата подозрительно близок к скору позитива, это, скорее всего, false negative (документ на самом деле релевантен, просто не размечен), такие выкидываете. Остальное идёт в обучение.

Связка этих приёмов даёт работающий пайплайн без размеченного датасета на старте:

  1. Берёте Qwen3-Embedding-0.6B как baseline.

  2. Прикручиваете instruction-промпт под свой домен.

  3. Генерируете синтетику запросов через сильную LLM.

  4. Майните hard negatives positive-aware фильтром.

  5. Дообучаете через LoRA на 1–2 GPU за пару дней.

На выходе — доменный эмбеддер, который на вашем бенчмарке выдаёт recall@10 в районе 0.8–0.9. На практике этого хватает.

Бенчмарк, кстати, придётся собрать руками. Минимум 200–500 пар. Это единственное место, где нельзя срезать: без него вы не отличите, ваш файнтюн улучшил качество или сломал.

Инференс: SGLang против vLLM

Когда вы переезжаете с энкодеров на декодерные эмбеддеры, дефолтный sentence-transformers перестаёт тянуть. Под капотом он гоняет через transformers/PyTorch, без flash attention, без префикс-кэша. На decoder-based эмбеддере вы на этом теряете половину скорости.

vLLM и SGLang — основные движки под продакшен. Оба умеют эмбеддинги, оба гоняют reranker через batched scoring. Разница в архитектуре кэша:

vLLM использует обычный prefix caching: один общий префикс для серии запросов.

SGLang использует RadixAttention — строит radix-дерево по всем кэшированным KV-страницам и переиспользует любой общий префикс между любыми запросами.

Для retrieval это важно в одном конкретном месте — реранкере. Он работает так: один запрос пользователя + 50 кандидатов из топа. В каждой паре префикс — это инструкция + запрос. Этот префикс одинаковый для всех 50 пар. SGLang за счёт RadixAttention считает его один раз и переиспользует во всех 50 forward-pass. На H100 это даёт до 6x ускорение на типичной RAG-нагрузке.

vLLM проще ставится, у него больше сообщество и шире поддержка железа. SGLang быстрее в RAG-сценариях, кодовая база чище, новый ресёрч обычно сначала появляется там. Если выбирать с нуля под retrieval — SGLang.

Хранилище: что менять в Qdrant

Когда источников много — внутренние вики, юридический корпус, бухгалтерия, тикеты поддержки — есть искушение свалить всё в одну коллекцию. Так делать не надо. Эмбеддер, даже хороший, путается между доменами, и юристу прилетит бухгалтерская справка.

Официальная рекомендация Qdrant — две схемы:

Collection-per-tenant. Подходит, если источников меньше 500, у них разный объём, нужна строгая изоляция (регуляторика, GDPR), разные размерности вектора.

Payload-based. Одна коллекция, в payload каждой точки лежит tenant_id (или source_id). Подходит, если источников тысячи и они однородные. Обязательно: keyword-индекс по tenant_id с флагом is_tenant=true, иначе Qdrant делает полное сканирование при каждом фильтре.

Метаданные — отдельная история, которую часто забывают. Дата создания, тип документа, автор, версия — всё это надо класть в payload. Тогда работают пре-фильтры (сначала отрезаем устаревшие документы, потом ищем) и пост-фильтры (нашли по семантике, отсортировали по дате). Без метаданных эмбеддер делает за вас то, что должна делать база.

И последнее: индекс не пересобирается с нуля. Никогда. Qdrant умеет инкрементальные апдейты, добавляйте точки по мере появления, удаляйте устаревшие. Если совсем надо переиндексировать — по расписанию раз в месяц.

Минимальный продакшен-стек на сегодня

Если бы я собирал retrieval сегодня с нуля, выглядело бы так:

Эмбеддер: Qwen3-Embedding-0.6B на старт. Если запросов много и качество не дотягивает — Qwen3-Embedding-4B.

Реранкер: Qwen3-Reranker-0.6B поверх топ-50 от эмбеддера.

Инференс: SGLang. Один pod на эмбеддер, один на реранкер.

Хранилище: Qdrant. Payload-based multi-tenancy с source_id в индексе.

BM25: оставляем, гибридный поиск. Эмбеддер хорошо ищет смысл, BM25 — артикулы, номера, имена собственные. Их результаты сливаем через reciprocal rank fusion.

Под домен: генерация синтетики + hard negatives + LoRA, как описано выше.

Этот стек по качеству бьёт классический BGE+BM25+cross-encoder на 15–20% recall и при этом инфраструктурно проще: одна архитектура (декодер) для эмбеддера и реранкера, один движок инференса, одна база.

Что осталось за кадром

Мультимодальные эмбеддеры. Qwen3-VL-Embedding мапит текст, картинки, PDF, видео в одно векторное пространство. Если ищете по корпусу со схемами и фотографиями — стоит посмотреть.

ModernBERT. Энкодер ещё не совсем мёртв. ModernBERT (декабрь 2024) — современный энкодер с flash attention, sliding window, длинным контекстом. На задачах semantic discrimination держится наравне с декодерами и в разы быстрее на инференсе. Если у вас классификация или кластеризация, а не retrieval — посмотрите в его сторону.

Сжатие декодерных эмбеддеров. Дистилляция в маленькие модели, квантизация, MRL-усечение. Тема активная, но это уже на следующую статью.


Переход с энкодеров на декодерные эмбеддеры — это не «возьмём модель побольше». Это смена архитектурного семейства. С ней приходят инструкции в промпте, длинный контекст и весь инференс-стек, который раньше был только у генераторов. И главное — порог входа в узкие домены упал. Там, где раньше уходили месяцы на сбор датасета, сейчас можно собрать рабочий пайплайн за пару недель.

Если у вас есть опыт перехода с энкодеров на decoder-эмбеддеры, особенно в узком домене — расскажите в комментариях. Интересно сравнить, какие модели и приёмы зашли, а какие нет.

Источники