Jae-Kyung Cho LLM Developers who was a Robotics engineer

MLOps study - Raviraja Week 5: Docker

Week 5는 Docker에 대한 내용입니다.




Fast api

ref: Async 를 이용한 비동기 프로그래밍 REST API의 5가지 method

FastAPI는 http 통신 방식으로 모델을 구동할 수 있게 만들어줍니다. ML 모델을 돌리는 것 뿐만 아니라 다양한 API들을 구현하는데 사용되는 라이브러리인데요. 웹개발과 http 통신에 대한 이해도 (REST API)가 있다면 조금 더 이해하기 편할 듯 합니다. 모델을 웹으로 만들어 줄 수 있는 아주 간편한 방법이니까 이것만 조금 더 공부해 보는 것도 나쁘지 X!!

# Week5.py file
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import uvicorn
from NLPmodel import ColaPredictor

app = FastAPI(title="MLOps Basic App")
predictor = ColaPredictor("models/model.onnx")

@app.get("/", response_class=HTMLResponse)
async def home():
    html = """
    <html>
        <h2>This is a sample NLP Project</h2>
    </html>
    """
    return HTMLResponse(content=html, status_code=200)

@app.get("/predict")
async def get_prediction(text: str):
    result = predictor.predict(text)
    return result

if __name__=='__main__':
    uvicorn.run("Week5:app", host="0.0.0.0", port=8000)

fastAPI는 swagger document 페이지를 제공합니다. (URL로 API를 사용하는 대신 supervise 페이지처럼 GUI를 사용할 수 있다는 것!) 동작하는지 확인하는데는 제격이네요.

localhost:8000/docs

위 코드에서 사실 API를 직접 사용하려면 이런식으로 쓰면 됩니다. (%20은 띄어쓰기를 의미한다)

localhost:8000/predict?text=Hi%20My%20name%20is%20Jack

이제 웹페이지를 만들어 주기만 하면, URL을 연결해서 사용할 수 있다는 뜻!!




Docker

Docker는 가장 유명한 container 관리 툴입니다. 일단 고래가 엄청나게 귀엽다는 장점도 있지만 무료로 제공된다는 점에서 굉장히 널리 사용되는 것 같습니다. Docker는 크게 3가지 (Docker file, Docker image, Docker container)로 구성된다고 볼 수 있습니다.

Docker file의 경우 dependency나 몇몇 code들, 어떻게 실행하는지 등등 다양한 정보가 저장되어 있다. Docker image는 가볍고, 독립적으로 실행 가능한 소프트웨어 패키지를 의미하며 전체 코드, 런타임, 라이브러리 등이 저장되어 있다. Dock container는 Docker image를 실행한 인스턴스로, 그 안에서 프로그램이 돌아가고 있다고 생각할 수 있다. 이를 모식도로 표현하면 이렇게 되겠습니다.
스크린샷 2022-11-16 오전 12 37 07



Docker file

Docker file 내부에 작성될 수 있는 내용들은 아래와 같습니다.

  • 어떤 OS 가 사용되었는지
  • 어떤 dependency가 설치되었는지
  • 어떻게 코드를 컴파일하는지 이외에도 다양한 정보들이 포함될 수 있죠.

Docker file 최고의 장점 중 하나는 이 정보들이 한 번 build되면 캐싱되기 때문에, 다시 build 과정에서 변화가 생기게 되면 단순히 바뀐 부분만을 rebuild 해준다는 점입니다. 시간이 그만큼 단축되겠죠.

우선 Dockerfile 이라는 이름의 파일을 생성해줍니다.

touch Dockerfile

안에 아래와 같은 내용을 넣어보겠습니다.

FROM huggingface/transformers-pytorch-cpu:latest
COPY ./ /app
WORKDIR /app
RUN pip install -r requirements_inference.txt
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
EXPOSE 8000
CMD ["uvicorn", "Week5:app", "--host", "0.0.0.0", "--port", "8000"]

(혹시나 UTF-8 관련 에러가 뜨면 여기를 참고)

각각에 대해서 조금 더 알아보겠습니다.

명령어 설명  
From base image, Docker hub에서 가져오는 것이다. ubuntu:latest 등으로 ubuntu os를 가져오는 것이 일반적이다.
COPY local의 파일들 중 container에도 추가하여 사용할 파일들. 위에서는 /app과 현재의 하위 폴더 전체를 container에 추가한다.  
WORKDIR working directory  
RUN container에서 어떤 커맨드를 돌릴 것인지 특정한다. dependency 설치를 하는 것이 일반적이다.  
EXPOSE 어떤 port를 열어둘 것인지 특정한다.  
CMD 가장 처음 container를 돌릴 때 어떤 command들이 포함될 것인지 특정한다.  

그러니까 위에 작성한 Dockerfile의 경우 huggingface에서 제공하는 docker image를 기반으로 하고, requirements.txt 를 통해 Dependency library들을 설치하며, CMD를 통해 FastAPI 관련 프로세스를 실행하는 거죠.

이제 Docker file을 빌드해주면 Docker image가 생성됩니다.

docker build -t <도커 파일 REPOSITORY>:<도커 파일 TAG> .

Repository랑 Tag는 docker hub에 올라가는 것이기 때문에 custom으로 해도 되고, 기존의 것을 사용해도 됩니다.



Docker image

빌드 된 Docker image를 확인해 보겠습니다.

docker images

스크린샷 2022-11-15 오후 11 41 19

(이미지를 삭제하려면? docker rmi [ID])



Docker container

이제 Container를 이용해 만들어진 docker image의 instance를 만들어보겠습니다.

docker run -it -p 8000:8000 --name <container 이름> <docker image repository>:<docker image tag>

그러면 우리가 위에서 FastAPI를 사용했던 것이 그대로 돌아가네요!!!!!X100

docker run를 사용할 때 가장 많이 사용되는 옵션들을 간단히 살펴보면 아래와 같습니다. (출처)

옵션 설명
-it 터미널 입출력을 위한 옵션
-p 포트포워딩을 위한 옵션 (호스트와 컨테이너의 포트를 연결)
–name 컨테이너 이름 설정
-e 컨테이너 내부의 환경변수 설정
-d 백그라운드 모드
-v 호스트의 디렉토리를 컨테이너에 마운트
-rm 프로세스 종료 시 자동으로 컨테이너 삭제
–link 컨테이너 연결 <컨테이너명:별칭>

이외에도 알아두면 좋을 여러가지 명령어들을 기록해두겠습니다. 언젠간 다시 볼 날이…

명령어 설명
docker rm 해당 이름의 container의 삭제
docker ps 현재 돌아가고 있는 container들을 확인
docker ps -a 남아있는 container들을 확인 (에러로 종료된 것들을 container가 여기에 남아버린다)
docker rmi $(docker images -f “dangling=true” -q) 에러로 종료된 container들을 삭제
docker create 해당 이름의 container를 생성 (프로세스는 시작하지 않음)
docker start 해당 이름의 container 시작 (create로 생성된 경우 사용 가능)
docker stop 돌아가고 있는 container를 stop
docker detach/attach 백그라운드에서 container 돌도록/다시 컨테이너 내부로
ctrl+p, ctrl+q docker detach 단축키
docker exec <명령어> 컨테이너 내부에서 <명령어>를 실행



Compose file

Docker compose 설치
sudo apt-get install docker-compose-plugin

Docker compose file을 이용해서 여러 개의 도커를 쉽게 실행할 수 있습니다. 나중에 MLOps 제대로 하게 되면 컨테이너끼리 통신도 공부해야 하는 것 같아요…!! docker-compose.yaml 파일을 만들어보도록 하겠습니다.

# docker-compose.yaml
version: '3'
services:
  prediction_api:
    build: .
    container_name: 'inference_container'
    ports:
      - '8000:8000'

그리고

docker compose up

명령어 실행을 통해서 실행이 가능합니다. Services에 여러개의 docker 정보를 넣어주면 한번에 돌아간다능!! (여기서는 하나 뿐이지만~)




py 파일 다운로드 NLP 모델 파일 다운로드 requirements.txt 다운로드

references:

Comments