Spaces:
Sleeping
Sleeping
File size: 6,802 Bytes
bf5fb5f 47d1597 bf5fb5f 47d1597 8ffb539 47d1597 bf5fb5f 1a758de bf5fb5f ef3b361 bf5fb5f 1a758de bf5fb5f 1a758de bf5fb5f 1a758de bf5fb5f 1a758de 47d1597 bf5fb5f 43d4438 bf5fb5f ed87211 1a758de 47d1597 1a758de 47d1597 bf5fb5f 1a758de ed87211 47d1597 ed87211 47d1597 1a758de 2e5a32e 1a758de 47d1597 2e5a32e 47d1597 ed87211 47d1597 bf5fb5f 1a758de ed87211 bf5fb5f 43d4438 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
#!/usr/bin/env python3
# =========================
# Fichier: main.py
# =========================
import os
import logging
import hydra
import mlflow
from omegaconf import DictConfig, OmegaConf
from config import Config
from trainers.cuml.svm_trainer import SvmTrainer
from trainers.cuml.random_forest_trainer import RandomForestTrainer
from trainers.cuml.logistic_regression_trainer import LogisticRegressionTrainer
from trainers.cuml.linear_regression_trainer import LinearRegressionTrainer
from trainers.huggingface.huggingface_transformer_trainer import HuggingFaceTransformerTrainer
from optimizers.optuna_optimizer import OptunaOptimizer
from optimizers.ray_tune_optimizer import RayTuneOptimizer
from mlflow_integration.mlflow_decorator import MLflowDecorator
import tempfile
import pickle
import pandas as pd
from utilities.cuml_pyfunc_wrapper import CuMLPyFuncWrapper
logger = logging.getLogger(__name__)
def get_trainer(config: Config):
"""
Crée et retourne l'instance du trainer approprié en fonction de la configuration.
"""
model_type = config.model.type.lower()
# Mapping des types de modèles vers leurs trainers
trainer_map = {
"svm": SvmTrainer,
"random_forest": RandomForestTrainer,
"logistic_regression": LogisticRegressionTrainer,
"linear_regression": LinearRegressionTrainer,
"transformer": HuggingFaceTransformerTrainer,
"bert": HuggingFaceTransformerTrainer,
"roberta": HuggingFaceTransformerTrainer,
}
if model_type not in trainer_map:
raise ValueError(f"Type de modèle non supporté: {model_type}")
trainer_class = trainer_map[model_type]
return trainer_class(
config=config,
data_path=config.data.path,
target_column=config.data.target_column
)
def get_optimizer(config: Config):
"""
Crée et retourne l'instance d'optimizer appropriée en fonction de la configuration.
"""
optimizer_type = config.hyperparameters.optimizer.lower()
optimizer_map = {
"optuna": OptunaOptimizer,
"raytune": RayTuneOptimizer,
}
if optimizer_type not in optimizer_map:
raise ValueError(f"Type d'optimizer non supporté: {optimizer_type}")
return optimizer_map[optimizer_type]()
def log_cuml_model_to_mlflow(trainer_instance, run_id=None):
"""
Sérialise le vectorizer et le classifier dans un répertoire temporaire
puis log le tout dans MLflow en tant que modèle PyFunc.
Les artifacts sont ainsi stockés dans mlruns, liés au run en cours.
"""
logger.info("Logging du modèle CuML via mlflow.pyfunc.log_model...")
input_example = pd.DataFrame({"example_text": ["exemple"]})
# On va utiliser mlflow.pyfunc.log_model pour stocker le wrapper PyFunc + nos artifacts
with tempfile.TemporaryDirectory() as tmpdir:
vectorizer_path = os.path.join(tmpdir, "vectorizer.pkl")
classifier_path = os.path.join(tmpdir, "classifier.pkl")
# Sauvegarde sur disque
with open(vectorizer_path, "wb") as vf:
pickle.dump(trainer_instance.vectorizer, vf)
with open(classifier_path, "wb") as cf:
pickle.dump(trainer_instance.classifier, cf)
# PyFunc wrapper (placeholder, héberge la logique de load_model)
pyfunc_wrapper = CuMLPyFuncWrapper(
vectorizer=None,
classifier=None
)
# Log en PyFunc; "cuml_model" est le chemin (artifact_path) où sera stocké le modèle dans MLflow
mlflow.pyfunc.log_model(
artifact_path="cuml_model",
python_model=pyfunc_wrapper,
artifacts={
"vectorizer": vectorizer_path,
"classifier": classifier_path
},
input_example=input_example
)
logger.info("Le modèle et ses artifacts ont été enregistrés dans MLflow.")
@hydra.main(config_path="conf", config_name="config", version_base=None)
def main(cfg: DictConfig) -> None:
"""
Point d'entrée principal de l'application.
"""
try:
config = Config(**OmegaConf.to_container(cfg, resolve=True))
except Exception as e:
logger.error(f"Erreur lors de la validation Pydantic de la configuration: {e}")
logger.error(f"Configuration après fusion Hydra: \n{OmegaConf.to_yaml(cfg)}")
raise
logger.info(f"Configuration Pydantic finale chargée: {config}")
# Sélection du tracker MLflow
mlflow.set_tracking_uri(config.mlflow.tracking_uri)
trainer = get_trainer(config)
trainer.build_components()
def run_pipeline(trainer_instance):
"""
Exécute la séquence complète :
- Optimisation hyperparamètres (si besoin)
- Entraînement
- Évaluation
- Logging MLflow (paramètres, métriques, et modèles)
"""
logger.info("Vérification et lancement de l'optimisation des hyperparamètres si nécessaire...")
trainer_instance.optimize_if_needed()
logger.info("Lancement de l'entraînement...")
trainer_instance.train()
logger.info("Lancement de l'évaluation...")
metrics = trainer_instance.evaluate()
logger.info(f"Metrics calculés: {metrics}")
# Log des métriques
mlflow.log_metrics(metrics)
# Log des paramètres uniquement si ce n'est pas un trainer Hugging Face
# car le Trainer HF logue déjà ses propres paramètres (TrainingArguments)
if not isinstance(trainer_instance, HuggingFaceTransformerTrainer):
logger.info("Logging des paramètres...")
trainer_instance.log_parameters_to_mlflow()
else:
logger.info("Logging des paramètres désactivé pour HuggingFaceTransformerTrainer (géré par HF Trainer).")
# Log du modèle final (vectorizer+classifier) sous forme PyFunc
# Note: Cette fonction est spécifique aux modèles cuML pour le moment
if hasattr(trainer_instance, 'vectorizer') and trainer_instance.vectorizer is not None:
log_cuml_model_to_mlflow(trainer_instance)
else:
logger.info("Logging du modèle PyFunc non applicable pour ce type de trainer.")
logger.info("Pipeline MLflow complet terminé.")
# On utilise un décorateur défini pour centraliser le démarrage/arrêt du run
mlflow_decorator = MLflowDecorator(
experiment_name=config.mlflow.experiment_name,
tracking_uri=config.mlflow.tracking_uri
)
run_pipeline_with_mlflow = mlflow_decorator(run_pipeline)
logger.info("Lancement du pipeline complet avec MLflow...")
run_pipeline_with_mlflow(trainer)
logger.info("Pipeline MLflow terminé avec succès.")
if __name__ == "__main__":
main()
|