
Utilizăm Python destul de mult la Zendesk pentru a construi produse de învățare automată (ML). Una dintre problemele comune de performanță pe care le-am întâlnit cu aplicațiile de învățare automată este reprezentată de scurgeri de memorie și vârfuri. Codul Python este de obicei executat în containere prin intermediul cadrelor de procesare distribuite, cum ar fi Hadoop, Spark și AWS Batch. Fiecărui container i se alocă o cantitate fixă de memorie. Odată ce execuția codului depășește limita de memorie specificată, containerul se va termina din cauza erorilor de lipsă de memorie.
O soluție rapidă este de a crește alocarea de memorie. Cu toate acestea, acest lucru poate duce la risipă de resurse și poate afecta stabilitatea produselor din cauza vârfurilor de memorie imprevizibile. Cauzele scurgerilor de memorie pot include:
- lingerea obiectelor mari care nu sunt eliberate
- cicluri de referință în cadrul codului
- biblioteci subiacente/extensii C care pierd memorie
Un exercițiu util este realizarea profilului de utilizare a memoriei aplicațiilor pentru a obține o mai bună înțelegere a eficienței spațiale a codului și a pachetelor subiacente utilizate. Această postare acoperă:
- profilarea utilizării memoriei aplicației de-a lungul timpului
- cum să inspectați utilizarea memoriei într-o anumită parte a programului
- sfaturi pentru depanarea problemelor de memorie
Puteți examina utilizarea memoriei care variază de-a lungul timpului în timpul execuției codului Python folosind pachetul 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

Opțiunea include-children va include utilizarea memoriei oricărui proces copil generat prin intermediul procesului părinte. Graficul A prezintă un proces iterativ de formare a modelului care face ca memoria să crească în cicluri pe măsură ce se procesează loturi de date de formare. Obiectele sunt eliberate odată ce colectarea gunoiului intră în funcțiune.
Dacă utilizarea memoriei crește constant, există o problemă potențială de scurgeri de memorie. Iată un exemplu de script fictiv pentru a ilustra acest lucru.

Un punct de întrerupere al depanatorului poate fi setat odată ce utilizarea memoriei depășește un anumit prag folosind opțiunea pdb-mmem, care este utilă pentru depanare.
Memory Dump at a Point in the Time
Este important să se înțeleagă numărul așteptat de obiecte mari din program și dacă acestea ar trebui să fie duplicate și/sau transformate în diferite formate.
Pentru a analiza în continuare obiectele din memorie, se poate crea un heap dump în timpul anumitor linii de cod din program cu muppy.

O altă bibliotecă utilă de profilare a memoriei este objgraph care poate genera grafice de obiecte pentru a inspecta filiera obiectelor.
Încercați să obțineți o buclă de feedback rapidă
O abordare utilă este crearea unui mic „caz de testare” care rulează doar codul cu pierderi de memorie în cauză. Luați în considerare utilizarea unui subset de date eșantionate aleatoriu dacă rularea datelor de intrare complete este îndelungată.
Executați sarcinile cu utilizare intensivă a memoriei în procese separate
Python nu eliberează neapărat memoria imediat înapoi către sistemul de operare. Pentru a se asigura că memoria este eliberată după ce o bucată de cod a fost executată, aceasta trebuie să ruleze într-un proces separat. Această pagină oferă mai multe detalii despre garbage collection Python.
Debuggerul poate adăuga referințe la obiecte
Dacă se utilizează un debugger cu punct de întrerupere, cum ar fi pdb, orice obiecte create și la care se face referire manual din debugger vor rămâne în profilul de memorie. Acest lucru poate crea o senzație falsă de scurgeri de memorie în cazul în care obiectele nu sunt eliberate în timp util.
Atenție la pachetele care pot avea scurgeri de memorie
Câteva biblioteci Python ar putea avea potențial scurgeri de memorie. De exemplu, pandas are destul de multe probleme cunoscute de scurgeri de memorie.
Vânătoare fericită!