[살아 움직이는 머신러닝 파이프라인 설계] 8. 모델 분석 및 검증
인공지능/Tensorflow Extended

[살아 움직이는 머신러닝 파이프라인 설계] 8. 모델 분석 및 검증

머신러닝 모델을 배포하는 세가지 방법

학습된 머신러닝 모델을 배포하는 방법은 보통 세가지가 있다. 가장 많이 사용하는 방법은 모델 서버를 따로 두어 사용자 요청과 함께 들어온 입력 샘플을 받아 모델 예측을 수행한다. 하지만 입력 샘플이나 사용자 요청에 개인 정보가 들어있어 서버로 보낼 수 없는 상황에서는 모델 서버 대신 클라이언트의 브라우저에서 모델 예측을 수행하는 방법을 사용한다. 이 방법은 웹 페이지와 함께 모델을 함께 보내 브라우저에서 직접 실행한다. 마지막으로 모델 서버와 클라이언트의 연결을 보장할 수 없는 경우에는 에지 장치를 두는 방법도 선택할 수 있다.

파이썬 API 서버로 배포시 단점

Flask나 Django와 같은 프레임워크로 서버를 만들어 모델을 배포할 수 있다. 하지만 이러한 방식에는 세가지 단점이 존재한다.
먼저 데이터 과학자의 코드와 API 팀과의 업무 구분이 모호해진다. 모델 서버 구현 코드에 모델 배포와 API 엔드포인트 코드가 혼재되어 있다면 데이터 과학자가 모델을 업데이트를 할 때 API 팀의 코드를 건들게 될 수 있다. 이렇게 되면 두 팀간의 충돌이 불가피해진다. 데이터 과학팀은 모델 학습에, 모델 배포 팀은 API 개발에 집중하기 위해서는 모델 배포와 API 구현은 분리되야 한다.
두번째 문제점은 모델 버전에 따른 배포를 직접 구현해야 한다는 점이다. 새로운 모델을 배포하면 새 모델을 위해 이전 버전과 중복되는 API 엔드 포인트를 작성해야 하고 이전 버전의 API 코드도 유지보수해야 한다.
마지막으로 사용자 요청마다 모델 추론을 수행하므로 비효율적이다. 모델 자체는 미니 배치 단위로 추론할 수 있음에도 사용자가 요청할 때마다 한 샘플에 대해 예측하기 때문에 비효율적인 처리일 수 밖에 없다.

텐서플로우 서빙(Tensorflow Serving)의 구조

텐서플로우 서빙의 구조, 출처: https://www.tensorflow.org/tfx/serving/architecture?hl=ko

텐서플로우 서빙은 크게 4개의 부분으로 나눌 수 있지만, 여기서 크게 주목할 부분을 Loader와 DynamicManager다. Loader는 정해진 Source에서 학습한 모델을 가져오는 역할을 한다. 만약 새로운 모델이 Source에 추가되면 이를 발견하고 알려주는 역할도 수행한다. DynamicManager는 개발자가 정한 VersionPolicy에 따라 모델을 배포할지 결정한다. DynamicManager는 일정한 시간 간격이나 특정 조건에 따라 최신 버전 또는 특정 버전의 모델을 가져와 이를 배포할 수 있도록 도와준다.

학습한 모델 저장하기

모델 서명

Trainer에서 학습한 모델을 배포할 때 학습된 가중치와 함께 모델 서명(Model Signature)을 SavedModel 형식으로 저장한다. 여기서 모델 서명은 모델의 입출력에 대한 정보를 담는 역할을 한다. 모델 서명 방식과 입출력 정보를 바탕으로 텐서플로우 서빙은 요청과 함께 들어온 입력 데이터를 모델에 전달한다.

모델 서명의 종류

텐서플로우 서빙이 지원하는 모델 서명은 Predict, Classify, Regress 세가지를 지원한다.

  • Predict
    • 세가지 서명 방식 중 가장 자유로운 방식이자 기본 설정
    • 다중 입력, 다중 출력을 지원한다
  • Classify
    • 분류 모델을 정의하는 서명 방식
    • 입력은 하나만 사용 가능
    • 출력은 class와 score 두가지 제공
  • Regress
    • 회귀 모델을 정의하는 서명 방식
    • 단일 입력, 단일 출력만 가능
    • 둘 중 하나 이상은 사용해야 한다

저장된 모델 직접 검사해보기

SavedModel 형식으로 저장된 모델은 saved_model_cli 을 통해 모델 서명을 확인하거나 데이터를 직접 집어넣어 결과물을 살펴볼 수 있다.

텐서플로 서빙을 통해 모델 서버 구성하기

텐서플로 서빙을 통해 지속적으로 최신 모델을 배포할 수 있다. 텐서플로 서빙에게 모델 이름과 저장된 위치를 전달하면 텐서플로는 지정된 위치에서 모델 이름에 해당하는 최신 모델을 가져온다. 만약 지정 위치에 새로운 버전의 모델을 추가하면 로더가 이를 인식해 새로운 모델로 교체한다. 이러한 기능을 핫 스왑(Hot Swap)이라 부른다.
또한 원하는 모델 여러개를 동시에 서버에 올릴 수 있다. 이 때에는 프로토콜 버퍼 형식으로 모델 설정 파일을 작성하면 된다.

model_config_list {  
  config {  
    name: 'my_first_model'  
    base_path: '/tmp/my_first_model/'  
    model_platform: 'tensorflow'  
  }  
  config {  
    name: 'my_second_model'  
    base_path: '/tmp/my_second_model/'  
    model_platform: 'tensorflow'  
  }  
}

모델 설정파일에 배포를 원하는 모델의 이름과 저장 위치를 적어두면 텐서플로 서빙이 해당 모델의 최신 버전을 클라이언트에게 제공한다. 또한 원하는 버전의 모델만 배포하고싶을 때에도 모델 설정파일에 해당 버전을 적어두면 된다.

텐서플로 서빙의 API 유형

텐서플로 서빙은 REST와 gRPC 두가지 API 유형을 지원한다. REST는 웹 서비스에서 가장 많이 사용되는 방식으로 GET, POST와 같은 표준 HTTP method를 통해 소통한다. 모델 서버를 REST 방식으로 제공하면 다음과 같은 장점이 있다.

  • 학습 부담이 적다
    • 이미 널리 사용되는 방식이기 때문에 웹 어플리케이션 서버를 구현해봤다면 REST를 통한 모델 서버 구현도 어렵지 않다.
  • 엔드 포인트 추론이 쉽다.
    • GET, POST, DELETE와 같이 정해진 규칙에 따라 구현하면 API 사용자가 요청을 보낼 때 어떤 method를 보내야하는지 바로 알아챌 수 있다.
  • 테스트가 쉽다
    • 이미 REST 기반 API 테스트 도구들이 널리 퍼져있기 때문에 이들을 활용해 모델 서버를 테스트해볼 수 있다. 심지어 웹 브라우저를 통해서 요청을 보낼 수도 있다.
  • 광범위하게 사용하기 좋다
    • 클라이언트 환경에 REST를 처리하는 기능이 있을 가능성이 매우 높다. 웹 브라우저만 있어도 REST 요청을 주고받을 수 있기 때문에 클라이언트가 굳이 REST 요청을 보낼 수 있는지 확인하지 않아도 된다.
      gRPC은 구글이 제안한 원격 프로시저 프로토콜이다. gRPC는 표준 데이터 모델을 프로토콜 버퍼를 이용하기 때문에 이를 이용한 모델 서버는 다음과 같은 장점을 가질 수 있다.
  • 지연시간이 적다.
    • 데이터를 직렬화한 상태로 보낼수 있어 모델이 이를 처리하는 시간을 아낄 수 있다. REST를 통해 전송할 때 입력 샘플을 JSON이나 XML 형식으로 전달할 때가 많은데 이를 tf.Example로 변환하는데 시간이 걸린다. 하지만 클라이언트에서 tf.Example를 직렬화한 상태로 보낼 수 있어 지연 시간을 줄일 수 있다.
  • 요청이 많을 때 처리 능력이 높다.
    • 페이로드가 REST보다 작기 때문에 더 많은 요청을 처리할 수 있다.
      다만 gRPC가 러닝 커브가 가파르고 클라이언트에 gRPC를 처리하는 기능을 추가해줘야 하는 단점도 존재한다.

모델 서버에 A/B 테스트 도입하기

어떤 모델이 고객을 더 만족시키는지 알고싶다면 두 모델을 직접 적용해보는 수 밖에 없다. 이때 자주 사용되는 방법이 A/B 테스트다. A/B 테스트란 고객들을 두 그룹으로 묶어 서로 다른 기능을 제공해 두 기능 중 어떤 쪽이 더 만족도가 높은지 확인하는 테스트 방법이다.
아쉽게도 텐서플로우 서빙에는 A/B 테스트 기능을 제공하지 않는다. 다만 고객마다 요청 URL을 달리하거나 Istio같은 라우팅 도구를 통해 서로 다른 모델 서버에게 요청하는 방식으로 A/B테스트를 진행해볼 수 있다.

피드백 루프에 모델 메타데이터 달기

모델에 대한 고객 평가를 받을 때 어떤 모델의 추론을 제공받았는지 아는 것은 중요하다. 하지만 A/B 테스트처럼 고객이 어떤 모델을 사용했는지 알 수 없는 상황도 존재한다. 이 때에는 모델 서버에게 모델 메타데이터를 요청해 클라이언트가 가지고 있다가 피드백과 함께 전달하면 된다.
텐서플로우 서빙은 클라이언트가 모델 메타데이터를 요청할 수 있는 기능을 제공한다. 모델에 추론을 요청할 때 거의 동일안 URL을 통해 메타데이터를 요구할 수 있다.

배치 단위로 추론 요청 처리하기

모델 서버를 간단하게 구현하는 방법은 클라이언트 요청이 들어오자마자 모델 추론을 수행하는 방법이다. 하지만 이러한 방식은 GPU나 CPU의 가용 메모리를 활용하지 못한다는 단점이 있다. 그래서 요청을 받은 즉시 추론하기 보다 미니 배치를 모은 다음 한번에 처리하는 방식을 사용하는 것이 좋다.
텐서플로우 서빙은 이러한 추론 요청 배치 처리 기능을 제공한다. 배치 크기와 대기 시간을 설정하면 대기 시간동안 배치 크기만큼 요청을 모은다. 배치 크기만큼 채우거나 대시 시간이 지나면 모델 추론을 수행하고 결과를 전달한다.