본문 바로가기

공부/컴퓨터

[python] Flask로 app.run() 실행시 두개의 Process가 뜨는 문제

오늘도 트러블슈팅

문제 상황

  • AI 엔진을 띄우면 GPU를 사용하는 Process가 2개가 뜨면서 GPU RAM을 쓸데 없이 두번 먹는 현상.

문제 분석

  • 웹 서버를 띄울때 Flask를 활용하고 있음
  • "main" 에서 model을 로딩하면 최초 실행된 python process가 GPU 메모리를 1.5GB 정도 사용
  • 이후 Flask의 app.run 을 실행.
  • Flask의 app.run을 실행하면 python process가 1개 더 뜨면서 GPU 메모리를 1.5GB 정도 사용
  • 아마도 app.run 실행시 python process 가 fork() 되면서 GPU메모리까지 clone 되는것으로 예측??

문제 확인

  • main부분에서 바로 model을 로딩하지 않고, 바로 Flask의 app.run을 실행
  • 최초 predict request시 model을 한번만 로딩하도록 코드 수정
  • nvidia-smi 확인시 /usr/bin/python3.7 단 1개만 GPU를 사용하는것을 확인

해결법 제안 ( 1번 방식 )

  • Flask 사용시 app.run 이전에 최대한 메모리 사용을 하지 않도록 코드 작성 필요
  • Flask 의 Context가 초기화 된 직후, Flask process에서 모델을 로딩하도록 수정.
    • 예1> 코드에 model이 null 인 경우에만, 초기화 ( 아래 그림 )
    • 예2> Flask의 annotaion 중 app.before_first_request 를 사용하여, 최초 requset 직전에 GPU 사용하는 모델을 로딩하도록 수정 필요

진짜 문제 상황

진짜 문제 해결 ( 2번 방식 )

  • 그래서 어쩌면 되냐고? auto reload 모드를 끄면 된다고 한다.
  • python 코드 안에서 설정하기 : app.run(use_reloader=False)
  • 하지만, pyhon web.py와 같은 방식으로 실행시키는 경우 코드가 두번 실행되는 이슈가 있으니, flask run --no-reload 방식으로 실행시키라고 이야기 하고 있다.
  • 관련 링크 3 : https://flask.palletsprojects.com/en/1.1.x/server/

그럼 뭘 써야 할까?

  • 개발을 할 때는 코드가 변경되었을때 바로바로 업데이트되면 편하니깐, Debug를 켜두고 1번 방식을 적용하면 좋을것이다.
  • 실제로 production에서 사용할꺼면, debug 모드도 끄고, reload도 끄는게 좋을 테니깐 2번 방식을 적용하면 더 좋을것이다. 물론 2번 방식을 적용할때 1번 방식을 같이 적용해도 괜찮을것이다.