Spaces:
Sleeping
Sleeping
Commit
·
1a758de
1
Parent(s):
513cd3c
maj
Browse files- src/base_trainer.py +12 -3
- src/cuml_trainer.py +9 -3
- src/main.py +18 -19
- src/mlflow_integration/mlflow_decorator.py +1 -1
- src/trainers/cuml/linear_regression_trainer.py +4 -2
- src/trainers/cuml/logistic_regression_trainer.py +4 -2
- src/trainers/cuml/random_forest_trainer.py +4 -2
- src/trainers/cuml/svm_trainer.py +4 -2
- src/trainers/huggingface/huggingface_transformer_trainer.py +5 -2
src/base_trainer.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
# =========================
|
4 |
|
5 |
from abc import ABC, abstractmethod
|
6 |
-
from typing import Union, Optional
|
7 |
import cupy as cp
|
8 |
from scipy.sparse import csr_matrix
|
9 |
|
@@ -55,10 +55,12 @@ class BaseTrainer(ABC):
|
|
55 |
pass
|
56 |
|
57 |
@abstractmethod
|
58 |
-
def evaluate(self) ->
|
59 |
"""
|
60 |
Méthode abstraite. Évalue le modèle entraîné, par exemple
|
61 |
sur un jeu de validation ou de test, et calcule les métriques.
|
|
|
|
|
62 |
"""
|
63 |
pass
|
64 |
|
@@ -114,7 +116,14 @@ class BaseTrainer(ABC):
|
|
114 |
Implementé ici en tant que méthode non-abstraite, mais la logique de logging
|
115 |
devrait être assurée dans l'environnement MLflow approprié.
|
116 |
"""
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
def _prepare_input_for_fit(
|
120 |
self, X: Union[cp.ndarray,
|
|
|
3 |
# =========================
|
4 |
|
5 |
from abc import ABC, abstractmethod
|
6 |
+
from typing import Union, Optional
|
7 |
import cupy as cp
|
8 |
from scipy.sparse import csr_matrix
|
9 |
|
|
|
55 |
pass
|
56 |
|
57 |
@abstractmethod
|
58 |
+
def evaluate(self) -> dict:
|
59 |
"""
|
60 |
Méthode abstraite. Évalue le modèle entraîné, par exemple
|
61 |
sur un jeu de validation ou de test, et calcule les métriques.
|
62 |
+
|
63 |
+
:return: Dictionnaire contenant les métriques calculées.
|
64 |
"""
|
65 |
pass
|
66 |
|
|
|
116 |
Implementé ici en tant que méthode non-abstraite, mais la logique de logging
|
117 |
devrait être assurée dans l'environnement MLflow approprié.
|
118 |
"""
|
119 |
+
import mlflow
|
120 |
+
# Logue les paramètres du config.model
|
121 |
+
if self.config.model.params:
|
122 |
+
mlflow.log_params(self.config.model.params)
|
123 |
+
|
124 |
+
# Logue aussi les hyperparamètres du classifieur s'il offre get_params()
|
125 |
+
if self.classifier and hasattr(self.classifier, "get_params"):
|
126 |
+
mlflow.log_params(self.classifier.get_params())
|
127 |
|
128 |
def _prepare_input_for_fit(
|
129 |
self, X: Union[cp.ndarray,
|
src/cuml_trainer.py
CHANGED
@@ -57,7 +57,9 @@ class CuMLTrainer(BaseTrainer, ABC):
|
|
57 |
data = cudf.read_csv(self.data_path)
|
58 |
|
59 |
# Séparation des textes et des étiquettes
|
60 |
-
|
|
|
|
|
61 |
labels = data[self.target_column].values
|
62 |
|
63 |
# Vectorisation des textes
|
@@ -66,7 +68,7 @@ class CuMLTrainer(BaseTrainer, ABC):
|
|
66 |
# Entraînement du modèle
|
67 |
self.classifier.fit(X_prepared, labels)
|
68 |
|
69 |
-
def evaluate(self) ->
|
70 |
"""
|
71 |
Évalue le classifieur et calcule les métriques.
|
72 |
Cette implémentation générique fonctionne pour tous les trainers cuML.
|
@@ -75,7 +77,9 @@ class CuMLTrainer(BaseTrainer, ABC):
|
|
75 |
data = cudf.read_csv(self.data_path)
|
76 |
|
77 |
# Séparation des textes et des étiquettes
|
78 |
-
|
|
|
|
|
79 |
y_true = data[self.target_column].values
|
80 |
|
81 |
# Vectorisation et prédiction
|
@@ -93,6 +97,8 @@ class CuMLTrainer(BaseTrainer, ABC):
|
|
93 |
|
94 |
# Afficher les résultats
|
95 |
print(f"Métriques d'évaluation {prefix}: {metrics}")
|
|
|
|
|
96 |
|
97 |
def _prepare_input_for_fit(self, X: Union[cp.ndarray,
|
98 |
csr_matrix]) -> cp.ndarray:
|
|
|
57 |
data = cudf.read_csv(self.data_path)
|
58 |
|
59 |
# Séparation des textes et des étiquettes
|
60 |
+
# Supposons que la colonne de texte est la première colonne qui n'est pas la colonne cible
|
61 |
+
text_column = [col for col in data.columns if col != self.target_column][0]
|
62 |
+
texts = data[text_column] # Extraire la série de texte
|
63 |
labels = data[self.target_column].values
|
64 |
|
65 |
# Vectorisation des textes
|
|
|
68 |
# Entraînement du modèle
|
69 |
self.classifier.fit(X_prepared, labels)
|
70 |
|
71 |
+
def evaluate(self) -> dict:
|
72 |
"""
|
73 |
Évalue le classifieur et calcule les métriques.
|
74 |
Cette implémentation générique fonctionne pour tous les trainers cuML.
|
|
|
77 |
data = cudf.read_csv(self.data_path)
|
78 |
|
79 |
# Séparation des textes et des étiquettes
|
80 |
+
# Supposons que la colonne de texte est la première colonne qui n'est pas la colonne cible
|
81 |
+
text_column = [col for col in data.columns if col != self.target_column][0]
|
82 |
+
texts = data[text_column] # Extraire la série de texte
|
83 |
y_true = data[self.target_column].values
|
84 |
|
85 |
# Vectorisation et prédiction
|
|
|
97 |
|
98 |
# Afficher les résultats
|
99 |
print(f"Métriques d'évaluation {prefix}: {metrics}")
|
100 |
+
|
101 |
+
return metrics
|
102 |
|
103 |
def _prepare_input_for_fit(self, X: Union[cp.ndarray,
|
104 |
csr_matrix]) -> cp.ndarray:
|
src/main.py
CHANGED
@@ -24,6 +24,7 @@ from mlflow_integration.mlflow_decorator import MLflowDecorator
|
|
24 |
|
25 |
# Import de la configuration
|
26 |
from config import Config
|
|
|
27 |
|
28 |
# Configuration du logging
|
29 |
logger = logging.getLogger(__name__)
|
@@ -40,7 +41,7 @@ def get_trainer(config: Config):
|
|
40 |
Une instance concrète de BaseTrainer
|
41 |
"""
|
42 |
model_type = config.model.type.lower()
|
43 |
-
|
44 |
# Mapping des types de modèles vers leurs trainers
|
45 |
trainer_map = {
|
46 |
"svm": SvmTrainer,
|
@@ -49,10 +50,10 @@ def get_trainer(config: Config):
|
|
49 |
"linear_regression": LinearRegressionTrainer,
|
50 |
"transformer": HuggingFaceTransformerTrainer,
|
51 |
}
|
52 |
-
|
53 |
if model_type not in trainer_map:
|
54 |
raise ValueError(f"Type de modèle non supporté: {model_type}")
|
55 |
-
|
56 |
# Création de l'instance du trainer avec la configuration
|
57 |
trainer_class = trainer_map[model_type]
|
58 |
return trainer_class(
|
@@ -73,16 +74,16 @@ def get_optimizer(config: Config):
|
|
73 |
Une instance concrète de HyperparameterOptimizer
|
74 |
"""
|
75 |
optimizer_type = config.hyperparameters.optimizer.lower()
|
76 |
-
|
77 |
# Mapping des types d'optimizers
|
78 |
optimizer_map = {
|
79 |
"optuna": OptunaOptimizer,
|
80 |
"raytune": RayTuneOptimizer,
|
81 |
}
|
82 |
-
|
83 |
if optimizer_type not in optimizer_map:
|
84 |
raise ValueError(f"Type d'optimizer non supporté: {optimizer_type}")
|
85 |
-
|
86 |
# Création de l'instance de l'optimizer
|
87 |
optimizer_class = optimizer_map[optimizer_type]
|
88 |
return optimizer_class()
|
@@ -99,16 +100,17 @@ def main(cfg: DictConfig) -> None:
|
|
99 |
# Conversion de la configuration Hydra en configuration Pydantic
|
100 |
config_dict = OmegaConf.to_container(cfg, resolve=True)
|
101 |
config = Config(**config_dict)
|
102 |
-
|
103 |
logger.info(f"Configuration chargée: {config}")
|
104 |
-
|
105 |
# Création du trainer approprié
|
106 |
trainer = get_trainer(config)
|
107 |
-
|
108 |
# Construction des composants (vectorizer, classifier, etc.)
|
109 |
trainer.build_components()
|
110 |
-
|
111 |
-
|
|
|
112 |
mlflow_decorator = MLflowDecorator(
|
113 |
experiment_name=config.mlflow.experiment_name,
|
114 |
tracking_uri=config.mlflow.tracking_uri
|
@@ -117,23 +119,20 @@ def main(cfg: DictConfig) -> None:
|
|
117 |
train_with_mlflow = mlflow_decorator(trainer.train)
|
118 |
evaluate_with_mlflow = mlflow_decorator(trainer.evaluate)
|
119 |
log_params_with_mlflow = mlflow_decorator(trainer.log_parameters_to_mlflow)
|
120 |
-
optimize_if_needed_with_mlflow = mlflow_decorator(trainer.optimize_if_needed)
|
121 |
-
|
122 |
logger.info("Vérification et lancement de l'optimisation des hyperparamètres si nécessaire (avec MLflow)...")
|
123 |
optimize_if_needed_with_mlflow()
|
124 |
-
|
125 |
-
# Exécuter l'entraînement (toujours avec MLflow)
|
126 |
logger.info("Lancement de l'entraînement avec MLflow...")
|
127 |
train_with_mlflow()
|
128 |
-
|
129 |
-
# Exécuter l'évaluation (toujours avec MLflow)
|
130 |
logger.info("Lancement de l'évaluation avec MLflow...")
|
131 |
evaluate_with_mlflow()
|
132 |
|
133 |
-
# Logger les paramètres (toujours avec MLflow)
|
134 |
logger.info("Logging des paramètres avec MLflow...")
|
135 |
log_params_with_mlflow()
|
136 |
-
|
137 |
logger.info("Entraînement, évaluation et logging des paramètres terminés avec succès via MLflow.")
|
138 |
|
139 |
|
|
|
24 |
|
25 |
# Import de la configuration
|
26 |
from config import Config
|
27 |
+
import mlflow
|
28 |
|
29 |
# Configuration du logging
|
30 |
logger = logging.getLogger(__name__)
|
|
|
41 |
Une instance concrète de BaseTrainer
|
42 |
"""
|
43 |
model_type = config.model.type.lower()
|
44 |
+
|
45 |
# Mapping des types de modèles vers leurs trainers
|
46 |
trainer_map = {
|
47 |
"svm": SvmTrainer,
|
|
|
50 |
"linear_regression": LinearRegressionTrainer,
|
51 |
"transformer": HuggingFaceTransformerTrainer,
|
52 |
}
|
53 |
+
|
54 |
if model_type not in trainer_map:
|
55 |
raise ValueError(f"Type de modèle non supporté: {model_type}")
|
56 |
+
|
57 |
# Création de l'instance du trainer avec la configuration
|
58 |
trainer_class = trainer_map[model_type]
|
59 |
return trainer_class(
|
|
|
74 |
Une instance concrète de HyperparameterOptimizer
|
75 |
"""
|
76 |
optimizer_type = config.hyperparameters.optimizer.lower()
|
77 |
+
|
78 |
# Mapping des types d'optimizers
|
79 |
optimizer_map = {
|
80 |
"optuna": OptunaOptimizer,
|
81 |
"raytune": RayTuneOptimizer,
|
82 |
}
|
83 |
+
|
84 |
if optimizer_type not in optimizer_map:
|
85 |
raise ValueError(f"Type d'optimizer non supporté: {optimizer_type}")
|
86 |
+
|
87 |
# Création de l'instance de l'optimizer
|
88 |
optimizer_class = optimizer_map[optimizer_type]
|
89 |
return optimizer_class()
|
|
|
100 |
# Conversion de la configuration Hydra en configuration Pydantic
|
101 |
config_dict = OmegaConf.to_container(cfg, resolve=True)
|
102 |
config = Config(**config_dict)
|
103 |
+
|
104 |
logger.info(f"Configuration chargée: {config}")
|
105 |
+
|
106 |
# Création du trainer approprié
|
107 |
trainer = get_trainer(config)
|
108 |
+
|
109 |
# Construction des composants (vectorizer, classifier, etc.)
|
110 |
trainer.build_components()
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
mlflow_decorator = MLflowDecorator(
|
115 |
experiment_name=config.mlflow.experiment_name,
|
116 |
tracking_uri=config.mlflow.tracking_uri
|
|
|
119 |
train_with_mlflow = mlflow_decorator(trainer.train)
|
120 |
evaluate_with_mlflow = mlflow_decorator(trainer.evaluate)
|
121 |
log_params_with_mlflow = mlflow_decorator(trainer.log_parameters_to_mlflow)
|
122 |
+
optimize_if_needed_with_mlflow = mlflow_decorator(trainer.optimize_if_needed)
|
123 |
+
|
124 |
logger.info("Vérification et lancement de l'optimisation des hyperparamètres si nécessaire (avec MLflow)...")
|
125 |
optimize_if_needed_with_mlflow()
|
126 |
+
|
|
|
127 |
logger.info("Lancement de l'entraînement avec MLflow...")
|
128 |
train_with_mlflow()
|
129 |
+
|
|
|
130 |
logger.info("Lancement de l'évaluation avec MLflow...")
|
131 |
evaluate_with_mlflow()
|
132 |
|
|
|
133 |
logger.info("Logging des paramètres avec MLflow...")
|
134 |
log_params_with_mlflow()
|
135 |
+
|
136 |
logger.info("Entraînement, évaluation et logging des paramètres terminés avec succès via MLflow.")
|
137 |
|
138 |
|
src/mlflow_integration/mlflow_decorator.py
CHANGED
@@ -36,7 +36,7 @@ class MLflowDecorator:
|
|
36 |
def wrapper(*args, **kwargs):
|
37 |
mlflow.set_tracking_uri(self.tracking_uri)
|
38 |
mlflow.set_experiment(self.experiment_name)
|
39 |
-
with mlflow.start_run():
|
40 |
result = func(*args, **kwargs)
|
41 |
return result
|
42 |
|
|
|
36 |
def wrapper(*args, **kwargs):
|
37 |
mlflow.set_tracking_uri(self.tracking_uri)
|
38 |
mlflow.set_experiment(self.experiment_name)
|
39 |
+
with mlflow.start_run(log_system_metrics=True):
|
40 |
result = func(*args, **kwargs)
|
41 |
return result
|
42 |
|
src/trainers/cuml/linear_regression_trainer.py
CHANGED
@@ -68,13 +68,15 @@ class LinearRegressionTrainer(CuMLTrainer):
|
|
68 |
# Inheriting from CuMLTrainer => loads data, vectorizes, fits
|
69 |
super().train()
|
70 |
|
71 |
-
def evaluate(self) ->
|
72 |
"""
|
73 |
Évalue le classifieur LinearRegression et calcule les métriques appropriées.
|
74 |
|
75 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
76 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
77 |
et du calcul des métriques via le metrics_calculator.
|
|
|
|
|
78 |
"""
|
79 |
# Inheriting from CuMLTrainer => loads data, vectorizes, calls the metrics calculator
|
80 |
-
super().evaluate()
|
|
|
68 |
# Inheriting from CuMLTrainer => loads data, vectorizes, fits
|
69 |
super().train()
|
70 |
|
71 |
+
def evaluate(self) -> dict:
|
72 |
"""
|
73 |
Évalue le classifieur LinearRegression et calcule les métriques appropriées.
|
74 |
|
75 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
76 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
77 |
et du calcul des métriques via le metrics_calculator.
|
78 |
+
|
79 |
+
:return: Dictionnaire contenant les métriques calculées.
|
80 |
"""
|
81 |
# Inheriting from CuMLTrainer => loads data, vectorizes, calls the metrics calculator
|
82 |
+
return super().evaluate()
|
src/trainers/cuml/logistic_regression_trainer.py
CHANGED
@@ -67,12 +67,14 @@ class LogisticRegressionTrainer(CuMLTrainer):
|
|
67 |
"""
|
68 |
super().train()
|
69 |
|
70 |
-
def evaluate(self) ->
|
71 |
"""
|
72 |
Évalue le classifieur LogisticRegression et calcule les métriques appropriées.
|
73 |
|
74 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
75 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
76 |
et du calcul des métriques via le metrics_calculator.
|
|
|
|
|
77 |
"""
|
78 |
-
super().evaluate()
|
|
|
67 |
"""
|
68 |
super().train()
|
69 |
|
70 |
+
def evaluate(self) -> dict:
|
71 |
"""
|
72 |
Évalue le classifieur LogisticRegression et calcule les métriques appropriées.
|
73 |
|
74 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
75 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
76 |
et du calcul des métriques via le metrics_calculator.
|
77 |
+
|
78 |
+
:return: Dictionnaire contenant les métriques calculées.
|
79 |
"""
|
80 |
+
return super().evaluate()
|
src/trainers/cuml/random_forest_trainer.py
CHANGED
@@ -70,15 +70,17 @@ class RandomForestTrainer(CuMLTrainer):
|
|
70 |
"""
|
71 |
super().train()
|
72 |
|
73 |
-
def evaluate(self) ->
|
74 |
"""
|
75 |
Évalue le classifieur RandomForest et calcule les métriques appropriées.
|
76 |
|
77 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
78 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
79 |
et du calcul des métriques via le metrics_calculator.
|
|
|
|
|
80 |
"""
|
81 |
-
super().evaluate()
|
82 |
|
83 |
def _get_binary_predictions(self, X: cp.ndarray) -> cp.ndarray:
|
84 |
"""
|
|
|
70 |
"""
|
71 |
super().train()
|
72 |
|
73 |
+
def evaluate(self) -> dict:
|
74 |
"""
|
75 |
Évalue le classifieur RandomForest et calcule les métriques appropriées.
|
76 |
|
77 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
78 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
79 |
et du calcul des métriques via le metrics_calculator.
|
80 |
+
|
81 |
+
:return: Dictionnaire contenant les métriques calculées.
|
82 |
"""
|
83 |
+
return super().evaluate()
|
84 |
|
85 |
def _get_binary_predictions(self, X: cp.ndarray) -> cp.ndarray:
|
86 |
"""
|
src/trainers/cuml/svm_trainer.py
CHANGED
@@ -70,15 +70,17 @@ class SvmTrainer(CuMLTrainer):
|
|
70 |
"""
|
71 |
super().train()
|
72 |
|
73 |
-
def evaluate(self) ->
|
74 |
"""
|
75 |
Évalue le classifieur SVC et calcule les métriques appropriées.
|
76 |
|
77 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
78 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
79 |
et du calcul des métriques via le metrics_calculator.
|
|
|
|
|
80 |
"""
|
81 |
-
super().evaluate()
|
82 |
|
83 |
def _get_binary_predictions(self, X: cp.ndarray) -> cp.ndarray:
|
84 |
"""
|
|
|
70 |
"""
|
71 |
super().train()
|
72 |
|
73 |
+
def evaluate(self) -> dict:
|
74 |
"""
|
75 |
Évalue le classifieur SVC et calcule les métriques appropriées.
|
76 |
|
77 |
Utilise l'implémentation fournie par la classe parente CuMLTrainer,
|
78 |
qui s'occupe du chargement des données, de la vectorisation, de la prédiction
|
79 |
et du calcul des métriques via le metrics_calculator.
|
80 |
+
|
81 |
+
:return: Dictionnaire contenant les métriques calculées.
|
82 |
"""
|
83 |
+
return super().evaluate()
|
84 |
|
85 |
def _get_binary_predictions(self, X: cp.ndarray) -> cp.ndarray:
|
86 |
"""
|
src/trainers/huggingface/huggingface_transformer_trainer.py
CHANGED
@@ -62,12 +62,15 @@ class HuggingFaceTransformerTrainer(BaseTrainer):
|
|
62 |
"""
|
63 |
pass
|
64 |
|
65 |
-
def evaluate(self) ->
|
66 |
"""
|
67 |
Évalue le modèle Hugging Face; la logique de calcul
|
68 |
des métriques est en partie assurée par le HF Trainer.
|
|
|
|
|
69 |
"""
|
70 |
-
|
|
|
71 |
|
72 |
def _create_torch_dataset(self, texts: cudf.Series,
|
73 |
labels: cp.ndarray) -> torch.utils.data.Dataset:
|
|
|
62 |
"""
|
63 |
pass
|
64 |
|
65 |
+
def evaluate(self) -> dict:
|
66 |
"""
|
67 |
Évalue le modèle Hugging Face; la logique de calcul
|
68 |
des métriques est en partie assurée par le HF Trainer.
|
69 |
+
|
70 |
+
:return: Dictionnaire contenant les métriques calculées.
|
71 |
"""
|
72 |
+
# À implémenter
|
73 |
+
return {}
|
74 |
|
75 |
def _create_torch_dataset(self, texts: cudf.Series,
|
76 |
labels: cp.ndarray) -> torch.utils.data.Dataset:
|