A Zendesknél elég sokat használjuk a Python nyelvet gépi tanulási (ML) termékek építéséhez. Az egyik gyakori teljesítményprobléma, amellyel a gépi tanulási alkalmazásoknál találkoztunk, a memóriaszivárgás és a tüskék. A Python kódot általában konténerekben hajtjuk végre olyan elosztott feldolgozási keretrendszereken keresztül, mint a Hadoop, a Spark és az AWS Batch. Minden konténerhez fix mennyiségű memóriát rendelnek. Amint a kód végrehajtása túllépi a megadott memóriakorlátot, a konténer memóriahiány miatt leáll.
A gyors megoldás a memória kiosztásának növelése. Ez azonban erőforrás-pazarláshoz vezethet, és a kiszámíthatatlan memóriacsúcsok miatt befolyásolhatja a termékek stabilitását. A memóriaszivárgások okai lehetnek:
- nagy objektumok leragasztása, amelyek nem kerülnek felszabadításra
- hivatkozási ciklusok a kódon belül
- alapozó könyvtárak/C bővítmények memóriaszivárgás
Hasznos gyakorlat az alkalmazások memóriahasználatának profilozása, hogy jobban megértsük a kód és a használt alapcsomagok helyhatékonyságát. Ez a bejegyzés a következőket tartalmazza:
- az alkalmazás memóriahasználatának időbeli profilozása
- hogyan vizsgálhatjuk a memóriahasználatot a program adott részén
- tippek a memóriaproblémák elhárításához
A memory-profile csomag segítségével megnézhetjük a Python kód végrehajtása során időben változó memóriahasználatot.
# 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
Az include-children opció a szülőfolyamaton keresztül indított gyermekfolyamatok memóriahasználatát is tartalmazza. Az A. ábra egy iteratív modellképzési folyamatot mutat, amelynek következtében a memória ciklikusan növekszik, ahogyan a képzési adatok kötegeit feldolgozzák. Az objektumok felszabadulnak, amint a szemétgyűjtés beindul.
Ha a memóriahasználat folyamatosan növekszik, akkor fennáll a memóriaszivárgás potenciális problémája. Íme egy dummy mintaszkript ennek illusztrálására.
A pdb-mmem opcióval a hibakeresésnél praktikusan használható debugger töréspontot lehet beállítani, amint a memóriahasználat meghalad egy bizonyos küszöbértéket.
Memóriadump egy adott időpontban
Nem mindegy, hogy a programban várhatóan hány nagyméretű objektum lesz, és hogy ezeket duplikálni kell-e és/vagy különböző formátumba kell-e alakítani.
A memóriában lévő objektumok további elemzéséhez a program bizonyos kódsorai alatt a muppy segítségével heap dumpot készíthetünk.
Egy másik hasznos memóriaprofilozó könyvtár az objgraph, amely objektumgrafikonokat tud készíteni az objektumok vonalának vizsgálatához.
Gyors visszacsatolási hurokra törekvés
Hasznos megközelítés egy kis “teszteset” létrehozása, amely csak a kérdéses memóriaszivárgási kódot futtatja. Fontolja meg a véletlenszerűen mintavételezett adatok egy részhalmazának használatát, ha a teljes bemeneti adatok futtatása hosszadalmas.
Futtasson memóriaigényes feladatokat külön folyamatban
Aython nem feltétlenül adja vissza azonnal a memóriát az operációs rendszernek. Ahhoz, hogy egy kódrészlet végrehajtása után a memória felszabaduljon, azt egy külön folyamatban kell futtatni. Ez az oldal további részleteket tartalmaz a Python szemétgyűjtésről.
A debugger hozzáadhat hivatkozásokat objektumokra
Ha egy töréspontos debuggert, például a pdb-t használjuk, a debuggerből manuálisan létrehozott és hivatkozott objektumok a memóriaprofilban maradnak. Ez a memóriaszivárgás hamis érzetét keltheti, amikor az objektumok nem szabadulnak fel időben.
Vigyázzon a szivárgó csomagokkal
Egyes Python könyvtárak potenciálisan memóriaszivárgást okozhatnak. Pl. a pandasnak elég sok ismert memóriaszivárgási problémája van.
Boldog vadászatot!