[torchserve에서 기본으로 제공하는 API]
torchserve는 기본적으로 아래 3가지 Service API를 제공하고 있습니다.
- Inference API
- Management API
- Metrics API
그리고 각각의 API는 다른 포트와 path 로 구분을 하여 request 합니다.
각 API 별 curl 예시는 아래와 같습니다.
<curl example>
API | curl example | PORT | path |
inference | http://127.0.0.1:8080/predictions/resnet-18/2.0 -T kitten_small.jpg | 8080 | predictions |
management | http://127.0.0.1:8081/models/noop | 8181 | models |
metrics | http://127.0.0.1:8082/metrics | 8082 | metrics |
여기서 8080 PORT 는 기본적으로 inference로 쓰지만,
디폴트로 설정되어있는 API가 하나 더 있는데,
explanation API입니다.
(https://pytorch.org/serve/inference_api.html#explanations-api)
[torchserve의 explanations API]
explanation API는 아래처럼 입력한 데이터에 대해
정의한 설명을 response로 받을 수 있습니다.
아래는 공식 documnet에 있는 예시입니다.
API | curl example | PORT | path |
inference | http://127.0.0.1:8080/predictions/resnet-18/2.0 -T kitten_small.jpg | 8080 | predictions |
explanation | http://127.0.0.1:8080/explanations/mnist -T test_data/0.png | 8080 | explanations |
이 때 inference와 explanation 모두
request시 handler파일의 'handle' 함수를 실행하기 때문에
어떤 경우에 inference를 실행하고,
어떤 경우에 explanation을 실행할지를 지정해야합니다.
다행히 이는 BaseHandler에 구현이 되어있어서 해당 코드를 참고해서 구현할 수있습니다.
https://github.com/pytorch/serve/blob/master/ts/torch_handler/base_handler.py
이때 inference를 할 것이냐 explanation을 할 것이냐는
self._is_explain() return 값을 받아서 판단합니다.
_is_explain() 함수를 실행했을때
어떻게 True, False를 return하는지 좀더 보겠습니다.
def handle(self, data, context):
self.context = context
metrics = self.context.metrics
if self._is_describe():
output = [self.describe_handle()]
else:
data_preprocess = self.preprocess(data)
if not self._is_explain():
output = self.inference(data_preprocess)
output = self.postprocess(output)
else:
output = self.explain_handle(data_preprocess, data)
return output
BaseHandler의 메소드인 _is_explain() 을 보면,
BaseHandler가 갖는 self.context의 값에서 "explain" 여부를 판단하는것을 볼 수있습니다.
기본적으로 BaseHandler는 초기화 당시
self.explain = False
를 기본값으로 갖고있지만
explanation API를 request를 한 경우에
이 self.explain 값을 True로 바꾸게 되고
이것을 기준으로 삼아서, 위의 handle 함수에서
inference 와 explanation을 실행하는것을 알 수있습니다.
def _is_explain(self):
if self.context and self.context.get_request_header(0, "explain"):
if self.context.get_request_header(0, "explain") == "True":
self.explain = True
return True
return False
[explanation API를 request해도 is_explain() = False인 경우]
하지만, explanation API 를 reqeust 했음에도
_is_explain()의 결과가 False로 나오는 오류가 발생해서
해결방법을 찾던 중
CustomHandler에 handle함수를 구현하지 않고
해당 클래스를 import한 다른 handler 파일을 만든후 handle 함수를 구현해서
self.explain값이 바뀌지 않는다는 것을 확인했습니다.
그리고 굳이 그렇게 handle 함수만 뽑아서 구현할 필요가 없음을 확인하고
기존에 CustomHandler 클래스의 메소드로 추가하여 만들었습니다.
이후 is_explain()값이 True로 잘 바뀐것을 확인하였습니다.
<오류가 났던 handler 파일 예시>
from CustomHandler import *
_service = ImageCLFHandler()
def handle(data, context):
if not _service._is_explain():
if data is None:
return None
else:
data = _service.preprocess(data)
data = _service.inference(data)
data = _service.postprocess(data)
return data
else:
_service.explain_handle()
return 202
'Engineering > 토치서브(Torchserve)' 카테고리의 다른 글
[Torchserve] java.lang.NoSuchMethodError (0) | 2022.11.14 |
---|---|
[Torchserve] ImportError: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (0) | 2022.11.14 |
[Torchserve] torchserve Backend worker did not respond in given time (0) | 2022.08.31 |
[Torchserve] torchserve error - java.io.IOException: Failed to bind ② (0) | 2022.08.31 |
[Torchserve] torchserve API PORT change (0) | 2022.08.30 |
댓글