2023년 3월 7일 화요일

BentoML 사용법 요약

> D:\2023\poop_wrn로 이동


bentoml serve service:svc --port 3010 --reload   # bentoml 서비스 실행
locust --headless -u 100 -r 1000 --run-time 1m
--host http://127.0.0.1:3010  # stress test, locustfile.py필요
bentoml build    # bentofile.yaml 필요
bentoml list   # 생성된 bento 확인
bentoml serve poopup_demo:latest
--production --port 3010   # nox39에서 실패 후, 관리자 모드로 다시 창 열어 성공
bentoml containerize poopup_demo:latest  # docker image 생성
docker run -it --rm -p 3015:3000 --gpus all poopup_demo:ov37ue65xqb4
serve --production  # docker 서비스 시작
docker save -o poopup.tar poopup_demo:~~  # docker image의 hdd저장
docker load -i poopup.tar  # docker image의 재 로드

도커 실행 명령

> docker inspect <container-id>
...
"MergedDir":~,
"UpperDir":~,  # 여기 경로에 jpg파일이 저장
"WorkDir":~
...
# docker 실행(container 생성) 시,
> docker run -it --rm -p 30xx:3000 poopup_demo:kb2~~ serve --production
> docker exec -it <container-id> /bin/bash
>> cd src  # 여기에서 jpg파일 확인 가능


1. windows에서는 set 명령으로 환경변수를 볼 수 있으며, BENTOML_HOME=d:\2023으로 설정된 것 확인 가능

> set 

2. DNN학습->Bento 생성->Docker 이미지 생성의 순으로 진행됨. 

> bentoml build  # Bento파일 생성

> bentoml containerize <bentofile:tag>

3. Bento파일 생성 시에, bentofile.yaml 설정파일 사용. Custom docker를 위해서 bentofile.yaml에 지정된 Dockerfile.template 사용

{% extends bento_base_template %}
{% block SETUP_BENTO_BASE_IMAGE %}
{{ super() }}
{% endblock %}

{% set bento__user = "poop" %}
{% set bento__home = "/home/" ~  bento__user %}
{% set bento__path = "/home/" ~ bento__user ~ "/bento" %}
{% set bento__uid_gid = 1000 %}  

{% block SETUP_BENTO_COMPONENTS %}
{{ super() }}
{% endblock %}

4. 생성된 Bento파일(BENTNML_HOME 아래)의 해당 경로에 만들어진 Dockerfile을 봐서 Dockerfile.template 적용 확인 

5. Bento 파일을 이용하여 Docker 이미지 생성

> bentoml containerize poopup_demo:latest

6. 컨테이너 실행

> docker run --user poop -it --rm -p 3010:3000 --gpus all poopup_demo:leo2pupckkeizqb4 serve --production

# --------------- service.py -------------------------------------------
from __future__ import annotations
import typing as t
from typing import TYPE_CHECKING
from torchvision import transforms
import numpy as np
from PIL.Image import Image as PILImage

import bentoml
from bentoml.io import Image
from bentoml.io import NumpyNdarray


if TYPE_CHECKING:
    from numpy.typing import NDArray

poop_runner = bentoml.models.get("poopup:latest").to_runner()
svc = bentoml.Service(name="poopup_demo", runners=[poop_runner])

xforms = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])

def to_numpy(tensor):
    return tensor.detach().cpu().numpy()


@svc.api(input=Image(), output=NumpyNdarray(dtype="int64"))
async def predict_image(f: PILImage) -> "np.ndarray[t.Any, np.dtype[t.Any]]":
    assert isinstance(f, PILImage)

    img = np.expand_dims(xforms(f), 0)
    output_tensor = await poop_runner.async_run(img)
    # print(output_tensor, type(output_tensor))
    return output_tensor.detach().cpu().numpy()

댓글 8개:

  1. *** AWS EC2 설정 ***
    참고: https://jinjinyang.tistory.com/46


    mobaxterm 터미널에서
    > open /home/mobaxterm
    뜨는 위치에 aws키(pem) 파일 복사. 현재는 download폴더 아래의 23년 3/7 있음.

    > ssh -i "poop.pem" ubuntu@ec2-13-125-199-65.ap-northeast-2.compute.amazonaws.com
    AWS에 ssh로 들어감
    : 인스턴스 ID -> 연결 -> SSH에 연결정보 나옴


    > 환경 설정 및 설치
    2 df
    3 lsb_release -a # linux version
    4 sudo apt update # python 설치
    5 sudo apt install software-properties-common
    6 sudo add-apt-repository ppa:deadsnakes/ppa
    7 sudo apt install python3.9 # python 설치 완료
    9 python3 -V
    10 which python3
    14 sudo apt install python3.10-venv # 가상환경툴 설치
    15 python3 -m venv py10 # 가상환경 생성
    16 ls -la

    31 sudo apt-get install python3-pip # pip툴 설치
    38 pip install virtualenv
    40 source ~/py10/bin/activate # 가상환경 진입
    41 pip install jupyter # lib설치
    42 pip install pandas
    sudo apt update
    sudo apt-get -y install libgl1-mesa-glx
    43 pip install opencv-python
    46 pip install scikit-learn
    47 pip install matplotlib
    48 pip install bentoml


    * 도커 설치: https://insight.infograb.net/docs/aws/installing-docker-on-aws-ec2/


    * 인스턴스 ID -> 연결 -> SSH 연결정보 나옴
    * AWS-EC2 기본사용법(생활코딩) 비디오 보고, 포트 포워딩 설정하였음:
    보안그룹 숫자 클릭->인바운드편집->규칙추가->사용자지정TCP->포트번호지정


    curl -X 'POST' 'http://localhost:3015/predict_image' -H 'accept: application/json' -H 'Content-Type:image/x-tga' --data-binary '@dog.jpg'



    curl -X 'POST' 'http://localhost:3015/predict_image' -H 'accept: application/json' -H 'Content-Type:image/x-tga' --data-binary '@dog.jpg'
    curl -X 'POST' 'http://3.34.141.166:3015/predict_image' -H 'accept: application/json' -H 'Content-Type:image/x-tga' --data-binary '@dog.jpg'

    docker run -it --rm -p 3015:3000 --gpus all poopup_demo:ovx37anue65qxqb4 serve --production
    docker run -it --rm -p 3015:3000 poopup_demo:ajkyn2f3z2fqlqb4 serve --production



    답글삭제
    답글
    1. bentoml 1.2.19의 Yolo example(https://github.com/bentoml/BentoYolo)에서 python client호출(bentoml.SyncHTTPClient~부분)을 사용하면 응답 시간 지연을 일으킴. 다음 처럼 curl로 호출하면 응답지연 없이 실행되었음:

      > curl -X POST http://localhost:3000/predict -H "accept:application/json" -H "Content-Type:multipart/form-data" -F "images=@apple.jpg;type=image/jpg"


      2개 이상 이미지 보낼 때:
      curl -X POST http://localhost:3000/predict -H "accept:application/json" -H "Content-Type:multipart/form-data" -F "images=@apple.jpg;type=image/jpg" -F "images=@banana.jpg;type=image/jpg"

      삭제
  2. *** Docker log check ***
    sudo docker logs --tail 100 -f aa7a8b30639a

    답글삭제
  3. [bento model 제거]
    > bentoml models list # listing
    > bentoml models delete poopup:jwrtba~~~

    [bento 제거]
    > bentoml list # listing bento
    > bentoml delete poopup_demo:wienqk6uk~~~

    답글삭제
  4. # 실행 중인 container로 container-id이용하여 들어가기
    > docker exec -it {container-id} /bin/bash
    > cd ~ # container내의 home 위치

    # container내 특정 폴더를 host 폴더로 복사하기
    > docker cp {container-id}:/home/bentoml/bento/src/ ~/Downloads/poop/output

    # 우분투에서 파일 찾기 명령: 루트 / 부터 검색
    > su # su로 권한 변경 후 검색
    > find / -name '20230418_233254_620788_100.jpg'

    # container 내 저장 파일의 절대 경로
    /var/snap/docker/common/var-lib-docker/overlay2/{container관련 id}/diff/home/bentoml/bento/src/20230419_022024_931951_121.jpg

    # 미사용 container 정리
    > docker system prune --all


    # Docker volume 명령 (참고: https://www.daleseo.com/docker-volumes-bind-mounts/)
    > docker volume create vol_name # volume 생성
    > docker volume ls # 생성 volume 보기
    > docker volume inspect vol_name # 상세 정보 조회
    > ls /var/lib/docker/volumes # 생성 volume 위치
    > docker run -v my_vol:/app poopup:~~ # container생성 시 volume 연결

    답글삭제
  5. bentoml build에서 bento 파일을 만들 때, 디폴트 bentoml을 poop으로 변경하였을 경우, 실행 방법:

    > docker run --user poop -it --rm -p 3010:3000 --gpus all poopup_demo:leo2pupckkeizqb4 serve --production
    > docker run --restart always --user poop -v /home/vislab/Downloads/poop/output/src:/home/poop/bento/src -it -p 3025:3000 poopup_demo:leo2pupckkeizqb4 serve --production
    > curl -X POST -F file=@IMG_1752.JPG "http://xx.xx.xxx.xxx:3025/predict_image"

    답글삭제
  6. [nvidia gpu 인식 못하는 문제]
    * 출처: https://bluecolorsky.tistory.com/110 참고해서 해결함

    > docker run --restart always --user poop -v /home/vislab/Downloads/poop/output/src:/home/poop/bento/src -it -p 3015:3000 --gpus all poopup_demo:leo2pupckkeizqb4 serve --production

    답글삭제
  7. [bentoml과 service.py, model의 predict 사용 시]
    1. bentoml은 service.py에서 이미지를 받아서 model로 이미지를 보낸다.
    2. service.py에서 numpy 이미지를 runner로 넘기면(즉, model의 predict), 무조건 torch Tensor로 자동으로 바뀐다.
    3. model만들 때 {'batchable': False}로 설정이 될 때와 True로 설정이 될 때 predict함수로 넘어오는 tensor의
    차원이 달라진다. 각각 3차(h,w,3)와 4차(1,h,w,3)가 된다.
    4. 모델의 predict함수 만들 때, jupyter에서 만들 경우, 보통 pil이나 numpy이미지를 받아서 처리하도록 하는데, 만든 코드를
    수정을 줄이면서 사용하려면 tensor를 pil이나 numpy로 다시 바꾸어 줘야 한다.

    답글삭제