From 20553583e29f51103526a12db5b5dc82f99471ef Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Mon, 12 Jan 2026 00:26:02 +0100 Subject: [PATCH] fix: adjust CatBoost depth dynamically based on loss_function (#39) * sensible depth for catboost adjusting depth to sensible values to fit VRAM for GPU mode. * fix: adjust CatBoost depth dynamically based on loss_function Dynamically adjust max_depth for CatBoost based on task_type and loss_function: - GPU pairwise modes (YetiRank, PairLogitPairwise, QueryCrossEntropy): max_depth=8 - GPU other modes: max_depth=16 - CPU: max_depth=16 Per CatBoost documentation, pairwise loss functions on GPU are limited to depth 8. Co-authored-by: jokedoke <13506976+jokedoke@users.noreply.github.com> * chore: bump strategy version to 3.10.9 * chore: bump model version to 3.10.9 --------- Co-authored-by: jokedoke Co-authored-by: jokedoke <13506976+jokedoke@users.noreply.github.com> --- .../freqaimodels/QuickAdapterRegressorV3.py | 2 +- .../user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 23 ++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 03249cc..c79c1fa 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -87,7 +87,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): https://github.com/sponsors/robcaulk """ - version = "3.10.8" + version = "3.10.9" _TEST_SIZE: Final[float] = 0.1 diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index 583c076..62dc859 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -110,7 +110,7 @@ class QuickAdapterV3(IStrategy): _PLOT_EXTREMA_MIN_EPS: Final[float] = 0.01 def version(self) -> str: - return "3.10.8" + return "3.10.9" timeframe = "5m" timeframe_minutes = timeframe_to_minutes(timeframe) diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index 13f87a1..95120b0 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -1632,6 +1632,12 @@ _CATBOOST_GPU_RSM_LOSS_FUNCTIONS: Final[tuple[str, ...]] = ( "PairLogitPairwise", ) +_CATBOOST_GPU_PAIRWISE_LOSS_FUNCTIONS: Final[tuple[str, ...]] = ( + "YetiRank", + "PairLogitPairwise", + "QueryCrossEntropy", +) + def get_ngboost_dist(dist_name: str) -> type: from ngboost.distns import Exponential, Laplace, LogNormal, Normal, T @@ -2443,13 +2449,25 @@ def get_optuna_study_model_parameters( elif regressor == REGRESSORS[4]: # "catboost" # Parameter order: boosting -> tree structure -> regularization -> sampling task_type = model_training_parameters.get("task_type", "CPU") + loss_function = model_training_parameters.get("loss_function", "RMSE") + + if ( + task_type == "GPU" + and loss_function in _CATBOOST_GPU_PAIRWISE_LOSS_FUNCTIONS + ): + max_depth = 8 + elif task_type == "GPU": + max_depth = 16 + else: # CPU + max_depth = 16 + if task_type == "GPU": default_ranges: dict[str, tuple[float, float]] = { # Boosting/Training "iterations": (100, 2000), "learning_rate": (0.001, 0.3), # Tree structure - "depth": (4, 12), + "depth": (4, max_depth), "min_data_in_leaf": (1, 20), "border_count": (128, 255), "max_ctr_complexity": (2, 6), @@ -2470,7 +2488,7 @@ def get_optuna_study_model_parameters( "iterations": (100, 2000), "learning_rate": (0.001, 0.3), # Tree structure - "depth": (4, 10), + "depth": (4, max_depth), "min_data_in_leaf": (1, 20), # Regularization "l2_leaf_reg": (1, 10), @@ -2550,7 +2568,6 @@ def get_optuna_study_model_parameters( ), } - loss_function = model_training_parameters.get("loss_function", "RMSE") if task_type == "CPU" or loss_function in _CATBOOST_GPU_RSM_LOSS_FUNCTIONS: params["rsm"] = trial.suggest_float( "rsm", -- 2.43.0