[인공지능] TensorFlow Serving - Docker Container 실행 하기, gRPC
- 인공지능
- 2022. 3. 15. 17:58
참조
소개
- Docker를 이용하여 TensorFlow Serving 실행하는 방법을 정리합니다.
Docker를 이용한 TensorFlow Serving 실행
- 모델을 SavedModel 포맷으로 저장한 이후에 이를 TensorFlow Serving에서 로드해서 API 서버로 만들 수 있습니다.
- 보통 TensorFlow Serving은 Docker를 이용해서 실행합니다.
- Docker를 이용해서 TensorFlow Serving을 실행하는 방법은 다음과 같습니다.
TensorFlow Serving 이미지 다운로드
- 먼저 docker hub에서 TensorFlow Serving 이미지를 다운로드 받습니다.
docker pull tensorflow/serving
TensorFlow Serving 컨테이너 실행
- 앞서 docker hub에서 TensorFlow Serving 이미지를 다운로드 받았습니다.
- 다음으로 TensorFlow Serving 컨테이너를 실행합니다.
docker run -t --rm -p 8500:8500 -p 8501:8501 \
-v "C:/src/test_data/save_model/tensorflow/Xception:/models/model" \
tensorflow/serving \
--model_name=mnist-model
- 각각의 명령어 인자값에 대한 설명은 다음과 같습니다.
- -p : 서버에서 데이터를 주고 받는데 사용할 포트를 지정합니다. (위 예시의 경우, 8501 포트)
- -v : 불러올 모델이 SavedModel 포맷으로 저장된 전체 경로(full path)를 의미합니다. (위 예시의 경우, C:/src/test_data/save_model/tensorflow/Xception 경로에서 모델 파일을 불러 옵니다.), :뒤에는 모델을 실행할 REST API URL을 의미합니다. (위 예시의 경우, models/mnist_model)
TensorFlow Serving 서버 실행 화면
- TensroFlow Serving 서버가 정상적으로 실행 되었다면, 다음과 같이 8501 포트로 REST API 서버가 구성되었다는 로그를 확인할 수 있습니다.
2022-03-14 02:13:03.418553: I tensorflow_serving/model_servers/server.cc:89] Building single TensorFlow model file config: model_name: mnist-model model_base_path: /models/model
2022-03-14 02:13:03.418740: I tensorflow_serving/model_servers/server_core.cc:465] Adding/updating models.
2022-03-14 02:13:03.418771: I tensorflow_serving/model_servers/server_core.cc:591] (Re-)adding model: mnist-model
2022-03-14 02:13:03.575600: I tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: mnist-model version: 1}
2022-03-14 02:13:03.575652: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: mnist-model version: 1}
2022-03-14 02:13:03.575665: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: mnist-model version: 1}
2022-03-14 02:13:03.578387: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/model/1
2022-03-14 02:13:03.630984: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve }
2022-03-14 02:13:03.631036: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/model/1
2022-03-14 02:13:03.632147: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-03-14 02:13:03.764954: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle.
2022-03-14 02:13:03.784500: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 3600010000 Hz
2022-03-14 02:13:07.343446: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/model/1
2022-03-14 02:13:07.445745: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 3867359 microseconds.
2022-03-14 02:13:07.456866: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/model/1/assets.extra/tf_serving_warmup_requests
2022-03-14 02:13:07.525380: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: mnist-model version: 1}
2022-03-14 02:13:07.528142: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models
2022-03-14 02:13:07.528241: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled
2022-03-14 02:13:07.528698: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ...
[warn] getaddrinfo: address family for nodename not supported
[evhttp_server.cc : 245] NET_LOG: Entering the event loop ...
2022-03-14 02:13:07.532548: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501
gRPC를 통한 이미지 데이터 전송 및 예측 결과
- 앞서 Docker를 이용하여 TensroFlow Serving 컨테이너를 정상적으로 실행 완료 하였습니다.
- 이제 TensorFlow Serving 을 실행할 때 지정한 아래 URL(models/model)로 Input Data를 전송한 후, 해당 Input Data에 대한 예측 결과 값을 반환 받을 수 있습니다.
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import grpc
from PIL import Image
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
def list_chunk(list, num):
return [list[idx:idx+num] for idx in range(0, len(list), num)]
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train, x_test = x_train / 255.0, x_test / 255.0
test_images = x_test[0:5]
host = 'localhost'
port = 8500
model = 'mnist-model'
channel = grpc.insecure_channel(f'{host}:{port}')
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
# Send request
# See prediction_service.proto for gRPC request/response details.
request = predict_pb2.PredictRequest()
request.model_spec.name = model
request.model_spec.signature_name = 'serving_default'
request.inputs['conv2d_input'].CopyFrom(
tf.make_tensor_proto(test_images))
result = stub.Predict(request, 10.0) # 10 secs timeout
response = np.array(result.outputs['dense_1'].float_val)
response = list_chunk(response.tolist(), 10)
for idx, list in enumerate(response):
prediction = np.argmax(list)
print('실제 값 : {} / 예측 값 : {}'.format(y_test[idx], prediction))
실행 결과
- 정상적으로 TensorFlow Serving 과 gRPC로 통신하여 Inference 된 것을 확인할 수 있습니다.
실제 값 : 7 / 예측 값 : 7
실제 값 : 2 / 예측 값 : 2
실제 값 : 1 / 예측 값 : 1
실제 값 : 0 / 예측 값 : 0
실제 값 : 4 / 예측 값 : 4
gRPC Request Input, Ouput 파마미터 값 정보
- 위의 gRPC 소스 코드를 보게 되면 아래와 같은 코드가 있습니다.
- 아래 코드에서 inputs['conv2d_input'], result.outputs['dense_1'] 이라고 해서
conv2d_input
,dense_1
2개의 파라미터 정보가 있습니다. - 해당 파라미터 정보는 모델 마다 다른 것으로 확인이 되고, 파라미터 정보를 확인 하려면 다음 주소를 통해서 Input, Output 파라미터 정보를 확인할 수 있습니다.
- http://localhost:8501/v1/models/mnist-model/metadata 위 주소로 접속하게 되면 TensorFlow Serving 컨테이너 실행하면서 만든 model의 Metadata를 확인할 수 있고 해당 내용에 input, output 파라미터 정보를 확인할 수 있습니다.
request.inputs['conv2d_input'].CopyFrom(
tf.make_tensor_proto(test_images))
...
response = np.array(result.outputs['dense_1'].float_val)
메타데이터 정보 예시
- 다음은 input, output 파라미터 정보를 확인할 수 있는 메타데이터 정보 예시 입니다.
{
"model_spec":{
"name": "mnist-model",
"signature_name": "",
"version": "1"
}
,
"metadata": {"signature_def": {
"signature_def": {
"serving_default": {
"inputs": {
"conv2d_input": {
"dtype": "DT_FLOAT",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
},
{
"size": "28",
"name": ""
},
{
"size": "28",
"name": ""
},
{
"size": "1",
"name": ""
}
],
"unknown_rank": false
},
"name": "serving_default_conv2d_input:0"
}
},
"outputs": {
"dense_1": {
"dtype": "DT_FLOAT",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
},
{
"size": "10",
"name": ""
}
],
"unknown_rank": false
},
"name": "StatefulPartitionedCall:0"
}
},
"method_name": "tensorflow/serving/predict"
},
"__saved_model_init_op": {
"inputs": {},
"outputs": {
"__saved_model_init_op": {
"dtype": "DT_INVALID",
"tensor_shape": {
"dim": [],
"unknown_rank": true
},
"name": "NoOp"
}
},
"method_name": ""
}
}
}
}
}
728x90
'인공지능' 카테고리의 다른 글
[인공지능] 텐서플로우 - 1에서 10까지 예측 모델 구하기(선형회귀) (0) | 2022.03.20 |
---|---|
[인공지능] gRPC 메타데이터 input, ouput 정보 가져오기 (0) | 2022.03.16 |
[인공지능] TensorFlow Serving - Docker Container 실행 하기, REST API (0) | 2022.03.15 |
[인공지능] 텐서플로우 서빙이란?(TensorFlow Serving) (0) | 2022.03.14 |
[인공지능] TensorFlow Could not load library cudnn_cnn_infer64_8.dll. Error code 126 에러 해결 (7) | 2022.02.23 |
이 글을 공유하기