]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
feat(quickadapter): add VRAM-aware CatBoost GPU hyperparameter ranges
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 15 Feb 2026 14:21:02 +0000 (15:21 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 15 Feb 2026 14:21:02 +0000 (15:21 +0100)
README.md
quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index 6e9a3878fec8841ddf33a68086c65a95fbb93b7c..c4e8e79b626bca9c1174e1dfc588e5a93ad8fd12 100644 (file)
--- a/README.md
+++ b/README.md
@@ -59,6 +59,8 @@ docker compose up -d --build
 | reversal_confirmation.max_natr_multiplier_fraction             | 0.075                         | float [0,1]                                                                                                                                  | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold.                                                                                                                                                                                                                                                                                                                                                                                                  |
 | _Regressor model_                                              |                               |                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
 | freqai.regressor                                               | `xgboost`                     | enum {`xgboost`,`lightgbm`,`histgradientboostingregressor`,`ngboost`,`catboost`}                                                             | Machine learning regressor algorithm.                                                                                                                                                                                                                                                                                                                                                                                                                                              |
+| _Model training parameters_                                    |                               |                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| freqai.model_training_parameters.gpu_vram_gb                   | 80                            | enum {8,10,12,16,24,32,40,48,64,80}                                                                                                          | GPU VRAM capacity (GB) for CatBoost. Constrains `depth`, `border_count`, and `max_ctr_complexity` ranges to fit memory.                                                                                                                                                                                                                                                                                                                                                            |
 | _Data split parameters_                                        |                               |                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
 | freqai.data_split_parameters.method                            | `train_test_split`            | enum {`train_test_split`,`timeseries_split`}                                                                                                 | Data splitting strategy. `train_test_split` for sequential split, `timeseries_split` for chronological split with configurable gap.                                                                                                                                                                                                                                                                                                                                                |
 | freqai.data_split_parameters.test_size                         | 0.1 / None                    | float (0,1) \| int >= 1 \| None                                                                                                              | Test set size. Float for fraction, int for count. Default: 0.1 for `train_test_split`, None for `timeseries_split` (sklearn dynamic sizing).                                                                                                                                                                                                                                                                                                                                       |
index d428194a3d91f0e2a5411ec0a950d27dc0a0c1f4..c1d08a7d1135d14e1e5458675c47dd2480352d79 100644 (file)
@@ -96,7 +96,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     https://github.com/sponsors/robcaulk
     """
 
-    version = "3.11.2"
+    version = "3.11.3"
 
     _TEST_SIZE: Final[float] = 0.1
 
index 789bd9cf8a22e4d9152164d9fe726da7b4f1a87a..d40dc6948680f21d29ba601f231993f06dc06402 100644 (file)
@@ -109,7 +109,7 @@ class QuickAdapterV3(IStrategy):
     _PLOT_EXTREMA_MIN_EPS: Final[float] = 0.01
 
     def version(self) -> str:
-        return "3.11.2"
+        return "3.11.3"
 
     timeframe = "5m"
     timeframe_minutes = timeframe_to_minutes(timeframe)
index 4f04d08969424bd161f0cd6f07fa6c78dab99d1f..598cda3631dbd9e586f0875836bb1177ad9ea5b5 100644 (file)
@@ -2129,6 +2129,23 @@ _CATBOOST_GPU_PAIRWISE_LOSS_FUNCTIONS: Final[tuple[str, ...]] = (
     "QueryCrossEntropy",
 )
 
+# CatBoost GPU param ranges keyed by VRAM capacity (GB).
+# Formula: VRAM_MB = 58778 * 2^(depth-12) * (border_count+1) / 256
+_CATBOOST_GPU_VRAM_PARAM_RANGES: Final[dict[int, dict[str, tuple[int, int]]]] = {
+    8: {"depth": (4, 9), "border_count": (32, 192), "max_ctr_complexity": (1, 4)},
+    10: {"depth": (4, 9), "border_count": (32, 255), "max_ctr_complexity": (1, 4)},
+    12: {"depth": (4, 10), "border_count": (32, 160), "max_ctr_complexity": (1, 4)},
+    16: {"depth": (4, 10), "border_count": (32, 224), "max_ctr_complexity": (1, 5)},
+    24: {"depth": (4, 10), "border_count": (32, 255), "max_ctr_complexity": (1, 5)},
+    32: {"depth": (4, 11), "border_count": (32, 192), "max_ctr_complexity": (1, 5)},
+    40: {"depth": (4, 11), "border_count": (32, 255), "max_ctr_complexity": (1, 6)},
+    48: {"depth": (4, 11), "border_count": (32, 255), "max_ctr_complexity": (1, 6)},
+    64: {"depth": (4, 12), "border_count": (32, 192), "max_ctr_complexity": (1, 6)},
+    80: {"depth": (4, 12), "border_count": (32, 255), "max_ctr_complexity": (1, 6)},
+}
+
+_CATBOOST_GPU_VRAM_DEFAULT: Final[int] = 80
+
 
 def get_ngboost_dist(dist_name: str) -> type:
     from ngboost.distns import Exponential, Laplace, LogNormal, Normal, T
@@ -2397,8 +2414,9 @@ def fit_regressor(
         task_type = model_training_parameters.get("task_type", "CPU")
         loss_function = model_training_parameters.get("loss_function", "RMSE")
         if task_type == "GPU":
-            model_training_parameters.setdefault("max_ctr_complexity", 4)
+            model_training_parameters.pop("gpu_vram_gb", None)
             model_training_parameters.pop("n_jobs", None)
+            model_training_parameters.setdefault("max_ctr_complexity", 4)
             if loss_function not in _CATBOOST_GPU_RSM_LOSS_FUNCTIONS:
                 model_training_parameters.pop("rsm", None)
         else:
@@ -2962,26 +2980,30 @@ def get_optuna_study_model_parameters(
         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 = 12
-        else:  # CPU
-            max_depth = 10
-
         if task_type == "GPU":
+            gpu_vram_gb = model_training_parameters.get(
+                "gpu_vram_gb", _CATBOOST_GPU_VRAM_DEFAULT
+            )
+            matched_vram_gb = max(
+                (v for v in _CATBOOST_GPU_VRAM_PARAM_RANGES if v <= gpu_vram_gb),
+                default=min(_CATBOOST_GPU_VRAM_PARAM_RANGES.keys()),
+            )
+            param_ranges = _CATBOOST_GPU_VRAM_PARAM_RANGES[matched_vram_gb]
+
+            if loss_function in _CATBOOST_GPU_PAIRWISE_LOSS_FUNCTIONS:
+                max_depth = min(8, param_ranges["depth"][1])
+            else:
+                max_depth = param_ranges["depth"][1]
+
             default_ranges: dict[str, tuple[float, float]] = {
                 # Boosting/Training
                 "iterations": (100, 2000),
                 "learning_rate": (0.001, 0.3),
                 # Tree structure
-                "depth": (4, max_depth),
+                "depth": (param_ranges["depth"][0], max_depth),
                 "min_data_in_leaf": (1, 20),
-                "border_count": (128, 255),
-                "max_ctr_complexity": (2, 6),
+                "border_count": param_ranges["border_count"],
+                "max_ctr_complexity": param_ranges["max_ctr_complexity"],
                 # Regularization
                 "l2_leaf_reg": (1, 10),
                 "model_size_reg": (0.0, 1.0),
@@ -2999,7 +3021,7 @@ def get_optuna_study_model_parameters(
                 "iterations": (100, 2000),
                 "learning_rate": (0.001, 0.3),
                 # Tree structure
-                "depth": (4, max_depth),
+                "depth": (4, 10),
                 "min_data_in_leaf": (1, 20),
                 # Regularization
                 "l2_leaf_reg": (1, 10),