ANN: приближённый поиск соседей (B3)
Two-tower заканчивается словами «замороженные эмбеддинги → ANN» — здесь этот ANN построен прозрачно: собственный IVF-индекс на numpy поверх реальных айтем-эмбеддингов, ручка nprobe, честный замер recall ↔ доля скана ↔ latency и boundary problem поимённо на конкретных фильмах.
⚠ На нашем каталоге (~10k айтемов) точный поиск и так укладывается в доли миллисекунды (замер — в таблице ниже, протокол — в контракте в конце страницы) — ANN здесь не нужен, и продовый /similar остаётся точным. Модуль показывает механику и цену сделки, которая становится обязательной на миллионах векторов.
строим IVF-индекс и меряем…
Теория простым языком
На больших каталогах retrieval должен укладываться в latency-бюджет без полного скана — воронка обещает «отобрать сотни кандидатов из миллионов за миллисекунды», и точный перебор ломает это обещание первым; отсюда ANN, партиционирование и candidate pruning. На малых каталогах exact может быть проще и лучше — наш /similar именно такой. ANN-индекс — инженерная цена, которой two-tower-подход оплачивает скорость на масштабе.
▸Зачем ANN, если можно посчитать точно
IVF-Flat: простейший производственный индекс
Идея из двух шагов — и оба видны в лаборатории выше:
# build (офлайн, при обновлении эмбеддингов) centroids = kmeans(item_vectors, n_clusters) # сферический: всё L2-нормировано lists[c] = [i for i in items if nearest(i) == c] # inverted lists # search (онлайн, на запрос) probed = top_nprobe(centroids @ query) # дёшево: n_clusters ≪ N candidates = concat(lists[c] for c in probed) # сканируем только их return top_k(candidates @ query) # точный скор на кандидатах
Дальше по этой же оси развиваются продовые индексы: HNSW (граф «маленького мира» вместо кластеров — жадный спуск по соседям), PQ/OPQ (сжатие векторов в коды, чтобы миллиарды влезали в память; скор становится приближённым ещё и по значению), IVF-PQ / ScaNN (комбинации). Ручки другие — сделка та же: точность ↔ скорость ↔ память.
Инженерные следствия (то, что спрашивают на дизайне)
1. Recall@ANN — guardrail, а не наблюдение. Только считать бюджет качества воронки перемножением нельзя: recall@ANN меряет пересечение с точным top-K, где все позиции равноправны, а важна судьба одного конкретного релевантного айтема — и это разные величины (замер выше показывает, насколько разные). Мониторить guardrail — значит держать эталонный набор запросов и мерить на нём сквозной recall (стык с B7).
2. Индекс живёт отдельной жизнью. Эмбеддинги переобучили — индекс надо перестроить; между ретрейнами новые айтемы либо доиндексируются инкрементально, либо их нет в retrieval вовсе — это ещё одно лицо cold-start (B5).
3. Несбалансированные кластеры → хвост latency. §2: плотные регионы дают толстые inverted-lists; p50 красивый, p95 — нет. В проде лечат балансировкой, квотами на скан, ранним выходом.
⚠️ Что может пойти не так
- Мерить только скорость и не мерить recall@ANN — индекс может тихо резать лучших кандидатов, офлайн-метрики воронки съедут без видимой причины.
- Считать recall@ANN константой — он зависит от распределения запросов и дрейфует вместе с ним и с каждым ретрейном эмбеддингов.
- Забыть про обновление индекса — новые айтемы не существуют для retrieval, пока не проиндексированы (cold-start на ровном месте).
- Тянуть ANN на маленький каталог — на десятках тысяч векторов exact-поиск проще, точнее и уже укладывается в бюджет (наш /similar — точный).
- Сравнивать ANN-индексы по одной точке — это кривая recall↔latency↔память; сравнивают кривые при фиксированном recall.
🧠 Проверь себя: После ретрейна two-tower офлайн-NDCG вырос, а онлайн-метрики retrieval просели. ANN-индекс не перестраивали. Что проверить первым?
Где это в дорожной карте
Это B3 — ANN-под-этап retrieval-диагностики: последний недостающий кусок пути «эмбеддинги → кандидаты» (two-tower → ANN → воронка). Дальше по треку — B4 feature store и B6 re-rank constraints, ведущие к полному capstone.
Бюджет качества: почему два recall нельзя перемножать
Что дальше
Чем продолжить — прямых наследников у модуля нет — это следующий шаг по карте
Можно читать параллельно — тот же блок, порядок между ними не важен
До финальной сборки не хватает ещё 11 модулей по этому пути.
Порядок здесь — рекомендация из карты курса, ничего не блокируется. Отметка «прочитано» хранится только в этом браузере.
Источники
- Efficient and Robust Approximate Nearest Neighbor Search Using HNSW GraphsYu. A. Malkov, D. A. Yashunin · 2016 · статьяустройство графа HNSW и смысл параметров ef/M
- Billion-Scale Similarity Search with GPUs (FAISS)J. Johnson, M. Douze, H. Jégou · 2017 · статьяIVF и квантование — вторая ветка компромисса «точность против скорости»
- Accelerating Large-Scale Inference with Anisotropic Vector Quantization (ScaNN)R. Guo et al. · 2019 · статьяквантование, оптимизированное под скалярное произведение, а не под расстояние