Часть 2: Как обучить модель, когда много данных и мало разметки?
Это история о том, как мы Точке классифицируем клиентские обращения
Модель для онлайн-разметки показала невысокую точность — всего 80%. Поэтому мы решили добыть золотую разметку и попросили супер экспертов разметить 2000 объектов. Задачу поставили в бинарном сетапе, то есть, использовали только два тега #Тариф и #ВсёОстальное.
На dev-выборке в 1000 объектов получили такие метрики few-shot:
📌 Precision — 68%
📌 Recall — 89%
📌 F1 — 0,77
Получается, что тэг #Тариф мы определяли правильно лишь в 68% случаев. А 11% вообще не попали под нашу классификацию.
Тогда мы решили взять ризонинг-модель и использовать её рассуждения. Это дало незначительный прирост качества +2% к F1.
Какие выводы мы в итоге сделали:
📝 Не получается подобрать инструкцию, чтобы определять метку с высокой точностью.
📝 Сложно масштабироваться на новые теги.
📝 Есть трудности с маскирацией персональных данных.
📝 Высокая стоимость — для GPT-4о от 2000$ в месяц даже без сложных цепочек ризонинга.
Как мы решили эти проблемы, расскажем уже в следующем посте.
Это история о том, как мы Точке классифицируем клиентские обращения
Модель для онлайн-разметки показала невысокую точность — всего 80%. Поэтому мы решили добыть золотую разметку и попросили супер экспертов разметить 2000 объектов. Задачу поставили в бинарном сетапе, то есть, использовали только два тега #Тариф и #ВсёОстальное.
Чтобы получить больше разметки, попросили экспертов объяснить, как они определяют, к какому тэгу относится обращение. Затем на основе их ответов написали инструкцию-промпт для GPT.
На dev-выборке в 1000 объектов получили такие метрики few-shot:
📌 Precision — 68%
📌 Recall — 89%
📌 F1 — 0,77
Получается, что тэг #Тариф мы определяли правильно лишь в 68% случаев. А 11% вообще не попали под нашу классификацию.
Тогда мы решили взять ризонинг-модель и использовать её рассуждения. Это дало незначительный прирост качества +2% к F1.
Какие выводы мы в итоге сделали:
📝 Не получается подобрать инструкцию, чтобы определять метку с высокой точностью.
📝 Сложно масштабироваться на новые теги.
📝 Есть трудности с маскирацией персональных данных.
📝 Высокая стоимость — для GPT-4о от 2000$ в месяц даже без сложных цепочек ризонинга.
Как мы решили эти проблемы, расскажем уже в следующем посте.
❤23🔥11👍7😁4
Часть 3: Как обучить модель, когда много данных и мало разметки?
Это завершающий пост о том, как мы Точке классифицируем клиентские обращения с помощью ML-модели.
Тестовая dev-выборка показала низкую точность и высокую полноту. Тогда мы решили использовать комбинированный подход: LLM + Weak Supervision.
Что такое Weak Supervision?
Самый простой способ — голосование большинством. Но у этого метода есть минусы:
📌 Наличие корреляции — если один вопрос задан много раз, он будет доминировать и мы будем склоняться к ответу этой группы.
📌 Размёточные функции могут вступать в противоречие, которое нужно разрешить.
Поэтому в качестве итогового классификатора мы использовали Snorkel.
Применили размёточные функции на большой выборке и научили модель разбираться в корреляционной структуре, где метки вступают в противоречие. Затем взяли языковую модель, которая сама придумывает размёточные функции. Использовали для этого тяжёлую умную модель GPT, а применили их на лёгкой T1-Lite.
В результате эксперимента мы получили:
📍Высокую точность.
📍Прежний уровень recall.
Таким образом, благодаря этому подходу мы:
📝 Получили модель с более высокой точностью, чем у few-shot.
📝 Сэкономили деньги. Потратились на обучение один раз, а инференс получили условно бесплатно.
📝 Сэкономили время. На разметку данных ушло всего две недели, а готовый метод можно применить почти молниеносно, имея на руках золотую выборку.
💜 Серию постов написал Артур Сосновиков, тимлид нескольких ML-команд в Точка Банк.
Это завершающий пост о том, как мы Точке классифицируем клиентские обращения с помощью ML-модели.
Тестовая dev-выборка показала низкую точность и высокую полноту. Тогда мы решили использовать комбинированный подход: LLM + Weak Supervision.
Что такое Weak Supervision?
Это обучение со слабым контролем. Мы не можем разметить всё вручную, поэтому используем набор слабых источников разметки. Каждый из них по отдельности может быть неточным, но вместе они дают сильный сигнал, который можно использовать для обучения.
Самый простой способ — голосование большинством. Но у этого метода есть минусы:
📌 Наличие корреляции — если один вопрос задан много раз, он будет доминировать и мы будем склоняться к ответу этой группы.
📌 Размёточные функции могут вступать в противоречие, которое нужно разрешить.
Поэтому в качестве итогового классификатора мы использовали Snorkel.
Применили размёточные функции на большой выборке и научили модель разбираться в корреляционной структуре, где метки вступают в противоречие. Затем взяли языковую модель, которая сама придумывает размёточные функции. Использовали для этого тяжёлую умную модель GPT, а применили их на лёгкой T1-Lite.
В результате эксперимента мы получили:
📍Высокую точность.
📍Прежний уровень recall.
Таким образом, благодаря этому подходу мы:
📝 Получили модель с более высокой точностью, чем у few-shot.
📝 Сэкономили деньги. Потратились на обучение один раз, а инференс получили условно бесплатно.
📝 Сэкономили время. На разметку данных ушло всего две недели, а готовый метод можно применить почти молниеносно, имея на руках золотую выборку.
💜 Серию постов написал Артур Сосновиков, тимлид нескольких ML-команд в Точка Банк.
❤26🔥10👏8👍2😁2
Почему LLM без Alignment — это риск?
Обучение на миллиардах токенов даёт языковой модели грамотность, но не гарантирует адекватность. Без Alignment она может:
📌 выдавать логически неверные ответы,
📌 генерировать небезопасный контент,
📌 игнорировать бизнес-ограничения.
Что такое Alignment? Это дообучение с учётом предпочтений и ограничений, которое делает модель предсказуемой и управляемой.
Написали статью на Хабр, в которой разбираем:
📝 Методы Alignment: от PPO (Proximal Policy Optimization) до новых подходов DPO и KTO.
📝 Наш опыт: как мы в Точка Банк настроили LLM под конкретные сценарии, обучили модель наград и сократили затраты по сравнению с классическим RLHF.
📝 Грабли и лайфхаки: как работать с несбалансированным датасетом и не дать модели обмануть функцию награды.
📝 Где применять Alignment за пределами LLM: от cost-sensitive классификации до vision-language моделей.
Точно будет полезно, если строите собственную LLM — читайте и задавайте вопросы в комментариях!
Обучение на миллиардах токенов даёт языковой модели грамотность, но не гарантирует адекватность. Без Alignment она может:
📌 выдавать логически неверные ответы,
📌 генерировать небезопасный контент,
📌 игнорировать бизнес-ограничения.
Что такое Alignment? Это дообучение с учётом предпочтений и ограничений, которое делает модель предсказуемой и управляемой.
Написали статью на Хабр, в которой разбираем:
📝 Методы Alignment: от PPO (Proximal Policy Optimization) до новых подходов DPO и KTO.
📝 Наш опыт: как мы в Точка Банк настроили LLM под конкретные сценарии, обучили модель наград и сократили затраты по сравнению с классическим RLHF.
📝 Грабли и лайфхаки: как работать с несбалансированным датасетом и не дать модели обмануть функцию награды.
📝 Где применять Alignment за пределами LLM: от cost-sensitive классификации до vision-language моделей.
Точно будет полезно, если строите собственную LLM — читайте и задавайте вопросы в комментариях!
Хабр
LLM на прокачку: практический гайд по Alignment
Мы в Точка Банке делаем свою LLM. Чтобы она работала хорошо, недостаточно просто обучить её на куче текстов. Для получения осмысленного и предсказуемого поведения модели, нужен Alignment — дообучение...
👍28❤15🔥11👎1😁1
Многие, кто обучал большие модели искусственного интеллекта, сталкивались с ситуацией, когда необходимы данные из множества источников. Но если источники совсем не из одной корпорации, то из-за GDPR или законах о защите персональных данных нет возможности обмениваться данными напрямую.
Как быть, если нужно обучать большие модели, но нельзя собирать всю информацию в одном месте?
Решение —федеративное обучение . Это система, в которой центральное устройство (сервер) объединяет усилия множества участников (устройства): каждый совершает операции на своих данных, а сервер собирает только результаты, не забирая саму информацию.
В зависимости от специфики задачи, данные на устройствах могут храниться по-разному. На основе того, как делится матрица признаков между участниками, можно выделить два подвида федеративного обучения:
📌 Горизонтальное федеративное обучение (HFL)
Суть: у разных участников данные имеют одинаковые фичи (одинаковые столбцы), но разные строки (разные пользователи/наблюдения).
📌 Вертикальное федеративное обучение (VFL)
Суть: у разных участников есть одни и те же сэмплы (одни и те же строки), но разные признаки (разные столбцы).
При этом нельзя сказать, что примеры выше оторваны от реальности. Например, Google применяет федеративное обучение для улучшения работы клавиатуры Gboard. Вместо сбора всех данных о нажатиях на своих серверах, центральное устройство получает только агрегированные обновления модели. То есть, обучение происходит прямо на устройствах пользователей, но без нарушения приватности.
💜 Этот пост написал Сергей Станко, ML-инженер в Точка Банк.
Как быть, если нужно обучать большие модели, но нельзя собирать всю информацию в одном месте?
Решение —
В зависимости от специфики задачи, данные на устройствах могут храниться по-разному. На основе того, как делится матрица признаков между участниками, можно выделить два подвида федеративного обучения:
📌 Горизонтальное федеративное обучение (HFL)
Суть: у разных участников данные имеют одинаковые фичи (одинаковые столбцы), но разные строки (разные пользователи/наблюдения).
Пример: несколько банков обучают модель для предсказания мошеннических транзакций. У всех есть одинаковые признаки по транзакциям (сумма, время, место, категория операции и т.п.), но набор клиентов у каждого банка свой. Объединяя данные через HFL, они получают более устойчивую модель, не раскрывая данные клиентов напрямую.
📌 Вертикальное федеративное обучение (VFL)
Суть: у разных участников есть одни и те же сэмплы (одни и те же строки), но разные признаки (разные столбцы).
Пример: банк и страховая компания имеют одних и тех же клиентов. У банка есть финансовые характеристики (история транзакций, кредитный рейтинг), у страховой — медицинская история и страховые выплаты. Объединив признаки в VFL, они могут построить более точную модель для оценки рисков по клиенту.
При этом нельзя сказать, что примеры выше оторваны от реальности. Например, Google применяет федеративное обучение для улучшения работы клавиатуры Gboard. Вместо сбора всех данных о нажатиях на своих серверах, центральное устройство получает только агрегированные обновления модели. То есть, обучение происходит прямо на устройствах пользователей, но без нарушения приватности.
💜 Этот пост написал Сергей Станко, ML-инженер в Точка Банк.
❤24👍11👏6😁1
А вы знаете ещё реальные примеры использования федеративного обучения?
Anonymous Poll
8%
Да, из своей практики
17%
Да, из практики других компаний
75%
Нет, впервые слышу о федеративном обучении
❤4🔥4🍾1
Большинство советов по ускорению Pandas звучат одинаково: «уберите циклы», «используйте apply», «снижайте размер типов». Но правда в том, что в реальном проекте эти правила работают не всегда — иногда даже замедляют пайплайн и увеличивают потребление памяти.
В статье на Хабре мы собираем бенчмарки скорости и памяти на разных сценариях и делаем практические выводы, какие из лайфхаков реально работают и при каких ограничениях. А именно:
👾 Iterrows vs itertuples: почему официальная рекомендация из документации pandas может привести к Out of Memory и замедлению пайплайна.
👾 apply с raw=True: малоизвестный аргумент, который даёт почти тот же прирост, что NumPy-векторизация — без полного переписывания кода.
👾 merge → loc или reindex: правда ли merge — швейцарский нож в мире датафреймов?
👾 Типы данных: int8 vs int64, float32 vs float64, categorical и sparse — что реально экономит ресурсы, а что даёт мизерный эффект.
👾 Параллелизация: pandarallel и multiprocessing — какой инструмент выбрать и почему (или не выбирать ни один).
Если вы работаете с большими объёмами данных на Pandas, наша статья поможет избавиться от «оптимизаций ради оптимизаций».
В статье на Хабре мы собираем бенчмарки скорости и памяти на разных сценариях и делаем практические выводы, какие из лайфхаков реально работают и при каких ограничениях. А именно:
👾 Iterrows vs itertuples: почему официальная рекомендация из документации pandas может привести к Out of Memory и замедлению пайплайна.
👾 apply с raw=True: малоизвестный аргумент, который даёт почти тот же прирост, что NumPy-векторизация — без полного переписывания кода.
👾 merge → loc или reindex: правда ли merge — швейцарский нож в мире датафреймов?
👾 Типы данных: int8 vs int64, float32 vs float64, categorical и sparse — что реально экономит ресурсы, а что даёт мизерный эффект.
👾 Параллелизация: pandarallel и multiprocessing — какой инструмент выбрать и почему (или не выбирать ни один).
Если вы работаете с большими объёмами данных на Pandas, наша статья поможет избавиться от «оптимизаций ради оптимизаций».
Хабр
Ускорить Pandas в 60 раз: проверяем лайфхаки из интернета на реальном проекте и обкладываемся бенчмарками
Привет! Если после заголовка вы решили, что это очередная статья в стиле «Топ-10 способов ускорить Pandas», то не торопитесь с выводами. Вместо топов и подборок предлагаю взглянуть на бенчмарки...
❤22🔥14👍9👏2😁1
Почему Polars blazingly-fast: дело не только в Rust
Когда данных много, pandas часто упирается в память и «однопоточность» Python, а множественные агрегации могут выполняться в течение часов или даже дней. Какие же существуют альтернативы? Давайте разберёмся, как устроен Polars и какие архитектурные решения делают его blazingly-fast.
Как оно работает
📌 Колоночный движок на Rust + Arrow-модель памяти
Polars использует модель памяти Apache Arrow для хранения данных в колоночных буферах — плотных, типизированных массивах без Python-объектов. Что важно: формат адаптирован под высокие кэш-хит-рейты и быстрое выполнение SIMD-инструкций. Ядро на Rust исполняется вне интерпретатора Python и не упирается в GIL, что позволяет эффективнее утилизировать CPU и распараллеливать вычисления.
📌 Lazy-режим и оптимизатор
Вы описываете всю трансформацию целиком, а движок сам решает порядок шагов: «проталкивает» фильтры к источнику, отбрасывает лишние столбцы ещё на чтении. По сути Python — это интерфейс, который помогает собрать программу на внутреннем оптимизированном DSL Polars. В итоге это сокращает I/O и использование памяти.
📌 Логический → физический план: как Polars оптимизирует запрос
Когда вы описываете запрос с использованием lazy frame и lazy computations, Polars строит логическое дерево и заранее проверяет типы/схему. Затем оптимизатор уплотняет работу: проталкивает select/filter к источнику, выкидывает лишнее, объединяет выражения. После этого выбираются конкретные алгоритмы и распараллеливание (какой join, как считать group_by), формируется физический план. На исполнении читаются только нужные столбцы и куски данных, при необходимости — потоково; в конце всё собирается одним collect(). Для диагностики полезно смотреть план через lf.explain() (при необходимости — с учётом движка) и включать POLARS_VERBOSE=1, чтобы видеть, как выглядит итоговое оптимизированное дерево.
Когда данных много, pandas часто упирается в память и «однопоточность» Python, а множественные агрегации могут выполняться в течение часов или даже дней. Какие же существуют альтернативы? Давайте разберёмся, как устроен Polars и какие архитектурные решения делают его blazingly-fast.
Как оно работает
📌 Колоночный движок на Rust + Arrow-модель памяти
Polars использует модель памяти Apache Arrow для хранения данных в колоночных буферах — плотных, типизированных массивах без Python-объектов. Что важно: формат адаптирован под высокие кэш-хит-рейты и быстрое выполнение SIMD-инструкций. Ядро на Rust исполняется вне интерпретатора Python и не упирается в GIL, что позволяет эффективнее утилизировать CPU и распараллеливать вычисления.
📌 Lazy-режим и оптимизатор
Вы описываете всю трансформацию целиком, а движок сам решает порядок шагов: «проталкивает» фильтры к источнику, отбрасывает лишние столбцы ещё на чтении. По сути Python — это интерфейс, который помогает собрать программу на внутреннем оптимизированном DSL Polars. В итоге это сокращает I/O и использование памяти.
📌 Логический → физический план: как Polars оптимизирует запрос
Когда вы описываете запрос с использованием lazy frame и lazy computations, Polars строит логическое дерево и заранее проверяет типы/схему. Затем оптимизатор уплотняет работу: проталкивает select/filter к источнику, выкидывает лишнее, объединяет выражения. После этого выбираются конкретные алгоритмы и распараллеливание (какой join, как считать group_by), формируется физический план. На исполнении читаются только нужные столбцы и куски данных, при необходимости — потоково; в конце всё собирается одним collect(). Для диагностики полезно смотреть план через lf.explain() (при необходимости — с учётом движка) и включать POLARS_VERBOSE=1, чтобы видеть, как выглядит итоговое оптимизированное дерево.
❤26🔥10✍6👍2😁1
Ключевые внутренние паттерны
📝 Predicate / projection / slice pushdown
Фильтры, выбор столбцов и срезы применяются максимально близко к моменту чтения (scan_parquet/scan_csv). Проще говоря, читаем ровно то, что нужно, а не «всё подряд». Это резко ускоряет последующие join и group_by и снижает нагрузку на память.
📝 Параллельные join и group_by
Polars разбивает данные на части и обрабатывает их на нескольких ядрах, используя быстрые хэш-джоины и продуманные стратегии агрегации. Ускорение особенно заметно на широких таблицах и конвейерах с множественными агрегациями. Конкретный тип join и форма пайплайна могут влиять на распараллеливание и потребление памяти — это видно в плане.
📝 Streaming / out-of-core
Длинные пайплайны можно исполнять «потоково»: данные обрабатываются батчами, не накапливаясь целиком в памяти — это уменьшает пики памяти и стабилизирует задержки. Включается это явно: lf.collect(engine="streaming"). Важно: не все операции поддержаны в стриминге; где это невозможно, движок прозрачно перейдёт к in-memory выполнению (это нормально, но стоит контролировать план).
📝 SQL поверх выражений
Нужен знакомый синтаксис — регистрируете фреймы и используйте SQL; внутри всё равно сработает оптимизатор выражений. Это возможно благодаря SQLContext/pl.sql, что удобно для смешанных команд (аналитики + инженеры).
Анти-паттерны «под капотом»
📎 Построчные apply/map_rows на Python
Любая функция, которая ходит по строкам в Python, возвращает вас к GIL и убирает параллелизм. Если нужна UDF — старайтесь выразить логику через выражения Polars или переносить вычисления ближе к движку.
📎 Постоянное использование read_* вместо scan_*
read_* сразу загружает всё в память и ограничивает оптимизатор в pushdown-приёмах. Для конвейеров и больших наборов данных предпочитайте scan_* с lazy-планом — это откроет путь для predicate/projection/slice pushdown и стриминга. Для быстрых «снимков» и интерактивной разведки read_* допустим, но указывайте columns=[...] и другие параметры чтения, чтобы не тянуть лишнее.
📎 dtype=object/pl.Object
Polars умеет хранить Python-объекты в специальных столбцах, но это вырывает данные из arrow колоночной модели и выключает многие векторные оптимизации. Используйте только при крайней необходимости и как можно раньше приводите к нативным типам Polars.
Скорость Polars — не «магия», а архитектура
Arrow-модель памяти, lazy-планирование с агрессивными оптимизациями, потоковое исполнение там, где это возможно, и ядро на Rust, обходящее GIL. Практический эффект зависит от формулировки запроса и формата данных — корректный выбор scan_*, выражений и режима исполнения часто даёт многократный выигрыш.
В следующем посте мы расскажем, как использовать Polars в проде: от чтения паркетов до передачи фичей в модели.
💜 Этот пост написал Всеволод Богодист, Data Scientist в Точка Банк.
📝 Predicate / projection / slice pushdown
Фильтры, выбор столбцов и срезы применяются максимально близко к моменту чтения (scan_parquet/scan_csv). Проще говоря, читаем ровно то, что нужно, а не «всё подряд». Это резко ускоряет последующие join и group_by и снижает нагрузку на память.
📝 Параллельные join и group_by
Polars разбивает данные на части и обрабатывает их на нескольких ядрах, используя быстрые хэш-джоины и продуманные стратегии агрегации. Ускорение особенно заметно на широких таблицах и конвейерах с множественными агрегациями. Конкретный тип join и форма пайплайна могут влиять на распараллеливание и потребление памяти — это видно в плане.
📝 Streaming / out-of-core
Длинные пайплайны можно исполнять «потоково»: данные обрабатываются батчами, не накапливаясь целиком в памяти — это уменьшает пики памяти и стабилизирует задержки. Включается это явно: lf.collect(engine="streaming"). Важно: не все операции поддержаны в стриминге; где это невозможно, движок прозрачно перейдёт к in-memory выполнению (это нормально, но стоит контролировать план).
📝 SQL поверх выражений
Нужен знакомый синтаксис — регистрируете фреймы и используйте SQL; внутри всё равно сработает оптимизатор выражений. Это возможно благодаря SQLContext/pl.sql, что удобно для смешанных команд (аналитики + инженеры).
Анти-паттерны «под капотом»
📎 Построчные apply/map_rows на Python
Любая функция, которая ходит по строкам в Python, возвращает вас к GIL и убирает параллелизм. Если нужна UDF — старайтесь выразить логику через выражения Polars или переносить вычисления ближе к движку.
📎 Постоянное использование read_* вместо scan_*
read_* сразу загружает всё в память и ограничивает оптимизатор в pushdown-приёмах. Для конвейеров и больших наборов данных предпочитайте scan_* с lazy-планом — это откроет путь для predicate/projection/slice pushdown и стриминга. Для быстрых «снимков» и интерактивной разведки read_* допустим, но указывайте columns=[...] и другие параметры чтения, чтобы не тянуть лишнее.
📎 dtype=object/pl.Object
Polars умеет хранить Python-объекты в специальных столбцах, но это вырывает данные из arrow колоночной модели и выключает многие векторные оптимизации. Используйте только при крайней необходимости и как можно раньше приводите к нативным типам Polars.
Скорость Polars — не «магия», а архитектура
Arrow-модель памяти, lazy-планирование с агрессивными оптимизациями, потоковое исполнение там, где это возможно, и ядро на Rust, обходящее GIL. Практический эффект зависит от формулировки запроса и формата данных — корректный выбор scan_*, выражений и режима исполнения часто даёт многократный выигрыш.
В следующем посте мы расскажем, как использовать Polars в проде: от чтения паркетов до передачи фичей в модели.
💜 Этот пост написал Всеволод Богодист, Data Scientist в Точка Банк.
👍34❤20🔥11✍2😁1🏆1🫡1
Polars в продакшене: best practices
Когда нужно готовить фичи и витрины «здесь-и-сейчас», pandas-пайплайн часто даёт лишние задержки. Разберёмся, как построить на Polars быстрый и устойчивый конвейер для ETL и ML.
Чтобы что?
📌 Меньше TCO на ETL. За счёт pushdown и параллельности вы читаете меньше данных, тратите меньше CPU и памяти. На том же кластере — больше задач и стабильнее SLA.
📌 Быстрые фичи для моделей. Окна, джоины и агрегации считаются в Polars, а в модель уходят уже компактные матрицы/тензоры — время обучения и инференса сокращается.
📌 Порог входа ниже. С SQLContext команда может начать с SQL и постепенно переходить к выражениям, не теряя производительности.
Базовый набор шагов
📝 Начинайте со scan_* и Lazy. Схема простая: scan_parquet/csv → select/filter/with_columns → финальный collect(). Ранний select() экономит I/O.
📝 Для отладки используйте fetch(), он подходит для быстрых «прогонов» на маленьком сэмпле.
📝 Настройте джоины. Для джойнов по времени — join_asof, сортировка фреймов по ключам, для строковых ключей используйте тип Categorical и включённый StringCache, чтобы джоины были и быстрее, и стабильнее по памяти.
📝 Создавайте новые фичи выражениями. Конструируйте логику через when/then/otherwise, pl.struct, селекторы pl.selectors — это заменяет циклы и apply, оставляя работу на стороне внутреннего оптимизированного движка polars.
📝 Подружите свой пайплайн с ML-стеком. NumPy/torch/sklearn: df.to_numpy()/s.to_numpy() → torch.from_numpy() — минимум копий между слоями. Pandas-мир: to_pandas(use_pyarrow_extension_array=True) включает Arrow-бэкенд и помогает экономить память за счет zero-copy операций.
📝 Включайте streaming там, где длинные пайплайны. collect(engine="streaming") и sink_* уменьшают пиковую память и сглаживают латентность. sink_* позволяет обрабатывать и записывать данные на диск батчами, чтобы не перегружать RAM.
📝 Где уместно — SQL. Регистрируйте фреймы в SQLContext, пишите запросы на SQL, а узкие места постепенно переносите на выражения. Данная практика хороша для быстрого переезда на polars в командах, которые плохо знакомы с синтаксисом polars, но разбираются в SQL-выражениях.
Анти-паттерны в продакшене
Кейс Точка Банк
📝 Контекст
Задача реал-тайм рекомендаций. Узкое место — джоины, фильтры и сортировки на горячем потоке данных.
📝 Что сделали
Перенесли препроцессинг с pandas на Polars, переписали джоины в lazy-план, навели порядок в типах (категориальные ключи + общий словарь) и добавили join_asof для временных связок.
📝 Результат
Пайплайн стал выполняться примерно в 5 раз быстрее end-to-end на том же железе — основной прирост дали «проталкивание» фильтров и параллельные джоины.
Получается, что если собирать пайплайн с учетом всех лучших практик работы с polars — lazy, pushdown, выражения, аккуратные джоины и понятные мосты в ML — вы получаете устойчивый прирост скорости и контроля над ресурсами.
💜 Этот пост написал Всеволод Богодист, DS в Точка Банк
Когда нужно готовить фичи и витрины «здесь-и-сейчас», pandas-пайплайн часто даёт лишние задержки. Разберёмся, как построить на Polars быстрый и устойчивый конвейер для ETL и ML.
Чтобы что?
📌 Меньше TCO на ETL. За счёт pushdown и параллельности вы читаете меньше данных, тратите меньше CPU и памяти. На том же кластере — больше задач и стабильнее SLA.
📌 Быстрые фичи для моделей. Окна, джоины и агрегации считаются в Polars, а в модель уходят уже компактные матрицы/тензоры — время обучения и инференса сокращается.
📌 Порог входа ниже. С SQLContext команда может начать с SQL и постепенно переходить к выражениям, не теряя производительности.
Базовый набор шагов
📝 Начинайте со scan_* и Lazy. Схема простая: scan_parquet/csv → select/filter/with_columns → финальный collect(). Ранний select() экономит I/O.
📝 Для отладки используйте fetch(), он подходит для быстрых «прогонов» на маленьком сэмпле.
📝 Настройте джоины. Для джойнов по времени — join_asof, сортировка фреймов по ключам, для строковых ключей используйте тип Categorical и включённый StringCache, чтобы джоины были и быстрее, и стабильнее по памяти.
📝 Создавайте новые фичи выражениями. Конструируйте логику через when/then/otherwise, pl.struct, селекторы pl.selectors — это заменяет циклы и apply, оставляя работу на стороне внутреннего оптимизированного движка polars.
📝 Подружите свой пайплайн с ML-стеком. NumPy/torch/sklearn: df.to_numpy()/s.to_numpy() → torch.from_numpy() — минимум копий между слоями. Pandas-мир: to_pandas(use_pyarrow_extension_array=True) включает Arrow-бэкенд и помогает экономить память за счет zero-copy операций.
📝 Включайте streaming там, где длинные пайплайны. collect(engine="streaming") и sink_* уменьшают пиковую память и сглаживают латентность. sink_* позволяет обрабатывать и записывать данные на диск батчами, чтобы не перегружать RAM.
📝 Где уместно — SQL. Регистрируйте фреймы в SQLContext, пишите запросы на SQL, а узкие места постепенно переносите на выражения. Данная практика хороша для быстрого переезда на polars в командах, которые плохо знакомы с синтаксисом polars, но разбираются в SQL-выражениях.
Анти-паттерны в продакшене
📎 collect() после каждого шага. Так вы рвёте план и теряете оптимизации. Копите цепочку и собирайте один раз в конце.
📎 Маятник между pandas и Polars. Постоянные конвертации туда-сюда съедают выигрыш. Держите данные в Polars до последнего шага; если нужна совместимость, используйте Arrow-бэкенд.
📎 Игнорирование специфики типов. Оставлять ключи строками = призывать медленные джоины. Перекладывайте ключи в Categorical и включайте общий словарь.
Кейс Точка Банк
📝 Контекст
Задача реал-тайм рекомендаций. Узкое место — джоины, фильтры и сортировки на горячем потоке данных.
📝 Что сделали
Перенесли препроцессинг с pandas на Polars, переписали джоины в lazy-план, навели порядок в типах (категориальные ключи + общий словарь) и добавили join_asof для временных связок.
📝 Результат
Пайплайн стал выполняться примерно в 5 раз быстрее end-to-end на том же железе — основной прирост дали «проталкивание» фильтров и параллельные джоины.
Получается, что если собирать пайплайн с учетом всех лучших практик работы с polars — lazy, pushdown, выражения, аккуратные джоины и понятные мосты в ML — вы получаете устойчивый прирост скорости и контроля над ресурсами.
💜 Этот пост написал Всеволод Богодист, DS в Точка Банк
👍32❤20🔥12
Вероятно, прочитав наши предыдущие посты про Polars, вы подумали: «Вау, классный инструмент, жаль мы на него не переедем, у нас слишком много инфраструктуры завязано на pandas». Это довольно частая ситуация: разработчики библиотек не могут переехать на более современный табличный бэкенд, потому что большинство их пользователей использует pandas.
Так как же всё-таки слезть с иглы pandas?
Для этого существует Narwhals — библиотека, которая предоставляет Polars-подобный API и служит слоем совместимости между разными DataFrame-библиотеками. Она позволяет писать один набор логики, который выполняется нативно на бэкенде входных данных и возвращает тот же тип DataFrame, что был на входе.
В итоге мы получаем возможность писать библиотеки и утилиты, не беспокоясь о том, какой табличный бэкенд использует команда. Этим преимуществом уже пользуются такие популярные проекты, как Plotly, Bokeh и Darts.
💜 Этот пост написал Виталий Прахов, DS в Точка Банк
Так как же всё-таки слезть с иглы pandas?
Для этого существует Narwhals — библиотека, которая предоставляет Polars-подобный API и служит слоем совместимости между разными DataFrame-библиотеками. Она позволяет писать один набор логики, который выполняется нативно на бэкенде входных данных и возвращает тот же тип DataFrame, что был на входе.
📎 Narwhals не конвертирует постоянно таблицы в один центральный формат — он оборачивает/переводит вызовы в нативный API бэкенда, чтобы сохранить вычисления «нативными» (т.е. избегать дорогих конвертаций). Это снижает накладные расходы и сохраняет производительность.
📎 Поддерживает индекс pandas, несмотря на то, что в других бэкендах его вообще нет.
📎 Есть ленивые вычисления — для тех, кто любит оптимизацию и отложенное выполнение.
В итоге мы получаем возможность писать библиотеки и утилиты, не беспокоясь о том, какой табличный бэкенд использует команда. Этим преимуществом уже пользуются такие популярные проекты, как Plotly, Bokeh и Darts.
💜 Этот пост написал Виталий Прахов, DS в Точка Банк
👍24🔥13❤🔥8❤1
Model-Centric vs Data-Centric подходы в ML
Существуют разные подходы к улучшению ML-моделей. Предположим, у нас есть классификатор эмоций и мы хотим поднять метрики.
Что можно сделать:
📌 Поменять подход к обучению — поиграть с архитектурой, претрейнами, оптимизаторами.
📌 Поработать с данными — проверить датасет, пересмотреть разметку, найти шум и ошибки.
📌 Или в совсем отказаться от классической ML-модели и попробовать скормить всё LLM, надеясь на zero/few-shot способности модели.
Andrew Ng из DeepLearning.AI в одном из своих выступлений на примере задачи с детекцией дефектов на поверхности показывал, что:
📎 Если улучшать модель или подход к обучению, то мы не заметим улучшение качества, или оно будет минимальным.
📎 Если работать с данными, то мы увидим значимый прирост качества.
Поэтому, в ситуации с низкими метриками есть смысл тратить меньше времени на моделирование и эксперименты, и больше — на подготовку данных.
В следующем посте — подробнее про асессорскую разметку и оценку её качества.
Существуют разные подходы к улучшению ML-моделей. Предположим, у нас есть классификатор эмоций и мы хотим поднять метрики.
Что можно сделать:
📌 Поменять подход к обучению — поиграть с архитектурой, претрейнами, оптимизаторами.
📌 Поработать с данными — проверить датасет, пересмотреть разметку, найти шум и ошибки.
📌 Или в совсем отказаться от классической ML-модели и попробовать скормить всё LLM, надеясь на zero/few-shot способности модели.
Большинство инженеров выбирают первые два варианта. Но, как показывает практика, именно поиск ошибок в датасетах и улучшение качества данных даёт наиболее ощутимый прирост.
Andrew Ng из DeepLearning.AI в одном из своих выступлений на примере задачи с детекцией дефектов на поверхности показывал, что:
📎 Если улучшать модель или подход к обучению, то мы не заметим улучшение качества, или оно будет минимальным.
📎 Если работать с данными, то мы увидим значимый прирост качества.
Поэтому, в ситуации с низкими метриками есть смысл тратить меньше времени на моделирование и эксперименты, и больше — на подготовку данных.
В следующем посте — подробнее про асессорскую разметку и оценку её качества.
❤36🔥17👍15👏2🥴1
Асессорская разметка: как оценивать согласованность?
Обычно разметка проходит строго по этапам: сбор данных → создание гайда → запуск разметки обычно с перекрытием → агрегация меток → обучение модели → оценка качества.
В такой ситуации можно посчитать коэффициент согласованности — agreement. Он показывает долю совпадающих меток между асессорами.
В нашем случае средний попарный agreement — 83,9%, что достаточно неплохо. Но есть подвох: этот коэффициент, так же как и accuracy в случае бинарной классификации, может вводить в заблуждение при дисбалансе классов. В нашем датасете больше 70% меток приходятся на два класса — «Нейтральный» и «Замешательство». Давайте воспользуемся другими статистическими коэффициентами, чтобы удостовериться в высокой согласованности:
📌 Cohen‘s Kappa (Каппа Коэна) — попарный коэффициент. Оценивает нормализованное согласие между двумя асессорами.
Как интерпретировать результаты:
📌 Fleiss’s Kappa (Каппа Фляйна) — подходит для оценки согласованности между несколькими (более двух) асессорами.
В нашем случае Каппа Коэна варьируется от 0,7 до 0,84, что указывает на высокую согласованность. Для дополнительной проверки мы взяли несколько сотен случайных примеров из датасета и вручную расставили метки. Оказалось, что в 44% наши и асессорские метки расходились — то есть, асессоры в среднем согласованно ставят неправильные метки. Вот поэтому даже высокие показатели согласованности не гарантируют качественной разметки данных.
Что делать в такой ситуации — расскажем в следующем посте.
Обычно разметка проходит строго по этапам: сбор данных → создание гайда → запуск разметки обычно с перекрытием → агрегация меток → обучение модели → оценка качества.
Допустим, мы хотим получить разметку данных для классификатора сентимента обращений в поддержку. Мы получили метки от трех асессоров для некоторого количества реальных диалогов. Как же понять, насколько качественный результат разметки?
В такой ситуации можно посчитать коэффициент согласованности — agreement. Он показывает долю совпадающих меток между асессорами.
В нашем случае средний попарный agreement — 83,9%, что достаточно неплохо. Но есть подвох: этот коэффициент, так же как и accuracy в случае бинарной классификации, может вводить в заблуждение при дисбалансе классов. В нашем датасете больше 70% меток приходятся на два класса — «Нейтральный» и «Замешательство». Давайте воспользуемся другими статистическими коэффициентами, чтобы удостовериться в высокой согласованности:
📌 Cohen‘s Kappa (Каппа Коэна) — попарный коэффициент. Оценивает нормализованное согласие между двумя асессорами.
Как интерпретировать результаты:
<0,6 — плохая согласованность.
0,6…0,8 — хорошая согласованность, можно использовать в прикладных задачах.
>0,8 — очень высокая согласованность.
📌 Fleiss’s Kappa (Каппа Фляйна) — подходит для оценки согласованности между несколькими (более двух) асессорами.
В нашем случае Каппа Коэна варьируется от 0,7 до 0,84, что указывает на высокую согласованность. Для дополнительной проверки мы взяли несколько сотен случайных примеров из датасета и вручную расставили метки. Оказалось, что в 44% наши и асессорские метки расходились — то есть, асессоры в среднем согласованно ставят неправильные метки. Вот поэтому даже высокие показатели согласованности не гарантируют качественной разметки данных.
Что делать в такой ситуации — расскажем в следующем посте.
🔥24❤14👍11🤩1
Что делать, если асессорская разметка не совпала с экспертной?
В прошлом посте мы выяснили, что коэффициенты согласованности не всегда отражают финальное качество разметки и модели. В нашем случае почти половина примеров размечена неверно — асессоры согласны между собой, но не с экспертами. Как можно улучшить разметку:
📝 Проверить формулировку задачи и прописать подробный гайд с корнер-кейсами. Можно взять выборку, разметить её по гайду и посмотреть, где возникают споры — эти места нужно уточнить.
📝 Собрать тестовый датасет с золотой разметкой с помощью эксперта. После этого можно отобрать асессоров с высокими показателями на тестовом наборе или провести брифинг-встречу со всеми асессорами, чтобы обсудить ошибки.
📝 Разбить работу на чанки и добавить в каждый golden set для валидации. Это позволит оценивать качество разметки итеративно и следить, насколько асессоры попадают в золотой набор.
После внедрения этих шагов в нашей модели эмоций взвешенный F1 вырос с 0,61 до 0,7, а расхождение экспертной и асессорской разметки упало с 44% до 18%. Также хорошо подтянулись небольшие проблемные классы:
Важно:низкая согласованность не всегда означает плохую работу асессоров . Причинами могут быть:
📎 Неоднозначность задачи: она может подразумевать некоторую неопределенность. Например, такое часто встречается при подготовке диалоговых данных для LLM.
📎 Разный бэкграунд асессоров: внутренние AI-тренеры и внешние подрядчики могут понимать задачу по-разному. Это приводит к значительным различиям в оценках.
Поэтому ML-инженерам и датасаентистам важно самим вчитываться в данные и понимать, как они размечены.
Что делать с ошибочными разметками — расскажем в следующем посте.
В прошлом посте мы выяснили, что коэффициенты согласованности не всегда отражают финальное качество разметки и модели. В нашем случае почти половина примеров размечена неверно — асессоры согласны между собой, но не с экспертами. Как можно улучшить разметку:
📝 Проверить формулировку задачи и прописать подробный гайд с корнер-кейсами. Можно взять выборку, разметить её по гайду и посмотреть, где возникают споры — эти места нужно уточнить.
📝 Собрать тестовый датасет с золотой разметкой с помощью эксперта. После этого можно отобрать асессоров с высокими показателями на тестовом наборе или провести брифинг-встречу со всеми асессорами, чтобы обсудить ошибки.
📝 Разбить работу на чанки и добавить в каждый golden set для валидации. Это позволит оценивать качество разметки итеративно и следить, насколько асессоры попадают в золотой набор.
После внедрения этих шагов в нашей модели эмоций взвешенный F1 вырос с 0,61 до 0,7, а расхождение экспертной и асессорской разметки упало с 44% до 18%. Также хорошо подтянулись небольшие проблемные классы:
Благодарность — 0,8 → 0,76
Нейтральный — 0,7 → 0,75
Удовлетворительно — 0,68 → 0,74
Нетерпение — 0,57 → 0,53
Разочарование — 0,57 → 0,55
Замешательство — 0,46 → 0,7
Важно:
📎 Неоднозначность задачи: она может подразумевать некоторую неопределенность. Например, такое часто встречается при подготовке диалоговых данных для LLM.
📎 Разный бэкграунд асессоров: внутренние AI-тренеры и внешние подрядчики могут понимать задачу по-разному. Это приводит к значительным различиям в оценках.
Поэтому ML-инженерам и датасаентистам важно самим вчитываться в данные и понимать, как они размечены.
Что делать с ошибочными разметками — расскажем в следующем посте.
🔥19❤13✍6👍3🌚1
Что делать с ошибочными разметками?
Это продолжение поста об асессорской разметке данных. Если мы нашли ошибки в разметке, то можем:
📌 Передать несогласованные примеры на доразметку эксперту. Это самый простой вариант, но не всегда есть возможность привлечь доменного эксперта.
📌 Использовать библиотеку CleanLab для работы с шумными данными. В её основе лежит алгоритм confident learning, который автоматизирует поиск ошибок. Как это работает:
1) Обучаем произвольную модель — от градиентного бустинга до нейросетей.
2) Строим совместную матрицу вероятностей, чтобы выявить взаимосвязи и ошибки в предсказаниях (например, частые путаницы между классами).
3) Ищем подозрительные примеры — экземпляры с низкой вероятностью истинного класса.
В нашей задаче по эмоциям CleanLab помог отфильтровать набор примеров, которые отправились на дополнительную экспертную проверку.
📌 Далее можем построить Dataset Cartography, чтобы визуализировать, как модель учится на каждом примере. Для этого обучаем модель и сохраняем эволюцию предсказаний по эпохам для каждого класса, а затем рассчитываем коэффициенты:
🔍 Confidence — средняя вероятность предсказания истинного класса.
🔍 Variability — дисперсия вероятностей по эпохам. Показывает, насколько часто модель меняет своё предсказание с течением эпох.
🔍 Correctness — доля эпох, когда пример классифицировался верно.
На выходе мы получаем график, который делит примеры на три зоны (график смотрите ниже):
📝 Easy-to-learn: простые примеры, которые модель легко распознаёт.
📝 Ambiguous: неоднозначные примеры, которые нужны для обучения модели, чтобы она обобщалась.
📝 Hard-to-learn: вероятные ошибки в разметке.
Таким образом, для первичной фильтрации ошибок можно использовать CleanLab. А затем использовать Dataset Cartography, чтобы глубже понять структуру данных.
В следующем посте — про синтетическую разметку данных с помощью GPT.
Это продолжение поста об асессорской разметке данных. Если мы нашли ошибки в разметке, то можем:
📌 Передать несогласованные примеры на доразметку эксперту. Это самый простой вариант, но не всегда есть возможность привлечь доменного эксперта.
📌 Использовать библиотеку CleanLab для работы с шумными данными. В её основе лежит алгоритм confident learning, который автоматизирует поиск ошибок. Как это работает:
1) Обучаем произвольную модель — от градиентного бустинга до нейросетей.
2) Строим совместную матрицу вероятностей, чтобы выявить взаимосвязи и ошибки в предсказаниях (например, частые путаницы между классами).
3) Ищем подозрительные примеры — экземпляры с низкой вероятностью истинного класса.
В нашей задаче по эмоциям CleanLab помог отфильтровать набор примеров, которые отправились на дополнительную экспертную проверку.
📌 Далее можем построить Dataset Cartography, чтобы визуализировать, как модель учится на каждом примере. Для этого обучаем модель и сохраняем эволюцию предсказаний по эпохам для каждого класса, а затем рассчитываем коэффициенты:
🔍 Confidence — средняя вероятность предсказания истинного класса.
🔍 Variability — дисперсия вероятностей по эпохам. Показывает, насколько часто модель меняет своё предсказание с течением эпох.
🔍 Correctness — доля эпох, когда пример классифицировался верно.
На выходе мы получаем график, который делит примеры на три зоны (график смотрите ниже):
📝 Easy-to-learn: простые примеры, которые модель легко распознаёт.
📝 Ambiguous: неоднозначные примеры, которые нужны для обучения модели, чтобы она обобщалась.
📝 Hard-to-learn: вероятные ошибки в разметке.
Таким образом, для первичной фильтрации ошибок можно использовать CleanLab. А затем использовать Dataset Cartography, чтобы глубже понять структуру данных.
В следующем посте — про синтетическую разметку данных с помощью GPT.
🔥25❤9👍6
Можно ли заменить асессоров на LLM? Да, но с умом.
На первый взгляд, кажется, всё просто: пишем промт, отправляем его в модель и получаем результат. Это дешевле и быстрее, чем разметка людьми.
Но на практике, чтобы промт работал качественно, требуется множество итераций, улучшений и экспериментов. Например, для нашей модели эмоций мы потратили 3 недели на оптимизацию промпта. В результате получили хороший коэффициент согласованности LLM и асессоров — в среднем, 0,81.
Затем мы обучили два классификатора на разных датасетах:
📌 Исключительно с LLM-метками.
📌 С асессорскими метками после проведенной работы по улучшению согласованности и уменьшению ошибок.
В результате качество на LLM-метках лишь немного не дотягивает до эталонной разметки. При этом мы сэкономили большое количество времени и человеческих ресурсов.
Таким образом, на текущем этапе LLM можно рассматривать как джуниор-асессора. Модель отвечает примерно как человек, и в отсутствии ресурсов её можно использовать для разметки данных. В некоторых задачах это даст качество, сопоставимое с эталонной разметкой.
💜Серию постов про разметку написал Антон Земеров, ML-тимлид в круге «Общение с клиентом»
На первый взгляд, кажется, всё просто: пишем промт, отправляем его в модель и получаем результат. Это дешевле и быстрее, чем разметка людьми.
Но на практике, чтобы промт работал качественно, требуется множество итераций, улучшений и экспериментов. Например, для нашей модели эмоций мы потратили 3 недели на оптимизацию промпта. В результате получили хороший коэффициент согласованности LLM и асессоров — в среднем, 0,81.
Затем мы обучили два классификатора на разных датасетах:
📌 Исключительно с LLM-метками.
📌 С асессорскими метками после проведенной работы по улучшению согласованности и уменьшению ошибок.
Разметка LLM — Weighted F1 0,66
Разметка асессоров — Weighted F1 0,7
В результате качество на LLM-метках лишь немного не дотягивает до эталонной разметки. При этом мы сэкономили большое количество времени и человеческих ресурсов.
Таким образом, на текущем этапе LLM можно рассматривать как джуниор-асессора. Модель отвечает примерно как человек, и в отсутствии ресурсов её можно использовать для разметки данных. В некоторых задачах это даст качество, сопоставимое с эталонной разметкой.
💜Серию постов про разметку написал Антон Земеров, ML-тимлид в круге «Общение с клиентом»
🔥29👍13❤8
Всем привет! Как отдохнули?
Мы выходим с каникул с постом, в котором собрали самое интересное из вышедшего на канале. Если вдруг пропустили некоторые темы или хотите освежить знания — переходите по ссылкам и читайте 💜
Мы выходим с каникул с постом, в котором собрали самое интересное из вышедшего на канале. Если вдруг пропустили некоторые темы или хотите освежить знания — переходите по ссылкам и читайте 💜
❤13🎄1
Привет! Это канал ML-команды Точка Банка.
Мы — инженеры, исследователи и тимлиды. Здесь делимся инструментами и методами развития машинного обучения, которые используем в компании.
Разделили все важные темы на категории для удобной навигации:
📌 LLM и NLP
→ RoPE — Часть 1. Как закодировать позицию без обучения лишних весов.
→ RoPE — Часть 2. Зачем крутить вектора с разной частотой и как это помогает с длинным контекстом.
→ Чем LLM отличается от обычного трансформера, зачем там RMSNorm и почему все любят декодеры.
→ Как работает grokking, или почему модель может 1000 итераций ничего не делать, а на миллионной резко поумнеть.
📌 Hardware & High Performance
→ Векторные базы данных v1. Как работают хранение и поиск похожих векторов.
→ Векторные базы данных v2. Как использовать алгоритмы индексации для ускорения поиска.
→ SRAM vs DRAM. Как оптимизировать GPU и обходить ограничения CUDA с помощью Triton.
→ Почему Polars эффективнее pandas. Разбираем преимущества.
→ Как работает Polars в продакшене: кейсы от инженеров Точки.
📌 Data Mining & Методология
→ Культурное A/B-тестирование: почему не стоит расстраиваться, если нет прокраса, и зачем нужен Action Plan.
→ Техническое A/B-тестирование: разбираем ошибки с выбросами, стратификацией и метриками отношений.
→ Что делать, если нет разметки.
📌 Computer Vision
→ Как восстанавливать изображения и бороться с галлюцинациями моделей.
📝 Что еще интересного?
Мы регулярно выступаем на конференциях и проводим свои митапы. Анонсы и записи всех ивентов публикуем здесь.
А ещё пишем статьи на Хабре — туда вмещаются не только тексты, но и описания с картинками. Ссылки на материалы прикрепляем к постам.
Мы — инженеры, исследователи и тимлиды. Здесь делимся инструментами и методами развития машинного обучения, которые используем в компании.
Разделили все важные темы на категории для удобной навигации:
📌 LLM и NLP
Разбираем архитектуру, чтобы понимать, как обучать и инферить эффективнее.
→ RoPE — Часть 1. Как закодировать позицию без обучения лишних весов.
→ RoPE — Часть 2. Зачем крутить вектора с разной частотой и как это помогает с длинным контекстом.
→ Чем LLM отличается от обычного трансформера, зачем там RMSNorm и почему все любят декодеры.
→ Как работает grokking, или почему модель может 1000 итераций ничего не делать, а на миллионной резко поумнеть.
📌 Hardware & High Performance
Разбираем, как выжать максимум из оборудования, когда стандартного import torch и pandas недостаточно.
→ Векторные базы данных v1. Как работают хранение и поиск похожих векторов.
→ Векторные базы данных v2. Как использовать алгоритмы индексации для ускорения поиска.
→ SRAM vs DRAM. Как оптимизировать GPU и обходить ограничения CUDA с помощью Triton.
→ Почему Polars эффективнее pandas. Разбираем преимущества.
→ Как работает Polars в продакшене: кейсы от инженеров Точки.
📌 Data Mining & Методология
Разбираем, как работать с данными, когда их мало, и как не обмануть себя в тестах.
→ Культурное A/B-тестирование: почему не стоит расстраиваться, если нет прокраса, и зачем нужен Action Plan.
→ Техническое A/B-тестирование: разбираем ошибки с выбросами, стратификацией и метриками отношений.
→ Что делать, если нет разметки.
📌 Computer Vision
Разбираем, как работать с деградацией сигнала и собирать качественный Ground Truth
→ Как восстанавливать изображения и бороться с галлюцинациями моделей.
📝 Что еще интересного?
Мы регулярно выступаем на конференциях и проводим свои митапы. Анонсы и записи всех ивентов публикуем здесь.
А ещё пишем статьи на Хабре — туда вмещаются не только тексты, но и описания с картинками. Ссылки на материалы прикрепляем к постам.
🔥25👍9❤5
Анатомия
Написали статью о том, что происходит, когда соединение с клиентом обрывается и почему ваш код об этом ничего знает.
📝 Разбираемся, что происходит при обрыве соединения на всех уровнях стека — TCP → ASGI → FastAPI приложение → ваш код.
📝 Учимся правильно обрабатывать дисконнекты для стриминга и обычных эндпоинтов в FastAPI-приложениях — особенно актуально для LLM-врапперов.
📌 Читать и ставить лайки здесь:
https://medium.com/@shimovolos.stas/your-llm-is-streaming-to-nobody-how-to-handle-client-disconnects-in-fastapi-8cdf8c5d519e
http.disconnect: глушим FastAPI правильно Написали статью о том, что происходит, когда соединение с клиентом обрывается и почему ваш код об этом ничего знает.
📝 Разбираемся, что происходит при обрыве соединения на всех уровнях стека — TCP → ASGI → FastAPI приложение → ваш код.
📝 Учимся правильно обрабатывать дисконнекты для стриминга и обычных эндпоинтов в FastAPI-приложениях — особенно актуально для LLM-врапперов.
📌 Читать и ставить лайки здесь:
https://medium.com/@shimovolos.stas/your-llm-is-streaming-to-nobody-how-to-handle-client-disconnects-in-fastapi-8cdf8c5d519e
❤🔥21👍4🔥3