Как да отстраните грешки при изтичане на памет в python с cherrypy и pytorch

Имам приложение cherripy python, което в крайна сметка изяжда цялата ми RAM.
Как да отстраня грешки при изтичане на памет?

Имам pytorch модел и го увих в cherrypy, за да осигуря прост rest-api за извод.

cherrypy.tree.mount(MyServer(), '/')
cherrypy.config.update({
    'server.socket_port': 8080,
    'server.socket_host': "0.0.0.0",
    'server.thread_pool': 30,
    'log.access_file': "access1.log",
    'log.screen': True
})
try:
    cherrypy.engine.start()
    cherrypy.engine.block()
except KeyboardInterrupt:
    cherrypy.engine.stop()

Където Myserver is:

class MyServer(object):
    @cherrypy.expose
    def index(self):
        return "healthy"

    @cherrypy.expose('/inference')
    def inference(self):
        cl = cherrypy.request.headers['Content-Length']
        rawbody = cherrypy.request.body.read(int(cl))
        body = json.loads(rawbody)

        result = doSomePyTorchStuff(body)

        return json.dumps(result)

Първоначално приложението отнема около 800mb RAM, което най-вече за да вземе някои двоични файлове (предварително обучени модели) в паметта. С всяка нова заявка, използването на паметта продължава да расте и след 2 дни видях, че приложението зае цели 14G памет на моя GPU, без да прави нищо!

Виждам същия резултат, когато го стартирам на CPU вместо на GPU. 23G се консумират лесно и дори по-бързо.
Изпълнявам приложението си в докер контейнер, но когато се изпълнява без него - резултатът е същият - паметта се консумира постоянно.

Може ли някой да ме насочи в правилната посока? В този момент не мога да стесня проблема, дори не съм сигурен дали е заради cherrypy или поради pytorch, или поради нещо друго.


person Viacheslav Shalamov    schedule 26.11.2019    source източник
comment
Правите ли изводи с torch.no_grad()? Не че би трябвало да има значение, но autograd обикновено има огромна пропусклива повърхност   -  person Jatentaki    schedule 26.11.2019
comment
Опитайте да изхвърляте cprofile статистики някъде от време на време. Или използвайте py-spy. Или използвайте отдалечен дебъгер като PYTHONBREAKPOINT=pudb.remote.set_trace, за да се свържете там и да проверите какви обекти съществуват в средата за изпълнение на Python.   -  person webknjaz    schedule 27.11.2019
comment
Можете също така просто да извадите тази логика на pytorch и да я стартирате много пъти отделно, докато измервате растежа на паметта.   -  person webknjaz    schedule 27.11.2019
comment
@Jatentaki Използвам torch.no_grad(). Не знаех, че може да повлияе на изтичането.   -  person Viacheslav Shalamov    schedule 27.11.2019
comment
@webKnjaZ благодаря, ще ги пробвам.   -  person Viacheslav Shalamov    schedule 27.11.2019


Отговори (1)


Изглежда, че вашият модел се зарежда всеки път, когато се извиква извод (или по време на инстанциране на сървър). Понякога зареждането на модел отнема памет и време, така че ако го правите доста често, можете да се сблъскате с изтичане на памет.

Обичайна практика е моделът на горелката да се създава веднъж (напр. в сингълтън) и след това да се прави извод многократно (напр. в MyServer.inference).

person Grigory Feldman    schedule 29.11.2019