Обновить
29
Александр Зевайкин@ShuraZ

Разрабатываю YDB, Яндекс

7
Подписчики
Отправить сообщение

Хорошее замечание, спасибо.
У нас в планах есть автоматическое определение параметров векторного индекса.

Это будет работать для случаев добавления индекса в существующую таблицу, когда есть возможность проанализировать подборку векторов и вычислить нужные параметры вроде числа уровней в дереве.

В данной статье решается задача: как всегда быстро достать нужные 50 документов, даже когда пользователь включил фильтры и в одной категории осталось 6 тысяч текстов, а в другой — 2,5 млн. Это именно задача retrieval (поиска кандидатов) - и векторный поиск для этого самый рабочий инструмент.
GraphRAG тут не "вместо", а скорее "поверх": он может помочь связать найденные куски в более понятную аргументацию, но чтобы вообще было из чего строить граф и ранжировать, кандидатов всё равно нужно сначала вытащить

Да, можно строить несколько векторных индексов, а при выборке SELECT указывать нужный через VIEW index_name

Например:

DECLARE $query_vector AS List<Uint8>;

SELECT user, data
FROM my_table VIEW my_index
ORDER BY Knn::CosineSimilarity(embedding, $query_vector) DESC
LIMIT 10;


https://ydb.tech/docs/ru/dev/vector-indexes?version=v25.4#select

ни одной статьи "Как мы мигрировали на YDB с XXX" за последние 2 года (если я нормально посмотрел)

Вот же в статье про миграцию на YDB написано:

«Мы остановились на YDB, так как эта система позволяет работать с очень большим количеством транзакций…. Проект по модернизации расчетного центра Газпромбанка стартовал в середине 2023 года. Сейчас система уже обрабатывает до 3 млн транзакций в час», — Иван Варжавин, исполнительный вице-президент Газпромбанка для РБК


Спасибо за уточнение. Действительно, в ряде реализаций HNSW вектора хранятся прямо в графе, а в ряде реализаций - вне графа. Тут уже баланс между объемом памяти и временем поиска.

А по поводу перешардирование Qdrant - у них небольшая приписка: "Resharding is exclusively available on multi-node clusters across our cloud offering".
В случае YDB - немного иначе. СУБД, изначально рожденная в Яндексе, открыта в публичный доступ в OpenSource.

Мы смотрели в сторону разных алгоритмов.
Конкретно HNSW не подошел именно для нас.

Произвольный доступ к памяти – замедление дискового IO.
Увеличенное потребление памяти 2x–8x в зависимости от числа слоёв.
Сложно сделать граф эластичным, перешардироваться на лету.

Ну и наконец, мы целимся в миллиарды векторов.

RAG ищет тексты, близкие по смыслу к запросу, но если название неоднозначное, то результаты могут быть неточными. Чтобы избежать мусора в ответах, нужна фильтрация по метаданным (тип, год) или гибридный поиск (векторный + полнотекстовый).
Плюс никто не мешает строить такие запросы к LLM, чтобы она могла запросить дополнительные детали.

Да, согласен. Просто так использовать 1 бит на размерность нет смысла, слишком низкое качество. Но с реранкингом все гораздо лучше, как по скорости, так и полноте.

Действительно, слишком сильное квантование приводит к снижению полноты и это ожидаемо.
Выход - делать реранкинг, то есть в найденном поискать с помощью исходных несжатых векторов. После этого полнота сильно улучшается.
Пример запроса приведен в разделе "Приближённый векторный поиск без индекса"

Правильное замечание про RAG!
Мы уже работаем на полнотекстовым поиском. Ну а следующий этап - соединить полнотекстовый и векторный, получив гибридный поиск. Это хорошо ложится на нашу модель выполнения запросов.

Изначально вектор использует 32 бита для каждого числа (размерности), можно применять статическое квантование и использовать 1 бит на размерность.

Мы думали об этом, но это требует отдельных экспериментов по влиянию сжатия на производительность YDB CDC. Надеемся в какой-то момент реализовать.

У нас есть команда CLI для просмотра списка объектов: https://ydb.tech/docs/ru/reference/ydb-cli/commands/scheme-ls
А также есть команда для получения информации об объекте схемы: https://ydb.tech/docs/ru/reference/ydb-cli/commands/scheme-describe

какого рода вычислительная нагрузка на брокерах, что она может быть "повышенной"

Брокер сообщений выполняет множество вычислительно сложных операций: общение с писателями/читателями (терминация SSL, аутентификация, прием/отправка сообщений, подтверждение сообщений, буферизация, дедупликация), общение с другими брокерами (репликация), и на конец - запись на диск.

чем принципиально отличается добавление узлов Bookeeper от добавления узла Kafka

Добавление брокера в Kafka сильно сложнее, чем в Pulsar. Основная причина: данные партиций лежат прямо на брокерах и при увеличении числа брокеров данные нужно перебалансировать. Процесс переноса партиций между брокерами в Kafka называется partition reassignment и требует полного копирования данных затрагиваемых партиций.

что является ключом, что является значением, хранится в памяти или на диске и в каком виде.


В статье есть:
Ключом является уникальный номер пачки, а значением множество сообщений.
При записи свежие сообщения объединяются в пачку, на базе смещения формируется ключ, и эта пара отправляется в Key‑Value хранилище. При чтении, наоборот.

Ряд дополнительных подробностей про YBD Topics можно найти тут https://ydb.tech/docs/ru/concepts/topic

Выделенный слой хранения дает возможным независимо изменять число брокеров Pulsar и узлов хранения Bookeeper. Если повышенная вычислительная нагрузка на брокеры, то можно увеличить число узлов Pulsar. Если не хватает места на диске для требуемых гарантий времени хранения (retention), то можно увеличить число узлов Bookeeper. В Kafka такой гибкости не хватает, так как хранение данных производится непосредственно на брокерах. Добавил в тексте.

Действительно, "прокси отвечает", поправил, спасибо.

В результатах профайлера видно функцию TBatch::Serialize, внутри которой есть std::copy и memmove. Именно на это мы обратили внимание и пошли смотреть исходный код. А там уже нашли и убрали лишние склеивания строк.

Информация

В рейтинге
Не участвует
Откуда
Россия
Работает в
Зарегистрирован
Активность