1. Serving : 모델을 세상으로
1.1 Serving의 정의
serve: 음식을 나르는 행위 자체.
머신러닝 모델 Serving
모델의 예측 결과를 요청한 Client에게 제공하는 과정
데이터에 기반하여 모델 예측 결과를 제공하는 것

Research vs Production
Research는 집에서 요리, Production 은 고객에게 제공
즉, Production(Real World)은 환경에 모델을 사용할 수 있도록 배포하는 것

1.2 Serving의 대표적인 예시
-
유튜브 메인 화면

-
DeepL 번역기

-
쏘카 AI기반 세차 효율화

1.3 Serving의 종류
1) Batch Serving
- Batch : 일괄, 묶음
- 데이터를 일정 묶음 단위로 서빙(예 : 14시~15시 사이에 생성된 데이터)
Batch Serving은 많은 양을 일정 주기로 한꺼번에 서빙(=음식 배달, 택배)
2) Online(Real Time) Serving
- Online : 연결, 실시간
- 클라이언트가 요청할 때 서빙(예 : API Request)
- 요청할 때 데이터를 같이 제공
Online Serving은 한번에 하나씩 포장해서 배송 동시에 여러 주문이 들어올 경우 확장 가능하도록 준비해야 함
1.4 어떤 Serving을 사용해야 할까?
Batch Serving
Online Serving
상황
- 실시간 응답이 중요한 경우 : 즉각적으로 응답을 제시해야 하는 경우
- 개별 요청에 대한 맞춤 처리가 중요할 때
- 동적인 데이터에 대응할 때 : 데이터가 지속적으로 변하는 경우
인력
데이터 저장 형태
- 요청할 때 같이 데이터 제공
ex) 유튜브 추천 알고리즘, 번역, 은생사기탐지.
2. 단순한 Serving 패턴
2.1 디자인 패턴
소프트웨어를 어떻게 구성하고, 어떻게 상호 작용할지를 담은 내용
디자인 패턴 = 템플릿
과거부터 문제를 해결한 사람들이 반복된 내용을 패턴으로 정리
머신러닝 디자인 패턴
머신러닝의 특수성으로 별도의 디자인 패턴이 생김
- 일반적인 소프트웨어 개발: Only Code
- 머신러닝 개발의 특수성 : Data, Model, Code
머신러닝 서비스를 개발하다 고민하는 특수한 포인트
- 대용량 Model Load
- Model 관리
- 데이터를 대량으로 가져와서 전처리
- 데이터를 통계적으로 확인해서 이상치 제외
- 예측 요청 후 반응 시간이 오래 소요될 수 있음(모델이 연산하는 과정 이슈)
👉 상황에 따라 다르기에 이런 방법들이 항상 Best는 아니지만 구현하기 전에 참고할 수 있음 소개하는 여러 패턴을 합쳐서 하나의 패턴으로 만들 수도 있음
2.2 Batch 패턴
- 주기적으로 이 추천 모델에 사용자가 본 영화 데이터를 Input Data로 넣어서 예측하고,
Output 으로 나오는 사용자 별 추천 영화를 DB에 저장하기
- 추천 결과를 활용하는 서버쪽에서는 이 DB에 주기적으로 접근해 추천 결과를 노출
즉, 실시간성이 필요 없는 경우에 주기적으로 예측 결과를 DB에 저장하고 활용하는 쪽은 DB에서 결과를 읽어와서 사용

Job Management Server
- 작업을 실행하는 서버
- Apache Airflow 등을 주로 사용
- 특정 시간에 주기적으로 Batch Job을 실행시키는 주체
Job
- 어떤 작업 실행에 필요한 모든 활동
- Job이 실행되는 과정에 Model Load, Data Load도 포함
- Python Script를 그냥 실행시키는 경우도 있고, Docker Image로 실행하는 경우도 존재
Data
- 서비스에서 사용하는 DB(AWS RDS 등) 또는 데이터 웨어하우스에 저장
- 서비스 서버에서도 데이터를 불러오는 스케줄링 Job이 존재 => 특정 시간 단위로 가져옴
Batch 장단점
장점
- 기존에 사용하던 코드를 재사용 가능
- API 서버를 개발하지 않아도 되는 단순함
- 서버 리소스를 유연하게 관리할 수 있음(오래 걸릴 Job에 서버 리소스 추가 투입)
고민할 점
- 별도의 스케줄러(예 : Apache Airflow) 필요
실시간서버
모델이 항상 Load 된 상태에서 예측을 해주는 API 서버를 만들고,
추천 결과가 필요한 경우 서비스 서버에서 이 예측 서버에 직접 요청
2.3 Web Single 패턴
API 서버 코드에 모델을 포함시킨 뒤 배포
예측이 필요한 곳(클라이언트, 서버 등)에서 직접 Request 요청

Client
앱에서 직접 요청할 수도 있고, 앱이 서비스 서버에 요청하고 서비스 서버가 예측
서버에게 또 요청할 수도 있음(개발을 어떻게 했는지에 따라 다름)
Data
Load Balancer
- 트래픽을 분산시켜서 서버에 과부하를 걸리지 않도록 해줌
- Nginx, Amazon ELB(Elastic Load Balancing) 등을 사용
예측/추론 Server
- FastAPI, Flask 등으로 단일 REST API 서버를 개발 후 배포
예 : POST api-server-url/predict로 예측
- API 서버가 실행될 때 모델을 로드
- API 로직 내에 전처리도 같이 포함
장점
- 보통 하나의 프로그래밍 언어로 진행
- 아키텍처의 단순함
- 처음 사용할 때 좋은 방식
고민할 점
- 구성 요소 하나(모델, 전처리 코드 등)가 바뀌면 전체 업데이트가 필요
- 모델이 큰 경우, 로드에 시간이 오래 걸릴 수 있음
- 요청 처리가 오래 걸리는 경우, 서버에 부하가 걸릴 수 있음
👉 처음 할때는 이게 좋아 보임.
2.4 Synchronous 패턴
Synchronous: 동기식
하나의 작업이 끝날 때까지 다른 작업을 시작하지 않고 기다리고, 작업이 끝나면 새로운 작업을 시작하는 방식
- 클라이언트는 API 서버로 요청을 한 뒤 이 요청이 끝날 때까지 기다려야 함
- 앞에서 설명한 Web Single 패턴을 동기적(Synchronous)으로 서빙
- 기본적으로 대부분의 REST API 서버는 동기적으로 서빙

"wait for response" 해야 한다.
장점
- 아키텍처의 단순함
- 예측이 완료될 때까지 프로세스가 다른 작업을 할 필요가 없어서 Workflow가 단순해짐
고민할 점
- 예측 속도가 병목이 됨
(동시에 1000개의 요청이 올 경우 대기 시간이 길어지거나 Drop 혹은 Timeout)
- 예측 지연으로 사용자 경험이 악화될 수 있음
2.5 Asynchronous 패턴
하나의 작업을 시작하고, 결과를 기다리는 동안 다른 작업을 할 수 있음
작업이 완료되면 시스템에서 결과를 알려줌
- API 서버의 부하가 늘지 않게 요청을 하며 다 처리할 수 있어야 함
- 클라이언트는 당장 결과를 받지 않더라도, 최종적으로 결과를 받아야 함

Queue
- 클라이언트와 예측 서버 사이에 메시지 시스템(Queue)을 추가
- 대표적인 메시지 프레임워크 : Apache Kafka
- 지하철 물품 보관소와 유사한 역할
- Push : 메시지 저장
- Pull : 메시지를 가지고 와서 작업(예측) 수행
장점
- 클라이언트와 예측 프로세스가 분리 => 관계가 의존적이지 않음
- 클라이언트가 예측을 기다릴 필요가 없음
고민할 점
- 메시지 Queue 시스템을 만들어야 함
- 전체적으로 구조가 복잡해짐
- 완전한 실시간 예측엔 적절하지 않음(메시지를 가져갈 때 시간이 소요될 수 있음
3. Anti Serving 패턴
Anti는 일반적으로 권장되지 않는 것을 의미
즉, Anti Serving 패턴은 권장되지 않는 Serving 패턴, 즉 주의해야 할 패턴
대표적인 2가지 패턴
- Online Bigsize 패턴
- All-in-one 패턴
3.1 Online Bigsize 패턴
실시간 대응이 필요한 온라인 서비스에 예측에 오래 걸리는 모델을 사용하는 경우
문제
- 일반적으로 Bigsize 모델은 배포할 때 서버 실행과 서빙이 느림
- 속도와 비용 Tradeoff를 조절해 모델 경량화하는 작업이 필요
대안
- 실시간이 아닌 배치로 변경하는 것도 가능한지 검토
- 중간에 캐시 서버를 추가하고, 전처리를 분리하는 것도 Bigsize를 탈피하는 방법
3.2 All-in-one 패턴
하나의 서버에 여러 예측 모델을 띄우는 경우
문제
- 라이브러리 선택 제한이 존재함
- 장애가 발생할 경우(서버가 갑자기 다운) 시스템이 마비됨 (SPOF, Single Point Of
Failure)
대안
- 모델 별로 서버를 분리하여 배포 (Microservice 패턴)
4. 참고사항
우버ML
https://www.uber.com/en-KR/blog/scaling-michelangelo/
ML on real-time
https://huyenchip.com/2020/12/27/real-time-machine-learning.html