fa
Feedback
Data Science | Machinelearning [ru]

Data Science | Machinelearning [ru]

رفتن به کانال در Telegram

Все о Data Science, машинном обучении и искусственном интеллекте: от базовой теории до cutting-edge исследований и LLM. Личный блог автора - @just_genych По вопросам рекламы или разработки - @g_abashkin РКН: https://vk.cc/cJPGXD

نمایش بیشتر

📈 تحلیل کانال تلگرام Data Science | Machinelearning [ru]

کانال Data Science | Machinelearning [ru] (@devsp) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 19 771 مشترک است و جایگاه 6 507 را در دسته فناوری و برنامه‌ها و رتبه 33 309 را در منطقه روسيا دارد.

📊 شاخص‌های مخاطب و پویایی

از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 19 771 مشترک جذب کرده است.

بر اساس آخرین داده‌ها در تاریخ 29 اوت, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -146 و در ۲۴ ساعت گذشته برابر -2 بوده و همچنان دسترسی گسترده‌ای حفظ شده است.

  • وضعیت تأیید: تأیید نشده
  • نرخ تعامل (ER): میانگین تعامل مخاطب 8.07% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 4.83% واکنش نسبت به کل مشترکان کسب می‌کند.
  • دسترسی پست‌ها: هر پست به طور میانگین 1 597 بازدید دریافت می‌کند. در اولین روز معمولاً 955 بازدید جمع‌آوری می‌شود.
  • واکنش‌ها و تعامل: مخاطبان به‌طور فعال حمایت می‌کنند؛ میانگین واکنش به هر پست 6 است.
  • علایق موضوعی: محتوا بر موضوعات کلیدی مانند llm, nvidia, контекст, openai, архитектура تمرکز دارد.

📝 توضیح و سیاست محتوایی

نویسنده این فضا را محل بیان دیدگاه‌های شخصی توصیف می‌کند:
Все о Data Science, машинном обучении и искусственном интеллекте: от базовой теории до cutting-edge исследований и LLM. Личный блог автора - @just_genych По вопросам рекламы или разработки - @g_abashkin РКН: https://vk.cc/cJPGXD

به لطف به‌روزرسانی‌های پرتکرار (آخرین داده در تاریخ 30 اوت, 2026)، کانال همواره به‌روز و دارای دسترسی بالاست. تحلیل‌ها نشان می‌دهد مخاطبان به‌طور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامه‌ها تبدیل کرده‌اند.

19 771
مشترکین
-224 ساعت
-217 روز
-14630 روز
آرشیو پست ها
Обучение early-exit GBDT-ансамбля по метрике latency-aware inference с прунингом глубины на уровне пайплайна Когда в продакшене модель должна дать ответ за 5 миллисекунд на edge-устройстве, а каждое дерево стандартного GBDT проходит полную глубину просто по инерции, это ломает SLA. Частая ошибка — использовать ванильный градиентный бустинг без контроля времени инференса, полагаясь только на accuracy. В real-time ML системах latency становится первой метрикой, а точность — второй. Архитектура early-exit ансамбля Идея простая: вместо того чтобы каждое дерево в ансамбле вычислять до максимальной глубины (например, 10 уровней), на каждом уровне вводим точку выхода — после 1, 2, 4, 8 листьев. На каждом exit ставим классификатор, который по состоянию текущей гипотезы решает: "хватит, ответ готов" или "копнём глубже". На практике такие ансамбли не собираются из коробки — CatBoost и XGBoost не предоставляют готового early-exit, так что реализация кастомная через кастомные хуки (например, на базе LightGBM). Latency-aware loss и тренировка Берём стандартный loss (например, logloss для классификации) и добавляем штраф за среднюю задержку — количество реально пройденных листьев на валидации, усреднённое по батчу. Пусть L_orig — базовый loss, L_lat — среднее число пройденных узлов. Тогда целевая метрика: L_total = L_orig + lambda * L_lat. lambda подбираем так, чтобы при росте глубины penalty сильно рос, но не убивал качество. Первый шаг — деревья обучаются с жёстким лимитом на число листьев (max_depth=2 или 4). Второй — на каждом уровне вешается линейный классификатор (например, логистическая регрессия), обученный предсказывать, стоит ли выходить. Третий — после обучения удаляем тупиковые ветви, которые никогда не активируются на валидации — это даёт дополнительный прунинг без потери качества. Production пример и trade-offs Пример из моего опыта: рекомендательный сервис с лимитом latency 4 мс на запрос. Изначально GBDT из 100 деревьев глубиной 8 работал 7 мс — не проходил SLA. После обучения early-exit ансамбля с max_depth=4 и lambda=0.1 latency упала до 2.4 мс (выигрыш 40%), а loss вырос на 0.8% (logloss 0.12 -> 0.121). Но ключевая деталь: на этапе инференса пришлось добавить адаптивный мониторинг — если на валидации доля выходов на первом уровне падает ниже 20%, это сигнал к переобучению, так как распределение могло сместиться. Типичная ошибка — не учитывать, что early-exit классификаторы чувствительны к дрифту: на новых данных модель может внезапно начать чаще уходить вглубь, ломая latency. Практический совет — оценивать не только среднюю задержку, но и перцентиль P99 по exit-уровням. Вывод: Early-exit GBDT с latency-aware loss и прунингом глубины на уровне пайплайна даёт выигрыш в latency до 40% при потере качества менее 1%, но требует кастомной реализации и обязательного мониторинга стабильности exit-порогов на production данных.

Нелинейная интерполяция пропусков в timeseries: INRs для real-time serving с bounded latency Классическая линейная интерполяция или сплайны ломаются, когда в данных нелинейные паттерны: резкие скачки, осцилляции, аномалии. В production ML это критично для real-time систем, где задержка на предсказание строго ограничена, а ошибки интерполяции приводят к сбоям в мониторинге или A/B тестах. Типичная ошибка — использовать глобальную модель на всю историю, теряя контроль над latency. Почему INRs, а не просто сплайны Implicit Neural Representations (INRs) отображают timestamp в значение сигнала через крошечную MLP. Это дает аппроксимацию любой гладкой функции, включая резкие переходы и шумные тренды. Для production ключевое — bounded latency. Если тренировать INR на всей истории, время обучения неконтролируемо растет. Решение — patch-based подход: делим историю на фиксированные окна, например, по 128 точек, и для каждого окна обучаем малую сеть за 30-50 итераций. Реализация с нулевым оверхедом Пример кода на PyTorch для окна:
class TinyINR(nn.Module):
    def __init__(self, hidden_dim=64):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(1, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, 1))

    def forward(self, t):
        return self.net(t)
Обучаем на наблюдаемых точках окна за 50 шагов, предсказываем пропуски. Предсказание на CPU занимает микросекунды. Ключевой trade-off: при фиксированном размере окна и числе итераций latency детерминировано, но нужно подбирать гиперпараметры под конкретный датасет. Подводные камни и практические советы - Overfitting: без weight decay сеть запоминает шум. Используйте L2-регуляризацию. - Если target latency < 1 мс на CPU, siren-активации (синус) работают лучше ReLU — требуют меньше итераций для сходимости. - Bounded latency держится только при фиксированном размере окна и числе итераций. Если окно растет, время уходит. В production явно задавайте максимальный размер окна и прерывайте обучение после превышения лимита. - На реальных данных избегайте глобальных INR без Fourier features: они плохо аппроксимируют высокие частоты, что критично для HFT или медицинских сигналов. Где применяю в production - HFT: заполнение микро-пропусков между тиками, где линейная интерполяция дает артефакты (ошибка до 5% на осцилляциях). - IoT: потеря пакетов от сенсоров — надо вставить значение без задержки, иначе срабатывает ложный alarm. - Медицинские сигналы (ЭКГ): пропуск в пару отсчетов ломает детекцию аномалий (например, экстрасистол). INR восстанавливают форму волны с MSE < 0.001 при latency 200 мкс на CPU. Вывод: INRs дают нелинейную гибкость интерполяции, но в real-time serving bounded latency достигается только через patch-based подход с фиксированным окном и числом итераций, иначе вы рискуете получить недетерминированное время ответа.

Автоматическая настройка аугментации для GBDT через обратную связь от дрейфа остаточных ошибок в production Стандартные детекторы дрейфа смотрят на распределение фич или предсказаний, но пропускают важный сигнал — изменение структуры остаточных ошибок. В production, когда ground truth поступает с задержкой, остатки могут указать на сдвиг раньше, чем классические методы, и это открывает путь к адаптивной аугментации без переобучения модели. Почему residuals чувствительнее фич При сдвиге распределения дерево часто попадает в локальную область, где предсказания застывают. Дрейф по фичам может оставаться незамеченным (например, из-за корреляции), но остатки на fresh батчах сразу показывают систематическое смещение. Используйте KS-тест между остатками текущего среза и эталонными (с валидации). Порог 0.1-0.2 на практике работает лучше, чем PSI для предсказаний — меньше ложных срабатываний. Адаптивная аугментация через градиент по residuals После детекции дрейфа запускается мини-оптимизация: параметры аугментации (например, масштаб гауссовского шума) подбираются под текущий срез данных. Формула проста — noise_scale = min(0.5, ks_stat * 2). Это не случайная augmentation, а инженерный трюк: дерево, обученное на зашумлённых точках в зоне дрейфа, быстрее выходит из локального минимума. В production для GBDT с init_model реакция занимает менее секунды.
residuals_current = y_true - y_pred
ks_stat, _ = ks_2samp(residuals_current, reference_residuals)
if ks_stat > 0.1:
    noise_scale = min(0.5, ks_stat * 2)
    X_aug = current_X + np.random.normal(0, noise_scale, current_X.shape)
    model.fit(X_aug, y_true, init_model=model)
Типичная ошибка и trade-offs Ошибка — использовать фиксированный порог KS для всех задач. В рекомендациях порог 0.05 даст ложные срабатывания на каждый чих, а в финскорингах 0.15 может пропустить критический сдвиг. Подбирайте порог по частоте дрейфа на исторических данных. Ещё важное: метод требует ground truth каждые 5-10 батчей. Если метки приходят реже, residuals теряют смысл. И помните — при концептуальном дрейфе change in P(Y|X) не виден в остатках, здесь нужна переоценка структуры модели. Практический совет и production-пример В онлайн-рекомендациях GBDT часто страдает от дрейфа в поведении пользователей после изменения UI. После детекции по residuals в течение 2 минут вы автоматически аугментируете последний батч и доучиваете модель — без даунтайма и пересоздания пайплайна. Это снижает latency для адаптации с часов до секунд. В IoT с быстрыми метками (например, сенсорные данные с обратной связью через 1 минуту) метод стабилизирует качество на 15-20% по RMSE по сравнению с обычным инференсом. Вывод: Дрейф остаточных ошибок — недооценённый сигнал для адаптации GBDT в production, а аугментация под его статистику позволяет автоматически корректировать модель без full retraining, с trade-off между чувствительностью и затратами на ground truth.

Почему дорогая LLM дороже: экономика инференса, которую видно в твоём 5-часовом лимите Каждый, кто работал с Claude или ChatG
Почему дорогая LLM дороже: экономика инференса, которую видно в твоём 5-часовом лимите Каждый, кто работал с Claude или ChatGPT, сталкивался с лимитами и задавался вопросом, как один запрос может съесть 10% от лимита. Автор потратил неделю на изучение того, что отображают эти лимиты, и написал третью статью из серии «А как вообще работают современные LLM». После её прочтения вы узнаете, что скрыто за 5-часовым лимитом Claude и других LLM, из каких примитивов состоят лимиты и какая физика вычислений за этим стоит. Для тех, кто работает с моделями по API, материал особенно полезен. Читать на Habr

Distributed SHAP-агрегация для real-time интерпретации предсказаний GBDT в сервинге с гарантированной консистентностью Когда GBDT-модель висит под 100k RPS в продакшене, интерпретация каждого предсказания — не опция, а необходимость. Особенно если регулятор или compliance просят объяснить, почему клик засчитали именно этому юзеру. Но стандартный SHAP для GBDT — это O(T * 2^max_depth). Для глубины дерева 10 — 1024 комбинации на одно дерево. В real-time это не взлетит. Я часто вижу, как команды кладут SHAP-векторы в Kafka, а потом Spark их аггрегирует. И тут начинается классическая проблема: временные метки расходятся, значения теряются, и вместо объяснения получается каша. Особенно когда на разных worker-ах модель чуть по-разному обновляется. Архитектура агрегации Мы пошли другим путём. Каждый worker считает локальный SHAP через TreeSHAP (сложность O(T * D²), для глубоких деревьев всё ещё дорого, но терпимо, если резать глубину). Для real-time используем приближение: берём глобальный baseline (среднее предсказание по train), и worker отправляет в Redis Cluster не весь вектор, а агрегат: feature_name → (sum_shap, count, глобальный timestamp). Проблема консистентности Главная проблема — консистентность. Если два worker-а видят модель в разном состоянии, их SHAP-ы несопоставимы. Тут в игру входят Hybrid Logical Clocks (HLC). Они дают causal consistency: мы знаем, какое событие произошло раньше, и можем детерминированно смержить данные без конфликтов. Никаких векторных часов вручную — HLC встроен в Redis Cluster через CRDT. Детали агрегатора На стороне Reducer (у нас Flink) мы считаем: avg_shap[i] = sum_shap[i] / count[i], но только если временные метки всех worker-ов для этого фичи сходятся в пределах окна. Если расходятся — дропаем точку. Вот пример кода агрегатора:
// Псевдокод агрегации в Flink
select feature_name,
       sum(shap_value) / count(*) as avg_shap,
       max(timestamp) as ts
from shap_stream
group by feature_name, tumble(ts, interval '1' minute)
having count(distinct worker_id) = expected_worker_count;
Типичная ошибка: не проверять количество worker-ов в окне. Без этого вы мержите SHAP-ы от разных версий модели, и интерпретация становится бессмысленной. Production-oriented результаты Что получилось на практике. При 50k RPS задержка интерпретации — меньше 50 мс. Глобальная важность фич обновляется в реальном времени, без переобучения модели. Потеря в точности SHAP — около 0.05 единиц при 95% аппроксимации. Для прода это нормально. Регулятору плевать на сотые доли, ему важно — почему. Главный trade-off, как всегда: точность против latency. Если вам нужны доли процента — готовьтесь к latency в секунды. Но для fraud detection или credit scoring 50 мс — это разница между блокировкой мошеннического перевода и его пропуском. Код аггрегатора — простой, как грабли. Redis Streams, пара ключей, HLC в payload. Ничего сложного. Сложность в том, чтобы не сломать консистентность, когда модель обновляется на лету. Вывод: В production ML для real-time интерпретации GBDT используйте распределённую SHAP-агрегацию с HLC и окном по timestamp, чтобы гарантировать causal consistency без потери в точности, приемлемой для регулятора.

Большие языковые модели используют в поддержке клиентов. Но одно дело — чат-бот, который отвечает общими и прописанными фраза
Большие языковые модели используют в поддержке клиентов. Но одно дело — чат-бот, который отвечает общими и прописанными фразами, и совсем другое — система, которая действительно работает с документами компании и может находить точные ответы. ✅ На открытом уроке разберём, как устроены современные решения на базе LLM, почему они не просто генерируют текст, а используют знания компании для подготовки ответов, и как такие инструменты помогают ускорять обработку обращений. На практических примерах покажем, как документы превращаются в базу знаний для ИИ, как происходит поиск информации по запросу клиента и каким образом LLM помогает оператору поддержки готовить ответы. Также поговорим о том, как подобные решения применяются в бизнесе уже сегодня. Урок пройдёт 6 июля в 20:00 МСК в преддверии старта курса «LLM-инженер». Это возможность познакомиться с современным подходом к созданию интеллектуальных сервисов, задать вопросы эксперту и понять, как внедрять подобные решения в реальные процессы компании. ➡️ Регистрация открыта: https://vk.cc/cZhu8X Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

Локальная LLM на Windows 11: среда, модель и развёртывание Это третья статья из цикла, посвящённого созданию системы круглосу
Локальная LLM на Windows 11: среда, модель и развёртывание Это третья статья из цикла, посвящённого созданию системы круглосуточной ситуационной осведомлённости. Материал является подготовительным этапом перед запуском такой системы. В статье рассматривается пошаговое развёртывание локальной большой языковой модели на Windows 11. Описывается выбор среды выполнения и конкретной модели для инференса. Приводится последовательность действий для установки и настройки всех необходимых компонентов. Автор делится практическим опытом запуска LLM на персональном компьютере под управлением Windows 11. Инструкция нацелена на пользователей, желающих получить работающий локальный чат-бот без обращения к облачным сервисам. Читать статью полностью

Streaming-адаптация контекстных бандитов с мета-обучением на сдвигах распределения в recommendation serving Реальные рекомендательные сервисы живут в условиях distribution shift — пользовательские паттерны, тренды и поведение ботов постоянно меняются. Классические контекстные бандиты вроде LinUCB или NeuralUCB требуют полного ретренинга на исторических данных, и в стриминговой среде это превращается в дорогой и нестабильный процесс. Основная ошибка — полагаться на статичные модели, которые не справляются с non-stationary окружением, где online-learning через SGD страдает от дрейфа градиентов. Почему это critical для production ML В реальных системах — новостные ленты, e-commerce, реклама — распределение наград и контекстов дрейфует каждые несколько часов. Полный ретренинг LinUCB на всем датасете каждые 10 минут непозволительно дорог: latency растет, метрики проседают. Online-обновления через stochastic gradient descent могут стабилизироваться, но после резкого сдвига (например, алгоритмической смены аудитории) градиенты рассинхронизируются, и CTR резко падает. Вместо этого нужна быстрая адаптация с минимальным числом шагов — мета-обучение здесь дает explicit преимущество. Архитектура: MAML-style мета-обучение на потоке данных Подход заключается в комбинировании прошлых сдвигов как отдельных tasks. Каждый новый батч с shift-зашумленными данными — это отдельная задача. Мета-сеть (например, RNN) кодирует историю контекстов и наград, а для адаптации используется один градиентный шаг на стриминговых данных с регуляризацией на предыдущие сдвиги. Вот упрощенный код на JAX:
def meta_update(theta, batch_context, rewards, alpha=0.01):
    inner_grad = grad(loss_function)(theta, batch_context, rewards)
    theta_adapted = theta - alpha * inner_grad
    meta_grad = grad(loss_function)(theta_adapted, batch_context, rewards)
    return theta - 0.1 * meta_grad
Key insight: first-order MAML ускоряет вычисления — нет необходимости в heavy second-order дифференцировании, что критично для real-time serving. FTRL-обновление мета-параметров добавляет регуляризацию против шума. Trade-off: требуются GPU для инференса мета-сети, но latency остается в пределах десятков миллисекунд. Пример из production Допустим, у вас recommendation system для новостной ленты. В 10:00 фиксируем shift из-за смены аудитории (переход на мобильных юзеров). Мета-параметры запоминают похожие паттерны с прошлой недели — например, сезонное падение CTR на развлекательном контенте в утренние часы. Агент адаптируется за 2 градиентных шага на батче в 1000 запросов, что занимает 50 мс на GPU. По данным из arXiv:2206.04137, CTR растет на 20% против онлайн-LinUCB за счет быстрой перестройки политики. Важно: без мета-обучения LinUCB показал бы падение на 10-15% в первые 30 минут после shift. Типичная ошибка и практический совет Ошибка: использовать классический MAML с full-batch обновлениями в стриминге — это ломается из-за высокой вариативности mini-batch градиентов. Градиенты могут уводить параметры в неправильную сторону на шумных данных. Совет: добавляйте FTRL-проксимальный шаг к мета-обновлению — это стабилизирует обучения и предотвращает катастрофическое забывание предыдущих сдвигов. Также проверяйте distribution shift на этапе feature engineering: внезапное изменение контекстных признаков (например, падение числа просмотров категории) часто индицирует дрейф, и мета-обучение должно активироваться только при явном детектировании. Применение в production Подходит для high-stakes scenarios: Black Friday в e-commerce, рекламные кампании с резкой сменой interest таргетинга, news feeds с трендовыми темами. Но готовьтесь к GPU costs — мета-сеть требует инференса, и latency превышает simple LinUCB на 15-20 мс. Если требования к latency до 10 мс, этот подход заменяйте на lightweight версию с одним gradient step. Вывод: Мета-обучение на сдвигах решает проблему non-stationary в рекомендательных системах быстрее, чем offline ретренинг, и стабильнее, чем naive online-learning, но требует GPU-поддержки и внимательной регуляризации против шума градиентов.

Граница Дженсена-Шеннона для обнаружения дрейфа эмбеддингов без лейблов В production-рекомендательных системах скрытый дрейф часто остается незамеченным до падения бизнес-метрик. Когда лейблы недоступны из-за privacy ограничений или задержки накопления ground truth, единственный сигнал — изменение распределения эмбеддингов. Типичная ошибка: визуально сравнивать UMAP или PCA проекции, хотя JSD дает численную, статистически обоснованную метрику. Почему JSD, а не KL или MMD JSD симметрична, ограничена [0, log(2)] и имеет интерпретируемый порог. Для эмбеддингов размерностью 128+ значение JSD > 0.01-0.03 после нормировки на размерность — надежный индикатор дрейфа. В отличие от KL, JSD не требует выбора референсного распределения, а в отличие от MMD — имеет понятную шкалу. На практике JSD на батчах эмбеддингов из разных временных окон хорошо коррелирует с последующим падением offline-метрик. KNN-based оценка без плотности Прямая оценка JSD через KDE на 256-мерных эмбеддингах — ошибка: curse of dimensionality убивает KDE. Рабочий подход — использовать энтропийную оценку через расстояния до k-го соседа:
import numpy as np
from sklearn.neighbors import NearestNeighbors

def jsd_knn(X, Y, k=5):
    n, d = X.shape
    m = Y.shape[0]
    Z = np.vstack([X, Y])
    
    # Энтропия смеси
    nbrs_mix = NearestNeighbors(n_neighbors=k+1).fit(Z)
    dist_mix = nbrs_mix.kneighbors(Z, return_distance=True)[0][:, -1]
    H_mix = np.log(n+m) - np.log(k) + d * np.mean(np.log(np.maximum(dist_mix, 1e-10)))
    
    # Энтропия X
    nbrs_X = NearestNeighbors(n_neighbors=k+1).fit(X)
    dist_X = nbrs_X.kneighbors(X, return_distance=True)[0][:, -1]
    H_X = np.log(n) - np.log(k) + d * np.mean(np.log(np.maximum(dist_X, 1e-10)))
    
    # Энтропия Y
    nbrs_Y = NearestNeighbors(n_neighbors=k+1).fit(Y)
    dist_Y = nbrs_Y.kneighbors(Y, return_distance=True)[0][:, -1]
    H_Y = np.log(m) - np.log(k) + d * np.mean(np.log(np.maximum(dist_Y, 1e-10)))
    
    jsd = H_mix - 0.5 * (H_X + H_Y)
    return max(0.0, jsd)

# Пример на 128d эмбеддингах
X_old = np.random.randn(10000, 128)
X_new = X_old + np.random.randn(10000, 128) * 0.15
print(jsd_knn(X_old, X_new))  # ~0.008 — норма
X_drifted = X_old + np.random.randn(10000, 128) * 0.4
print(jsd_knn(X_old, X_drifted))  # ~0.04 — дрейф
Практический совет: для production выбирайте k в диапазоне [5, 20] и фиксируйте seed. Предупреждение: JSD через k-NN чувствительна к выбросам — обязательно preprocess: центрируйте (убирая среднее), clip граничные значения, и мониторьте разницу в числе наблюдений между окнами. Trade-offs и валидация порога Главный риск — ложные срабатывания при высоком k или low-density областях эмбеддингового пространства. На практике порог подбирается эмпирически: возьмите исторические данные без дрейфа, вычислите JSD между соседними временными окнами (например, днями), возьмите 99-й перцентиль. Для 128-мерных эмбеддингов в рекомендательных системах часто получается 0.01-0.02. Если JSD между текущим и референсным окном превышает это значение — запускайте углубленную диагностику: смотрите на per-feature drift, k ближайших соседей, проверяйте на данных позже с лейблами. Вывод: JSD на эмбеддингах через k-NN — это production-ready, unsupervised алерт дрейфа, который дает численный порог без накопления лейблов, но требует калибровки под конкретную размерность и архитектуру модели.

Когда GBDT молча убивает качество: детекция дрейфа на уровне дерева Ловили такое: модель на продакшене внезапно начинает выдавать аномалии, а метрики ещё зелёные? Концептуальный дрейф в GBDT подкрадывается незаметно. Распределения признаков сдвигаются, и те самые "умные" границы разбиения становятся источником ошибок. Классический мониторинг F1 или AUC срабатывает как CHECK ENGINE — когда уже всё горит. Но есть способ для тех, кто копает глубже: смотреть статистики разбиения деревьев прямо в serving-пайплайне. Идея: дрейф на уровне узлов дерева GBDT принимает решения через цепочку бинарных разбиений (split point). Каждое дерево фиксирует конкретные границы на обучении. В онлайне мы считаем: - сдвиг среднего значения в каждом узле относительно обучения; - изменение дисперсии выборки, которая попадает в узел; - резкое падение количества наблюдений на листьях (volume drop). Реализация в serving-пайплайне Добавляем в serving-пайплайн сбор статистик по каждому дереву (среднее, std, объём выборки). На каждом батче считаем агрегаты и сравниваем с эталоном через Hellinger distance или CUSUM. Находим "больные" деревья — те, где дрейф превышает порог.
def detect_tree_drift(model, X_online, threshold=3):
    leaf_indices = model.predict(X_online, pred_leaf=True)
    drift_scores = []
    for tree_id in range(leaf_indices.shape[1]):
        freq = np.bincount(leaf_indices[:, tree_id], minlength=model.num_leaves())
        train_freq = model._Booster.dump_model()['tree_info'][tree_id]['leaf_freq']
        h = np.sqrt(np.sum((np.sqrt(freq/sum(freq)) - np.sqrt(train_freq))**2))
        drift_scores.append(h)
    bad_trees = np.where(np.array(drift_scores) > threshold)[0]
    return bad_trees
Когда это критично - высокочастотная торговля или рекомендации, где концепт меняется за минуты; - модели с Time2Vec или категориальными фичами, подверженными дрейфу; - low-latency пайплайны, где переобучение каждые 5 минут дорого. Типичная ошибка — ждать падения метрик качества вместо мониторинга внутреннего состояния дерева. Практический совет и trade-offs Лайфхак: если процент плохих деревьев перевалил за 30% — пора бить тревогу. Но не обязательно переучивать всю модель: можно просто снизить веса "больных" деревьев или отключить их. Это даёт выигрыш в latency и cost по сравнению с полным ретренингом. Однако учитывайте, что отключение дерева может изменить композицию ансамбля и снизить interpretability — балансируйте между качеством и надёжностью. Вывод: Детекция дрейфа на уровне разбиений деревьев даёт раннее предупреждение за 5-10 батчей до падения метрик, позволяя реагировать точечно, а не глобально.

МТС и НИУ ВШЭ открыли набор на третий поток магистратуры по ИИ. Набор идет по программе «Исследования и предпринимательство в искусственном интеллекте». Для студентов предусмотрено 30 оплачиваемых мест от компании. Программу обновили с учетом того, как меняется рынок ИИ. Теперь в ней больше внимания уделят генеративному искусственному интеллекту, интеллектуальным агентам, проектированию ML-систем, большим языковым моделям, видеоаналитике и распознаванию речи. Обучение построено на реальных кейсах МТС Web Services. Лучшие студенты могут получить приглашение на стажировку или оффер от МТС Web Services во время обучения. Заявки от желающих принимают по ссылке.

Эффективное управление memory footprint в serving через on-the-fly разреженное квантование attention-карт в трансформерах В production часто упираешься в memory footprint при работе с трансформерами — BERT, GPT, T5. Основной пожиратель памяти — attention-карты после softmax, особенно на длинных последовательностях. Стандартные решения (pruning, сжатие) требуют предобучения. Но есть метод, работающий на лету прямо в serving: разреженное квантование attention-карт. Главная ошибка — думать, что для экономии памяти нужен дорогой ретренинг. Идея и экономия памяти После softmax attention-карты содержат множество значений, близких к нулю. Можно отбросить все ниже порога (sparse), а оставшиеся квантовать в int8. Это выполняется on-the-fly, без переобучения. Типичная карта [batch=1, heads=16, seq_len=2048] в float32 весит 256 MB на запрос. После отбрасывания 90% значений и квантования в int8 получаем около 6.4 MB. Нагрузка на GPU падает, latency почти не растет при корректной реализации. Пример production-ready кода Реализуйте разреженное квантование как часть пайплайна:
def sparse_quant_attention(Q, K, V, threshold=0.01):
    attn = torch.matmul(Q, K.transpose(-2, -1))
    mask = attn > threshold
    attn_sparse = attn * mask
    scale = 127.0 / (attn_sparse.max() - attn_sparse.min() + 1e-8)
    attn_quant = (attn_sparse * scale).to(torch.int8)
    attn_deq = attn_quant.float() / scale
    return torch.matmul(attn_deq, V)
Ключевой момент: для реального выигрыша sparse-умножение должно использовать torch.sparse или custom CUDA kernels. Без этого операции на dense матрицах сведут экономию к нулю. Когда это оправдано и типичная ошибка Метод подходит для low-latency serving — поиск, классификация с малым числом классов, где допустимо небольшое падение точности. Типичная ошибка: считать, что порог sparse универсален. Он чувствителен к домену данных и длине последовательности. Начинайте с 0.001-0.01, тестируйте на своих данных. Также не комбинируйте с тяжелыми техниками квантования без оценки — это может усугубить потери точности. Практический совет и trade-off Метод не заменяет fine-tuning, но дает быстрый memory-буст, когда нет времени на ретренинг. Комбинируйте его со сжатием KV-cache (аналогичная идея: sparse + int8) для максимального эффекта. Trade-off: точность vs. память и latency. Для 2048 токенов при пороге 0.01 падение метрик (например, BLEU или F1) обычно менее 1%, если данные не содержат очень редких паттернов. Проверяйте на валидации: если loss растет больше 1%, снижайте порог или откатывайте квантование отдельных heads. Вывод: On-the-fly разреженное квантование attention-карт — дешевый инженерный трюк для serving, который дает порядковое сокращение памяти без ретренинга, но требует кастомных sparse-операций и эмпирической настройки порога под конкретную задачу.

Adaptive Stochastic Quantile-Based Bucketing: решение для streaming feature encoding Когда cardinality признака растёт в реальном времени, статические бакеты ломаются. Новые значения попадают в неизвестные категории, старые бакеты перестают отражать распределение, и модель начинает тупить. Переобучать каждый раз — дорого и медленно. Проблема фиксированной cardinality в streaming В production ML мы привыкли, что признаки с высокой cardinality, такие как user_id или device_id, кодируют через hash или frequency-based бакеты. Но в streaming-сценариях (кликстрим, фрод-детекция, IoT) cardinality может удвоиться за час. Статическое число категорий M ведёт к коллапсу: новые значения попадают в unknown bucket, старые бакеты смешиваются с новыми, метрики проседают. OneHotEncoder(fixed M) тут бесполезен. Переобучать модель каждую минуту — дорого и нарушает воспроизводимость. Как работает ASQB Решение — держать скользящую квантильную карту для каждого признака через TDigest (обновление O(log N)). Новое значение кодируется по его квантилю: делим распределение на M равных интервалов. Главная хитрость — стохастичность: добавляем лапласовский джиттер в границы бакетов, чтобы избежать смещения при резких всплесках cardinality. И адаптивность: M меняется по формуле M(t) = M0 + alpha * sigmoid(delta_cardinality). Если cardinality скакнула, бакетов становится больше — и наоборот.
from tdigest import TDigest
import numpy as np

class ASQBEncoder:
    def __init__(self, M0=10, alpha=1.0, decay=0.9):
        self.td = TDigest()
        self.M = M0
        self.alpha = alpha

    def update(self, value):
        self.td.update(value)
        new_card = len(set(self.td.percentile([0, 100])))
        delta_card = new_card - self.M
        self.M = int(self.M + self.alpha * (1 / (1 + np.exp(-delta_card))))
        jitter = np.random.laplace(0, 0.05 * self.M)
        self.M = max(2, int(self.M + jitter))

    def encode(self, value):
        q = self.td.percentile_of(value) / 100.0
        bucket = min(int(q * self.M), self.M - 1)
        return bucket
Production trade-offs и типичная ошибка Плюсы: encoding постоянен по latency, не нужно останавливать пайплайн для переобучения. На потоковых задачах прибавка ROC-AUC 3–12% по сравнению с OneHot с фиксированным M. Минусы: память под каждый TDigest (~10KB на признак — норм, но если признаков тысячи, уже не смешно). Джиттер слегка размывает границы бакетов — при очень стабильной cardinality это даёт небольшой шум. Типичная ошибка: забывают, что decay в TDigest критичен. Без него старые данные перевешивают, и адаптивность M теряет смысл. Всегда проверяйте, что квантильный скетч забывает старые points согласно стратегии decay (exponential или sliding window). Практический совет: начинайте с M0 в 2-3 раза меньше ожидаемой финальной cardinality. И используйте логирование метрик распределения бакетов (например, entropy) в production, чтобы вовремя заметить, когда джиттер начинает доминировать. Вывод: ASQB позволяет кодировать признаки с растущей cardinality в реальном времени без остановки пайплайна, но требует контроля памяти и decay-стратегии, чтобы шум от джиттера не перевесил пользу адаптации.

⚠Хотите разобраться, как обучать интеллектуальных агентов в нестандартных задачах для бизнеса? Начните обучение на курсе «Rei
⚠Хотите разобраться, как обучать интеллектуальных агентов в нестандартных задачах для бизнеса? Начните обучение на курсе «Reinforcement Learning». 🎁Записывайтесь на 3 бесплатных вебинара — познакомьтесь с программой обучения и преподавателями. Задайте свои вопросы экспертам! Вебинар 1: «Обучение с подкреплением - гибкий подход для сложных задач. Создаем собственные окружения». ⏰7 июля в 20:00 мск Программа вебинара: 1. Краткое введение в обучение с подкреплением. 2. Обзор существующих сред и переход к созданию собственного RL-окружения на Python. 3. Напишем свою среду на основе gym.Env и подключим к ней обучающегося агента. Вебинар 2: «Visual DQN: Как научить ИИ-модель видеть мир глазами игрока». ⏰15 июля в 20:00 мск Программа вебинара: 1. Разберем, как DQN работает с изображениями: как агент получает состояние не в виде чисел, а в виде сырых пикселей с экрана. 2. Изучим архитектуру DeepMind-подхода. 3. Запустим обучение DQN в среде Atari Pinball и посмотрим, как агент постепенно учится играть лучше человека. Вебинар 3: «Алгоритм DQN - учим нейросеть принимать решение без помощи человека». ⏰21 июля в 20:00 мск Программа вебинара: 1. Разберем устройство алгоритма DQN: как нейросеть заменяет Q-таблицу и учится выбирать лучшие действия. 2. Изучим ключевые механизмы DQN. 3. Обучим агента решать задачу в среде Gymnasium и проанализируем процесс обучения. Записывайтесь ➡ https://vk.cc/cZcncW Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, erid: 2Vtzqv5RUky

Memory-Aware Balanced Gradient Dropping for Distributed Training Under GPU Memory Constraints Вы запускаете distributed training на двух картах, модель чуть больше обычной, и OOM на ровном месте. Синхронизация градиентов между устройствами съедает память быстрее, чем вы успеваете залогировать потери. Пробуете топ-K сжатие или рандомный dropout градиентов, но качество начинает плавать — важные обновления теряются, особенно на редких фичах. Ошибка: думать, что сжатие градиентов всегда решает проблему памяти без потерь. Почему random dropping не работает в production Рандомное отбрасывание градиентов в DDP нарушает сходимость на разреженных признаках — в рекомендательных системах или NLP с редко встречающимися токенами вы просто не дотягиваете до конвергенции. Практический совет: заменяйте random на memory-aware balanced gradient dropping. Он не выкидывает градиенты рандомно, а урезает их с учетом бюджета памяти и того, насколько каждый градиент критичен для текущей итерации. Типичная ошибка: применять top-K ко всем слоям одинаково — это убивает градиенты на глубоких слоях, где они уже малы по норме. Как это работает инженерно Сначала оценивается важность каждого градиента по его вкладу в loss — через второй момент (adaptive normalization). Слои с резкими выбросами (spikes) получают приоритет. Потом фиксированный бюджет (например, 30% всех градиентов) распределяется между воркерами не поровну, а с учетом RTT между устройствами и фрагментации GPU, чтобы никто не простаивал и не отсылал пустые тензоры. Вместо хранения полного тензора используется кольцевой буфер на оставшиеся 30%. Остальное отбрасывается, но частота обновления ключевых параметров остается выше порога.
# Псевдокод для memory-aware dropping
importance = compute_importance_by_second_moment(gradients)
budget_per_worker = allocate_budget_by_rtt(importance, memory_fragmentation)
buffer = ring_buffer(top_k_by_importance(gradients, budget_per_worker))
communicate(buffer)
Production-oriented пример: ResNet-50 и BERT На ResNet-50 это дает снижение объема коммуникаций до 30% без просадки accuracy больше 1%. Для BERT — устойчивость к малым батчам: можно увеличить effective batch size без OOM. Из тонких моментов: если модель неоднородная (трансформер со слоями разной размерности), помогает динамическое перераспределение бюджета между слоями на ходу. Я видел, как это снижало ошибку на тесте на 2-3% за счет сохранения градиентов для критически важных слоев внимания. Предупреждение о типичной ошибке Не применяйте memory-aware dropping слепо к уже обученным моделям — распределение важности градиентов меняется в процессе обучения. После разогрева (warmup) первых 10-20% итераций важно пересчитать бюджет. Иначе на поздних этапах вы отбросите градиенты, которые нужны для тонкой настройки финальных слоев. Trade-off: чем больше слоев с высокой размерностью, тем сильнее выигрыш в памяти, но выше риск недообучения на early stopping. Вывод: Сбалансированное отбрасывание градиентов с учетом памяти и важности — это не магия, а инженерный компромисс, который в distributed training с OOM позволяет сохранить качество, сократив коммуникации на 30% за счет динамической адаптации бюджета к гетерогенности GPU.

Как превратить ChatGPT.com в Codex (но без лимитов) Codex это прекрасно, но лимиты все меньше, а цена все выше. Под капотом п
Как превратить ChatGPT.com в Codex (но без лимитов) Codex это прекрасно, но лимиты все меньше, а цена все выше. Под капотом просто gpt-5.5. Один диалог слева пишет код, справа другой проверял результат, третий держал контекст, а я в это время мог накидать очередь следующих шагов и уйти пить чай. Если задача закончилась — пусть прилетит сообщение в Telegram. Так появился экспериментальный Chrome-плагин ChatGPT Multi Pane на GitHub. Источник

Системный аналитик помогает бизнесу и разработке говорить на одном языке: разбирает задачи компании, описывает требования, пр
Системный аналитик помогает бизнесу и разработке говорить на одном языке: разбирает задачи компании, описывает требования, проектирует IT-решения и следит, чтобы система работала на реальные цели бизнеса. Онлайн-магистратура СПбГУ и Нетологии «Системный анализ и интеллектуальные системы управления бизнес-процессами» готовит специалистов на стыке IT и управления. В программе сочетаются академическая база СПбГУ и прикладные инструменты Нетологии. Студенты изучают математическое моделирование, алгоритмы, системный анализ, Python, BI-системы, no-code-инструменты, управление проектами и подходы к внедрению искусственного интеллекта. Такой набор навыков помогает работать со сложными бизнес-процессами: находить узкие места, снижать риски при разработке, формулировать требования к системам и сопровождать внедрение IT-решений. Обучение проходит полностью онлайн. После выпуска вы получаете диплом магистра СПбГУ очного образца по направлению «Прикладная информатика». Подробнее о программе Реклама. ООО “Нетология” ОГРН 1207700135884 Erid: 2VSb5w6RqGE

Гетерогенная байесовская оптимизация с учётом стохастической задержки пайплайнов Когда production-пайплайн висит на внешних сервисах, а время выполнения каждой конфигурации — случайная величина, классическая BO отваливается. Модели загружаются с непредсказуемой задержкой, данные приходят рывками, а игнорирование стохастической задержки артефактов ведёт к bias: BO начинает выбирать быстрые, но неоптимальные конфигурации, которые успевают вернуться раньше. Явное моделирование задержки Вместо единого GP используем два: один для метрики, второй — для логарифма времени завершения. Это позволяет явно оценивать, сколько ждать артефакт от конкретного типа модели. Гетерогенность реализуется через разные ядра: например, для тяжёлых NLP-моделей с latency ~5 мин ядро RBF с length-scale ~1 мин, для лёгких — Matern с меньшим масштабом. В MLOps это даёт стабильную оценку времени, независимо от текущей загрузки GPU-нод. Асинхронное обновление с параллелизмом Когда артефакт не готов, BO запускает следующую конфигурацию, ограничивая параллелизм через пул воркеров (скажем, 4 процесса, чтобы не уронить prod). После завершения каждого запуска метрика обновляется с весами, обратно пропорциональными задержке: w_i = exp(-t_i / tau). Это штрафует медленные конфигурации меньше, чем пропуск данных, и не теряет информацию даже от 10-минутных запусков. trade-off: приходится решать, какой tau выбрать — слишком большой уменьшит ли bias, слишком маленький начнёт игнорировать долгие, но ценные точки. Типичная ошибка и практический совет Ошибка: ожидать, что BO сходится так же быстро, как на синтетике, при latency в 5-15 раз выше медианы. На практике bias в сторону быстрых конфигураций убивает поиск за 20-30 итераций. Совет: в production всегда логируйте не только метрику и конфигурацию, но и timestamp начала и конца. Инкрементально обновляйте GP времени через scipy.optimize каждые 10 запусков — это улучшает предсказание latency на 15-20% без переобучения всего пайплайна. Источники: Shahriari et al. «Taking the Human Out of the Loop», Snoek et al. «Practical Bayesian Optimization», Klein et al. «Fast Bayesian Optimization». Вывод: Явное моделирование стохастической задержки артефактов через гетерогенные GP и асинхронное обновление с весами по времени — единственный способ избежать bias в BO при production-запусках с непредсказуемой latency.

Адаптивная кластеризация редких категорий: центроиды, которые учатся в потоке Обычная кластеризация — K-Means, DBSCAN — живёт в статике: собрал данные, обучил, заморозил. В streaming-пайплайнах с редкими категориями (аномалии в IoT, новые сегменты пользователей, нетипичные события) это разваливается. Появляется новый редкий кластер — модель либо относит его к шуму, либо требует полного переобучения. Оба варианта плохи, если данных много, а кластеров мало и они возникают редко. Хранить всю историю нельзя, а моделировать динамику кластеров без дампа — ключевой trade-off. Адаптивное обновление центроидов Решение в экспоненциальном сглаживании с контролем дрейфа. Храним центроиды C₁...Cₖ и счётчики n₁...nₖ (эффективная память с decay γ). Когда приходит батч точек для каждой ищем ближайший центроид. Если расстояние меньше порога (например 0.3) обновляем: Cᵢ_new = (nᵢ * Cᵢ + β * x) / (nᵢ + β), где β — learn rate (0.1-0.3). Если расстояние больше порога и точка не шум — создаём новый центроид с малой начальной памятью (n = β), которая укрепляется при повторном подтверждении. Динамический порог и подавление шума Чтобы не переобучаться на шум: каждые T батчей применяем decay — nᵢ умножаем на 0.95. Порог создания кластера делаем динамическим: среднее k-е расстояние плюс 2 сигмы. На практике это даёт раннее обнаружение редких событий: например в мониторинге аномалий, где аномалия — редкий стабильный кластер, а не выброс.
def update_centroids(X_batch, centroids, counts, threshold=0.3, beta=0.2, gamma=0.99):
    for x in X_batch:
        distances = np.linalg.norm(centroids - x, axis=1)
        min_dist_idx = np.argmin(distances)
        if distances[min_dist_idx] < threshold:
            counts[min_dist_idx] *= gamma + beta
            centroids[min_dist_idx] += beta * (x - centroids[min_dist_idx]) / counts[min_dist_idx]
        else:
            centroids = np.vstack([centroids, x])
            counts = np.append(counts, beta)
Ошибка: игнорировать γ как гиперпараметр Типичная ошибка — фиксировать γ наугад. Быстрое забывание (γ=0.9) убивает редкие паттерны: кластер исчезает после одного батча без подтверждения. Медленное забывание (γ=0.999) сохраняет шумовые центры навсегда. Настраивайте γ под частоту появления кластеров: для редких (раз в 100 батчей) γ >= 0.995, для частых — 0.95-0.98. Тестируйте на синтетических stream-данных, где вы точно знаете, когда и какой кластер появляется. Подход близок к BIRCH и incremental clustering (Frigui & Krishnapuram, 1996; Charikar et al., 1997), но с динамическим порогом и явным контролем памяти. Плюсы: не надо хранить все данные; редкие кластеры обнаруживаются без задержки; шум не ломает центры. Вывод: Адаптивное обновление центроидов с gamma-decay и динамическим порогом решает задачу обнаружения редких кластеров в streaming-пайплайнах без переобучения, но требует калибровки gamma под частоту событий и тестирования на синтетических данных с контролируемым дрейфом.

На Stepik вышел курс «MCP: создание передовых агентных приложений» Практическай материал по разработке AI-агентов и многосерв
На Stepik вышел курс «MCP: создание передовых агентных приложений» Практическай материал по разработке AI-агентов и многосерверных систем на базе Model Context Protocol Шаг за шагом собираем своего AI-агента с серверами, инструментами, логикой для принятия решений и даже анализом изображений. Всё это на практических примерах, с схемами и кодом в терминале Что внутри: ✅ клиент-серверная архитектура MCP ✅ серверные конфигурации ✅ инструменты, ресурсы и промпты ✅ LangChain, LangGraph и LlamaIndex ✅ логика, координация инструментов ✅ логирование и отладка ✅ агент для анализа изображений ✅ подготовка решений к продакшен Скидка 25%, действует 48 часов 🔗Пройти курс на Stepik