8 minute read

Chapter 3

3.1 학습환경과 추론환경

3.1.1 시작하기

  • 학습을 빠르게 반복하는 것에 치중하다보면…
    1. 가독성이 낮고
    2. 테스트가 작성되어 있지 않으며
    3. 재현성도 보장하지 않는

    코드가 생길 수 있다.

  • 학술적인 목적이라면 문제 X → 비즈니스 목적으로 개발한다면 가치 창출이 중요.
    • 성공적으로 릴리즈해서 실제 환경에서 추론할 수 없는 모델이라면 비용 낭비이다.
  • 이번 챕터의 중점
    1. 실제 시스템으로 릴리즈하는 방법
    2. 안티 패턴 알아보기

3.1.2 학습환경과 추론환경

  • 학습환경과 추론환경은 목적도 다르고 비용구조가 다르다. 전혀 다른 리소스, 코드, 라이브러리가 사용될 수 있다.

    1.png

  • 릴리즈 시 문제점들은 이러한 괴리에 기인하는 부분이 많다.
    1. 학습 페이즈에서는 초기 비용이 컴퓨팅 자원에 투자되며, 코드 리뷰나 단위 테스트, 리팩터링은 거의 없다.
      • “실험 당사자만이 이해하고 실행 가능한” 코드로 학습이 이뤄지는 문제가 생긴다.
    2. 추론 페이즈에서는 실제 시스템에 추론 코드가 포함되어 다른 시스템과 연계 가동되고 운용된다.
      • 추론기가 장애가 발생하거나 잘못된 추론을 하는 경우, 비즈니스에 손실이 생기기 때문에 즉시 복구해야 한다.
      • 엔지니어는 문제 코드를 파악하고, 시스템을 이해하고, 장애를 특정, 개선할 수 있어야 한다.
      • 이러한 트러블슈팅의 효율을 높이려면 시스템 추적이 가능하도록 코드를 설계하고 작성해야 하며, 특정 인원만이 실행할 수 있게 해서는 안 된다.
    3. 추론환경은 계속 가동되어야 한다.
      • 비용 문제 발생 → 필요 자원을 최소한으로 조정하고, 부하에 따라 오토 스케일하는 설계가 바람직하다.
      • 코드 안정성 → 학습환경에서는 즉시 코드 수정이 가능하나, 추론환경에서는 다른 시스템에 대한 영향까지도 고려하며 대응해야 한다.
  • 학습, 추론환경에서 공통으로 사용하는 컴포넌트도 있다.
    1. 모델 파일 (당연히 같은 것을 사용한다).
    2. 입출력 데이터의 타입 (Float16 등)과 형태 (3차원 배열 등) → 바뀌는 경우는 없으며, 바뀌어서도 안 된다.
      • 학습과 추론 양쪽 환경을 모두 파이썬으로 개발하다 보면 어느 쪽이든 데이터 타입을 직접 정의하지 않는 경우가 생긴다. → 데이터 타입이 다르면 잘못된 추론 결과가 출력될 수 있다.

3.2 안티 패턴 (버전 불일치 패턴)

  • 모델을 추론기로 릴리즈할 때 가장 문제가 되는 점 → 학습환경과 추론환경의 차이
    • OS, 라이브러리

3.2.1 상황

  • 버전 불일치 오류 → 학습환경과 추론환경에서 같은 라이브러리를 사용하고 있으나, 버전이 일치하지 않는 경우.
  • 모델 로딩 오류 → 추론기로 모델을 불러올 수 없는 경우.
  • 잘못된 추론 오류 → 추론 결과가 학습환경에서 예상했던 추론 결과와 일치하지 않는 경우.

3.2.2 구체적인 문제

  • 언어와 라이브러리 버전을 일치시켜야 한다. → 파이썬 2.7로 모델을 학습하고, 추론기에서 파이썬 3.9를 사용하면 당연히 문제가 된다.
    • GPU 장비, GPU 드라이버, CUDA, CuDNN 등을 고려해야 한다.

    2.png

  • 버전 호환성 문제 회피 방법: ONNX (https://onnx.ai/)
    • ONNX (Open Neural Network Exchange)
      • 머신러닝 모델의 중간 표현.
      • 서로 다른 라이브러리에서 학습한 모델을 공통된 ONNX 형식으로 변환해주는 역할.
    • ONNX 형식으로 변환한 모델은 ONNX Runtime이라고 하는 공통의 추론엔진으로 가동시킬 수 있다.
    • 모든 머신러닝 라이브러리를 지원하는 것은 아니다 → 지원하는 버전의 호환 여부를 공개하고 있으니 확인하고 진행해야 한다.
  • 공통으로 사용되는 라이브러리는 버전까지 포함해서 공유하는 구조를 만들어 두는 것이 좋다.
    • pip install -r requirements.txt를 추론환경에서 실행해 전체 설치를 할 수 있다.
    • 목록이 없을 경우 pip list freeze > requirements.txt를 실행하면 만들 수 있다.
    • 적어도 버전의 불일치가 발생하는 사태를 막을 수 있다.

3.2.3 이점

  • 라이브러리 버전에 따른 호환성을 검증할 수 있음.

3.2.4 과제

  • 모델을 불러올 수 없음.
  • 모델을 불러올 수는 있지만, 추론 결과가 학습할 때와 다름.

3.2.5 해결방법

  • 학습환경에서 사용한 라이브러리와 버전을 출력해서 추론기의 개발에 공유하는 구조나 워크플로를 구성함.

3.3 모델의 배포와 추론기의 가동

  1. 모델 파일이 수MB 이상의 사이즈인 경우
    • 배포/교체 과정에서 네트워크와 추론기 로딩만으로도 수십 초가 소요되기도 한다.
    • 시스템이 멈추지 않도록 배포하고 갱신해야 한다.
    • 카나리 릴리즈 방식으로 기존 추론기와 새로운 추론기의 가동을 병행해 점차 새로운 추론기를 추가하며, 충분한 시간을 두고 교체하는 것이 좋다.
  2. 배포 대상 추론기와의 호환성
    • 추론기에 설치된 라이브러리가 모델과 일치해야 하며, 라이브러리 버전을 관리해 두는 것이 좋다.
  3. 인벤토리 관리
    • 추론기의 OS나 라이브러리, 버전, 가동 중인 모델, 데이터 형식, 모델의 목적 (분류, 회귀, 클러스터링 등)을 관리해야 한다.
    • 세월이 흘러 담당 엔지니어의 이동이 발생하면 히스토리를 알 수 없게 된다.

3.3.2 학습환경과 추론환경의 라이브러리와 버전 선정

  • 라이브러리의 취약성과 업데이트를 고려해야 하여 학습환경의 라이브러리를 업데이트하거나 대체 라이브러리를 사용해야 한다.

3.3.3 추론기에 모델 포함하기

  • 추론기로 가동할 때 필요한 컴포넌트
    1. 인프라: 서버, CPU, 메모리, 스토리지, 네트워크
    2. OS: Linux, Windows 등
    3. 런타임 (모델을 불러오고 가동하기 위한 라이브러리): ONNX Runtime이나 TensorFlow Serving 등.
    4. 모델 파일: 학습된 모델 파일
    5. 프로그램: 추론 요청에 대해 전처리, 추론, 후처리를 수행하고 응답하는 프로그램.
  • 인프라, OS, 런타임은 기존의 것을 이용하는 경우가 많고, 직접 구성하는 경우는 드물다.
  • 모델 릴리즈 패턴 2가지
    1. 모델-인-이미지 패턴
    2. 모델 로드 패턴

    3.png

3.4 모델-인-이미지 패턴

  • 추론기의 이미지에 모델 파일을 포함해서 빌드하는 방식.
  • 모델을 포함해서 빌드하기 때문에 해당 모델의 전용 추론기 이미지를 생성할 수 있다.

3.4.1 유스케이스

  • 서버 이미지와 추론 모델의 버전을 일치시키고 싶은 경우.
  • 추론 모델에 개별 서버 이미지를 준비하는 경우.

3.4.2 해결하려는 과제

  • 서버로 모델을 불러와서 추론이 가능한 상태로 만들어야 한다.
  • 오직 빌트인 모델만을 가동시키는 서버를 구축하여 서버-모델을 일대일로 정리한다.

3.4.3 아키텍처

  • 사전에 클라우드에서 빌드한 서버 이미지를 이용해 서버를 가동시킨다.
  • 추론 서버의 이미지에 학습이 끝난 모델을 포함시키기 때문에 학습과 서버 이미지의 구축을 워크플로로 만들 수 있다.
    • 아래와 같이 모델을 포함한 추론용 서버 이미지를 빌드하고, 추론기를 준비할 때는 서버 이미지를 pull한 뒤 기동시킨다.

    4.png

3.4.4 구현

  • 서버 부팅과 동시에 바로 가동되게 구성한다.
  • 추론기를 웹 API로 가동시켜 GET/POST 요청으로 접근하게 한다.
    • Docker, Kubernetes, Python 3.8
    • Gunicorn + FastAPI
    • scikit-learn
    • ONNX Runtime
  • 학습이 끝난 모델은 Dockerfile을 준비하여 도커 이미지에 포함하고, 이미지를 푸쉬해둔다.
    • Dockerfile 코드 생략 (코드 3.2 참고)
  • 쿠버네티스에서는 YAML을 통해 사용할 리소스를 정의한다.
    • 도커 이미지나 네트워크에 관한 정의를 포함하는데, 이렇게 정의한 파일을 매니페스트 (Manifest)라 한다. (e.g., deployment.yaml)
  • 쿠버네티스 매니페스트

    5.png

    6.png

  • 배포를 통해 정상적인 추론이 가능함을 확인한다

3.4.5 이점

  • 가동 확인이 끝난 서버와 모델의 편성을 하나의 추론용 서버 이미지로 관리가 가능함.
  • 서버와 모델을 일대일 대응으로 관리할 수 있어 운용상 간편함.

3.4.6 검토사항

  • 학습한 모델의 수만큼 서버 이미지의 수도 늘어나는 구조다. → 불필요한 서버 이미지를 삭제하여 스토리지를 절약해야 한다.
  • 추론기의 가동 시간만큼 스케일 아웃의 소요 시간이 늘어난다. → 서버의 베이스 이미지를 미리 다운로드 받아 둔다.

3.5 모델 로드 패턴

3.5.1 유스케이스

  • 서버 이미지 버전보다 추론 모델의 버전을 더 빈번하게 갱신하는 경우.
  • 동일한 서버 이미지로 여러 종류의 추론 모델 가동이 가능한 경우.

3.5.2 해결하려는 과제

  • 만약 동일한 전처리 기법과 동일한 의사결정나무 모델을 다른 데이터셋으로 여러 번 학습하는 경우
    • 학습할 때마다 서버 이미지를 빌드하게 된다.
    • 데이터셋만 지속적으로 바꾸어 가며 새로운 모델을 생성하는 것이 바람직하다.
    • 이런 경우엔 모델 로드 패턴이 최적의 모델 배포 방법이다.

3.5.3 아키텍처

  • 서버 이미지와 모델을 별도로 관리하여, 서버 이미지를 경량화할 수 있다.
  • 범용성을 높여 동일한 서버 이미지를 여러 추론 모델에 응용할 수 있다.
  • 추론기를 배치할 때 서버 이미지를 pull한 뒤 추론기를 기동하고, 이후에 모델 파일을 취득해서 추론기를 본격적으로 가동한다.
    • 환경변수 등으로 추론 서버에서 가동하는 모델을 유연하게 변경할 수도 있다.

    7.png

  • 단점
    • 모델이 라이브러리 버전에 의존적일 경우, 서버 이미지의 버전 관리와 모델 파일의 버전 관리를 별도로 수행해야 한다 → 운용 부하.

3.5.4 구현

  • 모델 파일을 도커 이미지에 포함시키지 않고, 도커 컨테이너를 기동할 때 모델을 다운로드한다.
    • 모델 파일은 스토리지 (AWS, GCP)에 저장해 두고, 필요할 때 다운로드할 수 있게 한다.
  • 모델 파일의 다운로드는 쿠버네티스의 initContainer를 사용한다.
    • 컨테이너를 기동하기 전에 필요한 초기화를 실행할 수 있다.
  • 파일 다운로드 파이썬 코드 생략 (코드 3.4 참고)
  • 추론기의 Dockerfile에는 모델 파일을 포함시키지 않은 채 모델을 실행하기 위한 코드를 빌드한다.
    • 추론기 Dockerfile 코드 생략 (코드 3.5 참고)
  • 쿠버네티스 매니페스트

    8.png

    9.png

    10.png

3.5.5 이점

  • 서버 이미지의 버전과 모델 파일의 버전 분리 가능
  • 서버 이미지의 응용성이 향상
  • 서버 이미지 경량화

3.5.6 검토사항

  • 모델 로드 패턴에서는 서버 이미지와 모델의 버전 불일치를 해결하는 구조가 필요하다.
  • 모델의 갱신은 서버 이미지의 갱신에 뒤따라야 한다.
    • 만약 버그로 인해 모델 다운그레이드를 해야 한다면 서버 이미지도 되돌릴 수 있는 상태를 만드는 것이 중요하다.

3.5 모델의 배포와 스케일 아웃

  • 두 패턴은 추론기의 릴리즈뿐만 아니라 스케일러빌리티 (Scalability)의 관점에서 차이가 있다.
    • 모델-인-이미지 패턴에서는 도커 이미지의 사이즈가 커지는 경향이 있어 소요 시간이 오래 걸린다.
    • 모델 로드 패턴에서는 도커 이미지의 다운로드가 추가로 발생하지 않고, 모델을 다운로드하는 것 만으로도 추론기를 기동시킬 수 있다.
  • 항상 모델 로드 패턴이 빠른 것은 아니다. → 모델 파일의 리드 타임이 느린 경우
    • 초기 기동: 모델 로드 패턴 (빠름) > 모델-인-이미지 패턴 (느림)
    • 스케일 아웃: 모델 로드 패턴 (느림) < 모델-인-이미지 패턴 (빠름)
  • 클라우드의 경우 네트워크 대역이 문제가 되는 경우가 적지만, 온프레미스 등 네트워크 대역에 제한이 있는 환경에서는 도커 이미지나 모델의 다운로드 속도가 항상 고려해야 할 지표가 된다.
  • 신속한…
    • 모델-인-이미지 패턴을 위해서는: 도커 이미지 용량을 줄여야 한다.
    • 모델 로드 패턴을 위해서는: 모델 다운로드 속도를 높이기 위한 대책 (추론기 근처에 저장, CDN 이용 등)

      11.png

Tags:

Categories:

Updated: