[demos] Update tf serving example with resnet model
This commit is contained in:
parent
6cb368fbbe
commit
91dd93d9a4
@ -55,9 +55,9 @@ Now users could send inference request with server certificates (`server.crt`).
|
|||||||
|
|
||||||
There are prebuilt docker images could be used for the examples, either in the following docker way or [`kubernates`](./kubernetes/) way. Users could pull them directly and try the example.
|
There are prebuilt docker images could be used for the examples, either in the following docker way or [`kubernates`](./kubernetes/) way. Users could pull them directly and try the example.
|
||||||
```
|
```
|
||||||
docker pull occlum/init_ra_server:0.29.2-ubuntu20.04
|
docker pull occlum/init_ra_server:0.29.5-ubuntu20.04
|
||||||
docker pull occlum/tf_demo:0.29.2-ubuntu20.04
|
docker pull occlum/tf_demo:0.29.5-ubuntu20.04
|
||||||
docker pull occlum/tf_demo_client:0.29.2-ubuntu20.04
|
docker pull occlum/tf_demo_client:0.29.5-ubuntu20.04
|
||||||
```
|
```
|
||||||
|
|
||||||
If users want to build or customize the images, please check below part.
|
If users want to build or customize the images, please check below part.
|
||||||
@ -66,11 +66,11 @@ If users want to build or customize the images, please check below part.
|
|||||||
|
|
||||||
Our target is to deploy the demo in separated container images, so docker build is necessary steps. Thanks to the `docker run in docker` method, this example build could be done in Occlum development container image.
|
Our target is to deploy the demo in separated container images, so docker build is necessary steps. Thanks to the `docker run in docker` method, this example build could be done in Occlum development container image.
|
||||||
|
|
||||||
First, please make sure `docker` is installed successfully in your host. Then start the Occlum container (use version `0.29.2-ubuntu20.04` for example) as below.
|
First, please make sure `docker` is installed successfully in your host. Then start the Occlum container (use version `latest-ubuntu20.04` for example) as below.
|
||||||
```
|
```
|
||||||
$ sudo docker run --rm -itd --network host \
|
$ sudo docker run --rm -itd --network host \
|
||||||
-v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock \
|
-v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
occlum/occlum:0.29.2-ubuntu20.04
|
occlum/occlum:latest-ubuntu20.04
|
||||||
```
|
```
|
||||||
|
|
||||||
All the following are running in the above container.
|
All the following are running in the above container.
|
||||||
@ -101,7 +101,7 @@ For the tensorflow-serving, there is no need rebuild from source, just use the o
|
|||||||
Once all content ready, runtime container images build are good to go.
|
Once all content ready, runtime container images build are good to go.
|
||||||
This step builds two container images, `init_ra_server` and `tf_demo`.
|
This step builds two container images, `init_ra_server` and `tf_demo`.
|
||||||
```
|
```
|
||||||
# ./build_container_images.sh <registry>
|
# ./build_container_images.sh <registry> <tag>
|
||||||
```
|
```
|
||||||
|
|
||||||
`<registry>` means the docker registry prefix for the generated container images.
|
`<registry>` means the docker registry prefix for the generated container images.
|
||||||
@ -128,12 +128,13 @@ usage: run_container.sh [OPTION]...
|
|||||||
-p <GRPC Server port> default 50051.
|
-p <GRPC Server port> default 50051.
|
||||||
-u <PCCS URL> default https://localhost:8081/sgx/certification/v3/.
|
-u <PCCS URL> default https://localhost:8081/sgx/certification/v3/.
|
||||||
-r <registry prefix> the registry for this demo container images.
|
-r <registry prefix> the registry for this demo container images.
|
||||||
|
-g <image tag> the container images tag, default it is "latest".
|
||||||
-h <usage> usage help
|
-h <usage> usage help
|
||||||
```
|
```
|
||||||
|
|
||||||
For example, using PCCS service from aliyun.
|
For example, using PCCS service from aliyun.
|
||||||
```
|
```
|
||||||
$ sudo ./run_container.sh -s localhost -p 50051 -u https://sgx-dcap-server.cn-shanghai.aliyuncs.com/sgx/certification/v3/ -r demo
|
$ sudo ./run_container.sh -s localhost -p 50051 -u https://sgx-dcap-server.cn-shanghai.aliyuncs.com/sgx/certification/v3/ -r demo -g <tag>
|
||||||
```
|
```
|
||||||
|
|
||||||
If everything goes well, the tensorflow serving service would be available by GRPC secure channel `localhost:9000`.
|
If everything goes well, the tensorflow serving service would be available by GRPC secure channel `localhost:9000`.
|
||||||
@ -142,12 +143,20 @@ If everything goes well, the tensorflow serving service would be available by GR
|
|||||||
|
|
||||||
There is an example python based [`inference client`](./client/inception_client.py) which sends a picture to tensorflow serving service to do inference with previously generated server certificate.
|
There is an example python based [`inference client`](./client/inception_client.py) which sends a picture to tensorflow serving service to do inference with previously generated server certificate.
|
||||||
|
|
||||||
|
Install the dependent python packages.
|
||||||
|
```
|
||||||
|
# pip3 install -r client/requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the inference request.
|
||||||
```
|
```
|
||||||
# cd client
|
# cd client
|
||||||
# python3 inception_client.py --server=localhost:9000 --crt ../ssl_configure/server.crt --image cat.jpg
|
# python3 resnet_client_grpc.py --server=localhost:9000 --crt ../ssl_configure/server.crt --image cat.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If everything goes well, you will get the most likely predication class (int value, mapping could be found on https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt) and its probability.
|
||||||
|
|
||||||
Or you can use the demo client container image to do the inference test.
|
Or you can use the demo client container image to do the inference test.
|
||||||
```
|
```
|
||||||
$ docker run --rm --network host <registry>/tf_demo_client:<tag> python3 inception_client.py --server=localhost:9000 --crt server.crt --image cat.jpg
|
$ docker run --rm --network host <registry>/tf_demo_client:<tag> python3 resnet_client_grpc.py --server=localhost:9000 --crt server.crt --image cat.jpg
|
||||||
```
|
```
|
||||||
|
@ -27,10 +27,11 @@ function build_tf_serving()
|
|||||||
# Dump tensorflow/serving container rootfs content
|
# Dump tensorflow/serving container rootfs content
|
||||||
./dump_rootfs.sh -i tensorflow/serving -d ${TF_DIR} -g 2.5.1
|
./dump_rootfs.sh -i tensorflow/serving -d ${TF_DIR} -g 2.5.1
|
||||||
pushd ${TF_DIR}
|
pushd ${TF_DIR}
|
||||||
# Download pretrained inception model
|
# Download pretrained resnet model
|
||||||
rm -rf INCEPTION*
|
rm -rf resnet*
|
||||||
curl -O https://s3-us-west-2.amazonaws.com/tf-test-models/INCEPTION.zip
|
wget https://tfhub.dev/tensorflow/resnet_50/classification/1?tf-hub-format=compressed -O resnet.tar.gz
|
||||||
unzip INCEPTION.zip
|
mkdir -p resnet/123
|
||||||
|
tar zxf resnet.tar.gz -C resnet/123
|
||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import grpc
|
import grpc
|
||||||
import tensorflow as tf
|
import tensorflow as tf
|
||||||
import argparse, time, grpc, asyncio
|
import argparse, time, grpc, asyncio
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from tensorflow_serving.apis import predict_pb2
|
from tensorflow_serving.apis import predict_pb2
|
||||||
from tensorflow_serving.apis import prediction_service_pb2_grpc
|
from tensorflow_serving.apis import prediction_service_pb2_grpc
|
||||||
@ -22,17 +24,22 @@ class benchmark_engine(object):
|
|||||||
def __prepare__(self):
|
def __prepare__(self):
|
||||||
for idx in range(self.concurrent_num):
|
for idx in range(self.concurrent_num):
|
||||||
# get image array
|
# get image array
|
||||||
with open(self.image, 'rb') as f:
|
# with open(self.image, 'rb') as f:
|
||||||
input_name = 'images'
|
# input_name = 'images'
|
||||||
input_shape = [1]
|
# input_shape = [1]
|
||||||
input_data = f.read()
|
# input_data = f.read()
|
||||||
|
|
||||||
|
# Load the image and convert to RGB
|
||||||
|
img = Image.open(self.image).convert('RGB')
|
||||||
|
img = img.resize((224,224), Image.BICUBIC)
|
||||||
|
img_array = np.array(img)
|
||||||
|
img_array = img_array.astype(np.float32) /255.0
|
||||||
# create request
|
# create request
|
||||||
request = predict_pb2.PredictRequest()
|
request = predict_pb2.PredictRequest()
|
||||||
request.model_spec.name = 'INCEPTION'
|
request.model_spec.name = 'resnet'
|
||||||
request.model_spec.signature_name = 'predict_images'
|
request.model_spec.signature_name = 'serving_default'
|
||||||
request.inputs[input_name].CopyFrom(
|
request.inputs['input_1'].CopyFrom(
|
||||||
tf.make_tensor_proto(input_data, shape=input_shape))
|
tf.make_tensor_proto(img_array, shape=[1,224,224,3]))
|
||||||
|
|
||||||
self.request_signatures.append(request)
|
self.request_signatures.append(request)
|
||||||
return None
|
return None
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import grpc
|
|
||||||
import tensorflow as tf
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
from tensorflow_serving.apis import predict_pb2
|
|
||||||
from tensorflow_serving.apis import prediction_service_pb2_grpc
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
with open(args.crt, 'rb') as f:
|
|
||||||
creds = grpc.ssl_channel_credentials(f.read())
|
|
||||||
channel = grpc.secure_channel(args.server, creds)
|
|
||||||
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
|
|
||||||
# Send request
|
|
||||||
with open(args.image, 'rb') as f:
|
|
||||||
# See prediction_service.proto for gRPC request/response details.
|
|
||||||
request = predict_pb2.PredictRequest()
|
|
||||||
request.model_spec.name = 'INCEPTION'
|
|
||||||
request.model_spec.signature_name = 'predict_images'
|
|
||||||
|
|
||||||
input_name = 'images'
|
|
||||||
input_shape = [1]
|
|
||||||
input_data = f.read()
|
|
||||||
request.inputs[input_name].CopyFrom(
|
|
||||||
tf.make_tensor_proto(input_data, shape=input_shape))
|
|
||||||
|
|
||||||
result = stub.Predict(request, 10.0) # 10 secs timeout
|
|
||||||
print(result)
|
|
||||||
|
|
||||||
print("Inception Client Passed")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--server', default='localhost:9000',
|
|
||||||
help='Tenforflow Model Server Address')
|
|
||||||
parser.add_argument('--crt', default=None, type=str, help='TLS certificate file path')
|
|
||||||
parser.add_argument('--image', default='Siberian_Husky_bi-eyed_Flickr.jpg',
|
|
||||||
help='Path to the image')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
main()
|
|
@ -1,4 +1,5 @@
|
|||||||
grpcio>=1.34.0
|
grpcio>=1.34.0
|
||||||
aiohttp>=3.7.0
|
aiohttp>=3.7.0
|
||||||
tensorflow>=2.3.0
|
tensorflow==2.11
|
||||||
tensorflow-serving-api>=2.3.0
|
tensorflow-serving-api==2.11
|
||||||
|
Pillow==9.4
|
||||||
|
48
example/client/resnet_client_grpc.py
Normal file
48
example/client/resnet_client_grpc.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import grpc
|
||||||
|
import tensorflow as tf
|
||||||
|
import argparse
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
from tensorflow_serving.apis import predict_pb2
|
||||||
|
from tensorflow_serving.apis import prediction_service_pb2_grpc
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open(args.crt, 'rb') as f:
|
||||||
|
creds = grpc.ssl_channel_credentials(f.read())
|
||||||
|
channel = grpc.secure_channel(args.server, creds)
|
||||||
|
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
|
||||||
|
|
||||||
|
# Load the image and convert to RGB
|
||||||
|
img = Image.open(args.image).convert('RGB')
|
||||||
|
img = img.resize((224,224), Image.BICUBIC)
|
||||||
|
img_array = np.array(img)
|
||||||
|
img_array = img_array.astype(np.float32) /255.0
|
||||||
|
|
||||||
|
# Create a request message for TensorFlow Serving
|
||||||
|
request = predict_pb2.PredictRequest()
|
||||||
|
request.model_spec.name = 'resnet'
|
||||||
|
request.model_spec.signature_name = 'serving_default'
|
||||||
|
request.inputs['input_1'].CopyFrom(
|
||||||
|
tf.make_tensor_proto(img_array, shape=[1,224,224,3]))
|
||||||
|
|
||||||
|
# Send the request to TensorFlow Serving
|
||||||
|
result = stub.Predict(request, 10.0)
|
||||||
|
|
||||||
|
# Print the predicted class and probability
|
||||||
|
result = result.outputs['activation_49'].float_val
|
||||||
|
class_idx = np.argmax(result)
|
||||||
|
print('Prediction class: ', class_idx)
|
||||||
|
print('Probability: ', result[int(class_idx)])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--server', default='localhost:9000',
|
||||||
|
help='Tenforflow Model Server Address')
|
||||||
|
parser.add_argument('--crt', default=None, type=str, help='TLS certificate file path')
|
||||||
|
parser.add_argument('--image', default='Siberian_Husky_bi-eyed_Flickr.jpg',
|
||||||
|
help='Path to the image')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
main()
|
@ -56,12 +56,12 @@ usage: build.sh [OPTION]...
|
|||||||
|
|
||||||
For example, below command generates three container images.
|
For example, below command generates three container images.
|
||||||
```
|
```
|
||||||
# ./build.sh -r demo -g 0.29.2
|
# ./build.sh -r demo -g 0.29.5
|
||||||
```
|
```
|
||||||
|
|
||||||
* **`demo/init_ra_server:0.29.2`** acts as key broker pod.
|
* **`demo/init_ra_server:0.29.5`** acts as key broker pod.
|
||||||
* **`demo/tf_demo:0.29.2`** acts as tensorflow serving pod.
|
* **`demo/tf_demo:0.29.5`** acts as tensorflow serving pod.
|
||||||
* **`demo/tf_demo_client:0.29.2`** acts as client.
|
* **`demo/tf_demo_client:0.29.5`** acts as client.
|
||||||
|
|
||||||
## How to test
|
## How to test
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ In default, only one replica for the tensorflow serving pod.
|
|||||||
### Try the inference request
|
### Try the inference request
|
||||||
|
|
||||||
```
|
```
|
||||||
$ docker run --rm --network host demo/tf_demo_client:0.29.2 python3 inception_client.py --server=localhost:31001 --crt server.crt --image cat.jpg
|
$ docker run --rm --network host demo/tf_demo_client:0.29.5 python3 resnet_client_grpc.py --server=localhost:31001 --crt server.crt --image cat.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
If successful, it prints the classification results.
|
If successful, it prints the classification results.
|
||||||
@ -120,7 +120,7 @@ If successful, it prints the classification results.
|
|||||||
Below command can do benchmark test for the tensorflow serving service running in Occlum.
|
Below command can do benchmark test for the tensorflow serving service running in Occlum.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ docker run --rm --network host demo/tf_demo_client:0.29.2 python3 benchmark.py --server localhost:31001 --crt server.crt --cnum 4 --loop 10 --image cat.jpg
|
$ docker run --rm --network host demo/tf_demo_client:0.29.5 python3 benchmark.py --server localhost:31001 --crt server.crt --cnum 4 --loop 10 --image cat.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
Try scale up the tensorflow serving pods number, better `tps` can be achieved.
|
Try scale up the tensorflow serving pods number, better `tps` can be achieved.
|
||||||
|
@ -29,8 +29,8 @@ spec:
|
|||||||
- occlum
|
- occlum
|
||||||
- run
|
- run
|
||||||
- /bin/tensorflow_model_server
|
- /bin/tensorflow_model_server
|
||||||
- --model_name=INCEPTION
|
- --model_name=resnet
|
||||||
- --model_base_path=/model/INCEPTION/INCEPTION
|
- --model_base_path=/models/resnet
|
||||||
- --port=9001
|
- --port=9001
|
||||||
- --ssl_config_file=/etc/tf_ssl.cfg
|
- --ssl_config_file=/etc/tf_ssl.cfg
|
||||||
ports:
|
ports:
|
||||||
|
@ -11,12 +11,12 @@ pushd occlum_server
|
|||||||
occlum run /bin/server ${GRPC_SERVER} &
|
occlum run /bin/server ${GRPC_SERVER} &
|
||||||
popd
|
popd
|
||||||
|
|
||||||
sleep 3
|
sleep 10
|
||||||
|
|
||||||
echo "Start Tensorflow-Serving on backgound ..."
|
echo "Start Tensorflow-Serving on backgound ..."
|
||||||
|
|
||||||
pushd occlum_tf
|
pushd occlum_tf
|
||||||
taskset -c 0,1 occlum run /bin/tensorflow_model_server \
|
taskset -c 0,1 occlum run /bin/tensorflow_model_server \
|
||||||
--model_name=INCEPTION --model_base_path=/model/INCEPTION/INCEPTION \
|
--model_name=resnet --model_base_path=/models/resnet \
|
||||||
--port=9000 --ssl_config_file="/etc/tf_ssl.cfg"
|
--port=9000 --ssl_config_file="/etc/tf_ssl.cfg"
|
||||||
popd
|
popd
|
||||||
|
@ -57,5 +57,5 @@ docker run --network host \
|
|||||||
--env GRPC_SERVER="${GRPC_SERVER}" \
|
--env GRPC_SERVER="${GRPC_SERVER}" \
|
||||||
${registry}/tf_demo:${tag} \
|
${registry}/tf_demo:${tag} \
|
||||||
taskset -c 0,1 occlum run /bin/tensorflow_model_server \
|
taskset -c 0,1 occlum run /bin/tensorflow_model_server \
|
||||||
--model_name=INCEPTION --model_base_path=/model/INCEPTION/INCEPTION \
|
--model_name=resnet --model_base_path=/models/resnet \
|
||||||
--port=9000 --ssl_config_file="/etc/tf_ssl.cfg" &
|
--port=9000 --ssl_config_file="/etc/tf_ssl.cfg" &
|
||||||
|
@ -2,10 +2,10 @@ includes:
|
|||||||
- base.yaml
|
- base.yaml
|
||||||
targets:
|
targets:
|
||||||
# copy model
|
# copy model
|
||||||
- target: /model
|
- target: /models
|
||||||
copy:
|
copy:
|
||||||
- dirs:
|
- dirs:
|
||||||
- ${TF_DIR}/INCEPTION
|
- ${TF_DIR}/resnet
|
||||||
- target: /bin
|
- target: /bin
|
||||||
copy:
|
copy:
|
||||||
- files:
|
- files:
|
||||||
|
Loading…
Reference in New Issue
Block a user