Chronos-2, le modèle de séries temporelles d’Amazon, peut être boosté grâce au fine-tuning. Découvrez 5 méthodes pour l’adapter à vos données, avec des exemples de code et des résultats concrets.
CHRONOS-2 : LE MODÈLE QUI COMPREND LES SÉRIES TEMPORELLES
Imaginez un modèle capable de prédire la consommation électrique d’un bâtiment sans aucune formation. C’est exactement ce que fait Chronos-2, un modèle de fondation pour les séries temporelles développé par Amazon. Dans la première partie de cette série, nous avions vu comment l’utiliser directement, avec des résultats impressionnants dès le départ. Mais parfois, une simple prédiction « zero-shot » (sans entraînement) ne suffit pas.
C’est là que le fine-tuning entre en jeu. Cette technique permet d’adapter le modèle à vos données spécifiques, pour obtenir des prévisions encore plus précises. Dans cet article, nous explorons cinq scénarios de fine-tuning pour Chronos-2, avec des exemples concrets et du code prêt à l’emploi.
POURQUOI LE FINE-TUNING EST-IL INDISPENSABLE ?
Le fine-tuning, c’est comme apprendre à un expert en météo à prévoir le temps dans votre ville. Même s’il connaît déjà les mécanismes généraux, il doit s’adapter aux particularités locales (le vent, l’humidité, les microclimats) pour être vraiment efficace. Avec Chronos-2, c’est la même chose : le modèle a déjà appris des structures générales sur des milliers de séries temporelles, mais il doit affiner ses prévisions pour coller à vos données.
Prenons un exemple concret : prédire la consommation électrique d’un bâtiment. Chronos-2 peut déjà donner une estimation correcte, mais si vous avez des données historiques précises, le fine-tuning permet de réduire les erreurs de moitié dans certains cas. Le gain est énorme, surtout pour des applications critiques comme la gestion énergétique ou la maintenance prédictive.
LORA : LA TECHNIQUE QUI REND LE FINE-TUNING POSSIBLE
Fine-tuner un modèle comme Chronos-2 (qui compte 120 millions de paramètres) peut coûter cher en calcul et en stockage. Heureusement, il existe une astuce : LoRA, ou Low-Rank Adaptation. Au lieu de modifier tous les paramètres du modèle, LoRA ajoute une petite couche d’adaptation qui ne pèse presque rien.
Voici comment ça marche : imaginons une couche du modèle avec une matrice de poids de 1024x1024. Pour la mettre à jour entièrement, il faudrait ajuster plus d’un million de paramètres. LoRA, lui, décompose cette mise à jour en deux petites matrices (par exemple, 8x1024 et 1024x8). Résultat : seulement 16 384 paramètres à ajuster au lieu d’un million .
Cette méthode a trois avantages majeurs :
- ↓ Moins de mémoire GPU utilisée (les gradients et états de l’optimiseur prennent moins de place).
- ↓ Des sauvegardes plus légères (on ne stocke que l’adaptateur, pas le modèle complet).
- ↓ Moins de risque de surapprentissage, surtout si vos données sont limitées.
CONFIGURER LORA POUR CHRONOS-2 : QUELLES COUCHES ADAPTER ?
Chronos-2 est un Transformer (un type de réseau de neurones très utilisé en IA), organisé en trois blocs principaux. Pour le fine-tuner avec LoRA, on se concentre sur deux de ces blocs :
- Les couches d’attention (qui analysent les relations entre les données temporelles).
- La couche de patch embedding (qui transforme les données brutes en représentations compréhensibles par le modèle).
Voici la configuration LoRA utilisée dans tous les scénarios de cet article :
LORA_CONFIG = {
"r": 8,
"lora_alpha": 16,
"target_modules": [
"self_attention.q",
"self_attention.v",
"self_attention.k",
"self_attention.o",
"outputpatchembedding.output_layer",
],
}
Ici, r=8 signifie que les matrices d’adaptation ont une taille de 8. Le paramètre lora_alpha=16 contrôle l’intensité de l’adaptation : plus il est élevé, plus le modèle s’éloigne de son état initial. Enfin, target_modules liste les couches à adapter.
SCÉNARIO 1 : FINE-TUNING SUR UN SEUL BÂTIMENT (UNIVARIÉ)
Première méthode : adapter Chronos-2 à un seul bâtiment. Imaginons que vous gérez un immeuble de bureaux et que vous avez des années de données sur sa consommation électrique. L’objectif ? Prédire sa consommation une semaine à l’avance (168 heures).
Voici comment préparer les données et lancer le fine-tuning :
story_building = "Building 03"
traindf = fulldf[full_df["timestamp"] < "2025-05-23"]
single_building_train = train_df[
train_df["building"].eq(story_building)
].sort_values("timestamp")
train_inputs = [
{
"target": single_building_train[["total_load_kw"]]
.to_numpy(dtype="float32")
.T
}
]
Quelques détails importants :
- Le
targetdoit être un tableau 2D avec la forme(numtargetseries, time_steps). Ici, on a un seul bâtiment, donc(1, T). - On utilise
.T(transpose) pour passer d’un format colonne à un format ligne, comme attendu par Chronos-2.
On prépare aussi les données de validation, en veillant à bien séparer les périodes d’entraînement et de test pour éviter les fuites de données :
validationdf = fulldf[full_df["timestamp"] < "2025-05-30"]
single_building_validation = validation_df[
validation_df["building"].eq(story_building)
].sort_values("timestamp")
validation_inputs = [
{
"target": single_building_validation[["total_load_kw"]]
.to_numpy(dtype="float32")
.T
}
]
Le fine-tuning se lance ensuite avec cette configuration :
finetunedmodel = base_model.fit(
train_inputs,
prediction_length=168,
validationinputs=validationinputs,
finetune_mode="lora",
loraconfig=LORACONFIG,
context_length=1080, # Fenêtre de 45 jours
learning_rate=2e-5,
num_steps=1000,
batch_size=32,
outputdir="finetunedmodels/finetuningmodes/single_target",
finetunedckptname="checkpoint",
callbacks=[EarlyStoppingCallback(earlystoppingpatience=6)],
save_steps=25,
eval_steps=25,
)
Quelques paramètres clés :
prediction_length=168: le modèle doit prédire 168 heures (1 semaine).context_length=1080(45 jours) : la fenêtre de données historiques à prendre en compte.earlystoppingpatience=6: si la perte de validation ne s’améliore pas pendant 6 évaluations consécutives, l’entraînement s’arrête.
Sur une carte graphique NVIDIA RTX 2000 Ada Laptop (8 Go de VRAM), ce fine-tuning a pris environ 42 secondes.
RÉSULTATS : UN BÂTIMENT, UNE AMÉLIORATION
Après fine-tuning sur le bâtiment 03, les prévisions sont plus précises. Voici les chiffres :
Le modèle a donc réduit son erreur, mais pas de manière spectaculaire. Pourquoi ? Parce que Chronos-2 est déjà très bon dès le départ. Le fine-tuning permet surtout de corriger les biais spécifiques à ce bâtiment.
SCÉNARIO 2 : FINE-TUNING SUR UN PORTEFEUILLE DE BÂTIMENTS
Et si on avait plusieurs bâtiments ? Par exemple, une chaîne de magasins avec 8 immeubles similaires. Peut-on adapter Chronos-2 pour tous en même temps ?
Oui, et c’est la deuxième méthode. Voici comment préparer les données :
targetcolumn = "totalload_kw"
train_inputs = [
{
"target": buildingdf[[targetcolumn]].to_numpy(dtype="float32").T,
}
for , buildingdf in train_df.groupby("building", sort=True)
]
validation_inputs = [
{
"target": buildingdf[[targetcolumn]].to_numpy(dtype="float32").T,
}
for , buildingdf in validation_df.groupby("building", sort=True)
]
Chaque bâtiment devient une tâche d’entraînement distincte. Le fine-tuning se lance ensuite avec la même configuration LoRA :
finetunedmodel = base_model.fit(
inputs=train_inputs,
validationinputs=validationinputs,
prediction_length=168,
context_length=1080,
loraconfig=LORACONFIG,
learning_rate=2e-5,
max_steps=1000,
)
Résultats après fine-tuning sur les 8 bâtiments :
SCÉNARIO 3 : INTÉGRER DES COVARIATES (VARIABLES EXTERNES)
Les scénarios 1 et 2 ne prennent en compte que la consommation électrique passée. Mais que se passe-t-il si on ajoute des variables externes comme la température extérieure, l’ensoleillement ou l’occupation du bâtiment ? C’est le scénario 3.
Voici les covariates (variables externes) utilisées :
knownfuturecolumns = [
"outdoortempc", # Température extérieure en °C
"occupancy", # Occupation du bâtiment (0 ou 1)
"solar_irradiance", # Ensoleillement
"is_weekend", # Week-end ou non
]
On prépare les données d’entraînement en ajoutant ces variables :
singlebuildingtrain = train_df[
traindf["building"].eq(storybuilding)
].sort_values("timestamp")
train_inputs = [
{
"target": singlebuildingtrain[["totalloadkw"]]
.to_numpy(dtype="float32")
.T,
"past_covariates": {
column: singlebuildingtrain[column].to_numpy(dtype="float32")
for column in knownfuturecolumns
},
"future_covariates": {
column: None
for column in knownfuturecolumns
},
}
]
Le fine-tuning se fait avec la même configuration LoRA :
finetunedmodel = base_model.fit(
train_inputs,
prediction_length=168,
validationinputs=validationinputs,
finetune_mode="lora",
loraconfig=LORACONFIG,
context_length=1080,
learning_rate=2e-5,
num_steps=1000,
batch_size=32,
outputdir="finetunedmodels/finetuningmodes/single_covariate",
finetunedckptname="checkpoint",
callbacks=[EarlyStoppingCallback(earlystoppingpatience=6)],
save_steps=25,
eval_steps=25,
)
Pour la prédiction, il faut fournir les covariates futures (par exemple, la météo prévue) :
contextwithcovariates = testcontextdf[
["building", "timestamp", "totalloadkw"] + knownfuturecolumns
]
futurecovariatesdf = testtruthdf[
["building", "timestamp"] + knownfuturecolumns
]
predsinglecovariate = finetunedmodel.predict_df(
contextwithcovariates,
futuredf=futurecovariates_df,
prediction_length=168,
quantile_levels=[0.025, 0.5, 0.975],
id_column="building",
timestamp_column="timestamp",
target="totalloadkw",
)
Résultat : l’erreur est encore réduite, surtout si les covariates sont fortement corrélées à la consommation (par exemple, la température pour la climatisation).
SCÉNARIO 4 : FINE-TUNING SUR UN PORTEFEUILLE AVEC COVARIATES
On combine les scénarios 2 et 3 : fine-tuning sur plusieurs bâtiments, en intégrant des covariates. Voici comment préparer les données :
train_inputs = []
for building, buildingdf in traindf.groupby("building", sort=True):
buildingdf = buildingdf.sort_values("timestamp")
train_inputs.append(
{
"target": buildingdf[["totalload_kw"]]
.to_numpy(dtype="float32")
.T,
"past_covariates": {
column: buildingdf[column].tonumpy(dtype="float32")
for column in knownfuturecolumns
},
"future_covariates": {
column: None
for column in knownfuturecolumns
},
}
)
Le fine-tuning et la prédiction suivent la même logique que le scénario 3, mais avec plusieurs bâtiments. Les résultats montrent une amélioration encore plus marquée, car le modèle apprend à généraliser les patterns entre les bâtiments.
SCÉNARIO 5 : FINE-TUNING AVEC APPRENTISSAGE CROISÉ (CROSS-LEARNING)
Dernier scénario : l’apprentissage croisé. L’idée ? Entraîner le modèle sur 7 bâtiments, puis l’utiliser pour prédire le 8ème, qu’il n’a jamais vu. C’est comme si un médecin apprenait sur 7 patients pour diagnostiquer le 8ème.
Voici comment préparer les données :
heldoutbuilding = "Building 06"
train_buildings = [
building
for building in sorted(train_df["building"].unique())
if building .= heldoutbuilding
]
train_inputs = []
for building in train_buildings:
buildingdf = traindf[
train_df["building"].eq(building)
].sort_values("timestamp")
train_inputs.append(
{
"target": buildingdf[["totalload_kw"]]
.to_numpy(dtype="float32")
.T,
"past_covariates": {
column: buildingdf[column].tonumpy(dtype="float32")
for column in knownfuturecolumns
},
"future_covariates": {
column: None
for column in knownfuturecolumns
},
}
)
On entraîne le modèle sur ces 7 bâtiments, puis on l’utilise pour prédire le bâtiment 06 :
building06context = testcontextdf[
testcontextdf["building"].eq(heldoutbuilding)
][["building", "timestamp", "totalloadkw"] + knownfuturecolumns]
building06futurecovariates = testtruth_df[
testtruthdf["building"].eq(heldoutbuilding)
][["building", "timestamp"] + knownfuturecolumns]
predheldout = finetunedmodel.predictdf(
building06context,
futuredf=building06futurecovariates,
prediction_length=168,
quantile_levels=[0.025, 0.5, 0.975],
id_column="building",
timestamp_column="timestamp",
target="totalloadkw",
)
Résultat : le modèle, bien que n’ayant jamais vu le bâtiment 06, parvient à faire des prédictions raisonnables grâce aux patterns appris sur les autres bâtiments. C’est une preuve que Chronos-2 peut généraliser ses connaissances.
QUEL SCÉNARIO CHOISIR ?
Chaque scénario a ses avantages :
- Scénario 1 (un seul bâtiment) : Simple et efficace si vous avez beaucoup de données sur un seul bâtiment.
- Scénario 2 (plusieurs bâtiments) : Idéal pour une flotte de bâtiments similaires.
- Scénario 3 (covariates) : À utiliser si vous avez des variables externes fortement corrélées à votre série temporelle.
- Scénario 4 (portefeuille + covariates) : Le plus complet, mais aussi le plus complexe.
- Scénario 5 (apprentissage croisé) : Parfait pour prédire des bâtiments nouveaux sans données historiques.
Le choix dépend de votre cas d’usage, de la quantité de données disponibles et des variables externes que vous possédez.
COMMENT UTILISER CES MÉTHODES SUR VOS DONNÉES ?
Pour reproduire ces scénarios avec vos propres données :
- Préparez vos données : organisez-les en un DataFrame avec une colonne pour le temps, une pour l’identifiant (ex: bâtiment), et une pour la valeur à prédire (ex: consommation électrique).
- Installez Chronos-2 : suivez les instructions de la première partie de cette série pour configurer l’environnement.
- Choisissez un scénario : adaptez le code fourni à votre cas d’usage.
- Lancez le fine-tuning : utilisez la configuration LoRA proposée et ajustez les paramètres si nécessaire.
- Évaluez les résultats : comparez l’erreur avant/après fine-tuning pour mesurer l’amélioration.
Avec ce template, vous avez tout ce qu’il faut pour adapter Chronos-2 à vos séries temporelles, quel que soit votre domaine (énergie, finance, santé, logistique…).
EN CONCLUSION : LE FINE-TUNING, UNE CLÉ POUR DES PRÉVISIONS PLUS PRÉCISES
Chronos-2 est un outil puissant, mais son potentiel est décuplé par le fine-tuning. Grâce à LoRA, cette adaptation devient accessible, même avec des ressources limitées. Les cinq scénarios présentés ici couvrent la plupart des cas d’usage : d’un seul bâtiment à un portefeuille complet, en passant par l’intégration de covariates ou l’apprentissage croisé.
Le fine-tuning n’est pas une option, mais une nécessité pour obtenir des prévisions vraiment fiables. Et avec le code fourni, vous pouvez démarrer immédiatement, sans avoir à réinventer la roue.
- Towards Data Science
L'indépendance de CLODCO est votre garantie.
Pour que l'actualité de l'IA reste sans filtre et sans concession, votre soutien est indispensable. Votre contribution est le seul moteur de notre liberté éditoriale.
Soutenir CLODCO


