#HMS
Пост коротких идей из минорых мест 2
11 место:
1. Использовали как инпут зоопарк модальностей:
STFT
MFCCMel-frequency cepstral coefficients
LFCClinear-frequency cepstrum coefficients
RMS
2. Усредняли KL-div loss по всем классам и лоссы по каждому классу индивидуально. Т.е. считали 6 One-Versus-Other лоссов дополнительно и все вместе усредняли
3. Стакнули на OOF модель второго уровня, которая давала буст 0.01 относительно простого усреднения. Всего было 16 базовых архитектур, каждая по 5 фолдов.Думайте, подписаться
10 место:
1. Взял все 19 каналов и просто нарисовал их амплитуду
2. Приправил картинками спектрограмм для вязкости
3. Добавил туда визуализацию STFT и других преобразованийчтобы обои точно отклеивались
4. Пожарил 20 моделей на своей гпу
5. Сказал "оххх, золото мое золото"
Нет вы просто зайдите по ссылке и посмотрите на его картинку входную, я не шучу.
Образ мышления грандмастеров сводит иногда с ума, но я кажется улавливаю. Следует ли из деепричастия причастие- вопрос открытый
Пост коротких идей из минорых мест 2
11 место:
1. Использовали как инпут зоопарк модальностей:
STFT
MFCC
LFCC
RMS
2. Усредняли KL-div loss по всем классам и лоссы по каждому классу индивидуально. Т.е. считали 6 One-Versus-Other лоссов дополнительно и все вместе усредняли
3. Стакнули на OOF модель второго уровня, которая давала буст 0.01 относительно простого усреднения. Всего было 16 базовых архитектур, каждая по 5 фолдов.
10 место:
1. Взял все 19 каналов и просто нарисовал их амплитуду
2. Приправил картинками спектрограмм для вязкости
3. Добавил туда визуализацию STFT и других преобразований
4. Пожарил 20 моделей на своей гпу
5. Сказал "оххх, золото мое золото"
Нет вы просто зайдите по ссылке и посмотрите на его картинку входную, я не шучу.
Образ мышления грандмастеров сводит иногда с ума, но я кажется улавливаю. Следует ли из деепричастия причастие- вопрос открытый
Kaggle
HMS - Harmful Brain Activity Classification
Classify seizures and other patterns of harmful brain activity in critically ill patients
😁11👍3❤2🔥1
#HMS
9 место:
1. Использовали двух и трехмодальные системы. На вход сырой ЭЭГ, ванильные спектрограммы от каггла и спектрограммы Криса Дейота (о его решении следующий пост).
2. Учили мультихед, который предсказывал конкретную запись и предсказывали, будет ли в этой записи Nan. Это скорее такой auxiliary loss, чтобы модель лучше генерализовывала данные и училась понимать саму доменную область, чем улучшала понимание задачи. Подробнее можно тут почитать: тык
3. Чтобы стакнуть свою кучу моделей использовали L-BFGS-B, а там 150 моделей было примерно.
4. Использовали аугментацию таргетов. Интуиция такая: раз у нас есть 15 разметчиков с одним мнением, то может нам в качестве аугментации использовать только часть из них?
Ситуация с таргетом не должна поменяться критически, но разнообразие это для модели внесет. Был вектор таргета
[1, 0, 0, 0, 14]
Мы можем «забыть одного размечающего» и из него получить
[0, 0, 0, 0, 14] и [1, 0, 0, 0, 13]
Делали так только для семплов, у которых число голосов было больше 10.У меня к сжоалению этот трюк не завелся
5. Использовали веса семплов равные числу голосов размечающих. Когда 3 человека говорят, что это судороги, это в тре раза надежнее, чем один человек.
9 место:
1. Использовали двух и трехмодальные системы. На вход сырой ЭЭГ, ванильные спектрограммы от каггла и спектрограммы Криса Дейота (о его решении следующий пост).
2. Учили мультихед, который предсказывал конкретную запись и предсказывали, будет ли в этой записи Nan. Это скорее такой auxiliary loss, чтобы модель лучше генерализовывала данные и училась понимать саму доменную область, чем улучшала понимание задачи. Подробнее можно тут почитать: тык
3. Чтобы стакнуть свою кучу моделей использовали L-BFGS-B, а там 150 моделей было примерно.
4. Использовали аугментацию таргетов. Интуиция такая: раз у нас есть 15 разметчиков с одним мнением, то может нам в качестве аугментации использовать только часть из них?
Ситуация с таргетом не должна поменяться критически, но разнообразие это для модели внесет. Был вектор таргета
[1, 0, 0, 0, 14]
Мы можем «забыть одного размечающего» и из него получить
[0, 0, 0, 0, 14] и [1, 0, 0, 0, 13]
Делали так только для семплов, у которых число голосов было больше 10.
5. Использовали веса семплов равные числу голосов размечающих. Когда 3 человека говорят, что это судороги, это в тре раза надежнее, чем один человек.
Cross Validated
What is auxiliary loss as mentioned in PSPNet paper
What is auxiliary loss that is mentioned in the PSPNet(Pyramid Scene Parsing Network) paper link ?
I'm quoting the part of the paper down below
An example of our deeply supervised ResNet101 [13]
I'm quoting the part of the paper down below
An example of our deeply supervised ResNet101 [13]
❤8👍2
#HMS #акакстакать
Поступил вопрос про пункт 3 и заявление, что там ничего не ясно. А там с одной стороны классика, с другой не совсем интуитивно:
Допустим у нас есть 150 моделей на одинаковых OOF и мы по ним хотим построить какой-то ансамбль, который будет лучше каждой индивидуальной.
1. Возьмем оптимизатор L-BFGS-B (знаю, в подписчиках есть фанаты) и на OOF построим оптимум заданной лосс функции. Это для нас будет линейная комбинация с положительными весами. Ну например [0.0001, 0.95, 0.003 ..., 0.0]
2. У какой-то доли моделей веса будут близкими к нулю, потому что они не слишком хорошо перформят относительно прочих. Так давайте установим трешхолд, например 0.01, и все модели с весом меньше этого из списка выкинем и пользоваться ими не будем
3. На оставшихся повторим процедуру и будем делать до тех пор, пока у всех моделей веса не будут больше, чем заданный наперед трешхолд
4. ...
5. Profit! У нас остались только уверенные и разнообразные модели
В этом смысле прием похож на совсем уж античную классику: отобрать фичи с помощью L1-регрессии и на выбраных фичах обучить уже обычную линейную/гребневую регрессию
Поступил вопрос про пункт 3 и заявление, что там ничего не ясно. А там с одной стороны классика, с другой не совсем интуитивно:
Допустим у нас есть 150 моделей на одинаковых OOF и мы по ним хотим построить какой-то ансамбль, который будет лучше каждой индивидуальной.
1. Возьмем оптимизатор L-BFGS-B (знаю, в подписчиках есть фанаты) и на OOF построим оптимум заданной лосс функции. Это для нас будет линейная комбинация с положительными весами. Ну например [0.0001, 0.95, 0.003 ..., 0.0]
2. У какой-то доли моделей веса будут близкими к нулю, потому что они не слишком хорошо перформят относительно прочих. Так давайте установим трешхолд, например 0.01, и все модели с весом меньше этого из списка выкинем и пользоваться ими не будем
3. На оставшихся повторим процедуру и будем делать до тех пор, пока у всех моделей веса не будут больше, чем заданный наперед трешхолд
4. ...
5. Profit! У нас остались только уверенные и разнообразные модели
В этом смысле прием похож на совсем уж античную классику: отобрать фичи с помощью L1-регрессии и на выбраных фичах обучить уже обычную линейную/гребневую регрессию
👍11🔥4❤3
#HMS
8 место, мастер-класс от Криса Дейота:
Самое первое, на чем акцентирует внимание Крисс: нам в соревновании не надо поставить диагноз, нам надо угадать мнения разметчиков. Казалось бы так всегда, но конкретно в этом соревновании из-за разнородности разметчиков это решало сильнее, чем обычно.
Крис прочитал статью организаторов и выяснил, что аннотаторов было всего 119 в трейне и 20 в тесте. А еще он вычитал, что судороги в трейне предсказывали в 18.8% случаев, а в тесте- 1.5%. И вот именно вычистку этих самых малоушмных экспертов из теста и делал хак с разделением трейна
Он так же посмотрел на то, как проходил процесс разметки данных и увидел там, что разметка проходила и по спектрограммам и по обычным графикам формы волны одновременно. Значит это и надо подавать как инпут моделей.
И того у него было три модели:
1. По сырым сигналам, a-la WaveNet
2. Трансформемер по спектрограммам
3. Трансформемер по plt.plot форм волныВ СМЫСЛЕ ОН ВЗЯЛ И ИСПОЛЬЗОВАЛ МАТПЛОТЛИБ ДЛЯ ИНПУТА, НУ ГЕНИЙ
Используя уже эти три модели он псевдолейблил кусочки трейна, в которых было меньше 10 размечающих.
Ну и все, 0.29 на приватном лидерборде.
Так же Крис заботливо выделил для нас лайфхаки:
1. Все сырые данные обработал с помощью библиотеки MNE. Она как раз специализированна для работы с ЭЭГ
2. Для перфоманса можно было все сырые ЭЭГ загрузить в RAM и формировать спектрограмы используя torchaudio.transforms
3. На каждой эпохе показывать одну ЭЭГ один раз, но семплировать каждый раз случайно.
4. Пользоваться его гайдом по подбору ЛР для модели
Скажу, что читать райтапы Криса- сплошной кайф. Однажды он прочитает моей райтап и скажет то же самое
8 место, мастер-класс от Криса Дейота:
Самое первое, на чем акцентирует внимание Крисс: нам в соревновании не надо поставить диагноз, нам надо угадать мнения разметчиков. Казалось бы так всегда, но конкретно в этом соревновании из-за разнородности разметчиков это решало сильнее, чем обычно.
Крис прочитал статью организаторов и выяснил, что аннотаторов было всего 119 в трейне и 20 в тесте. А еще он вычитал, что судороги в трейне предсказывали в 18.8% случаев, а в тесте- 1.5%. И вот именно вычистку этих самых малоушмных экспертов из теста и делал хак с разделением трейна
train.loc[train.vote_count>=10]
Он так же посмотрел на то, как проходил процесс разметки данных и увидел там, что разметка проходила и по спектрограммам и по обычным графикам формы волны одновременно. Значит это и надо подавать как инпут моделей.
И того у него было три модели:
1. По сырым сигналам, a-la WaveNet
2. Трансформемер по спектрограммам
3. Трансформемер по plt.plot форм волны
Используя уже эти три модели он псевдолейблил кусочки трейна, в которых было меньше 10 размечающих.
Ну и все, 0.29 на приватном лидерборде.
Так же Крис заботливо выделил для нас лайфхаки:
1. Все сырые данные обработал с помощью библиотеки MNE. Она как раз специализированна для работы с ЭЭГ
2. Для перфоманса можно было все сырые ЭЭГ загрузить в RAM и формировать спектрограмы используя torchaudio.transforms
3. На каждой эпохе показывать одну ЭЭГ один раз, но семплировать каждый раз случайно.
4. Пользоваться его гайдом по подбору ЛР для модели
Скажу, что читать райтапы Криса- сплошной кайф. Однажды он прочитает моей райтап и скажет то же самое
🔥20❤7👍1😁1
13% НДФЛ - лютейшая нищета на грани выживания
15% НДФЛ - обычная нищета, ипотека на 20 лет, кино и рестораны раз в неделю, еда из ашана
18% НДФЛ - нормальная жизнь, ипотека на 10 лет, машина среднего класса (B, C)
20% НДФЛ - хорошая жизнь, ипотека на 5 лет, путешествия
22% НДФЛ - достаточно хорошая жизнь, ипотека на 2 года, машина бизнес класса, девушка, возможность говорить с инженерами из реально топового квантиля
15% НДФЛ - обычная нищета, ипотека на 20 лет, кино и рестораны раз в неделю, еда из ашана
18% НДФЛ - нормальная жизнь, ипотека на 10 лет, машина среднего класса (B, C)
20% НДФЛ - хорошая жизнь, ипотека на 5 лет, путешествия
22% НДФЛ - достаточно хорошая жизнь, ипотека на 2 года, машина бизнес класса, девушка, возможность говорить с инженерами из реально топового квантиля
😁74🤡9💯6👎3😱2❤1👍1 1
Forwarded from Вадим | Оффер & Удалёнка
Тут мой старый знакомый, Александр Червов, автор sberloga, делает какой-то большой научный проект по нейронкам, которые собирают кубик рубика
👨🔬 Проект
В общем, ему нужны волонтёры для написания моделей и проведения экспериментов. Взамен вы получите опыт написания реальных RL, DL, ML моделей под наставничеством Александра. Участникам проекта нужно будет проводить эксперименты и создавать модели аналогичные AlphaGo для теории групп, например для группы кубика Рубика.
📜 Что вам это даст
- Реальный опыт работы с RL, DL, ML
- Ценный пункт в вашем резюме, который подчеркнет ваш профессионализм и знания в области
- Инсайты можно будет опубликовать в научной статье для научного журнала
💌 Пишите Саше Червову
👨🔬 Проект
В общем, ему нужны волонтёры для написания моделей и проведения экспериментов. Взамен вы получите опыт написания реальных RL, DL, ML моделей под наставничеством Александра. Участникам проекта нужно будет проводить эксперименты и создавать модели аналогичные AlphaGo для теории групп, например для группы кубика Рубика.
📜 Что вам это даст
- Реальный опыт работы с RL, DL, ML
- Ценный пункт в вашем резюме, который подчеркнет ваш профессионализм и знания в области
- Инсайты можно будет опубликовать в научной статье для научного журнала
💌 Пишите Саше Червову
🔥8🤣7❤2👎1
Я там тоже альтрузимом занимаюсь, и вас советую присоединиться. Однажды неизбежно надо будет диссер защищать
🔥15❤4🌚2
FOUND 1 #TODO
В португальском/испанском todo означается 'все' и является стоп-словом. Для пайчарма конечно это тоже стоп-слово и признак халутры
1👍13😁5❤3⚡2😱1
Кто такие ANN?
Вот сетап из 2018 года, которая отлично иллюстрирует, зачем нам нужны методы ускорения поиска похожих объектов, в частности, ANN (Approximate Nearest Neighbor). Сейчас все их используют для RAG, но мою историю я прочувствовал лично.
На одном из хакатонов PicsArt мы с двумя товарищами придумали интересное приложение: а что, если делать фотки людей и подбирать к ним наиболее похожих знаменитостей? Идея казалась крутой — пользователей точно бы привлекла, а дальше можно придумать, как на этом заработать. На хакатонах нужно быстро тестировать идеи и привлекать внимание, поэтому за ночь мы написали простенький апп для iPhone и сервер, который извлекал фичи из фотографий пользователей, а затем в векторном пространстве искал ближайшую знаменитость из нишевого жанра кино. 🔍
Маленькая деталь: по каким-то причинам почти все мужчины оказывались похожи на Стивена Вулфа
К сожалению, на том хакатоне первое место занял, кажется, Noize, а третье досталось девченкам, которые запустили домашку какого-то ММПшника с гитхаба по баесовским методам для склеивания нескольких плохих фоток в одну хорошую. Мы ничего не получили и на наш проект забили, а через полгода появился Gradient: Celebrity Look Like от того же PicsArt, который стал очень популярным и подозрительно похожим на нашу идею. Так я понял, зачем на самом деле нужны продуктовые хакатоны.
Представим, что мы бы продолжили наш сервис развивать. Пока у нас был датасет из 1000 знаменитостей, можно было справляться с поиском в лоб. Мы просто брали эмбеддинги размером в 512, меряли dot_distance каждый с каждым, и готово. Но дела сильно усложняются, если у нас миллион пользователей. А если хочется находить по-настоящему похожие фото, то может понадобиться и 100 миллионов изображений.
И вот тогда нужны ANN. Зачем сравниваться для запроса со всеми, если можно построить умную структуру данных и делать гораздо меньше сравнений? Примерно как в поиске по бинарному дереву, только сложнее и с учётом специфики задачи. ANN позволяет находить "почти ближайших соседей" за гораздо меньшее время, чем прямой перебор, что становится критически важным, когда база для поиска стремительно пухнет.
Если юзкейс кажется не очень, то представьте что мы на маркетплейсе все платья прогнали через Clip и хотим искать по текстовому запросу 'Красное платье' , даже если в описание указано, что платье 'Алое'.
В следующем посте расскажу, как я бенчмаркал Qdrant для поиска по картиночкам в разных режимах и разными моделями.
Вот сетап из 2018 года, которая отлично иллюстрирует, зачем нам нужны методы ускорения поиска похожих объектов, в частности, ANN (Approximate Nearest Neighbor). Сейчас все их используют для RAG, но мою историю я прочувствовал лично.
На одном из хакатонов PicsArt мы с двумя товарищами придумали интересное приложение: а что, если делать фотки людей и подбирать к ним наиболее похожих знаменитостей? Идея казалась крутой — пользователей точно бы привлекла, а дальше можно придумать, как на этом заработать. На хакатонах нужно быстро тестировать идеи и привлекать внимание, поэтому за ночь мы написали простенький апп для iPhone и сервер, который извлекал фичи из фотографий пользователей, а затем в векторном пространстве искал ближайшую знаменитость из нишевого жанра кино. 🔍
К сожалению, на том хакатоне первое место занял, кажется, Noize, а третье досталось девченкам, которые запустили домашку какого-то ММПшника с гитхаба по баесовским методам для склеивания нескольких плохих фоток в одну хорошую. Мы ничего не получили и на наш проект забили, а через полгода появился Gradient: Celebrity Look Like от того же PicsArt, который стал очень популярным и подозрительно похожим на нашу идею. Так я понял, зачем на самом деле нужны продуктовые хакатоны.
Представим, что мы бы продолжили наш сервис развивать. Пока у нас был датасет из 1000 знаменитостей, можно было справляться с поиском в лоб. Мы просто брали эмбеддинги размером в 512, меряли dot_distance каждый с каждым, и готово. Но дела сильно усложняются, если у нас миллион пользователей. А если хочется находить по-настоящему похожие фото, то может понадобиться и 100 миллионов изображений.
И вот тогда нужны ANN. Зачем сравниваться для запроса со всеми, если можно построить умную структуру данных и делать гораздо меньше сравнений? Примерно как в поиске по бинарному дереву, только сложнее и с учётом специфики задачи. ANN позволяет находить "почти ближайших соседей" за гораздо меньшее время, чем прямой перебор, что становится критически важным, когда база для поиска стремительно пухнет.
Если юзкейс кажется не очень, то представьте что мы на маркетплейсе все платья прогнали через Clip и хотим искать по текстовому запросу 'Красное платье' , даже если в описание указано, что платье 'Алое'.
В следующем посте расскажу, как я бенчмаркал Qdrant для поиска по картиночкам в разных режимах и разными моделями.
1👍44🔥15❤3
Что за HNSW такой?
Базовый подход, на котором работает Qdrant, — это HNSW (Hierarchical Navigable Small World). Давайте разберёмся, что это такое и как оно работает.
Small world graphs — это такие графы, которые характеризуются высоким коэффициентом кластеризации и малым расстоянием между любой парой вершин. Navigable Small World использует эти свойства для поиска ближайших соседей в многомерном пространстве. Представим, что мы строим такую структуру на наших эмбеддингах, чтобы перемещаться по ней было эффективно. Как добиться этой эффективности?
Начинаем с эмбеддинга случайного объекта из нашей базы и шагаем по рёбрам графа в сторону эмбеддинга-запроса, пока не сойдёмся к локальному минимуму. Для каждой пары эмбедингов мы можем посчитать расстояние, так что идти в сторону ближайшего к эмбедингу-запросу вполне себе можем на каждом шаге. Если бы мы связали ребрами все эмбеддинги, каждый с каждым, то минимальное расстояние находилось бы за один шаг, но пришлось бы просмотреть n дистанций. Если связать все эмбеддинги в двусвязный список, то на каждом шаге будет выполняться только одно сравнение, но шагов придётся сделать столько, сколько у нас точек, что тоже не очень эффективно. Зато уже n/2 в среднем! Как найти баланс?Никак, надо тестить на каждой новой базе
Но есть некоторое соображение: рёбра "средней длины" в графе часто оказываются наименее полезными. По ним мы движемся к точке с умеренной скоростью, но их слишком много, и приходится делать много шагов. Это как передвигаться на автобусе в пределах МКАДа — долго и автобусов слишком много, так что приходится делать кучу пересадок. Легче доехать на метро до нужной станции, а затем сделать последнюю милю на самокате.
Так что, построим наш граф поиска следующим образом:
1. Посчитаем расстояние от каждого объекта до каждого.
2. Возьмём случайный объект из базы и проверим, есть ли он в нашем графе поиска. Если есть — пропускаем.В первом прогоне его, конечно, там нет, но дальше цикл будет работать.
3. Возьмём X процентов ближайших объектов к целевому и построим между ними рёбра.
4. Сделаем то же самое с Y процентами самых дальних объектов.
5. Повторяем с пункта 2, пока не добавим в граф все объекты из базы.
Теперь на первых шагах мы будем часто пользоваться длинным ребрами, и в конце искать оптимум за счет коротких.
Да, в редких случаях (скажем, в 1% случаев) мы не найдём самого ближайшего соседа, но зато будем работать гораздо быстрее — скажем, в 12 раз. Конечно, всё сильно зависит от реализации, но ускорение впечатляет.
Вот и получается, что HNSW позволяет балансировать между количеством шагов и сравнений, что делает его отличным выбором для поиска ближайших соседей в больших базах данных.
А еще HNSW- в русской раскладке это РТЫЦ. Живите с этим
Базовый подход, на котором работает Qdrant, — это HNSW (Hierarchical Navigable Small World). Давайте разберёмся, что это такое и как оно работает.
Small world graphs — это такие графы, которые характеризуются высоким коэффициентом кластеризации и малым расстоянием между любой парой вершин. Navigable Small World использует эти свойства для поиска ближайших соседей в многомерном пространстве. Представим, что мы строим такую структуру на наших эмбеддингах, чтобы перемещаться по ней было эффективно. Как добиться этой эффективности?
Начинаем с эмбеддинга случайного объекта из нашей базы и шагаем по рёбрам графа в сторону эмбеддинга-запроса, пока не сойдёмся к локальному минимуму. Для каждой пары эмбедингов мы можем посчитать расстояние, так что идти в сторону ближайшего к эмбедингу-запросу вполне себе можем на каждом шаге. Если бы мы связали ребрами все эмбеддинги, каждый с каждым, то минимальное расстояние находилось бы за один шаг, но пришлось бы просмотреть n дистанций. Если связать все эмбеддинги в двусвязный список, то на каждом шаге будет выполняться только одно сравнение, но шагов придётся сделать столько, сколько у нас точек, что тоже не очень эффективно. Зато уже n/2 в среднем! Как найти баланс?
Но есть некоторое соображение: рёбра "средней длины" в графе часто оказываются наименее полезными. По ним мы движемся к точке с умеренной скоростью, но их слишком много, и приходится делать много шагов. Это как передвигаться на автобусе в пределах МКАДа — долго и автобусов слишком много, так что приходится делать кучу пересадок. Легче доехать на метро до нужной станции, а затем сделать последнюю милю на самокате.
Так что, построим наш граф поиска следующим образом:
1. Посчитаем расстояние от каждого объекта до каждого.
2. Возьмём случайный объект из базы и проверим, есть ли он в нашем графе поиска. Если есть — пропускаем.
3. Возьмём X процентов ближайших объектов к целевому и построим между ними рёбра.
4. Сделаем то же самое с Y процентами самых дальних объектов.
5. Повторяем с пункта 2, пока не добавим в граф все объекты из базы.
Теперь на первых шагах мы будем часто пользоваться длинным ребрами, и в конце искать оптимум за счет коротких.
Да, в редких случаях (скажем, в 1% случаев) мы не найдём самого ближайшего соседа, но зато будем работать гораздо быстрее — скажем, в 12 раз. Конечно, всё сильно зависит от реализации, но ускорение впечатляет.
Вот и получается, что HNSW позволяет балансировать между количеством шагов и сравнений, что делает его отличным выбором для поиска ближайших соседей в больших базах данных.
50❤14👍8🔥1
Ускоряем HNSW: Квантизация для ANN-поиска
Где красивые алгоритмы, там и красивые их ускорения от железа. Квантизация нейросетей — отличный способ уменьшить вес модели, ускорить инференс и жечь меньше электричества без значительных потерь в качестве. Так почему бы не применить этот подход в ANN-поиске?
Реализуем это максимально просто и эффективно: заменим все значения больше нуля на единицы, а все, что меньше нуля — на нули. Вот и все, Binary Quantization готова.
Что это дает? Значительное ускорение поиска. Вектор длиной 512 можно упаковать в 64 байта и использовать SIMD-инструкции на CPU. Почему это не сломает поиск? Потому что эмбединги как и сами нейросети содержат множество избыточных параметров, от которых можно избавиться без заметной потери качества. Иногда даже лучше становится!
Оптимальный подход — комбинированный. Сначала строим бинарный индекс, отбираем кандидатов с запасом например в два раза больше чем нам надо объектов, а затем выполняем полноценный поиск (либо в лоб, либо с использованием HNSW). Плюс ко всему, теперь весь бинарный индекс можно хранить в оперативной памяти и загружать полные вектора только по мере необходимости.
Ну все, теперь я вам всю базу рассказал, можно и оригинальный контент следующим постом закинуть.
Где красивые алгоритмы, там и красивые их ускорения от железа. Квантизация нейросетей — отличный способ уменьшить вес модели, ускорить инференс и жечь меньше электричества без значительных потерь в качестве. Так почему бы не применить этот подход в ANN-поиске?
Реализуем это максимально просто и эффективно: заменим все значения больше нуля на единицы, а все, что меньше нуля — на нули. Вот и все, Binary Quantization готова.
Что это дает? Значительное ускорение поиска. Вектор длиной 512 можно упаковать в 64 байта и использовать SIMD-инструкции на CPU. Почему это не сломает поиск? Потому что эмбединги как и сами нейросети содержат множество избыточных параметров, от которых можно избавиться без заметной потери качества. Иногда даже лучше становится!
Оптимальный подход — комбинированный. Сначала строим бинарный индекс, отбираем кандидатов с запасом например в два раза больше чем нам надо объектов, а затем выполняем полноценный поиск (либо в лоб, либо с использованием HNSW). Плюс ко всему, теперь весь бинарный индекс можно хранить в оперативной памяти и загружать полные вектора только по мере необходимости.
7🔥17👍11
Как ведет себя поиск по эмбедингам разных моделей при применении Binary Quantization?
Аккуратно, контент сложноприкольный. Возможно стоит перечитать пару последних постов отсюда
Собрав все предыдущие посты вместе, хочу поделиться недавними экспериментами.
У Qdrant есть не только векторная база данных, но и fastembed, питонический пакет для быстрого и простого извлечения эмбеддингов. Быстро — потому что поддержка параллелизации встроена из коробки и работает без лишних усилий на разных бекендах. Просто — потому что минимум зависимостей и все они лёгкие, без необходимости тянуть за собой 3 Гб torch или 1.5 Гб Tensorflow. Эмбеддинги можно извлекать как из текстов, так и из картинок.
Из четырёх моделей для картинок я добавил в репозиторий три, что позволило легко использовать именно этот инструмент.
Вопросы, которые я себе задал:
1. Как влияет использование разных моделей на производительность Qdrant?
2. Как изменяется время поиска для разных моделей при увеличении параметра EF (который отвечает за количество связей на очередном слое HNSW)?
3. Какие модели наименьшим образом деградируют при переключении в режим BQ?
4. Что объединяет модели, которые работают с BQ хорошо и плохо?
Для ответа на эти вопросы я взял 10% данных Imagenet с любимого Kaggle, заэмбеддил их и залил в базу. Бенчмарк сравнивал метрики качества поиска с Exact search (честное сравнение каждого запроса со всеми объектами в базе) по метрике Dot_product. Для тестирования использовал все доступные в fastembed модели для картинок:
clip-ViT-B-32-vision — живая классика.
Unicom-ViT-B-16 — специальная модель из open metric learning.
Unicom-ViT-B-32 — тоже модель для open metric learning (по менбше).
ResNet50 — полуживая классика.
Основные выводы:
1. Время поиска линейно зависит от параметра EF, а скорость поиска — от размера эмбеддингов.
2. Качество поиска от EF скейлится логарифмически, что делает этот компромисс очень выгодным.
3. ResNet50 плохо работает с BQ, в то время как модели, специально обученные для metric learning, показывают минимальную деградацию.
Общий вывод:
Если бы я начинал стартап по поиску похожих лиц, то выбрал бы Unicom-16b. Это позволило бы при росте числа лиц легко переключиться на Binary Quantization с оверсемплингом и минимально потерять в качестве.
А теперь приглашаю к обсуждению в комментариях:
1. Влияет ли loss-функция, на которую обучалась модель, на её деградацию в BQ?
2. Какие модели стоит ещё попробовать?
3. Какую другую метрику близости стоило использовать для сравнения и почему?
Собрав все предыдущие посты вместе, хочу поделиться недавними экспериментами.
У Qdrant есть не только векторная база данных, но и fastembed, питонический пакет для быстрого и простого извлечения эмбеддингов. Быстро — потому что поддержка параллелизации встроена из коробки и работает без лишних усилий на разных бекендах. Просто — потому что минимум зависимостей и все они лёгкие, без необходимости тянуть за собой 3 Гб torch или 1.5 Гб Tensorflow. Эмбеддинги можно извлекать как из текстов, так и из картинок.
Из четырёх моделей для картинок я добавил в репозиторий три, что позволило легко использовать именно этот инструмент.
Вопросы, которые я себе задал:
1. Как влияет использование разных моделей на производительность Qdrant?
2. Как изменяется время поиска для разных моделей при увеличении параметра EF (который отвечает за количество связей на очередном слое HNSW)?
3. Какие модели наименьшим образом деградируют при переключении в режим BQ?
4. Что объединяет модели, которые работают с BQ хорошо и плохо?
Для ответа на эти вопросы я взял 10% данных Imagenet с любимого Kaggle, заэмбеддил их и залил в базу. Бенчмарк сравнивал метрики качества поиска с Exact search (честное сравнение каждого запроса со всеми объектами в базе) по метрике Dot_product. Для тестирования использовал все доступные в fastembed модели для картинок:
clip-ViT-B-32-vision — живая классика.
Unicom-ViT-B-16 — специальная модель из open metric learning.
Unicom-ViT-B-32 — тоже модель для open metric learning (по менбше).
ResNet50 — полуживая классика.
Основные выводы:
1. Время поиска линейно зависит от параметра EF, а скорость поиска — от размера эмбеддингов.
2. Качество поиска от EF скейлится логарифмически, что делает этот компромисс очень выгодным.
3. ResNet50 плохо работает с BQ, в то время как модели, специально обученные для metric learning, показывают минимальную деградацию.
Общий вывод:
Если бы я начинал стартап по поиску похожих лиц, то выбрал бы Unicom-16b. Это позволило бы при росте числа лиц легко переключиться на Binary Quantization с оверсемплингом и минимально потерять в качестве.
А теперь приглашаю к обсуждению в комментариях:
1. Влияет ли loss-функция, на которую обучалась модель, на её деградацию в BQ?
2. Какие модели стоит ещё попробовать?
3. Какую другую метрику близости стоило использовать для сравнения и почему?
1 11🦄5❤4👍2🔥1
This media is not supported in the widget
VIEW IN TELEGRAM
🤡54👍6🌭2 2 2❤1😁1
Снова про Polars.
Очень рекомендую подкаст для свободных слушателей на английском о том, как библиотека построена с точки зрения Rust сообщества:
Spotify: https://open.spotify.com/episode/7CrTW3a3X2Kd2q6at3LsJW?si=xqIHROIlTKut5fYCKcda_Q
Self-hosted: https://rustacean-station.org/episode/ritchie-vink/
Вот пока слушал подкаст еще раз вдохновился всем объяснить почему polars круто и быстро.
Polars — это такая попытка взять лучшее из Spark и Pandas. Если грамотно спроектировать пайплайн на Polars, то можно обрабатывать данные без смены технологии до тех пор, пока они помещаются на физическую машину. Представьте: вытянуть кучу данных из S3-хранилища, выполнить сложные преобразования и вернуть их обратно, как на Spark, но при этом дебажить и экспериментировать с пайплайном можно так же быстро, как на Pandas. В итоге, это еще и работает быстрее, чем Pandas.
Достигается все известным трюкам, просто вынесенным в Python-интерфейс и выполняемым локально, а не на далекой и сложной для дебага JVM в облаке с множеством уровней доступа и доступ-привратниками Data Lake, которые тайно молятся Adeptus Mechanicus уже пять поколений.
Первый кирпичик — это ленивое вычисление (lazy evaluation). В Pandas для выполнения одной операции условно есть два пути: использовать исключительно Python-движок (так никто не делает, но можно), что, конечно, медленно. Второй вариант — конвертировать данные в Cython и обрабатывать их с его помощью. Для этого нужно сначала выести строгие типы данных, сконвертировать данные в них, подобрать нужный кусочек Cython-кода, выполнить вычисления, а затем сконвертировать данные обратно в Python-объекты и вернуть результат. Автоматически и без головной боли, но надо так делать для каждой операции, а их у нас в пайплайне могут быть сотни.
Ленивое вычисление позволяет уменьшить этот оверхед на конверсии данных туда и обратно. Сначала мы описываем все преобразования в пайплайне, затем по этому пайплайну строится граф вычислений, который компилируется в Rust и исполняется. Вдобавок, прямо из коробки идут два дополнительных преимущества: до компиляции граф можно оптимизировать и распараллелить на многопоточность с помощью очередей. Это позволяет выполнить меньше операций, а время выполнения сделать быстрее, потому что в среднем можем больше вычислительных ресурсов эффективно утилизировать в единицу времени.
Второй кирпичик — это стриминг (streaming). Предположим, данных стало существенно больше или ресурсов стало меньше. Классический пример: вам на Kaggle дали 250 ГБ таблиц для расчета фичей для вашего ML. У вас есть 32 ГБ ОЗУ, так что все эти таблицы вместе в память не влезут. Обычно решение выглядит так: мы считаем одну группу фич, сохраняем их в памяти для финального этапа (или пишем в CSV), и, ловко оперируя gc.collect() и del, выбрасываем ненужные промежуточные куски из памяти Python. Получается неудобно и костыльно.
Стриминг позволяет сделать что-то подобное, но интеллектуально и автоматически. Polars строит индекс по таблицам и разбивает все данные на части, не загружая их полностью в память. Затем вычисляет связи между этими батчами и оптимизирует граф их взаимодействий так, чтобы в самом "широком по памяти" месте графа использовать не более доступной памяти, но при этом обрабатывать каждый батч как можно быстрее. И только после этого читает каждый индексированный батч данных с диска, обрабатывает его и выполняет вычисления до конца пайплайна. А если вдруг где-то не хватит места, то Polars может притормозить и дампнуть какой-нибудь батч на диск, чтобы обработать прочие. Это можно сравнить с тем, как если нужно выкопать яму, вместо попытки сразу сдвинуть тонну песка, можно впятером быстро перекидать его лопатами. Только представьте, как это шикарно дружится с Parquet!
Если представить не можете, ставьте 🤔️️️️️️. Напишу пост про Parquet и станет сильно понятнее
Очень рекомендую подкаст для свободных слушателей на английском о том, как библиотека построена с точки зрения Rust сообщества:
Spotify: https://open.spotify.com/episode/7CrTW3a3X2Kd2q6at3LsJW?si=xqIHROIlTKut5fYCKcda_Q
Self-hosted: https://rustacean-station.org/episode/ritchie-vink/
Вот пока слушал подкаст еще раз вдохновился всем объяснить почему polars круто и быстро.
Polars — это такая попытка взять лучшее из Spark и Pandas. Если грамотно спроектировать пайплайн на Polars, то можно обрабатывать данные без смены технологии до тех пор, пока они помещаются на физическую машину. Представьте: вытянуть кучу данных из S3-хранилища, выполнить сложные преобразования и вернуть их обратно, как на Spark, но при этом дебажить и экспериментировать с пайплайном можно так же быстро, как на Pandas. В итоге, это еще и работает быстрее, чем Pandas.
Достигается все известным трюкам, просто вынесенным в Python-интерфейс и выполняемым локально, а не на далекой и сложной для дебага JVM в облаке с множеством уровней доступа и доступ-привратниками Data Lake, которые тайно молятся Adeptus Mechanicus уже пять поколений.
Первый кирпичик — это ленивое вычисление (lazy evaluation). В Pandas для выполнения одной операции условно есть два пути: использовать исключительно Python-движок (так никто не делает, но можно), что, конечно, медленно. Второй вариант — конвертировать данные в Cython и обрабатывать их с его помощью. Для этого нужно сначала выести строгие типы данных, сконвертировать данные в них, подобрать нужный кусочек Cython-кода, выполнить вычисления, а затем сконвертировать данные обратно в Python-объекты и вернуть результат. Автоматически и без головной боли, но надо так делать для каждой операции, а их у нас в пайплайне могут быть сотни.
Ленивое вычисление позволяет уменьшить этот оверхед на конверсии данных туда и обратно. Сначала мы описываем все преобразования в пайплайне, затем по этому пайплайну строится граф вычислений, который компилируется в Rust и исполняется. Вдобавок, прямо из коробки идут два дополнительных преимущества: до компиляции граф можно оптимизировать и распараллелить на многопоточность с помощью очередей. Это позволяет выполнить меньше операций, а время выполнения сделать быстрее, потому что в среднем можем больше вычислительных ресурсов эффективно утилизировать в единицу времени.
Второй кирпичик — это стриминг (streaming). Предположим, данных стало существенно больше или ресурсов стало меньше. Классический пример: вам на Kaggle дали 250 ГБ таблиц для расчета фичей для вашего ML. У вас есть 32 ГБ ОЗУ, так что все эти таблицы вместе в память не влезут. Обычно решение выглядит так: мы считаем одну группу фич, сохраняем их в памяти для финального этапа (или пишем в CSV), и, ловко оперируя gc.collect() и del, выбрасываем ненужные промежуточные куски из памяти Python. Получается неудобно и костыльно.
Стриминг позволяет сделать что-то подобное, но интеллектуально и автоматически. Polars строит индекс по таблицам и разбивает все данные на части, не загружая их полностью в память. Затем вычисляет связи между этими батчами и оптимизирует граф их взаимодействий так, чтобы в самом "широком по памяти" месте графа использовать не более доступной памяти, но при этом обрабатывать каждый батч как можно быстрее. И только после этого читает каждый индексированный батч данных с диска, обрабатывает его и выполняет вычисления до конца пайплайна. А если вдруг где-то не хватит места, то Polars может притормозить и дампнуть какой-нибудь батч на диск, чтобы обработать прочие. Это можно сравнить с тем, как если нужно выкопать яму, вместо попытки сразу сдвинуть тонну песка, можно впятером быстро перекидать его лопатами. Только представьте, как это шикарно дружится с Parquet!
Если представить не можете, ставьте 🤔️️️️️️. Напишу пост про Parquet и станет сильно понятнее
Rustacean Station
Polars with Ritchie Vink :: Rustacean Station
Come journey with us into the weird, wonderful, and wily world of Rust.
2🤔46👍22🔥5❤3🥰1💘1
Сергей Фиронов завел свой канал. Если вы не в курсе кто это, вам тем более надо подписаться
https://news.1rj.ru/str/abacabadabacaba404
https://news.1rj.ru/str/abacabadabacaba404
🔥7❤1
BeVIT на ваших эпл часах? А может лучше на роботе пылесосе?
Эпл добавил neural engine в часы и обещают инференсить dense transformers
Эпл добавил neural engine в часы и обещают инференсить dense transformers
😢2
Все, преза кончилась. Весь шитпост спрячу в первый пост. Спасибо, что были с нами
❤9
Вадим | Оффер & Удалёнка
Тут мой старый знакомый, Александр Червов, автор sberloga, делает какой-то большой научный проект по нейронкам, которые собирают кубик рубика 👨🔬 Проект В общем, ему нужны волонтёры для написания моделей и проведения экспериментов. Взамен вы получите опыт…
История с продвижением математики вперед с помощью ML пока не закончилась
Скоро будет онлайн-доклад от известного математического физика Сергея Гукова , где они решили один из вопросов в теории групп , который стоял 39 лет с помощью МЛ
https://news.1rj.ru/str/sberlogabig/514
Скоро будет онлайн-доклад от известного математического физика Сергея Гукова , где они решили один из вопросов в теории групп , который стоял 39 лет с помощью МЛ
https://news.1rj.ru/str/sberlogabig/514
🔥14❤3🤔3