中文翻译暂不可用,显示俄语原文。

Что такое Multi-vector retrieval и зачем он нужен?

Краткий тезис

Multi-vector retrieval — это подход, при котором один документ (или чанк) представляется не одним эмбеддингом, а множеством векторов: эмбеддинги заголовков, ключевых фраз, предложений или даже каждого токена. Это решает проблему «сжатия смысла»: обычный эмбеддинг сжимает весь текст в один вектор, теряя детали. Multi-vector сохраняет больше информации, что улучшает поиск на сложных запросах. Самый известный пример — ColBERT, где каждый токен документа имеет свой эмбеддинг, и релевантность считается через late interaction (попарное сравнение токенов запроса и документа).

Ключевая идея Один вектор — это «средняя температура по больнице». Много векторов — это детальная карта.


1. Термин: Multi-vector retrieval

Что это Метод, при котором каждый документ (или чанк) индексируется с использованием нескольких эмбеддингов, а не одного.

Сравнение

ПодходКоличество эмбеддингов на документЧто сохраняется
Single-vector (обычный RAG)1 (весь чанк)Смысл в среднем
Multi-vector (ColBERTN (каждый токен)Каждый токен, порядок
Multi-vector (HyDE1 (гипотетический ответ) + 1 (оригинал)Альтернативная перспектива
Multi-vector (Parent-child1 на дочерний, 1 на родительскийИерархия

Термин «Late interaction» (позднее взаимодействие Вместо того чтобы сворачивать документ в один вектор до поиска (early interaction), мы храним все векторы токенов документа, а при поиске сравниваем их с векторами токенов запроса попарно.


2. Проблема, которую решает Multi-vector retrieval

2.1 Проблема «сжатия» в одном векторе

Обычный подход (single-vector

Документ: "Кошка сидит на ковре. Собака бежит по траве."
→ Embedding модель → один вектор [0.12, -0.45, ...]

Потеря информации

  • Порядок слов? Потерян
  • Отношения между словами? Сглажены
  • Тонкие семантические нюансы? Усреднены

Пример, где single-vector ошибается

Запрос: "Кошка бежит"
Документ: "Собака бежит. Кошка сидит."

Single-vector может найти этот документ (есть и "кошка", и "бежит"), 
но на самом деле в документе кошка НЕ бежит.
Multi-vector (ColBERT) найдёт правильный документ, где кошка действительно бежит.

Термин «Token-level matching» Сравнение каждого токена запроса с каждым токеном документа. Это позволяет улавливать тонкие семантические отношения.


3. Пример реализации: ColBERT

Термин «ColBERT» (Contextualized Late Interaction over BERT Модель для chunks|multi-vector retrieval, где каждый токен документа и запроса получает свой эмбеддинг, а релевантность считается как сумма максимальных попарных сходств.

Как работает ColBERT

Шаг 1: Токенизация и эмбеддинги
Запрос: "кошка бежит"
→ Токены: [CLS] кошка бежит [SEP]
→ Эмбеддинги: E_query = [e_кошка, e_бежит]  (2 вектора)

Документ: "Собака бежит. Кошка сидит."
→ Токены: [CLS] собака бежит . кошка сидит [SEP]
→ Эмбеддинги: E_doc = [e_собака, e_бежит, e_., e_кошка, e_сидит]  (5 векторов)

Шаг 2: Late interaction (попарное сравнение)
Для каждого токена запроса:
    max_sim = max(cosine_similarity(e_запроса, e_документа) for e_документа)

score_кошка = max(cos(e_кошка, e_собака), cos(e_кошка, e_бежит), cos(e_кошка, e_.), cos(e_кошка, e_кошка), cos(e_кошка, e_сидит))
            = cos(e_кошка, e_кошка) = 1.0

score_бежит = max(cos(e_бежит, e_собака), cos(e_бежит, e_бежит), ...) = cos(e_бежит, e_бежит) = 1.0

Шаг 3: Итоговый score
total_score = score_кошка + score_бежит = 2.0

Шаг 4: Нормализация (обычно через сумму логарифмов или softmax)

Формула ColBERT (упрощённо

Score(q, d) = Σ_{i=[[1. Как бы вы спроектировали RAG-систему для 10 000 документов с разной структурой|1]]}^{|q|} max_{j=[[1. Как бы вы спроектировали RAG-систему для 10 000 документов с разной структурой|1]]}^{|d|} cos(E_q[i], E_d[j])

где:

  • |q| — количество токенов в запросе
  • |d| — количество токенов в документе
  • E_q[i] — эмбеддинг i-го токена запроса
  • E_d[j] — эмбеддинг j-го токена документа

Почему это хорошо

  • Токен "кошка" сопоставился с "кошка" (1.0)
  • Токен "бежит" сопоставился с "бежит" (1.0)
  • Модель НЕ сопоставила "кошка" с "собака" (низкий score)

Если бы в документе было "Кошка бежит

  • Тот же score 2.0 (хорошо) Если бы в документе было "Кошка сидит
  • score = 1.0 (кошка) + 0.2 (бежит vs сидит) = 1.2 (ниже, правильно)

4. Сравнение: Single-vector (Bi-encoder) vs ColBERT

ХарактеристикаBi-encoder (обычный RAG)ColBERT (multi-vector)
Эмбеддингов на документ1
Память на 1 млн документов1.5 GB (768d)150+ GB (512 * 768d)
Время поискаO(1) (косинусное расстояние)O(
10. Что такое Self-RAG и когда его использовать10]]. Что такое Self-RAG и когда его использовать10]]. Что такое Self-RAG и когда его использовать
Требования к GPUНизкиеВысокие
Когда использоватьБольшинство RAGСложные запросы, точность критична

Термин «Bi-encoder» Два энкодера — один для запроса, один для документа. Каждый сворачивает свой вход в один вектор.

Термин «Cross-encoder» Один энкодер обрабатывает пару (запрос, документ) вместе. Очень точно, но O(n²) — не масштабируется.

Место ColBERT на спектре

Bi-encoder (быстро, грубо) → ColBERT (баланс) → Cross-encoder (медленно, точно)

5. Другие варианты Multi-vector retrieval

5.1 Parent-child retrieval (иерархический)

Идея Документ разбивается на маленькие чанки (children) для поиска, но в LLM возвращается большой родительский чанк (parent).

# Индексируем маленькие чанки
child_embeddings = embed(child_chunks)

# При поиске: находим child
retrieved_child = search(query_emb, child_embeddings)

# Возвращаем родителя (большой чанк, содержащий этого ребёнка)
parent_chunk = get_parent(retrieved_child)

2 Как вы решаете проблему lost in the middle при работе с длинными контекстами|2 Как вы решаете проблему lost in the middle при работе с длинными контекстами|2 Как вы решаете проблему lost in the middle при работе с длинными контекстами|2 (Multi-vector retrieval в контексте lost in the middle|См. вопрос 2 (Multi-vector retrieval в контексте lost in the middle


5.2 HyDE как multi-vector

Идея Храним не только оригинальный чанк, но и гипотетический ответ на запрос.

  1. Что такое Hypothetical Document Embeddings (HyDE) и зачем|11. Что такое Hypothetical Document Embeddings (HyDE) и зачем|11. Что такое Hypothetical Document Embeddings (HyDE) и зачем|11 (HyDE|См. вопрос 11 (HyDE

5.3 Sparse + Dense (гибридный)

Идея Два вектора на чанк: dense (семантический) и sparse (лексический, например, SPLADE).

  1. Что такое гибридный поиск и когда он нужен|6. Что такое гибридный поиск и когда он нужен|6. Что такое гибридный поиск и когда он нужен|6 (гибридный поиск|См. вопрос 6 (гибридный поиск

6. Плюсы и минусы Multi-vector retrieval

Плюсы

ПлюсОбъяснение
Точность (recallНа 5-15% выше, чем у single-vector
Token-level matchingУлавливает тонкие семантические отношения
Устойчивость к перефразированиюЛучше находит смысл при разных формулировках
Работа с длинными документамиМожет находить релевантный токен внутри длинного документа

Минусы

МинусОбъяснение
ПамятьВ 100-500 раз больше, чем у single-vector
Скорость поискаМедленнее, особенно на больших коллекциях
Сложность индексацииНужно хранить и искать по множеству векторов
ИнструментыМеньше поддержки в векторных БД (Qdrant начинает поддерживать)

7. Когда использовать Multi-vector retrieval?

СценарийРекомендация
Сложные запросы с отрицаниямиColBERT лучше отличает "не"
Поиск по длинным документамToken-level matching находит релевантный кусок
Высокие требования к точности (медицина, юриспруденцияMulti-vector может быть оправдан
Маленькая коллекция (<1 млн документов)Память не проблема
Есть ресурсы (GPU, памятьColBERT требует мощного железа
Стандартный RAG (новости, поддержкаSingle-vector достаточно

8. ColBERT в действии (код)

# Установка: pip install colbert-ai
from colbert import Indexer, Searcher
from colbert.infra import Run, RunConfig

# Инициализация
with Run().context(RunConfig(nranks=1, experiment="notebook")):
    # Индексация документов
    indexer = Indexer(checkpoint="colbert-ir/colbertv2.0")
    indexer.index(name="my_index", collection=["doc1.txt", "doc2.txt"], overwrite=True)
    
    # Поиск
    searcher = Searcher(index="my_index", checkpoint="colbert-ir/colbertv2.0")
    results = searcher.search("кошка бежит", k=10)
    
    for passage, score, rank in zip(*results):
        print(f"{rank}: {passage} (score={score})")

Важно ColBERT требует много памяти. Для 1 млн документов (по 512 токенов) → 512 * 1M = 512M векторов × 128 байт = 65 GB памяти.


9. Пет-проект для закрепления

Задача Сравнить single-vector retrieval (BGE-m3) с ColBERT на 100 сложных запросах.

Инструменты Python, ColBERT, sentence-transformers, Qdrant

Шаги

  1. Подготовить коллекцию из 1000 документов (можно новости, статьи)
  2. Составить 100 запросов, которые требуют тонкого понимания:
    • С отрицаниями ("не содержит X")
    • С отношениями ("A связан с B")
    • Перефразированные
  3. Реализовать два подхода:
  4. Для каждого запроса найти top-10 документов
  5. Вручную оценить recall@10 для каждого подхода
  6. Замерить время индексации, память, время поиска
  7. Сделать вывод: когда ColBERT оправдывает затраты

Ожидаемый результат ColBERT даст recall@10 на 5-15% выше, но потребует в 100 раз больше памяти и будет в 10 раз медленнее.


Связь с другими вопросами

ВопросТема
1RAG архитектура (retrieval этап)
2Lost in the middle (parent-child multi-vector)
5Оценка retrieval (recall)
6Гибридный поиск (sparse + dense)
11HyDE (альтернативный multi-vector подход)
221-235ANN internals (как ускорить multi-vector поиск)

18. Что такое Multi-vector retrieval и зачем он нужен|18. Что такое Multi-vector retrieval и зачем он нужен|18. Что такое Multi-vector retrieval и зачем он нужен|18 полностью разобран. Переходим к вопросу 19, когда будете готовы|Вопрос 18 полностью разобран. Переходим к вопросу 19, когда будете готовы]]


Навигация