Как отладить утечку памяти в python с помощью cherrypy и pytorch

У меня есть приложение Cherripy Python, которое в конечном итоге съедает всю мою оперативную память.
Как устранить утечку памяти?

У меня есть модель 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)

Изначально приложению требуется около 800 МБ оперативной памяти, в основном для загрузки в память некоторых двоичных файлов (предварительно обученных моделей). С каждым новым запросом использование памяти продолжает расти, и через 2 дня приложение заняло полные 14G памяти на моем графическом процессоре, ничего не делая!

Я вижу тот же результат, когда запускаю его на процессоре, а не на графическом процессоре. 23G потребляются легко и даже быстрее.
Я запускаю свое приложение в контейнере докеров, но при запуске без него результат тот же - постоянно потребляется память.

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


person Viacheslav Shalamov    schedule 26.11.2019    source источник
comment
Вы делаете выводы с torch.no_grad()? Не то чтобы это имело значение, но у автограда вообще огромная протекающая поверхность   -  person Jatentaki    schedule 26.11.2019
comment
Попробуйте время от времени сбрасывать куда-нибудь статистику cprofile. Или используйте py-шпион. Или используйте какой-нибудь удаленный отладчик, например 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