Comment Utiliser les Fichiers Pickle en Python pour Sauvegarder Modèles et Données Intermédiaires ?

Introduction

En Python, un fichier pickle (.pkl ou .pickle) est un moyen de sérialiser et sauvegarder des objets Python sur disque — c'est-à-dire convertir des objets Python (listes, dictionnaires, modèles, DataFrames, etc.) en un flux de bytes, qui pourra ensuite être désérialisé (rechargé en mémoire exactement comme avant).

Ce que signifie “Pickling”

  • Pickling → convertir un objet Python en flux binaire (pour le sauvegarder dans un fichier ou l’envoyer par réseau).
  • Unpickling → convertir le flux binaire pour retrouver l’objet Python original.

Pourquoi c’est utile ?

Vous pouvez utiliser pickle pour :

  • Sauvegarder des modèles de machine learning (scikit-learn, XGBoost, etc.)
  • Stocker des données prétraitées ou des résultats intermédiaires
  • Mettre en cache des objets complexes (dictionnaires, listes, DataFrames, etc.)

Exemple d’utilisation

Sauvegarder (Pickler) un objet

1
2
3
4
5
6
7
import pickle

data = {'name': 'Benjamin', 'scores': [85, 92, 78]}

# Save to file
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)

'wb' signifie “write binary” (écriture binaire).

Charger (Unpickler) l’objet

1
2
3
4
5
6
7
8
import pickle

# Load from file
with open('data.pkl', 'rb') as f:
    loaded_data = pickle.load(f)

print(loaded_data)
# {'name': 'Benjamin', 'scores': [85, 92, 78]}

'rb' signifie “read binary” (lecture binaire).

Notes importantes

  1. Avertissement de sécurité :
    Ne jamais unpickler des données provenant d’une source non fiable.
    pickle.load() peut exécuter du code Python arbitraire.

  2. Compatibilité :
    Les fichiers pickle dépendent de la version Python.
    Un fichier créé sous Python 3.11 peut ne pas fonctionner parfaitement sous Python 3.9.

  3. Alternatives :

  4. Pour un stockage sûr et interopérablejson, csv, parquet

  5. Pour les modèles MLjoblib, torch.save, tf.keras.models.save

Exemples de Base avec Pickle

Exemple 1 : Pickler un DataFrame pandas

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd
import pickle

df = pd.DataFrame({
    'city': ['New York', 'Paris', 'Tokyo'],
    'temperature': [22, 19, 25]
})

# Save
with open('weather.pkl', 'wb') as f:
    pickle.dump(df, f)

# Load
with open('weather.pkl', 'rb') as f:
    df_loaded = pickle.load(f)

print(df_loaded)

Sortie :

1
2
3
4
city  temperature
0  New York           22
1     Paris           19
2     Tokyo           25

Méthode pratique via pandas :

1
2
df.to_pickle('weather.pkl')
df_loaded = pd.read_pickle('weather.pkl')

Exemple 2 : Pickler un modèle entraîné de machine learning

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
import pickle

X, y = load_iris(return_X_y=True)

model = RandomForestClassifier()
model.fit(X, y)

with open('rf_model.pkl', 'wb') as f:
    pickle.dump(model, f)

with open('rf_model.pkl', 'rb') as f:
    loaded_model = pickle.load(f)

print(loaded_model.predict([[5.1, 3.5, 1.4, 0.2]]))

Sortie :

1
[0]

Astuce : préférer joblib pour les gros modèles

1
2
3
4
import joblib

joblib.dump(model, 'rf_model.joblib')
model_loaded = joblib.load('rf_model.joblib')

Pickler plusieurs objets dans un seul fichier

La méthode la plus propre :
mettre tout dans un dictionnaire, puis pickler le dictionnaire.

Ainsi, un seul fichier .pkl contient :

  • modèle
  • scaler
  • noms des features
  • métadonnées
  • hyperparamètres, etc.

Exemple : Pickler plusieurs objets

 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
import pickle
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
import numpy as np

X = np.random.rand(100, 3)
y = np.random.rand(100)

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

model = RandomForestRegressor()
model.fit(X_scaled, y)

feature_names = ['feat1', 'feat2', 'feat3']
metadata = {'version': '1.0', 'created_by': 'Benjamin'}

bundle = {
    'model': model,
    'scaler': scaler,
    'features': feature_names,
    'metadata': metadata
}

with open('model_bundle.pkl', 'wb') as f:
    pickle.dump(bundle, f)

Chargement :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
with open('model_bundle.pkl', 'rb') as f:
    bundle = pickle.load(f)

model = bundle['model']
scaler = bundle['scaler']
features = bundle['features']
metadata = bundle['metadata']

print(metadata)
print(features)

Utilisation :

1
2
3
4
new_data = np.array([[0.2, 0.5, 0.9]])
new_data_scaled = scaler.transform(new_data)
pred = model.predict(new_data_scaled)
print(pred)

Bonne pratique : toujours packer tout dans un dictionnaire.

Checkpointing de longues boucles

Quand une boucle dure longtemps, on veut pouvoir reprendre après un crash.

Pickle est parfait pour cela.

Exemple 1 — Sauvegarder tous les N itérations

 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
import pickle
import os

progress_file = "progress.pkl"

if os.path.exists(progress_file):
    with open(progress_file, "rb") as f:
        data = pickle.load(f)
        start_index = data["index"]
        results = data["results"]
    print(f"Resuming from iteration {start_index}...")
else:
    start_index = 0
    results = []

for i in range(start_index, 1000000):
    try:
        result = i ** 2
        results.append(result)

        if i % 1000 == 0:
            with open(progress_file, "wb") as f:
                pickle.dump({"index": i + 1, "results": results}, f)
            print(f"Checkpoint saved at iteration {i}")

    except Exception as e:
        print("Error occurred:", e)
        break

Exemple 2 — Sauvegarder chaque itération

1
pickle.dump({"index": i + 1, "results": results}, open("progress.pkl", "wb"))

Exemple 3 — Sauver uniquement l’état minimal

1
2
state = {"i": i, "partial_result": partial_object}
pickle.dump(state, open("checkpoint.pkl", "wb"))

Exemple 4 — Sauvegarder uniquement en cas d’erreur

1
2
3
4
5
6
7
try:
    for i in range(start_index, N):
        do_work()
except Exception as e:
    print("Error detected, saving checkpoint...")
    pickle.dump({"i": i, "results": results}, open("progress.pkl", "wb"))
    raise e

Recharger

1
2
3
4
5
with open("progress.pkl", "rb") as f:
    data = pickle.load(f)

start_i = data["i"]
results = data["results"]

Ce qu’on peut sauvegarder

  • index courant
  • liste de résultats
  • objets temporaires
  • états intermédiaires de modèles
  • DataFrames partiels
  • métadonnées

Avertissements

Ne pas pickler d'immenses tableaux NumPy en boucle

préférez .npy, .parquet

Ne pas unpickler des fichiers suspects

risque d’exécution de code malveillant

Système de checkpointing réutilisable

1. Fonctions utilitaires

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pickle
import os

def save_checkpoint(path, data):
    with open(path, "wb") as f:
        pickle.dump(data, f)

def load_checkpoint(path, default=None):
    if os.path.exists(path):
        with open(path, "rb") as f:
            return pickle.load(f)
    return default

def delete_checkpoint(path):
    if os.path.exists(path):
        os.remove(path)

2. Exemple d’utilisation

 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
from checkpoint import save_checkpoint, load_checkpoint

checkpoint_path = "progress.pkl"

state = load_checkpoint(checkpoint_path, default={"i": 0, "results": []})

start_i = state["i"]
results = state["results"]

print(f"Resuming at iteration {start_i} with {len(results)} saved results.")

N = 1_000_000

for i in range(start_i, N):
    try:
        value = i ** 2
        results.append(value)

        if i % 1000 == 0:
            save_checkpoint(checkpoint_path, {"i": i + 1, "results": results})
            print(f"Checkpoint saved at iteration {i}")

    except Exception as e:
        print("ERROR OCCURRED — saving checkpoint before quitting...")
        save_checkpoint(checkpoint_path, {"i": i, "results": results})
        raise e

Après un crash : ré-exécuter → reprise automatique.

Références

Liens Site
pickle — Python object serialization Documentation Python
Serialization — Python Guide Persistence et pickle
DigitalOcean — Python Pickle Example Tutoriel pratique