Оптимізація гіперпараметрів Optuna та Ray Tune — досвід HPO

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1564 послуг
Оптимізація гіперпараметрів Optuna та Ray Tune — досвід HPO
Середній
~2-3 дні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1348
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    949
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1183
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    642
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    921

Ми часто бачимо: модель навчена, baseline accuracy начебто прийнятний, але гіперпараметри взяті «з прикладів». Після грамотної оптимізації гіперпараметрів (HPO) за допомогою Optuna, Ray Tune або Hyperopt на тих самих даних і тій самій архітектурі отримуємо +4–8% accuracy. Це не магія, а систематичний пошук за допомогою байєсівського пошуку. Байєсівський пошук дозволяє знаходити оптимальні гіперпараметри з меншою кількістю тріалів. Розберемо, як ми впроваджуємо HPO в production і економимо до 5× обчислювальних ресурсів.

Чому Bayesian Optimization виграє у Random Search?

Random Search ефективний при високій розмірності та малому бюджеті. Але коли важливих гіперпараметрів 3–5 (типовий випадок), Bayesian Optimization з TPE починає вигравати з ~30-го тріалу: потребує в 3–5 разів менше тріалів для досягнення тієї ж якості. TPE будує роздільні щільності для «хороших» (top-25%) та «поганих» конфігурацій, потім пропонує конфігурації з високим Expected Improvement. Grid Search сьогодні застосовний тільки до двох гіперпараметрів — далі комбінаторний вибух.

Як Optuna скорочує час пошуку?

Optuna — de-facto стандарт HPO в Python. Ключові переваги: Pythonic API без YAML-конфігів, вбудований pruning, інтеграція з MLflow та Weights & Biases. Ключова фішка — Hyperband Pruner, який обрізає погані тріали на ранніх rounds. На практиці з 200 тріалів LightGBM 40–60% обрізаються після 50–100 rounds замість повних 2000. Підсумкове прискорення: 3–5×. Optuna з Hyperband Pruner обрізає до 60% тріалів, прискорюючи пошук у 3 рази порівняно зі звичайним байєсівським пошуком. Random Search потребує приблизно в 3 рази більше тріалів, ніж байєсівський пошук.

Код оптимізації LightGBM
import optuna
from optuna.integration import LightGBMPruningCallback
import lightgbm as lgb
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import roc_auc_score
import numpy as np

def objective(trial: optuna.Trial, X, y) -> float:
    params = {
        'objective': 'binary',
        'metric': 'auc',
        'verbosity': -1,
        'boosting_type': trial.suggest_categorical('boosting', ['gbdt', 'dart']),
        'n_estimators': trial.suggest_int('n_estimators', 100, 2000),
        'learning_rate': trial.suggest_float('learning_rate', 1e-4, 0.3, log=True),
        'num_leaves': trial.suggest_int('num_leaves', 20, 300),
        'max_depth': trial.suggest_int('max_depth', 3, 12),
        'min_child_samples': trial.suggest_int('min_child_samples', 5, 300),
        'feature_fraction': trial.suggest_float('feature_fraction', 0.4, 1.0),
        'bagging_fraction': trial.suggest_float('bagging_fraction', 0.4, 1.0),
        'bagging_freq': trial.suggest_int('bagging_freq', 1, 7),
        'reg_alpha': trial.suggest_float('reg_alpha', 1e-9, 10.0, log=True),
        'reg_lambda': trial.suggest_float('reg_lambda', 1e-9, 10.0, log=True),
    }

    cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
    cv_scores = []

    for fold, (train_idx, val_idx) in enumerate(cv.split(X, y)):
        X_train, X_val = X[train_idx], X[val_idx]
        y_train, y_val = y[train_idx], y[val_idx]

        dtrain = lgb.Dataset(X_train, label=y_train)
        dval = lgb.Dataset(X_val, label=y_val, reference=dtrain)

        pruning_callback = LightGBMPruningCallback(trial, 'auc', valid_name='valid_1')

        model = lgb.train(
            params,
            dtrain,
            valid_sets=[dtrain, dval],
            num_boost_round=params['n_estimators'],
            callbacks=[
                lgb.early_stopping(stopping_rounds=50, verbose=False),
                lgb.log_evaluation(period=-1),
                pruning_callback,
            ],
        )

        y_pred = model.predict(X_val)
        cv_scores.append(roc_auc_score(y_val, y_pred))

    return float(np.mean(cv_scores))

sampler = optuna.samplers.TPESampler(
    n_startup_trials=20,
    multivariate=True,
    seed=42
)
pruner = optuna.pruners.HyperbandPruner(
    min_resource=50,
    max_resource=2000,
    reduction_factor=3
)

study = optuna.create_study(
    direction='maximize',
    sampler=sampler,
    pruner=pruner,
    study_name='lgbm_credit_scoring',
    storage='sqlite:///optuna_studies.db',
    load_if_exists=True
)

study.optimize(
    lambda trial: objective(trial, X, y),
    n_trials=200,
    n_jobs=4,
    timeout=3600,
    show_progress_bar=True
)

print(f'Best AUC: {study.best_value:.4f}')
print(f'Best params: {study.best_params}')

Візуалізація та аналіз важливості параметрів:

import optuna.visualization as vis

fig = vis.plot_param_importances(study)
fig.show()

fig = vis.plot_optimization_history(study)
fig.show()

fig = vis.plot_contour(study, params=['num_leaves', 'learning_rate'])
fig.show()

Аналіз fANOVA часто дає несподівані результати: num_leaves і min_child_samples виявляються важливішими за learning_rate для LightGBM на незбалансованих даних. Ефективність байєсівської оптимізації залежить від вибору acquisition function, а саме Expected Improvement (EI) або Upper Confidence Bound (UCB), які балансують між exploitation та exploration.

Коли варто обрати Ray Tune?

Ray Tune вирішує інше завдання — паралельний пошук на кластері GPU. Якщо Optuna з n_jobs=4 паралелить на одній машині, Ray Tune масштабується до сотень вузлів. Ray Tune краще підходить для розподіленого навчання з розподіленим навчанням на кластері, а Optuna — для класичного ML на одній машині. Для розподіленого навчання Ray Tune забезпечує масштабування.

from ray import tune
from ray.tune.schedulers import ASHAScheduler
from ray.tune.search.optuna import OptunaSearch
import torch

def train_transformer(config: dict):
    model = build_model(
        hidden_dim=config['hidden_dim'],
        num_heads=config['num_heads'],
        num_layers=config['num_layers'],
        dropout=config['dropout']
    )
    optimizer = torch.optim.AdamW(
        model.parameters(),
        lr=config['lr'],
        weight_decay=config['weight_decay']
    )

    for epoch in range(config['max_epochs']):
        train_loss = train_one_epoch(model, optimizer)
        val_loss, val_acc = evaluate(model)
        tune.report(val_loss=val_loss, val_acc=val_acc, epoch=epoch)

scheduler = ASHAScheduler(
    time_attr='epoch',
    max_t=100,
    grace_period=10,
    reduction_factor=3,
    metric='val_loss',
    mode='min'
)

search_alg = OptunaSearch(
    metric='val_loss',
    mode='min',
    sampler=optuna.samplers.TPESampler(seed=42)
)

search_space = {
    'hidden_dim': tune.choice([128, 256, 512]),
    'num_heads': tune.choice([4, 8, 16]),
    'num_layers': tune.randint(2, 8),
    'dropout': tune.uniform(0.0, 0.5),
    'lr': tune.loguniform(1e-5, 1e-2),
    'weight_decay': tune.loguniform(1e-8, 1e-3),
    'max_epochs': 100
}

analysis = tune.run(
    train_transformer,
    config=search_space,
    num_samples=100,
    scheduler=scheduler,
    search_alg=search_alg,
    resources_per_trial={'gpu': 1, 'cpu': 4},
    storage_path='s3://my-bucket/ray-results',
    name='transformer_hpo_v2'
)

best_config = analysis.get_best_config(metric='val_loss', mode='min')

Кейс: HPO для fraud detection моделі з нашої практики

Цей кейс з нашого досвіду для клієнта у fintech. Задача: бінарна класифікація транзакцій для клієнта, дисбаланс 1:340 (fraud:normal), 2.1M записів. Baseline XGBoost з дефолтними параметрами: PR-AUC = 0.412.

Optuna, 150 тріалів, 4 паралельних воркери, ~2.5 години:

  • search space: 11 параметрів XGBoost + scale_pos_weight (1–350)
  • метрика: PR-AUC на stratified 5-fold CV
  • pruner: MedianPruner

Результат: PR-AUC = 0.581 (+41% відносно baseline). Найважливіші параметри: scale_pos_weight (22%), min_child_weight (18%), subsample (15%). max_depth і n_estimators — сумарно 14%. Наш клієнт отримав приріст PR-AUC на 41%.

Етап для клієнта PR-AUC Recall при Precision=0.8
XGBoost default 0.412 0.34
Random Search (50 trials) 0.521 0.47
Optuna TPE (150 trials) 0.581 0.56
+ Feature engineering 0.634 0.62

Економія від впровадження: зниження хибних спрацьовувань на 23% зекономило клієнту $12,000 на місяць на ручній верифікації. Завдяки HPO клієнт заощадив $12,000 на місяць.

Optuna vs Ray Tune: коли що обрати

Критерій Optuna Ray Tune
Одна машина, 1–8 GPU + надлишковий
Кластер 10+ GPU/вузлів складніше +
Deep learning (PyTorch/JAX) + +
Класичний ML (sklearn, lgbm) + працює
Інтеграція з distributed training через callbacks native
Відновлення після збою SQLite/PostgreSQL backend +
Крива навчання для нової команди полога крутіша

Інтеграція з MLflow і Weights & Biases

import mlflow
import optuna

def objective_with_tracking(trial):
    with mlflow.start_run(nested=True):
        params = {
            'lr': trial.suggest_float('lr', 1e-5, 1e-1, log=True),
            'dropout': trial.suggest_float('dropout', 0.1, 0.5),
        }
        mlflow.log_params(params)
        val_acc = train_and_evaluate(params)
        mlflow.log_metric('val_acc', val_acc)
        return val_acc

with mlflow.start_run(run_name='hpo_study'):
    study.optimize(objective_with_tracking, n_trials=100)
    mlflow.log_metric('best_val_acc', study.best_value)
    mlflow.log_params(study.best_params)

Типові помилки та як їх уникнути

Data leakage в objective: якщо preprocessing (StandardScaler, target encoding) фітиться на всьому train-set перед CV — результати HPO оптимістично завищені, production-деградація гарантована. Scaler має фітитися тільки на train-fold всередині CV. Інша помилка: оптимізація accuracy замість бізнес-метрики при дисбалансі класів — знаходимо конфігурацію з accuracy 98.3% при recall на minority-клас 0.04.

Що входить у роботу під ключ

  • Аудит поточного пайплайну та вибір інструменту (Optuna / Ray Tune / Hyperopt)
  • Налаштування search space та метрик на основі бізнес-цілей
  • Реалізація HPO з pruning та паралельними тріалами
  • Інтеграція з MLflow для трекінгу експериментів
  • Документація з відтворення результатів
  • Навчання команди роботі з інструментом

Процес роботи

  1. Аналітика — збір вимог, вивчення даних, baseline моделі.
  2. Проєктування — вибір HPO-фреймворку, визначення search space, метрик.
  3. Реалізація — написання objective-функції, налаштування паралелізму та pruning.
  4. Тестування — запуск на CV, перевірка на holdout, порівняння з baseline.
  5. Деплой — впровадження найкращої конфігурації в CI/CD, моніторинг у production.

Терміни та вартість

Терміни: базова HPO з Optuna на одному завданні — 2–5 днів. Distributed HPO з Ray Tune та інтеграцією в CI/CD — 2–4 тижні. Вартість: базова HPO з Optuna — від $3,000, distributed HPO з Ray Tune — від $8,000. Оцінимо ваш проєкт безкоштовно — зв'яжіться з нами для консультації.

Наша команда має 7+ років досвіду у ML-продакшені, реалізувала понад 50 проєктів з HPO для клієнтів із fintech, e-commerce та рекламних технологій.

AutoML: AutoGluon, FLAML, Vertex AI AutoML і коли це працює

Коли бізнес хоче швидко отримати модель, ми пропонуємо впровадження AutoML платформ. Це не кнопка «зроби мені AI», а автоматизація перебору гіперпараметрів і вибору алгоритму. Різниця критична: без якісних даних і правильної постановки задачі навіть найкраща платформа видасть сміття. Але для конкретних задач AutoML економить тижні ручних ітерацій.

AutoML автоматизує вибір моделі та налаштування гіперпараметрів. На структурованих табличних даних сучасні системи конкурують з ручним ML-інжинірингом. Наприклад, на kaggle-змаганнях AutoGluon без жодного налаштування потрапляє в топ-10% на багатьох датасетах. Причина: він будує ансамбль з LightGBM, XGBoost, CatBoost, нейромереж і RF зі stacking — такий ансамбль часто перевершує одиночну найкращу модель на 5–10% за метрикою.

Як AutoML може прискорити створення моделей?

Хороші кандидати для AutoML платформ:

  • Стандартна бінарна/мультикласова класифікація або регресія на табличних даних
  • Задачі без жорстких обмежень на latency (< 50 мс) або розмір моделі (< 10 MB)
  • MVP або baseline перед ручною оптимізацією
  • Команди без глибокої ML-експертизи, яким потрібен робочий прототип за 1–2 тижні

Погані кандидати: кастомний loss, специфічні архітектури, real-time inference з жорсткими обмеженнями, domain-специфічні задачі (медична візуалізація, NLP на рідкісній мові).

Чому AutoGluon — найкращий вибір для табличних даних?

AutoGluon-Tabular — найсильніший AutoML для таблиць за більшістю бенчмарків. Ключова особливість — багаторівневий стекінг. Моделі першого шару (LightGBM, XGBoost, CatBoost, FastAI tabular, KNN) → їхні передбачення як фічі → моделі другого шару. Це налаштовується через num_stack_levels=2.

from autogluon.tabular import TabularPredictor

predictor = TabularPredictor(
    label='target',
    eval_metric='roc_auc',
    path='./ag_models'
).fit(
    train_data,
    time_limit=3600,  # 1 година
    presets='best_quality',  # vs 'medium_quality', 'high_quality'
)

Preset best_quality включає стекінг та ансамблі, займає максимум пам'яті та часу. medium_quality — баланс швидкість/якість, підходить для >1M рядків. optimize_for_deployment — прибирає важкі ансамблі, прискорює inference.

Типовий підводний камінь: AutoGluon навчає десятки моделей і зберігає всі на диск — від 2 до 10 GB на серйозних задачах. При деплої вивантажуйте лише фінальну модель через predictor.clone_for_deployment(). З пам'яттю теж обережно: при num_stack_levels=2 на 500k рядків можливий OOM на машинах з <32 GB RAM. Рішення: ag_args_fit={'num_cpus': 4, 'num_gpus': 0} і excluded_model_types=['NeuralNetFastAI'].

Порівняння preset-конфігурацій AutoGluon

Preset Час навчання (на 100k рядків) Типова якість (ROC-AUC) Рекомендація
medium_quality 10-30 хв 0.88-0.92 Швидкий baseline
best_quality 1-4 год 0.92-0.96 Найвища точність
optimize_for_deployment 30-60 хв 0.90-0.94 Production-деплой

Як FLAML економить ресурси та час?

FLAML (Fast and Lightweight AutoML) від Microsoft орієнтований на мінімальний бюджет обчислень при хорошій якості. Використовує cost-frugal search: спочатку пробує дешеві конфігурації, поступово переходячи до дорогих. Це дає виграш у часі до 2 разів порівняно з AutoGluon на однаковому бюджеті, хоча підсумкова якість може бути на 3–5% нижчою.

from flaml import AutoML
automl = AutoML()
automl.fit(X_train, y_train, task="classification", time_budget=120, metric="roc_auc")

Добре підходить для обмеженого обчислювального бюджету, задач з вимогою time_budget < 60 сек, інтеграції в CI/CD пайплайн. FLAML також підтримує fine-tuning LLM через flaml.autogen — автоматичний підбір промптів для GPT/Claude.

Коли вибрати Vertex AI AutoML?

Google Vertex AI AutoML — правильний managed сервіс, коли:

  • Немає своєї ML-інфраструктури
  • Потрібна інтеграція з BigQuery, Cloud Storage, Dataflow
  • Задача — Computer Vision або NLP (не лише таблиці)
  • Потрібен managed inference endpoint без DevOps

Вартість навчання обчислюється погодинно за використання нод. Для 100k рядків і 50 ознак зазвичай 2–4 години навчання. Для високонавантажених задач self-hosted AutoGluon вигідніший. Обмеження: менше контролю над архітектурою, експорт моделі лише в TF SavedModel або TFLite, без ONNX. Зате managed feature store, автоматичний моніторинг дрейфу та MLOps з коробки.

Порівняння основних AutoML платформ

Характеристика AutoGluon FLAML Vertex AI AutoML
Якість на таблицях ★★★★★ ★★★★ ★★★★
Швидкість навчання ★★★ ★★★★★ ★★★
Вимоги до інфраструктури Своя машина/GPU Будь-яке середовище Google Cloud
Гнучкість (кастомні loss та пайплайни) Висока Середня Низька
Підходить для Production, high-quality Швидкі експерименти Managed сервіс

Що входить у роботу з впровадження AutoML?

Ми надаємо повний цикл: від швидкого бенчмарку до production-системи з моніторингом. У deliverables входять:

  • EDA та підготовка даних (feature engineering, обробка пропусків, кодування)
  • Навчання та порівняння 3+ AutoML конфігурацій з фіксацією метрик
  • Вибір найкращої моделі та її експорт (ONNX, TF SavedModel, TorchScript)
  • Розгортання inference endpoint (Docker, Kubernetes, serverless)
  • Документація model card та інструкція з перенавчання
  • Навчання вашої команди роботі з платформою (2 години)

Гарантуємо: baseline за 5 робочих днів, production-рішення за 2–4 тижні залежно від складності. Типова економія бюджету клієнта — до 40% порівняно з ручною розробкою. Оцініть потенційну економію для вашого проєкту — зв'яжіться з нами.

Процес роботи та терміни

  1. Аналітика (1–2 дні) — збір вимог, EDA, визначення метрики якості.
  2. Бенчмарк (2–3 дні) — запуск AutoGluon medium_quality, FLAML, Vertex AI. Фіксація baseline.
  3. Оптимізація (3–5 днів) — feature engineering, ручне налаштування гіперпараметрів, стекінг.
  4. Тест та валідація (2–3 дні) — оцінка на відкладеній вибірці, перевірка дрейфу, A/B тест.
  5. Деплой (2–4 дні) — контейнеризація, CI/CD, метрики моніторингу.

Терміни: MVP — від 1 тижня. Повноцінна production-система з автоперенавчанням — від 3 тижнів.

Чому варто довірити впровадження нам?

У нас за плечима понад 5 років досвіду та більше 20 успішних проєктів з впровадження AutoML платформ у рітейлі, фінтесі та логістиці. Сертифіковані інженери з AWS Machine Learning та Google Cloud Professional Data Engineer. Ми не просто запускаємо код — ми навчаємо вашу команду та гарантуємо, що модель буде стабільно працювати в production.

Отримайте консультацію з AutoML для вашої задачі — залиште заявку. Або замовте безкоштовний бенчмарк: ми проаналізуємо ваші дані та скажемо, скільки часу та грошей заощадить AutoML.