Nous utilisons Python assez souvent chez Zendesk pour construire des produits d’apprentissage automatique (ML). L’un des problèmes de performance courants que nous avons rencontrés avec les applications d’apprentissage automatique est celui des fuites et des pics de mémoire. Le code Python est généralement exécuté dans des conteneurs via des cadres de traitement distribué tels que Hadoop, Spark et AWS Batch. Chaque conteneur se voit allouer une quantité fixe de mémoire. Une fois que l’exécution du code dépasse la limite de mémoire spécifiée, le conteneur se termine en raison d’erreurs de mémoire.
Une solution rapide consiste à augmenter l’allocation de mémoire. Cependant, cela peut entraîner un gaspillage de ressources et affecter la stabilité des produits en raison de pics de mémoire imprévisibles. Les causes des fuites de mémoire peuvent inclure :
- linguer de gros objets qui ne sont pas libérés
- des cycles de référence dans le code
- des bibliothèques sous-jacentes/des extensions qui fuient la mémoire
Un exercice utile est de profiler l’utilisation de la mémoire des applications pour avoir une meilleure compréhension sur l’efficacité de l’espace du code et des paquets sous-jacents utilisés. Ce post couvre:
- profilage de l’utilisation de la mémoire de l’application à travers le temps
- comment inspecter l’utilisation de la mémoire à une partie spécifique du programme
- trucs pour déboguer les problèmes de mémoire
Vous pouvez regarder l’utilisation de la mémoire variant à travers le temps pendant l’exécution du code Python en utilisant le paquet memory-profile.
# install the required packages
pip install memory_profiler
pip install matplotlib# run the profiler to record the memory usage
# sample 0.1s by defaut
mprof run --include-children python fantastic_model_building_code.py# plot the recorded memory usage
mprof plot --output memory-profile.png
L’option include-children inclura l’utilisation de la mémoire de tous les processus enfants engendrés via le processus parent. Le graphique A montre un processus itératif de formation de modèle qui entraîne une augmentation de la mémoire par cycles au fur et à mesure que les lots de données de formation sont traités. Les objets sont libérés une fois que la collecte des ordures entre en jeu.
Si l’utilisation de la mémoire augmente constamment, il y a un problème potentiel de fuites de mémoire. Voici un exemple de script factice pour illustrer cela.
Un point d’arrêt du débogueur peut être défini une fois que l’utilisation de la mémoire dépasse un certain seuil en utilisant l’option pdb-mmem qui est pratique pour le dépannage.
Dump de mémoire à un moment donné
Il est important de comprendre le nombre attendu de gros objets dans le programme et s’ils doivent être dupliqués et/ou transformés en différents formats.
Pour analyser davantage les objets en mémoire, un heap dump peut être créé pendant certaines lignes de code du programme avec muppy.