TorchServ 사용해보기
TorchServe를 시작하기 위한 요약입니다.
파이토치/서브NET에서 제공하는 학습 모델을 사용하여 RestApi로 추론하는 방법입니다.
Torchserve는 Docker 이미지를 사용합니다.
참조
https://github.com/pytorch/serve/tree/master/examples/image_classifier/densenet_161
모델 압축
모델이 훈련되면 pth 파일이 로컬로 생성됩니다. 이 모델 파일은 TorchServe에서 그대로 사용할 수 없으므로 훈련된 모델을 먼저 압축해야 합니다.
TorchServe에서 제공하는 모델을 다운로드합니다.
그래요 D:\save_model 경로에 넣어두겠습니다.
로컬 경로로 pytorch/torchserve -v 옵션으로 컨테이너 볼륨을 마운트한 후 컨테이너를 실행합니다.
> docker run --rm -it -v D:\save_model:/models/model pytorch/torchserve bash
| 옵션 | 설명 |
|---|---|
| –rm | 컨테이너가 다운되는 즉시 삭제 |
| -그것 | -i와 -t를 동시에 사용하여 컨테이너 터미널에 연결하여 명령어를 사용할 수 있습니다. |
| -V | 호스트의 로컬 디렉터리를 컨테이너의 디렉터리에 연결(마운트)합니다. |
| 세게 때리다 | -it를 사용하려면 마지막 bash 명령을 실행하십시오. |
컨테이너를 실행한 후 컨테이너 내에서 다음 명령을 실행합니다.
$ torch-model-archiver --model-name densenet161 --version 1.0 --model-file /models/model/model.py --serialized-file /models/model/densenet161-8d451a50.pth --export-path /models/model/ --handler image_classifier
| 옵션 | 설명 |
|---|---|
| –모델명 | 모델명 모델명으로 mar 파일이 생성됩니다. |
| –버전 1.0 | 버전 정보 |
| –모델 파일 | state_dict와 함께 .pth에 사용합니다. |
| –직렬화된 파일 | .pt 또는 .pth 파일 위치 |
| –내보내기 경로 | mar 파일 생성 위치 |
| –매니저 | 데이터 수신 시 전처리/추론/후처리를 관리하는 파일을 커스텀 파일로 생성할 수 있습니다. |
D:\save_model에게 densenet161.mar 파일이 생성되었으면 준비가 완료된 것입니다.
TorchServ 실행
이제 Inference Serving을 위해 컨테이너를 다시 시작합니다.
> docker run --rm -p 8080:8080 -p 8081:8081 -v D:\save_model\:/tmp/models pytorch/torchserve torchserve --model-store=/tmp/models/ --models /tmp/models/densenet161.mar
Torchserve version: 0.5.3
TS Home: /home/venv/lib/python3.8/site-packages
Current directory: /home/model-server
Temp directory: /home/model-server/tmp
Number of GPUs: 0
Number of CPUs: 16
Max heap size: 6384 M
Python executable: /home/venv/bin/python
Config file: config.properties
Inference address: http://0.0.0.0:8080
Management address: http://0.0.0.0:8081
Metrics address: http://0.0.0.0:8082
Model Store: /tmp/models
Initial Models: /tmp/models/densenet161.mar
Log dir: /home/model-server/logs
Metrics dir: /home/model-server/logs
Netty threads: 32
Netty client threads: 0
Default workers per model: 16
Blacklist Regex: N/A
Maximum Response Size: 6553500
Maximum Request Size: 6553500
Limit Maximum Image Pixels: true
Prefer direct buffer: false
Allowed Urls: (file://.*|http(s)?://.*)
Custom python dependency for model allowed: false
Metrics report format: prometheus
Enable metrics API: true
Workflow Store: /tmp/models
Model config: N/A
2022-03-22T01:53:50,124 (INFO ) main org.pytorch.serve.ModelServer - Loading initial models: /tmp/models/densenet161.mar
위의 로그가 찍히면 컨테이너가 정상적으로 실행되고 있는 것입니다.
{
"status": "Healthy"
}
위의 경로에서 추론 서버의 상태를 확인할 수 있습니다.
http://localhost:8080/predictions/densenet161
{
"code": 503,
"type": "InternalServerException",
"message": "Prediction failed"
}
모델 경로를 입력하면 예측이 실패했음을 알 수 있지만 정상적으로 작동합니다.
REST API 추론

그 이미지를 유추해보면 0 나와야합니다.
import json
import requests
import numpy as np
import cv2
from PIL import Image
from io import BytesIO
def preprocess(img_path_or_buf):
# Check whether image is a path or a buffer
raw_image = (
Image.fromarray(cv2.imread(img_path_or_buf))
if isinstance(img_path_or_buf, str)
else img_path_or_buf
)
# If buffer was np.array instead of PIL.Image, transform it
if type(raw_image) == np.ndarray:
raw_image = Image.fromarray(raw_image)
raw_image = raw_image.convert("RGB")
raw_image_bytes = BytesIO()
raw_image.save(raw_image_bytes, format="PNG")
raw_image_bytes.seek(0)
return raw_image_bytes.read()
data = preprocess('test_data/torch_dataset/kitten.jpg')
headers = {"content-type": "image/png"}
url = "http://localhost:8080/predictions/densenet161"
response = requests.post(url, data=data, headers=headers)
predictions = json.loads(response.text)
print('실제 값 : {} / 예측 값 : {}'.format('0', np.argmax(predictions)))
이 Python 코드는 로컬 이미지를 읽고 바이트로 변환한 다음 RESTAPI 경로로 보내 예측 값을 얻습니다.
실제 값 : 0 / 예측 값 : 0