Model의 동적 배포를 위해서, FaaS를 도입한 이야기를 정리하는 중입니다.
nuclio 기본 개념을 더 설명해야할 것 같아서 이번 글은 기초를 설명합니다
글의 구조는 아래와 같습니다.
- Nuclio 설치 방법
- Nuclio 실행 방법 - python hello world
- Nuclio 실행 방법 - vision - facebook (Segmenation Anyting Model)
글의 타깃 독자는 아래와 같습니다.
- Nuclio 설치가 궁금하신 분
- Nuclio hello world가 궁금하신 분
지난 포스팅에서는 아래 3가지를 적었고
- Vision MLOps 프로젝트 투입: https://mightytedkim.tistory.com/205
- 라벨링 툴로 CVAT을 선택한 이유: https://mightytedkim.tistory.com/206
- 모델 배포를 위해 FaaS를 도입한 이유: https://mightytedkim.tistory.com/209
이번에는 `Nuclio'를 코드를 설치부터 적용까지 기초를 정리하려고 해요.
1. Nuclio 설치 방법
설치 방법은 엄청 간단해요. 저희는 hello world니까, docker로 설치해볼게요
명령어를 줄바꿈해서 보면 특별한게 없지만, 에러가 있어요.
조심 포인트
1. docker.sock 의 경우 user 권한을 줘야해요 (sudo usermod -aG docker $USER)
2. volume mount를 삭제해줘요 docker vesion에 따라 실행이 안될 수 있따고 해요 (https://github.com/nuclio/nuclio/issues/3202)
docker run
--publish 18070:8070
--volume /var/run/docker.sock:/var/run/docker.sock
--name nuclio-dashboard
quay.io/nuclio/dashboard:stable-amd64
실행하면 이렇게 나와요 (2개의 container가 뜨지만 storage는 무시해주세요.)
$ docker ps | grep nuclio
51a1c06fe841 quay.io/nuclio/dashboard:stable-amd64 "/docker-entrypoint.…" 5 minutes ago Up 6 seconds (healthy) 80/tcp, 0.0.0.0:18070->8070/tcp, :::18070->8070/tcp nuclio-dashboard
6c941d441c66 gcr.io/iguazio/alpine:3.17 "/bin/sh -c '/bin/sl…" 8 minutes ago Up 8 minutes- nuclio-local-storage-reader
dashboard가 18070에 뜨는 것을 확인할 수 있습니다. 옆에 namespace는 k8s 용이니까 가볍게 무시해줍니다.
설치는 이게 끝입니다. 쉽죠?
2. Nuclio 실습
hello world는 여러개를 해볼게요
2-1. WEB UI로 Python api 만들기
Hello world 해보겠습니다. 프로젝트를 만들어줘요
new funcion을 클릭하면 검색이 있는데, hello world니까 hello 라고 검색해서 python을 선택해요
그대로 deploy 버튼을 클릭합니다.
초반에 빌드하는데 좀 시간이 걸려요. base 이미지를 pull해야하거든요
실제 완료되면 초록색으로 변해요
끝입니다. 쉽죠?
2-2. WEB UI로 Python api 만들고 테스트하기
이제 실제 상황에서 어떻게 사용할지 알아볼게요!
옆팀에서 갑자기 간단한 API를 만들어달라고 하네요.
어렵진 않죠.. 어렵진... 휴..
상황
- 급하게 api 샘플이 필요함
- post body에 특정 key값 필수
{'sample': 'sample_data_for_test'}
조치
- nuclio dashboard 들어가서 python 코드 작성 끝!
- 예전이었다면, fastapi로 코드 짜서 배포하며 테스트 했을 거에요.
테스트
- python으로 실행해봅니다. port는 ui 우측 상단에서 확인할 수 있어요
- k8s를 위한 FaaS라서 port 자동 할당도 32000번대입니다.
- 당연히 직접 할당할 수도 있고, ingress 등을 통할 수 있어요
import requests
import json
nuclio_endpoint_url = f"http://192.168.219.249:32769"
data = {'sample': 'mightytedkim'}
response = requests.post(nuclio_endpoint_url,
data=json.dumps(data),
headers={"Content-Type": "application/json"}
)
if response.status_code == 200:
result = response.text # Assuming the function returns a response
print(f"{result}")
else:
print(f"Error: {response.status_code}, {response.text}")
결과는 아래처럼 나와요 event.body['sample']로 데이터를 가져오면 되겠군요
2-3. command line으로 모델 배포하기 (nuctl)
여기서부터 조금 어려워져요. nuctl이라는 cli를 사용해야하거든요
nuctl은 Nuclio's command-line interface (CLI) 의 약자에요.
설치 방법은 아래와 같아요
curl -s https://api.github.com/repos/nuclio/nuclio/releases/latest \
| grep -i "browser_download_url.*nuctl.*$(uname)" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -O nuctl -qi - && chmod +x nuctl
build와 deploy 등의 커맨드가 있는데, 빠른 hello world를 위해 스킵하겠습니다.
CVAT의 github에 좋은 예시들이 많거든요.
https://github.com/cvat-ai/cvat/blob/develop/serverless/deploy_cpu.sh
그래도 간단하게 설명하면, web ui에서 저희가 했던 걸 아래처럼 할 수 있어요
- 프로젝트 생성: nuctl create project cvat --platform local
- 함수 배포: nuctl deploy --project-name cvat --path "./path" \ --file "./path.yaml" --platform local
설정은 function.yaml, 코드는 직접 main.py 로 구성되고 폴더 구조로는 아래와 같아요
점점 더 어려워지죠.. 조금만 참아요 거의 다 왔어요.
function.yaml에는 k8s deployment yaml과 거의 비슷해요
main.py는 위의 spec.handler에 있는 값이에요
# Facebook의 Segment Anything Model의 코드 예시에요
import json
import base64
from PIL import Image
import io
from model_handler import ModelHandler
def init_context(context):
context.logger.info("Init context... 0%")
model = ModelHandler()
context.user_data.model = model
context.logger.info("Init context...100%")
def handler(context, event):
context.logger.info("call handler")
data = event.body
pos_points = data["pos_points"]
neg_points = data["neg_points"]
buf = io.BytesIO(base64.b64decode(data["image"]))
image = Image.open(buf)
image = image.convert("RGB") # to make sure image comes in RGB
mask, polygon = context.user_data.model.handle(image, pos_points, neg_points)
return context.Response(body=json.dumps({
'points': polygon,
'mask': mask.tolist(),
}),
headers={},
content_type='application/json',
status_code=200
)
nuctl을 직접 이해하고 실행하는 것은 러닝커브가 있으니까, 오픈소스 CVAT 의 serverless 폴더를 참고할게요.
$ git clone https://github.com/cvat-ai/cvat/blob/develop/serverless/deploy_cpu.sh
$ cd serverless
$ ./deploy_cpu.sh ./pytorch/facebookresearch/sam/
이제 Facebook의 Segmentation Anythin Model을 배포했습니다ㅎ
다음 글은 MLOPS 구성을 위해, API를 이용해 Nuclio를 사용한 사례를 설명하도록 할게요
참고
https://github.com/cvat-ai/cvat/tree/develop/serverless
https://github.com/nuclio/nuclio
'AI > MLOps' 카테고리의 다른 글
데이터 잡부의 MLOps도전기 (3) - 모델 배포를 위해 FaaS를 도입해보자 #Nuclio (1) | 2024.03.31 |
---|---|
데이터 잡부의 MLOps도전기 (2) - 라벨링 툴로 CVAT을 선택한 이유 #VISION (0) | 2024.01.21 |
데이터 잡부의 MLOps도전기 (1) #이미지 불량탐지 (6) | 2024.01.07 |
Bentoml) Yatai 1.0 에서 무엇이 바뀌었을까 (0) | 2022.10.10 |
Mlflow) python, airflow로 테스트해보기 (0) | 2022.06.26 |