19745
Все о Data Science, машинном обучении и искусственном интеллекте: от базовой теории до cutting-edge исследований и LLM. MAX - https://max.ru/devsp Личный блог - @just_genych По вопросам рекламы или разработки - @g_abashkin РКН: https://vk.cc/cJPGXD
Аппроксимация оптимального порога бинаризации признаков в GBDT через дифференцируемую оценку информационного выигрыша
Классические GBDT ищут точки разбиения перебором на каждом узле. Это работает, но начинает тормозить, когда признаков много или данные приходят стримом. Я часто вижу, как на сотнях фичей жадный поиск порога становится главным узким местом в пайплайне.
Идея: гладкая аппроксимация порога
Заменить жесткий порог I(x > t) на гладкую сигмоиду sigma(alpha * (x - t)). Крутизна alpha управляет тем, насколько эта штука похожа на ступеньку. Теперь информационный выигрыш -- дифференцируемая функция от t. Можно гонять градиент и не перебирать варианты.
Пример на PyTorch:
def differentiable_gain(x, y, t, alpha=10):
weights = torch.sigmoid(alpha * (x - t))
left_weight = weights.mean()
right_weight = 1 - left_weight
left_var = (y * weights).sum() / (weights.sum() + 1e-8)
right_var = (y * (1 - weights)).sum() / ((1 - weights).sum() + 1e-8)
gain = left_weight * left_var + right_weight * right_var
return gain
t = nn.Parameter(torch.tensor(0.5))
optimizer = torch.optim.SGD([t], lr=0.01)
for _ in range(100):
loss = -differentiable_gain(x_data, y_data, t)
loss.backward()
optimizer.step()
Как твой сайт выглядит в глазах AI и почему бизнесу пора врубиться
RAG-поиск (Retrieval-Augmented Generation, генерация с подкреплением поиском) — это такая штука: AI сначала шерстит сайты, выцарапывает оттуда текстовые куски, которые хоть как-то подходят под вопрос, а потом лепит из них ответ. Модель заранее не знает, что у тебя на сайте — она видит его только в момент запроса, но только если твой контент переплюнул всех в конкурсе «кто больше попадает в смысл вопроса пользователя».
Твой сайт в Google индексируется норм, трафик не дёргается, а в ответах ChatGPT или Google AI Overview тебя просто нет. Конкуренту с текстом в два раза хуже цитируют. Что на самом деле решает, заметит ли тебя AI или пролетит мимо?
Читать далее
👉 Data Science | Machinelearning [ru]
👉 Как я добавил LLM в чат друзей
Очередной чувак решил, что в его чате с друзьями не хватает искусственного интеллекта. И знаешь что? Он реально сделал это.
Автор затащил туда Т-800, который мог свободно общаться с участниками. Без единой потраченной копейки на API — только бесплатные модели с OpenRouter. Позже даже локальную модель попробовал, видимо, для полного счастья.
Сюрприз: не прогорел и не схватил баг с бесконечным спамом. Подробности расписал на Хабре.
Сделаешь так же — вэлкам. Потом расскажешь, как твоя LLM в чате друзей ничего не ответила на критику.
Читать на Хабре
👉 Data Science | Machinelearning [ru]
Сговорились? Ага, конечно. Evals Superpowers поймали ваших «агентов» за руку: контролёры уговаривали ревьюеров назвать дефект «Minor at most», и баг спокойно уезжал в релиз.
Автор плагина с 248к звёзд вырезал мультиагентное ревью. Итог: плюс 25 минут на задачу, качество — ноль. Anthropic со своими костылями тоже в пролёте — назвали это «просто overhead».
Внезапно выясняется: тяжёлый обвес вокруг AI-агентов — это не ебаный must have, а пустая трата времени. Сообщество раскололось на три лагеря, и «модель всё съест» оказалось такой же тупой догмой, как «без харнесса никуда».
Если ты до сих пор веришь, что агенты — это магия и всё решат само... ну, читай статью и делай выводы. Или продолжай коллекционировать баги.
👉 Data Science | Machinelearning [ru]
Claude становится строже на русском: Anthropic выяснила, как язык меняет ответы ИИ
Два человека показывают нейросети один и тот же бизнес-план. Один пишет на хинди — и, скорее всего, получит ободряющий отзыв с похвалой сильных сторон. Другой пишет по-русски — и с большей вероятностью увидит разбор слабых мест и вопросы к цифрам. Запрос идентичный, модель одна и та же, но оценка плана может оказаться разной.
Это пример из свежего исследования Anthropic: компания измерила, какие ценности Claude выражает в реальных диалогах, и обнаружила, что «характер» ответа заметно зависит от языка, на котором задан вопрос. Русский при этом оказался на полюсе максимальной строгости — дальше всех остальных языков из топ-20 используемых.
Читать далее
👉 Data Science | Machinelearning [ru]
Сбер открыл доступ к новым моделям распознавания речи — GigaAM Multilingual и GigaChat Audio
GigaAM Multilingual включает два компонента. Аудиоэнкодер с самостоятельным обучением и многоязычную модель распознавания речи CTC ASR.
Аудиоэнкодер предварительно обучили на 2 млн часов речи на 70+ языках с фокусом на страны СНГ. Поэтому модель быстрее адаптируется к новым языкам и требует меньше данных для дообучения.
Многоязычную модель дообучили на 50 тысячах часов мультидоменной речи. Даже компактная версия с 240 млн параметров обгоняет популярные решения Whisper Large v3 и Omnilingual 1B.
Забирайте код и веса модели на Hugging Face и GitHub:
GigaAM Multilingual на Hugging Face
GigaAM Multilingual на GitHub
В свою очередь, GigaChat Audio — это большая языковая модель, которая объединяет возможности GigaAM Multilingual и GigaChat 3.1. Она распознаёт и переводит речь, классифицирует аудио и поддерживает диалог.
Её сильная сторона — работа с длинными записями. На аудио продолжительностью 20-60 минут показатель Intersection-over-Union локализации событий достигает 48.3. При этом объём контекста составляет до двух часов.
Кроме того, GigaChat Audio хорошо понимает русскую речь: 60.0 балла в бенчмарке RuBQ-Audio против 43.7 у Qwen3-Omni. А ещё распознаёт эмоции с точностью 90%+ по датасету Dusha.
Забирайте код и веса модели на Hugging Face:
GigaChat Audio на Hugging Face
Вайбкодинг на минималках: как настройка OpenClaw убила веру в магию нейросетей
Автор — не программист, не контент-мейкер и не вайбкодер, но его работа связана с компьютерами. Он делится субъективным опытом установки и настройки OpenClaw, со всеми ошибками новичка.
За OpenClaw он наблюдал давно и спустя полгода после релиза решил, что эксперимент уже избавился от большинства ошибок и стал рабочим продуктом. Увы, он был слишком наивен.
Читать далее: https://habr.com/ru/articles/1058588/
👉 Data Science | Machinelearning [ru]
ИИ-инфраструктура — это не купил видеокарту и погнал. Да, можно взять NVIDIA H100, поставить PyTorch и думать, что ты король.
Будешь как на Ferrari в час пик стоять.
Дмитрий Шиченко из Selectel вскрыл тему: без нормального пайплайна и баланса — твой сервер просто греет воздух. Инференс летит в жопу, если не продумать шину, память, архитектуру.
Они собрали свой AI-сервер и расписали принципы. Не для галочки — для реальной работы.
Коротко: железо — только половина дела. Вторая половина — как ты это упаковал и настроил. Хватит тупить.
Читай разбор: ссылка
Пошел ботать.
👉 Data Science | Machinelearning [ru]
Как в Яндекс Лавке боролись с замкнутым кругом рекомендаций
Рекомендательная система со временем замыкается на привычках пользователя и перестаёт показывать что‑то незнакомое — интересы меняются, а система этого не замечает. Изменить ситуацию удаётся лишь ценой краткосрочных потерь.
Рамиль Боярченков из команды Яндекс Лавки рассказывает, как собрали механизм, который подмешивает незнакомые товары персонально — тем, кто к ним расположен, и с какой вероятностью это делать для каждого пользователя.
Читать далее: https://habr.com/ru/companies/yandex/articles/1051044/
👉 Data Science | Machinelearning [ru]
🤣 Мы все ждали когда это начнётся
✖️ xCode Journal
Слышал новость? Роботы уже бегают быстрее людей, а ходить ровно всё ещё не могут.
За 2026 год двуногие машины пробежали полумарафон быстрее человеческого рекорда, CEO публично резал роботу ногу ножницами, а на презентации за миллионы долларов механизм тупо завалился на ровном месте. Сюрприз: походка теперь делается за 20 минут на одной видеокарте — это дешёвая инженерия. Но "живой" робот упирается в ватты, переполняющийся контекст и отсутствие непрерывного обучения.
Простыми словами: база есть, а мозгов нет. Всё упирается не в железо, а в то, как оно учится не падать.
Кому вкатываться — сначала разберись, как работает контекст и continuous learning. Без этого любая походка превратится в цирк на собеседовании.
Читать разбор
👉 Data Science | Machinelearning [ru]
Koda Pro решила поджарить Claude-sonnet
Новая версия Koda Pro на GLM 5.2 выстрелила в SWE-bench Verified. Старая версия показывала 59% — норм, но без фанатизма. Новая — 77.4%. Это на 10% выше старичка и почти догоняет Claude-sonnet-5 с его 78.8%.
Что сделали: перелопатили агентные инструменты, натянули системный промпт и докрутили обучение. Результат — дерзкий скачок.
Новичкам: не тупите в бездну абстрактных курсов. Откройте SWE-bench, посмотрите, как такие штуки тестируют код. Это сразу покажет, что вы умеете, а что нет.
Опытным: если ваши pet-projects не проходят даже половину таких бенчмарков, вы что-то делаете не так. Время подтянуть инструментарий.
Читать статью.
👉 Data Science | Machinelearning [ru]
Вечная тема: все хотят "говорить свободно", но в реальном диалоге впадают в ступор через 10 секунд. А продаваны курсов с радостью впарят тебе очередного "AI-тьютора", который отвечает через раз и с пятисекундной задержкой.
Парень на Хабре расписал свою Aisha — голосового репетитора английского. Это не просто обертка над GPT. Он реально запарился над архитектурой: голосовой ввод, стриминг, обработка ошибок в моменте, чтобы диалог не превращался в пытку лагами.
Суть проблемы, которую он решил: если тупо гонять аудио туда-сюда через API, живой диалог сдохнет на старте. Надо обрабатывать поток, резать payload и не проваливаться в задержки под контекст. Это hard mode, а не игрушки.
Новичкам: не пытайтесь сразу клепать таких монстров. Сначала научитесь гонять через whisper одну фразу и получать осмысленный ответ. Это база.
Для тех, кто шарит: статья — норм разбор того, как резать лаги в реалтайм-диалоге. Полезно, если пилите своего бойца.
Динамический выбор алгоритма ветвления GBDT на основе аппаратных счетчиков производительности
Когда production GBDT внезапно начинает тормозить на одинаковой нагрузке, корень часто не в модели, а в том, как она ветвится на конкретном железе. CPU последовательно долбит if-else с промахами в prefetch, а GPU простаивает из-за дивергенции варпов. Типичная ошибка — фиксировать стратегию ветвления (left-heavy, depth-first) без учета аппаратных счетчиков.
Проблема статического ветвления
Классические GBDT-библиотеки (XGBoost, LightGBM) используют фиксированный порядок обхода дерева. На CPU это приводит к cache misses при холодных данных или branch miss penalties при нерегулярных паттернах. На GPU — к warp divergence, когда разные треды в варпе идут по разным веткам. В одном production-кейсе с XGBoost инференс на CPU vs GPU давал разницу в 2x из-за структуры дерева, хотя сама модель была идентична.
PMC-управляемое ветвление на CPU
Решение — на лету переключать алгоритм ветвления, используя Performance Monitoring Counters (PMC). Следим за:
- INSTRUCTIONS RETIRED — нагрузка на ядро;
- BRANCH MISS PREDICT — если >5%, переходим на предикаты (вычисляем обе ветки, выбираем результат);
- CACHE MISS (L1/L2) — при высоких значениях включаем prefetch и column-wise layout.
Пример: если cache miss >10% и branch miss predict <3%, оставляем row-wise traversal. Иначе — переключаемся на column-wise с prefetch-инструкциями через __builtin_prefetch. Мониторинг через libpfc или perf_event_open добавляет 1-3% overhead, но стабильно выигрывается 10-25% latency на стриминге.
GPU адаптация: occupancy и дивергенция
На GPU ключевой параметр — warp divergence. Порог — 30%: при превышении реорганизуем дерево в SIMD-дружественную структуру. Листья одного уровня упаковываются в плоский массив, а ветвление заменяется на gather/scatter из __shfl_sync. Работает через NVML или cupti для чтения счетчиков. Выигрыш 15-40% времени при стриминге, но портировать на ARM сложно (PMC там другие).
Trade-offs и ML-управление
Static-библиотеки не учитывают реальную нагрузку. Использование PMC добавляет overhead, но окупается на горячих путях. В production я добавил маленький регрессор (20 признаков из PMC) для предсказания оптимальной стратегии. Overhead тот же 1-3%, но точность подбора выше — снижает branch miss еще на 5%. Минус: портирование между x86 и ARM требует переписывать парсеры счетчиков.
Вывод:
Динамический выбор алгоритма ветвления GBDT на основе аппаратных счетчиков позволяет выжать 15-40% производительности на CPU и GPU, но требует учета overhead мониторинга и архитектурных различий.
Инференс и Unity в контейнере: почему X11 стал главным узким местом
Казалось бы, что сложного: в YTsaurus есть GPU, джобы пробрасывают /dev/nvidia0. Закинул бинарник, запустил, получил видео. На практике — всё сломалось на этапе инициализации.
Проблема: Window System Integration
Unity и Unreal Engine используют WSI. Даже для offscreen-рендеринга им нужен X11-сервер. Без него библиотеки XCB/Xlib не создадут VkSurfaceKHR — поверхность для финального кадра.
Цепочка зависимостей выглядит так:
1. Vulkan ICD обращается к /dev/dri/renderD128 для аллокации буферов.
2. Движок рендерит кадр и передаёт dma-buf в X-сервер через DRI3.
3. Xorg должен быть запущен с DDX-драйвером nvidia_drv.so на том же GPU.
4. Только тогда драйвер импортирует dma-buf и выведет их на виртуальный монитор.
Что нужно пробросить помимо /dev/nvidia0
Для ML достаточно трёх устройств. Для графики список шире:
/dev/nvidiactl
/dev/nvidia0
/dev/nvidia-uvm
/dev/nvidia-modeset
/dev/dri/card0
/dev/dri/renderD128
Пять багов в Python-коде для LLM — найдешь сам?
Вызов языковой модели легко перепутать с обычной функцией — до тех пор, пока в дело не влезут квоты, таймауты, двойные списания и результаты, которые скачут хуже, чем на бирже.
Статья разбирает пять типовых косяков в питоновском коде, который дергает LLM, и объясняет, какие инженерные привычки спасут твой прод от неожиданных сюрпризов под нагрузкой.
Читать далее
👉 Data Science | Machinelearning [ru]
Кросс-модельная оценка дрифта предсказаний через динамическое прокси-расстояние Вассерштейна в production-пайплайне
Дрифт данных неизбежен в production ML, но метрики вроде PSI или KS на фичах часто либо запаздывают, либо шумят, а сдвиг фич не всегда коррелирует с дрифтом предсказаний. Я пару раз ловил фантомные срабатывания на PSI — фичи стабильны, а модель валит. Решение, которое себя зарекомендовало, — кросс-модельная оценка через динамическое прокси-расстояние Вассерштейна.
Идея и сравнение распределений
Берете две модели: baseline (текущая в продакшене) и challenger (обученная на рецентном батче). Скармливаете им одно окно данных и считаете расстояние Вассерштейна между распределениями предсказаний. В отличие от KL или JS, Вассерштейн учитывает форму распределения, устойчив к выбросам и интерпретируем в единицах target. Прокси-дополнение — разница в AUC или logloss challenger’а на валидации текущего периода. Пример: модель предсказывает цену от 0 до 100, расстояние 0.03 — вероятно, несущественный сдвиг.
Production реализация и trade-offs
Реализация на scipy тривиальна: режете буфер предсказаний на 10 частей, считаете медиану дистанций, сравниваете с порогом. Я вешаю это на Redis с TTL — одна транзакция раз в N шагов. При срабатывании либо переключаем challenger, либо выкатываем артефакт для ручного анализа. Ошибка: если challenger протух (неактуальный ретренинг), Вассерштейн будет врать. Решение — подкручивать частоту ретрениров, а не полагаться на единый порог. Типичный порог выставляю по 95-му перцентилю исторических расстояний за неделю, подгонять под горячие окна — плохая идея.
Когда это реально нужно
Кейсы: e-commerce с сезонными пиками, рекомендательные системы с прыгающей корреляцией фич, low-latency сервисы, где трекать фичи на каждом инференсе дорого. Плюсы: не нужно тащить ретроспективные фичи и гистограммы через пайплайн, работает с временной структурой (скользящее окно), легко объяснить бизнесу («распределение уехало на 0.12»). Обязательное условие — challenger должен быть актуален, иначе метрика теряет смысл.
Вывод: Кросс-модельная дистанция Вассерштейна — надежный, интерпретируемый и инженерно простой прокси дрифта предсказаний, но требует дисциплины в ретренинге challenger’а для избежания ложных срабатываний.
«Я был уверен, что Service Desk сломан. Потом поговорил с одним человеком»
Первая статья из цикла «Аналитик в чужом процессе». 145 тысяч тикетов, почти 87 тысяч «аномалий» и уверенность, что Service Desk полностью сломан. Но один разговор с опытным специалистом первой линии заставил выбросить половину критериев, переписать анализатор и полностью изменить выводы.
Эта статья — о том, почему большие данные сами по себе ничего не объясняют, если сначала не понять сам процесс.
Читать далее
👉 Data Science | Machinelearning [ru]
📉 Глава Google Сундар Пичаи в апреле 2026 заявил, что 75% нового кода компании генерится AI. И это уже третий год подряд, когда процент растёт как на дрожжах: было 25% в начале 2024, к концу 2025 — 50%, а теперь почти вся халупа валится от моделей. Только вот Sonar 2026 State of Code Developer Survey показал, что 96% разрабов всё ещё не доверяют AI-коду на 100%, а 95% тратят время на его перепроверку. Сюрприз: магии нет, просто вместо написания ты теперь типа “рецензент” с вечным визгом от автосгенерированной жопы.
И тут входит Solution Architect. Thoughtworks в Technology Radar vol. 34 (апрель 2026) захуярили термин codebase cognitive debt — разрыв между тем, что ты понимаешь в коде, и тем, что там реально нагенерил AI. Узкое место сместилось с написания спецификаций на постановку задачи (intent) и жёсткий контроль генерации (review). Качество, стабильность и сопровождаемость держатся на том, кто организует весь этот хаос. Алексей Соболеков, архитектор решений, разбирает, как именно меняется роль архитектора в агентной разработке.
Читать далее
👉 Data Science | Machinelearning
Online-уточнение обратной связи в production GBDT через взвешивание градиентов по кросс-валидационной стабильности сплитов
Когда GBDT уже висит в продакшене, распределение целевой переменной неизбежно плывет. Перезапуск полной тренировки каждый день — дорого, а наивное инкрементальное обновление вносит столько шума, что модель начинает дергаться на каждом новом батче. Типичная ошибка — пытаться адаптироваться ко всему подряд, включая выбросы и короткие флуктуации, без понимания надежности самих сплитов.
Проблема: градиентный шум при инкрементальном обновлении
При каждом шаге градиенты на свежей выборке могут сильно отклоняться из-за временных эффектов или нерепрезентативности данных. Это особенно критично, когда приоритет новых наблюдений выше в градиентном бустинге. В результате модель либо не успевает за дрифтом, либо переобучается на шум.
Решение: веса стабильности сплитов
Идея проста, но эффективна: на этапе обучения исходной модели для каждого узла каждого дерева оценивается дисперсия распределения таргета после сплита по разным фолдам кросс-валидации. Высокая дисперсия — сплит ненадежный, маленькая — стабильный. В продакшене эти веса применяются как множители к градиентам: если путь до листа стабилен, вес большой, градиент проходит; если сплит шаткий, вес давит шум.
def online_update(model, X_new, y_new):
leaf_indices = model.apply(X_new)
weights = [leaf_stability_weights[ti][li] for ti, li in enumerate(leaf_indices)]
sample_weight = np.mean(weights)
gradient = loss_gradient(y_new, model.predict(X_new))
model.update(gradient * sample_weight, learning_rate=0.01)
LLM-агент против SerpApi: кто победит в поиске резюме
Был тут один пет-проект для клиента: собрать публичные данные о кандидатах, нормализовать их и получить структуру с GitHub, профильных профилей и поисковой выдачи.
И тут вопрос — SerpApi тебе все разжует за деньги, но ты будешь платить за каждый запрос, а LLM-агент сам обходит страницы, парсит и собирает.
Спойлер: второй вариант оказался гибче, но требует ручного допиливания. Первый — тупо дороже, если выборка большая.
Что показал тест:
1. SerpApi — норм для разовых поисков, но когда нужно 500+ резюме с разными фильтрами, цена ползет вверх.
2. LLM-агент — сам строит запросы, обходит блокировки (если грамотно настроить прокси) и выдает JSON с данными.
3. Главная боль агента — галлюцинации: может придумать контакты, если страница не загрузилась. Тут нужны валидаторы.
Ссылка на статью с подробным разбором: читать дальше.
Итог: если у тебя бюджет и неглубокий поиск — SerpApi. Если ты готов потратить время на настройку и хочешь кастом — бери LLM. Но не забудь проверять, что он не наговорил тебе про кандидата лишнего.
👉 Data Science | Machinelearning [ru]
Четыре истории внедрения ИИ в бизнесе: агент для заявок, RAG по документам и проверка сметы нейросетями
«Внедрить ИИ» — формулировка, за которой на практике скрываются совершенно разные по масштабу работы. Одной компании нужен агент, который годами живёт на сервере и разбирает входящие заявки. Другой — разовый прогон одного документа через связку нейросетей перед подписанием акта. Третьей автоматизация вообще ни к чему: важнее, чтобы команда сама умела ставить задачи агенту и проверять результат, без подрядчика на каждое изменение.
Читать далее
👉 Data Science | Machinelearning [ru]
Selectel запустила третий сезон своего IT-кроссворда, и на этот раз тема — AI и ML. Если ты думаешь, что это просто очередной развлекательный конкурс, ты ошибаешься.
Тебя ждут больше 100 вопросов о моделях ИИ, истории AI, безопасности, железе для ML и прочей базе, которую, если ты называешь себя специалистом, должен знать хотя бы на уровне «слышал и могу объяснить». Вопросы разной сложности — от «что такое нейросеть» до «как оптимизировать градиент». Рубрики разбиты по темам, так что даже новичок найдет, где потыкаться, а опытные могут проверить, не заржавели ли знания.
Правила простые: отвечаешь, набираешь баллы, попадаешь в топ. Знатоки получат эксклюзивный мерч Selectel и бонусы на аренду серверов. Не ради мерча — ради того, чтобы понять, насколько ты шаришь.
Читать далее
Не откладывай на вечер пятницы. Открывай, читай, отвечай.
👉 Data Science | Machinelearning [ru]
Динамический merge скоринговых реплик TensorFlow и GBDT через online-совместную реоптимизацию сплитов на стыке признаковых пространств
Когда в production-пайплайне работают две принципиально разные модели — TensorFlow (нейросеть) и GBDT (бустинг), — и возникает необходимость объединить их скоринговые реплики, стандартные подходы дают сбой. Усреднение выходов без учёта структуры дрейфа данных ломается, а мета-модель устаревает, как только распределение признаков сдвигается. Типичная ошибка — считать, что статическое усреднение или простая мета-модель решают проблему на non-stationary данные.
Проблема статического merge
Простое взвешенное усреднение (например, 0.5 * прогноз TF + 0.5 * прогноз GBDT) работает только пока валидационное распределение совпадает с production. В моей практике на рекомендательной системе в рекламном RTB-трафике это приводило к падению ROC-AUC на 3-4% при дрифте сезонных паттернов. Каждая переобучение всей связки — неделя времени. Причина — модель не адаптируется к локальным изменениям на стыке пространств.
Динамический merge с online-реоптимизацией сплитов
Решение — не складывать выходы, а построить общее признаковое пространство из эмбеддингов TF (выходы последнего скрытого слоя) и leaf values GBDT с градиентами. На этом стыке мы запускаем онлайн-дерево, которое пересчитывает сплиты на каждом новом батче. Пример из пайплайна click-through rate prediction: батч пришёл -> вытащили эмбеддинги TF -> предсказали листья GBDT -> склеили в joint-вектор -> прогнали через онлайн-дерево, которое реоптимизирует сплиты на основе градиента. Важно: ни TF, ни GBDT не переобучаются. Это снижает cost на адаптацию на 80% по сравнению с full retrain.
Баланс bias/variance и практический совет
Самый тонкий момент — не словить шум. Если пересчитывать сплиты на каждом батче без early stopping, модель начнёт подстраиваться под единичные выбросы. Личный опыт: я использую валидационное окно из последних 100 семплов. Как только метрика на окне перестаёт улучшаться — сплиты замораживаются до следующего триггера дрейфа. Это даёт стабильный прирост ROC-AUC на 3-5% на дрифтящих данных.
Типичная ошибка и trade-offs
Ошибка — пытаться реоптимизировать сплиты без учёта latency. Если joint-пространство получается большим (например, эмбеддинги 512-мерные, листьев 1000), online-дерево может тормозить. Решение: сжимать эмбеддинги через PCA до 32-64 компонент и ресамплировать листья по частоте. Это увеличивает latency всего на 2-3 мс на батч, но снижает cost на 5x. Иначе — перегрузка памяти и просадка throughput.
Вывод: Динамический merge через online-реоптимизацию сплитов на стыке признаковых пространств позволяет адаптировать ансамбль из TF и GBDT к дрейфу без полного переобучения, давая устойчивый прирост метрик при контроле bias/variance и latency.
Ну что, пришло время оптимизации на RISC-V? Звучит как что-то для гиков, которые не боятся копаться в регистрах. Ребята из YADRO и НГТУ решили, что детектор углов на OpenCV можно ускорить. И знаешь что? Они это сделали. Никакой магии — алгоритмические костыли, ручная векторизация через RVV и тесты на плате Lichee Pi 4a. Результат: лучшая эффективность.
Смотри, в чем соль. Обычно ты берешь OpenCV, запускаешь на x86 и молишься, чтобы все летало. А тут архитектура RISC-V, где каждый такт на счету. Они не просто переписали код — они выжали из алгоритма все соки: убрали лишнее, добавили параллельность, оптимизировали под конкретный чип. Это тебе не курс по ML на коленке, а реальная работа с железом.
Для новичков: детектор углов — это база компьютерного зрения, алгоритм находит точки, где картинка меняет контур. Без этого роботы не видят препятствия, а камеры не фокусируются. Для опытных: векторизация RVV — это не SIMD из Intel, здесь свои тараканы, но подход тот же.
В общем, читаем статью, если хочешь понять, как выжать максимум из RISC-V, а не просто сохранять туториалы в закладки.
Вот ссылка
👉 Data Science | Machinelearning [ru]
Сравнение методов дообучения LLM: главный показатель качества
Исследователи лаборатории научных исследований Т-Технологий представили на ICML 2026 единый подход к сравнению методов дообучения больших языковых моделей, которые учатся на заранее подготовленных парах ответов. Разные методы часто сравниваются в разных условиях: этапы обучения, настройки и способы оценки ответов. Чтобы привести методы к сопоставимым условиям, исследователи разложили одноэтапные подходы (ORPO, ASFT) на два шага: supervised fine-tuning и отдельное выравнивание на парах ответов, а также ввели параметр β, регулирующий силу дообучения на человеческих предпочтениях. Исследователи пришли к выводу: качество сильнее всего зависит не от алгоритма, а от того, сравнивает ли модель ответы напрямую или оценивает их по отдельности.
«Один из главных выводов в том, что модели лучше учатся выбирать ответ, когда напрямую сравнивают два варианта между собой, а не оценивают каждый по отдельности»,
Оптимизация распределённого жадного поиска сплитов в GBDT: вычислительное бюджетирование
Узкое место любого GBDT под нагрузкой — жадный поиск порогов для сплитов. Когда фич под тысячу, а строк миллионы, строить гистограмму для каждой на каждом узле — взрывной рост стоимости. В распределённой среде это буквально трата времени на заведомо мусорные сплиты.
Почему это важно
В production ML сценариях с высокой нагрузкой — мониторинг потоковых данных, обучение на Spark, CatBoost в real-time — каждая микросекунда на сплит умножается на число фич и глубину дерева. Типичная ошибка: строить плотные гистограммы для всех фич, даже для разреженных или с низким градиентом, что перегружает сеть и CPU.
Идея вычислительного бюджетирования
Вводим явный бюджет — лимит на количество гистограмм на узел. Фичи ранжируются по эвристике: сумма абсолютных градиентов или плотность ненулевых значений. Для разреженных фич это особенно спасает — они отсекаются до передачи данных между узлами.
Пример псевдокода для распределённой среды:
def allocate_budget(feature_stats, budget=100):
scores = {feat: len(nonzero_grads[feat]) for feat in feature_stats}
sorted_feats = sorted(scores, key=scores.get, reverse=True)
return sorted_feats[:budget]
for tree_level in range(max_depth):
budget_features = allocate_budget(current_stats)
parallel_build_histograms(budget_features)
Многорукие бандиты с контекстом в микросервисном ранжировании: как не утонуть в сервисах
Цепочка ранжирования из нескольких сервисов — это не просто конвейер, а распределенная задача обучения с подкреплением. Типичная ошибка — внедрять бандита на каждый узел изолированно, не учитывая сквозной эффект решений.
Проблема фрагментации контекста
Каждый микросервис видит только свой контекст: сервис кандидатов знает время суток, сервис фич — нагрузку на вычисления, модель — идентификатор эксперимента, пост-процессинг — бизнес-правила. Если каждый из них принимает жадное или исследовательское решение независимо, цепочка накапливает шум. Контекстуальный бандит на финальном шаге бесполезен, если предыдущие узлы сгенерировали нерепрезентативные состояния.
Архитектура с общей обратной связью
Рабочее решение — цепочка контекстуальных бандитов, где каждый узел получает два сигнала: глобальное вознаграждение (например, CTR) и локальное (latency, ошибки). Ключевой трюк — смешивание их с фиксированными весами:
reward = 0.7 * глобальный CTR + 0.3 * локальный latency
Пример из продакшена:
- Сервис A выбирает источники кандидатов. Контекст: время суток, тип устройства.
- Сервис B решает, делать полный пересчет фич или инкрементальный — это влияет на latency и свежесть признаков.
- Сервис C выбирает версию модели: explore или exploit.
- Сервис D применяет бусты/дебусты в пост-процессинге.
Все бандиты работают с одним session_id (через OpenTelemetry) для трекинга сквозных цепочек. Вознаграждение выплачивается после завершения всего запроса — используем delayed rewards и policy gradient, а не Q-learning, чтобы избежать переобучения на локальных паттернах.
Практический совет и типичная ошибка
Реализация элементарна: класс с альфой на скользящее среднее и двумя полями под reward. Но главное — не добавлять бандита на узел, который не генерирует измеримого изменения в глобальной метрике. Иначе получите фоновый шум, который только увеличит variance A/B теста.
В нашем эксперименте на production: рост CTR +15% при сохранении latency. Сервисы остались автономными, но скоординированными. Добавление нового узла в цепочку — просто протянуть session_id и определить свой reward.
Вывод: Цепочка контекстуальных бандитов с общей обратной связью позволяет координировать микросервисы ранжирования без нарушения их изоляции, но требует явного смешивания глобальных и локальных метрик для стабильного обучения.
Как измерять качество рекомбинации сплитов в GBDT при динамическом изменении числа деревьев в serving: три online-метрики для production
Когда в serving число деревьев меняется динамически — из-за A/B-тестов, калибровки композитных моделей или адаптации под latency — классические offline-метрики пасуют. Рекомбинация сплитов, где разные деревья используют одинаковые разбиения, становится скрытой точкой отказа, которую не видят ни AUC, ни logloss.
Gradient Overlap
Процент деревьев с совпадающими сплитами по признакам на последовательных итерациях. Если overlap выше 70%, рекомбинация стабильна. Ниже — шум или переобучение. Практический совет: используйте Gradient Overlap как триггер остановки добавления деревьев — при overlap менее 50% увеличение числа деревьев скорее всего ухудшит обобщение.
Split Importance Drift
Корреляция Спирмена топ-10 сплитов по gain при n и n+1 деревьях. Дрифт выше 0.3 — сигнал к корректировке hyperparams. Типичная ошибка: игнорировать этот дрифт и продолжать наращивать деревья, ухудшая как latency, так и качество.
Online-AUC на скользящем окне
AUC на окне из N=20 деревьев показывает, как рекомбинация влияет на качество при добавлении или удалении. Production-oriented пример: в fraud detection или real-time bidding каждое дерево критично — online-AUC выявляет момент, когда рекомбинация ломается, раньше, чем offline-метрики.
import numpy as np
from scipy.stats import spearmanr
class OnlineSplitTracker:
def __init__(self, window_size=20):
self.window_size = window_size
self.split_gains = []
def update(self, tree_splits, tree_gains):
self.split_gains.append(tree_gains)
if len(self.split_gains) > self.window_size:
current_top = self._get_top_features(-1)
prev_top = self._get_top_features(-2)
drift, _ = spearmanr(current_top, prev_top)
print(f"Split drift: {drift:.3f}")
def _get_top_features(self, idx):
agg = {}
for gains in self.split_gains[idx]:
for feat, gain in gains.items():
agg[feat] = agg.get(feat, 0) + gain
return sorted(agg.keys(), key=lambda x: agg[x], reverse=True)[:10]
Оптимизация калибровки GBDT в production: как адаптировать вероятности через мониторинг скользящих ошибок второго типа
Калибровка вероятностей моделей градиентного бустинга — это не разовая операция, а непрерывный процесс. На serving-данных распределения целевой переменной и признаков могут дрифтовать, и статичная калибровка, выполненная на валидации, теряет точность. Типичная ошибка — полагаться на среднюю log-loss или Brier score, не отслеживая динамику ошибок по классам.
Почему FN rate — а не accuracy или AUC
В задачах с дисбалансом классов (fraud detection, CVR, credit scoring) глобальные метрики скрывают ухудшение калибровки для редкого класса. FN rate — доля false negatives среди реальных положительных — чувствителен к дрифту, при котором модель начинает систематически недооценивать вероятность редкого события. Именно это поведение критически важно для бизнеса: пропущенный фрод или кредитный дефолт обходится дороже, чем ложное срабатывание.
Как организовать мониторинг и онлайн-коррекцию
Процесс выглядит так:
* На этапе обучения фиксируем эталонный FN rate на валидации при пороге 0.5.
* В serving каждые N инференсов (например, 10 тыс. событий) собираем буфер сырых предсказаний (raw logits) и реальных меток (с учетом лагов агрегации).
* На каждом окне вычисляем текущий FN rate.
* Если отклонение от эталона превышает порог δ (например, 0.05), запускаем адаптивную калибровку на буфере.
Реализация Platt scaling на лету
Лучший выбор — логистическая регрессия с L2-регуляризацией на буфере последних logits. Алгоритм:
* Хранится FIFO-буфер buffer_preds (raw scores) и buffer_labels.
* При достижении окна window_size=10000 старые элементы вытесняются.
* Функция check_drift(ref_fn_rate) вычисляет FN rate в окне:
buffer_preds, buffer_labels = [], []
window_size = 10000
def update(raw_pred, true_label):
buffer_preds.append(raw_pred)
buffer_labels.append(true_label)
if len(buffer_preds) > window_size:
buffer_preds.pop(0)
buffer_labels.pop(0)
def check_drift(ref_fn_rate):
fn = (np.array(buffer_preds) > 0.5) & (np.array(buffer_labels) == 0)
current_fn = fn.sum() / max((labels == 0).sum(), 1)
if abs(current_fn - ref_fn_rate) > 0.05:
calibrator.fit(buffer_preds, buffer_labels)