-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tf-serving support model on NFS #688
Changes from 3 commits
6f344d0
8f384cb
61ce6b4
a4ecab0
8602b6b
0778285
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Serve a local model using Tensorflow Serving | ||
|
||
- Build NFS Server and allow your k8s machine to access. (more detail in [Setup an NFS Server](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nfs-mount-on-ubuntu-16-04)). Assume `/var/nfs/general` folder has exported now. | ||
|
||
- Put your model into NFS. In this tutorial, we also use inception model. So first download the whole model from [here](https://console.cloud.google.com/storage/browser/kubeflow-models/inception). Assume your model is located on `/var/nfs/general/inception`. | ||
|
||
- Install NFS Client Components on your k8s machine | ||
|
||
``` | ||
$ sudo apt-get update | ||
$ sudo apt-get install nfs-common | ||
``` | ||
|
||
- Check if model is available *(Optional)* | ||
|
||
``` | ||
$ sudo mkdir -p /nfs/general | ||
$ sudo mount NFS_SERVER_IP:/var/nfs/general /nfs/general | ||
$ ls /nfs/general | ||
inception | ||
``` | ||
|
||
- Create Persistent Volume(PV) and Persistent Volume Claim(PVC) *[learn more](https://github.com/kubernetes/examples/tree/master/staging/volumes/nfs)* | ||
|
||
- Create PV. You need to modify `NFS_SERVER_IP` to yours | ||
|
||
|
||
``` | ||
$ cat nfs-pv.yaml | ||
apiVersion: v1 | ||
kind: PersistentVolume | ||
metadata: | ||
name: nfs | ||
spec: | ||
capacity: | ||
storage: 1Mi | ||
accessModes: | ||
- ReadWriteMany | ||
nfs: | ||
server: NFS_SERVER_IP | ||
path: "/" | ||
|
||
$ kubectl create -f nfs-pv.yaml | ||
``` | ||
|
||
- Create PVC | ||
|
||
``` | ||
$ cat nfs-pvc.yaml | ||
apiVersion: v1 | ||
kind: PersistentVolumeClaim | ||
metadata: | ||
name: nfs | ||
spec: | ||
accessModes: | ||
- ReadWriteMany | ||
storageClassName: "" | ||
resources: | ||
requests: | ||
storage: 1Mi | ||
|
||
$ kubectl create -f nfs-pvc.yaml | ||
``` | ||
|
||
- Check PV and PVC *(Optional)* | ||
|
||
``` | ||
$ kubectl get pv | ||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE | ||
nfs 1Mi RWX Retain Bound default/nfs 20h | ||
|
||
$kubectl get pvc | ||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE | ||
nfs Bound nfs 1Mi RWX 20h | ||
``` | ||
|
||
- Create a Component for your model. You need to add `/mnt` before model path | ||
|
||
``` | ||
$ MODEL_COMPONENT=serveInceptionNFS | ||
$ MODEL_NAME=inception-nfs | ||
$ MODEL_PATH=/mnt/var/nfs/general/inception | ||
$ MODEL_STORAGE_TYPE=nfs | ||
$ NFS_PVC_NAME=nfs | ||
$ ks generate tf-serving ${MODEL_COMPONENT} --name=${MODEL_NAME} | ||
$ ks param set ${MODEL_COMPONENT} modelPath ${MODEL_PATH} | ||
$ ks param set ${MODEL_COMPONENT} modelStorageType ${MODEL_STORAGE_TYPE} | ||
$ ks param set ${MODEL_COMPONENT} nfsPVC ${NFS_PVC_NAME} | ||
``` | ||
|
||
- Deploy the model component. Ksonnet will pick up existing parameters for your environment (e.g. cloud, nocloud) and customize the resulting deployment appropriately | ||
|
||
``` | ||
$ ks apply ${KF_ENV} -c ${MODEL_COMPONENT} | ||
``` | ||
|
||
- Use the served model see [here](https://github.com/kubeflow/kubeflow/tree/master/components/k8s-model-server#use-the-served-model) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,13 @@ | |
runAsUser: 1000, | ||
fsGroup: 1000, | ||
}, | ||
volumeMounts+: if 'modelStorageType' om $.params then | ||
if $.params.modelStorageType == "nfs" then [{ | ||
name: "nfs", | ||
mountPath: "/mnt", | ||
}] | ||
else [] | ||
else [], | ||
}, // tfServingContainer | ||
|
||
tfServingContainer+: $.parts.tfServingContainerBase + | ||
|
@@ -217,6 +224,16 @@ | |
if $.util.toBool($.params.deployHttpProxy) then | ||
$.parts.httpProxyContainer, | ||
], | ||
volumes+: if 'modelStorageType' in $.params then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reasonable. Yesterday I tried to make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking just use a param, modelStorageType = cloud by default. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If using
It will shows an error:
When I replace
It runs well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean, just doing params:: { It will get overridden if you pass the param modelStorageType There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh ok! thanks for telling! |
||
if $.params.modelStorageType == "nfs" then | ||
[{ | ||
name: "nfs", | ||
persistentVolumeClaim: { | ||
claimName: $.params.nfsPVC, | ||
} | ||
}] | ||
else [] | ||
else [], | ||
}, | ||
}, | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's the
om
hereThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes! thanks for telling!