Home » AI » Comment compresser un modèle LSTM pour le retail ?

Comment compresser un modèle LSTM pour le retail ?

On compresse un LSTM en réduisant l’architecture, en élaguant par magnitude et en quantifiant en INT8 pour gagner place, vitesse et autonomie tout en gardant une précision acceptable. Ci‑dessous : protocole, code Keras/TFLite, impacts attendus et recommandations pour le déploiement edge retail.

Pourquoi déployer de l’IA retail en edge ?

Le déploiement d’IA en edge pour le retail répond à des besoins opérationnels concrets : décisions temps réel, protection des données locales et réduction des coûts réseau. Les magasins ont souvent besoin de décisions en moins d’une seconde pour des interactions clients ou des boucles de réassort immédiates, et une latence réseau de quelques centaines de millisecondes peut déjà dégrader l’expérience.

Les contraintes matérielles sont réelles et contraignantes. La mémoire est limitée : on parle souvent de microcontrôleurs avec 16–256 KB de RAM et quelques centaines de KB à quelques Mo de flash, contraintes ciblées par TensorFlow Lite for Microcontrollers (tensorflow.org/lite/microcontrollers). Les CPU/GPU embarqués ont peu de cœurs et des fréquences basses, la consommation énergétique doit rester minimale pour éviter surchauffe ou décharge rapide des batteries, et le coût d’inférence (cycles CPU × temps) impacte directement l’économie d’exploitation.

Contrainte Impact concret
Mémoire limitée Impossible de charger gros modèles ; swap ou OOM en boutique
CPU/GPU faibles Latence d’inférence élevée et débit réduit
Consommation / Batterie Durée de vie des capteurs et mobiles réduite
Sécurité des données Contraintes RGPD et besoin de traitements locaux

Exemples d’usages impactés : prévisions quotidiennes de demande en magasin (réindexation toutes les 24h mais réajustements intra-journaliers en <1s pour promos), alertes de réassortiment en rayon, détection d'anomalies sur capteurs (fuites, température) et traitements embarqués dans applications mobiles pour recommandations instantanées.

Un modèle compressé réduit la taille mémoire, diminue le nombre d’opérations et la consommation d’énergie, et permet d’inférer localement sans transfert réseau, ce qui protège les données sensibles. Des techniques comme la quantification, le pruning et l’encodage ont montré des gains massifs (voir Deep Compression, Han et al., 2016 : arxiv.org/abs/1510.00149).

Pour comparer sérieusement ces techniques dans le retail edge, il est nécessaire d’établir un protocole de benchmark reproductible mesurant latence, mémoire vive et flash, consommation énergétique et précision métier.

Quel benchmark et quelles données utiliser ?

Pour un benchmark pertinent, utiliser un jeu de données proche du cas d’usage réel et répéter les expériences pour assurer la robustesse des résultats.

  • Jeu de données utilisé : Dataset « Kaggle Item Demand forecasting » — 5 ans journaliers, 10 magasins, 50 articles.
  • Échantillon choisi pour le benchmark : Sélection de 5 magasins × 10 articles = 50 séries temporelles.
  • Construction des séquences : Fenêtres glissantes de 14 jours d’historique pour prédire le jour suivant (14 → 1).
  • Nombre d’échantillons : Avec 5 ans ≈ 1 825 jours par série, on obtient ~1 811 fenêtres par série, soit ≈90 550 fenêtres totales. Avec une séparation 80/20 train/test, le jeu d’entraînement contient ≈72 440 échantillons (≈72k).

Utiliser la métrique MAPE (Mean Absolute Percentage Error) définie par MAPE = (100/n) × Σ |(A_t − F_t) / A_t|, où A_t est la valeur réelle et F_t la prédiction.

  • Pourquoi MAPE en retail : Métrique interprétable en pourcentage, directement exploitable pour le pilotage des stocks et la communication métier.
  • Limites de MAPE : Sensible aux petites valeurs réelles (division par des nombres proches de zéro), biais vers des erreurs extrêmes. Voir Hyndman & Koehler (2006), « Another look at measures of forecast accuracy ».
  • Métriques complémentaires recommandées : MAE ou RMSE pour robustesse, et pour l’edge — taille binaire du modèle (.tflite), latence d’inférence (ms) sur la cible matérielle, consommation énergétique estimée (W·s ou mJ par inférence).

Protocole expérimental :

  • Répéter chaque configuration 3× et rapporter la moyenne et l’écart-type pour MAPE.
  • Mesure de latence : Effectuer cold start (première inférence après chargement) et warm runs (après 10 inférences), exécuter ≥100 itérations, rapporter médiane et 5/95 percentiles.
  • Conversion et taille : Convertir le modèle avec TensorFlow Lite (float32 et quantifié int8) et mesurer la taille du fichier .tflite pour la taille binaire finale.
  • Consommation énergétique : Mesurer via wattmètre externe ou RAPL (pour x86), ou estimer via consommation CPU × temps si mesure directe impossible.
Configuration Taille binaire MAPE moyen ± écart-type Latence (ms) Remarque
Baseline LSTM float32

Quel est le LSTM de référence et ses résultats ?

Voici le baseline utilisé comme point d’ancrage avant toute compression : un LSTM Keras standard (64 unités, dropout 0.2) avec une sortie Dense pour une prédiction un pas en avant. Le modèle pesait environ 66.25 KB après export, et donne un MAPE moyen 15.92% ±0.10 sur le jeu de test.

Construction du modèle et code complet prêt à exécuter :

import os
import tensorflow as tf

# Exemple minimal : X_train shape = (n_samples, timesteps, n_features)
# et y_train shape = (n_samples, 1)

model = tf.keras.Sequential([
    tf.keras.layers.LSTM(64, dropout=0.2, return_sequences=False, input_shape=(timesteps, n_features)),
    tf.keras.layers.Dense(1)  # prédiction un pas
])

# Choix de la loss : MAE (Mean Absolute Error) ou MAPE (Mean Absolute Percentage Error)
# MAE est stable, MAPE exprime l'erreur en pourcentage (attention aux zéros dans y).
model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss='mean_absolute_percentage_error',  # ou 'mean_absolute_error'
              metrics=['mean_absolute_percentage_error', 'mean_absolute_error'])

# Entraînement
history = model.fit(X_train, y_train,
                    validation_data=(X_val, y_val),
                    batch_size=32,
                    epochs=50,
                    callbacks=[tf.keras.callbacks.EarlyStopping(patience=5, restore_best_weights=True)])

# Sauvegarde du modèle Keras et mesure de taille (zip) puis conversion TFLite
save_dir = "lstm_baseline"
tf.keras.models.save_model(model, save_dir, include_optimizer=False)

# Mesurer taille du dossier zippé
import shutil
sh_file = save_dir + ".zip"
shutil.make_archive(save_dir, 'zip', save_dir)
print("Keras model zip size (KB):", os.path.getsize(sh_file) / 1024)

# Conversion TFLite (taille .tflite)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
print("TFLite size (KB):", os.path.getsize("model.tflite") / 1024)

Interprétation du MAPE obtenu et utilité comme référence :

  • Explication rapide : Le MAPE (Mean Absolute Percentage Error) mesure l’erreur absolue moyenne en pourcentage. Il indique en moyenne de combien, en pourcentage, les prédictions s’écartent des valeurs réelles.
  • Précaution : Le MAPE est instable si la série contient des zéros ou des valeurs très faibles; dans ce cas, préférer MAE ou SMAPE (Symmetric MAPE).
  • Utilité pratique : Le MAPE 15.92% ±0.10 sert de seuil de référence. Toute méthode de compression devra idéalement conserver une MAPE proche de ce niveau (variation tolérable définie selon le business, par exemple +1–2 points absolus).

Étapes de validation recommandées :

  • Faire un split temporel strict : entraînement sur périodes anciennes, validation sur périodes plus récentes, test sur la tranche la plus récente.
  • Utiliser une cross-validation temporelle (walk-forward) pour estimer la variance temporelle de la performance.
  • Surveiller distribution des erreurs par produit/segment pour détecter dégradations locales causées par la compression.

Ce baseline constitue le point d’ancrage pour comparer les trois techniques de compression que nous testerons ensuite.

Quelles techniques de compression appliquer ?

Pour compresser un LSTM (Long Short-Term Memory, un réseau récurrent adapté aux séries temporelles), trois techniques complémentaires sont pragmatiques et efficaces : redimensionnement d’architecture, magnitude pruning et quantification INT8.

Architecture sizing — Synthèse : Réduire le nombre d’unités cachées pour diminuer directement le nombre de paramètres.

Méthode et calculs : Pour un LSTM simple, on approxime le nombre de paramètres par :

paramètres ≈ 4 × (input_dim × hidden + hidden × hidden + hidden), où le facteur 4 vient des quatre portes internes à l’LSTM.

Exemples numériques pour input_dim = 1 :

  • Hidden = 64 → 4×(1×64 + 64×64 + 64) = 16 896 paramètres.
  • Hidden = 32 → 4×(1×32 + 32×32 + 32) = 4 352 paramètres.
  • Hidden = 16 → 4×(1×16 + 16×16 + 16) = 1 152 paramètres.

Workflow : Construire variantes (64→32→16), réentraîner chaque variante et comparer MAPE (Mean Absolute Percentage Error — erreur absolue en pourcentage).

# Exemple Keras pour 32 et 16 unités
import tensorflow as tf
def build_lstm(units):
    model = tf.keras.Sequential([
        tf.keras.layers.Input(shape=(timesteps, 1)),
        tf.keras.layers.LSTM(units),
        tf.keras.layers.Dense(1)
    ])
    model.compile(optimizer='adam', loss='mape')
    return model
# model32 = build_lstm(32); model32.fit(...)
# model16 = build_lstm(16); model16.fit(...)

Effets : Latence souvent réduite (moins d’opérations MAC), faible mémoire d’exécution, risque d’accuracy drift si on sous-dimensionne (surtout sur tendances complexes).

Magnitude pruning — Synthèse : Supprimer les poids de faible amplitude pour obtenir de la sparsité.

Méthode : Utiliser l’API TensorFlow Model Optimization (prune_low_magnitude). Paramétrage conseillé : schedule de sparsité progressive (par ex. polynomial_decay de 0→0.7), viser 50–80% de sparsité suivant tolérance.

import tensorflow_model_optimization as tfmot
prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude
pruning_params = {
  'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(
      initial_sparsity=0.0,
      final_sparsity=0.7,
      begin_step=0,
      end_step=end_step)
}
model_pruned = prune_low_magnitude(model, **pruning_params)
model_pruned.compile(optimizer='adam', loss='mape')
# Fine-tuning puis:
model_for_export = tfmot.sparsity.keras.strip_pruning(model_pruned)

Précautions : Toujours réentraîner (fine-tune) après élagage pour récupérer précision. Etude Deep Compression (Han et al., 2016) montre réductions mémoire 2–10× selon sparsité et quantification combinée.

Effets : Taille du modèle diminue, latence CPU/GPU peut varier (sparse ops mal supportées sur certains hardwares), intégration plus complexe, risque d’augmentation temporaire de MAPE si pas de fine-tuning.

INT8 quantization — Synthèse : Réduire la précision des poids/activations à 8 bits pour baisser taille et accélérer l’inférence.

Différences clés : Dynamic range quantization convertit poids en 8 bits sans calibration; Post-training quantization peut requérir calibration; Full integer quantization convertit tout (poids+activations) en int8 et nécessite un jeu de calibration représentatif.

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
def representative_dataset():
    for input_value in calibration_data:
        yield [input_value]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
tflite_model = converter.convert()

Effets : Taille ≈4× plus petite typiquement (TensorFlow Lite docs). Latence réduite surtout sur CPU et MCU optimisés pour INT8. Nécessite tests de robustesse : LSTM avec opérations récurrentes peut perdre un peu d’accuracy sans calibration soigneuse.

Merci d’ajouter un tableau synthétique comparant pour chaque technique : ratio de compression attendu, impact typique sur MAPE, complexité d’implémentation et meilleur cas d’usage.

Quelle technique choisir pour le déploiement retail ?

Choisir la bonne technique dépend des contraintes hardware et du compromis taille/précision ; souvent combiner réduction d’architecture (sizing) + quantification INT8 ou pruning + quantification donne le meilleur ratio. INT8 signifie représentation sur 8 bits en entier (réduit la taille d’un facteur ~4) et MAPE signifie Mean Absolute Percentage Error, indicateur d’erreur en pourcentage.

Étape 1 — Profilage matériel : Mesurer la mémoire flash disponible, la RAM libre, les cycles CPU et la présence d’un accélérateur (NPU/TPU/DSP).

Étape 2 — Objectif business : Fixer budget, contrainte de latence (ex. <200 ms) et MAPE maximal acceptable par rapport à la baseline.

Étape 3 — Pipeline d’expérimentation : Créer variants 32-bit et 16-bit (ré-entrainement si utile), appliquer pruning progressif (réduction de poids par sparsité), convertir en INT8 par quantification post-training puis tester Quantization Aware Training (QAT) si la précision chute. Mesurer MAPE, taille binaire et latence sur cible.

Étape 4 — Critères d’acceptation : Exemple pratique — MAPE ≤ baseline +2% ET taille ≤ 0.5× baseline OU latence < 200 ms. Accepter le compromis qui respecte les SLA business.

Recommandations pratiques :

  • Commencer par réductions d’architecture et quantification post-training : Faible effort, gain immédiat (quantification ≈4× taille, Jacob et al., 2018).
  • Utiliser pruning si besoin de gains supplémentaires : Potentiel élevé (jusqu’à 9× compress., Han et al., 2015) mais prévoir fine-tuning pour récupérer précision.
  • Privilégier QAT si INT8 post-training dégrade la précision : QAT simule l’effet de la quantification pendant l’entraînement.

Points à valider en production avant rollout :

  • Tests A/B en magasin pour mesurer KPI réels et UX.
  • Surveillance du drift des données et déclenchement de retraining.
  • Plan de rollback automatisé et critères de déclenchement.
  • Monitoring continu taille/latence/accuracy et alerting.
Approche Mobile app Capteur embarqué Serveur edge magasin Microcontroller périphérique
Sizing (réduction archi) Recommandé — bon compromis taille/prec. Moyen — utile si CPU limité. Bon — facile à scaler. Limité — souvent insuffisant seul.
Quantification INT8 Recommandé — taille ↓≈4×, latence ↓. Recommandé — excellente pour devices. Bon — si bibliothèque supportée. Recommandé — souvent nécessaire.
Pruning Moyen — nécessite fine-tuning. Recommandé si mémoire critique. Bon — combine bien avec sparsité HW. Utile mais complexité ↑.
Pruning + INT8 Très bon — meilleur ratio taille/prec. Idéal — pour contraintes extrêmes. Excellente option si latency critique. Souvent la seule voie pour tenir les contraintes.

Prêt à réduire la taille de vos modèles LSTM pour le retail ?

En résumé, compresser un LSTM pour le retail edge passe par un protocole reproductible : benchmarker avec des données proches du cas d’usage, définir un baseline mesuré (ici 66.25 KB et MAPE 15.92%), puis tester réduction d’architecture, pruning magnitude et INT8 quantization. La quantification apporte souvent ×4 de gain de taille, le pruning peut apporter gains supplémentaires à coût de fine‑tuning, et le sizing reste l’option la plus simple. En choisissant la combinaison adaptée selon mémoire, latence et tolérance d’erreur, vous gagnez vitesse, coût et autonomie—bénéfices directs pour vos opérations magasin.

FAQ

  • Quelles gains attendre de la quantification INT8 sur un LSTM ?
    La quantification INT8 réduit typiquement la taille du modèle d’environ 4× et améliore la vitesse d’inférence sur CPU sans gros retraining. Pour certains RNN/LSTM, il faut une calibration (representative dataset) ou quantization aware training si la précision chute.
  • Le pruning dégrade-t-il toujours la précision ?
    Pas forcément : un pruning progressif avec fine‑tuning permet souvent d’atteindre sparsités modérées (50–80%) avec une perte de précision minimale. Pour sparsités élevées il peut être nécessaire de réentraîner plus longuement.
  • Faut‑il commencer par réduire l’architecture ou par quantifier ?
    Commencez par la quantification post‑training (faible coût d’implémentation) et le sizing si les ressources sont encore insuffisantes. Le pruning vient ensuite si vous avez besoin d’un gain additionnel et pouvez supporter du fine‑tuning.
  • Comment mesurer la latence réelle sur un appareil edge ?
    Mesurez la latence en conditions réelles : cold start et warm start, sur le runtime cible (TFLite interpreter ou runtime natif), en multipliant les runs et en reportant médiane et 95e percentile pour éviter biais.
  • Peut-on combiner pruning et INT8 ?
    Oui, combiner pruning et quantification est courant (Deep Compression). L’ordre et la méthode (prune puis quantize ou quantize aware training après pruning) influencent le résultat ; testez les deux workflows et validez la précision et la latence.

 

 

A propos de l’auteur

Franck Scandolera — expert & formateur en tracking server‑side, analytics engineering, automatisation no/low code (n8n) et intégration IA en entreprise. Responsable de l’agence webAnalyste et de l’organisme de formation Formations Analytics. J’accompagne des acteurs comme Logis Hôtel, Yelloh Village, BazarChic ou la Fédération Française de Football sur modélisation, mise en production et optimisation de modèles ML pour le retail et les environnements edge. Dispo pour aider les entreprises => contactez moi.

Retour en haut
Vizyz