신규 서비스에 keras 이미지 분류 모델을 서빙해야한다. 도커 컨테이너를 따로 올려서 작업할 예정이지만 현재는 프로토 타입이라 django 서버안에서 model을 load해서 사용하고 있다.
해당 모델은 특정 엔드포인트 접근때만 이용한다. 절차는 다음과 같다.
현재 로컬에서 다음과 같은 절차에서 load되는 시간이 매우 크다. tensorflow==2.16.1 작성 날짜기준 매우 최근 버전을 사용 중이며, tf_keras(구버전 케라스) 패키지를 따로 받아서 tf_keras.models.load_model로 약 300mb 크기의 .h5파일을 읽어온다.
문제는 해당 엔드포인트로 접근할 때 마다 (load, 추론, 처리)가 이루어지는데 시간이 매우 길다. 실제로 m1 macos 로컬에서 이 정도 시간이라면 AWS EC2에서는 엄청나게 시간이 오래걸릴 것으로 추론된다.
load를 django runserver시 부터 쭉 유지해서 해당 model객체를 전역으로 유지하여, 필요할 때만(엔드포인트 접근시) 추론, 처리로 빠르게 끝내야 한다.
from django.apps import AppConfig
class PaintConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'your app name'
def ready(self):
import sys
if 'runserver' in sys.argv:
runserver시 AppConfig의 ready메서드를 오버라이딩 하여 ready안에 model을 로드하였다. DoctorsConfig내에 model을 로드해서 필요할 때마다 가져다 쓰면 불필요한 로드시간을 줄일 수 있을 것이다.
model은 로드가 되었지만 여전히 시간이 오래걸렸다. 계속 시간을 찍어보며 테스트 해본 결과 모델이 첫 사용이 필요하다는 것을 깨달았다.
웜업 (Warm-Up)
모델 웜업은 모델을 로드한 후, 몇 가지 더미 입력 데이터를 사용하여 모델을 한 번 실행하는 과정이다.
- 초기화 지연 제거: 모델이 처음으로 실행될 때는 다양한 초기화 작업이 수행된다. 예를 들어, 텐서플로우나 파이토치 같은 프레임워크는 첫 실행 시 메모리 할당, 최적화, 그래프 컴파일 등을 수행하며 이러한 작업들은 첫 예측에 지연을 초래할 수 있다. 웜업을 통해 이러한 지연을 미리 해결한다. 즉 한 번의 추론을 로드시에 실시한다.
- 캐싱 및 최적화: 일부 딥러닝 프레임워크는 첫 실행 시 내부적으로 최적화를 수행하고, 필요한 데이터를 캐시에 저장한다. 웜업을 통해 이후 예측을 위한 최적화된 상태를 만들 수 있다.
- GPU 메모리 할당: GPU를 사용하는 경우, 첫 실행 시 GPU 메모리가 할당된다. 웜업을 통해 이 과정이 미리 완료되어 이후 예측이 원활해진다.
ready부분에 load + 첫 추론까지 집어넣으니 서버를 실행시킬 때만 약 10초정도의 시간이 걸리고 문제가 되었던 기능의 속도는 개선되었다.
사실 웜업에 대해 알고있었는데 인공지능 공부할 때는 로드나 추론속도에 대해 신경을 많이 쓰지 않아서 놓치고 있었다. 근데 결국 텐서플로우의 x같은 종속성때문에 따로 인스턴스를 띄워야 할 것 같다.