Hướng dẫn này chỉ ra cách sử dụng các thành phần Phục vụ TensorFlow chạy trong bộ chứa Docker để phục vụ mô hình TensorFlow ResNet và cách triển khai cụm phân phối với Kubernetes.
Để tìm hiểu thêm về Dịch vụ TensorFlow, chúng tôi khuyên bạn nên sử dụng hướng dẫn cơ bản về Dịch vụ TensorFlow và hướng dẫn nâng cao về Dịch vụ TensorFlow .
Để tìm hiểu thêm về mô hình TensorFlow ResNet, chúng tôi khuyên bạn nên đọc ResNet trong TensorFlow .
- Phần 1 thiết lập môi trường của bạn
- Phần 2 hướng dẫn cách chạy image phục vụ Docker cục bộ
- Phần 3 trình bày cách triển khai trong Kubernetes.
Phần 1: Thiết lập
Trước khi bắt đầu, trước tiên hãy cài đặt Docker .
Tải xuống ResNet SavingModel
Hãy xóa thư mục mô hình cục bộ của chúng tôi trong trường hợp chúng tôi đã có:
rm -rf /tmp/resnet
Mạng dư sâu, hay gọi tắt là ResNet, đã cung cấp ý tưởng đột phá về ánh xạ nhận dạng để cho phép đào tạo các mạng thần kinh tích chập rất sâu. Trong ví dụ của chúng tôi, chúng tôi sẽ tải xuống TensorFlow SavingModel của ResNet cho tập dữ liệu ImageNet.
# Download Resnet model from TF Hub
wget https://tfhub.dev/tensorflow/resnet_50/classification/1?tf-hub-format=compressed -o resnet.tar.gz
# Extract SavedModel into a versioned subfolder ‘123’
mkdir -p /tmp/resnet/123
tar xvfz resnet.tar.gz -C /tmp/resnet/123/
Chúng tôi có thể xác minh rằng chúng tôi có SavingModel:
$ ls /tmp/resnet/*
saved_model.pb variables
Phần 2: Chạy trong Docker
Cam kết hình ảnh để triển khai
Bây giờ chúng tôi muốn chụp một hình ảnh phục vụ và cam kết tất cả các thay đổi đối với một hình ảnh mới $USER/resnet_serving
để triển khai Kubernetes.
Đầu tiên chúng tôi chạy một hình ảnh phục vụ dưới dạng daemon:
docker run -d --name serving_base tensorflow/serving
Tiếp theo, chúng tôi sao chép dữ liệu mô hình ResNet vào thư mục mô hình của vùng chứa:
docker cp /tmp/resnet serving_base:/models/resnet
Cuối cùng, chúng tôi cam kết vùng chứa sẽ phục vụ mô hình ResNet:
docker commit --change "ENV MODEL_NAME resnet" serving_base \
$USER/resnet_serving
Bây giờ hãy dừng container cơ sở phục vụ
docker kill serving_base
docker rm serving_base
Khởi động máy chủ
Bây giờ, hãy khởi động vùng chứa với mô hình ResNet để nó sẵn sàng phân phát, hiển thị cổng gRPC 8500:
docker run -p 8500:8500 -t $USER/resnet_serving &
Truy vấn máy chủ
Đối với máy khách, chúng tôi sẽ cần sao chép repo GitHub của TensorFlow Serve:
git clone https://github.com/tensorflow/serving
cd serving
Truy vấn máy chủ bằng resnet_client_grpc.py . Máy khách tải xuống một hình ảnh và gửi nó qua gRPC để phân loại thành các danh mục ImageNet .
tools/run_in_docker.sh python tensorflow_serving/example/resnet_client_grpc.py
Điều này sẽ dẫn đến kết quả đầu ra như:
outputs {
key: "classes"
value {
dtype: DT_INT64
tensor_shape {
dim {
size: 1
}
}
int64_val: 286
}
}
outputs {
key: "probabilities"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1001
}
}
float_val: 2.41628322328e-06
float_val: 1.90121829746e-06
float_val: 2.72477100225e-05
float_val: 4.42638565801e-07
float_val: 8.98362372936e-07
float_val: 6.84421956976e-06
float_val: 1.66555237229e-05
...
float_val: 1.59407863976e-06
float_val: 1.2315689446e-06
float_val: 1.17812135159e-06
float_val: 1.46365800902e-05
float_val: 5.81210713335e-07
float_val: 6.59980651108e-05
float_val: 0.00129527016543
}
}
model_spec {
name: "resnet"
version {
value: 123
}
signature_name: "serving_default"
}
Nó hoạt động! Máy chủ phân loại thành công hình ảnh con mèo!
Phần 3: Triển khai trong Kubernetes
Trong phần này, chúng tôi sử dụng container image được xây dựng trong Phần 0 để triển khai cụm phân phối với Kubernetes trong Google Cloud Platform .
Đăng nhập dự án GCloud
Ở đây, chúng tôi giả sử bạn đã tạo và đăng nhập vào dự án gcloud có tên tensorflow-serving
.
gcloud auth login --project tensorflow-serving
Tạo một cụm vùng chứa
Đầu tiên, chúng tôi tạo cụm Google Kubernetes Engine để triển khai dịch vụ.
$ gcloud container clusters create resnet-serving-cluster --num-nodes 5
Cái nào sẽ xuất ra cái gì đó như:
Creating cluster resnet-serving-cluster...done.
Created [https://container.googleapis.com/v1/projects/tensorflow-serving/zones/us-central1-f/clusters/resnet-serving-cluster].
kubeconfig entry generated for resnet-serving-cluster.
NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
resnet-serving-cluster us-central1-f 1.1.8 104.197.163.119 n1-standard-1 1.1.8 5 RUNNING
Đặt cụm mặc định cho lệnh vùng chứa gcloud và chuyển thông tin xác thực cụm cho kubectl .
gcloud config set container/cluster resnet-serving-cluster
gcloud container clusters get-credentials resnet-serving-cluster
điều này sẽ dẫn đến:
Fetching cluster endpoint and auth data.
kubeconfig entry generated for resnet-serving-cluster.
Tải lên hình ảnh Docker
Bây giờ chúng ta hãy đẩy hình ảnh của chúng ta lên Google Container Register để có thể chạy nó trên Google Cloud Platform.
Đầu tiên, chúng tôi gắn thẻ hình ảnh $USER/resnet_serving
bằng cách sử dụng định dạng Đăng ký vùng chứa và tên dự án của chúng tôi,
docker tag $USER/resnet_serving gcr.io/tensorflow-serving/resnet
Tiếp theo, chúng tôi định cấu hình Docker để sử dụng gcloud làm trình trợ giúp thông tin xác thực:
gcloud auth configure-docker
Tiếp theo chúng ta đẩy image vào Sổ đăng ký,
docker push gcr.io/tensorflow-serving/resnet
Tạo triển khai và dịch vụ Kubernetes
Việc triển khai bao gồm 3 bản sao của máy chủ resnet_inference
được kiểm soát bởi Triển khai Kubernetes . Các bản sao được hiển thị bên ngoài bởi Dịch vụ Kubernetes cùng với Bộ cân bằng tải bên ngoài .
Chúng tôi tạo chúng bằng ví dụ Kubernetes config resnet_k8s.yaml .
kubectl create -f tensorflow_serving/example/resnet_k8s.yaml
Với đầu ra:
deployment "resnet-deployment" created
service "resnet-service" created
Để xem trạng thái triển khai và nhóm:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
resnet-deployment 3 3 3 3 5s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
resnet-deployment-bbcbc 1/1 Running 0 10s
resnet-deployment-cj6l2 1/1 Running 0 10s
resnet-deployment-t1uep 1/1 Running 0 10s
Để xem trạng thái của dịch vụ:
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
resnet-service 10.239.240.227 104.155.184.157 8500/TCP 1m
Có thể mất một thời gian để mọi thứ được thiết lập và hoạt động.
$ kubectl describe service resnet-service
Name: resnet-service
Namespace: default
Labels: run=resnet-service
Selector: run=resnet-service
Type: LoadBalancer
IP: 10.239.240.227
LoadBalancer Ingress: 104.155.184.157
Port: <unset> 8500/TCP
NodePort: <unset> 30334/TCP
Endpoints: <none>
Session Affinity: None
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer
1m 1m 1 {service-controller } Normal CreatedLoadBalancer Created load balancer
Địa chỉ IP bên ngoài của dịch vụ được liệt kê bên cạnh LoadBalancer Ingress.
Truy vấn mô hình
Bây giờ chúng ta có thể truy vấn dịch vụ tại địa chỉ bên ngoài của nó từ máy chủ cục bộ của chúng ta.
$ tools/run_in_docker.sh python \
tensorflow_serving/example/resnet_client_grpc.py \
--server=104.155.184.157:8500
outputs {
key: "classes"
value {
dtype: DT_INT64
tensor_shape {
dim {
size: 1
}
}
int64_val: 286
}
}
outputs {
key: "probabilities"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1001
}
}
float_val: 2.41628322328e-06
float_val: 1.90121829746e-06
float_val: 2.72477100225e-05
float_val: 4.42638565801e-07
float_val: 8.98362372936e-07
float_val: 6.84421956976e-06
float_val: 1.66555237229e-05
...
float_val: 1.59407863976e-06
float_val: 1.2315689446e-06
float_val: 1.17812135159e-06
float_val: 1.46365800902e-05
float_val: 5.81210713335e-07
float_val: 6.59980651108e-05
float_val: 0.00129527016543
}
}
model_spec {
name: "resnet"
version {
value: 1538687457
}
signature_name: "serving_default"
}
Bạn đã triển khai thành công mô hình ResNet phục vụ như một dịch vụ trong Kubernetes!