For a more detailed guide refer to tensorflow or pytorch example or to the documentation on https://clipper.ai.


In [2]:
import mxnet as mx
import numpy as np

In [3]:
mx.__version__


Out[3]:
'1.4.1'

In [4]:
# random data generation
def get_test_point():
    return [np.random.randint(255)/255.0 for _ in range(785)]

In [5]:
data = [np.random.rand(785), np.random.rand(785)]

In [6]:
# MXNet model will read data from a file, so it is saved now
np.savetxt("mxnet.data", data, delimiter=",", fmt='%.3f')
# To see saved data uncomment the lines below
# data_load = np.loadtxt("mxnet.data", delimiter=",")
# print(data_load)

In [7]:
def predict(model, xs):
    data_iter = mx.io.NDArrayIter(xs)
    preds = model.predict(data_iter)
    preds = [preds[0]]
    return [str(p) for p in preds]

train_path = "mxnet.data"
data_iter = mx.io.CSVIter(
            data_csv=train_path, data_shape=(785, ), batch_size=1)

# Create a MXNet model
# Configure a two layer neural network
data = mx.symbol.Variable('data')
fc1 = mx.symbol.FullyConnected(data, name='fc1', num_hidden=128)
act1 = mx.symbol.Activation(fc1, name='relu1', act_type='relu')
fc2 = mx.symbol.FullyConnected(act1, name='fc2', num_hidden=10)
softmax = mx.symbol.SoftmaxOutput(fc2, name='softmax')

# Initialize the module and fit it
mxnet_model = mx.mod.Module(softmax)
mxnet_model.fit(data_iter, num_epoch=0)

train_data_shape = data_iter.provide_data

In [8]:
from clipper_admin import ClipperConnection, DockerContainerManager
from clipper_admin.deployers.mxnet import deploy_mxnet_model

In [9]:
clipper_conn = ClipperConnection(DockerContainerManager())

In [10]:
clipper_conn.start_clipper()


19-05-31:10:26:33 INFO     [docker_container_manager.py:154] [default-cluster] Starting managed Redis instance in Docker
19-05-31:10:26:36 INFO     [docker_container_manager.py:232] [default-cluster] Metric Configuration Saved at /tmp/tmp_13jf67b.yml
19-05-31:10:26:37 INFO     [clipper_admin.py:143] [default-cluster] Clipper is running

In [11]:
clipper_conn.connect()
clipper_conn.get_all_apps()


19-05-31:10:26:39 INFO     [clipper_admin.py:156] [default-cluster] Successfully connected to Clipper cluster at localhost:1337
Out[11]:
[]

In [12]:
clipper_conn.get_all_models()


Out[12]:
[]

In [13]:
clipper_conn.register_application(name="mxnet-app", input_type="doubles", 
                                  default_output="-1.0", slo_micros=100000)


19-05-31:10:26:40 INFO     [clipper_admin.py:220] [default-cluster] Application mxnet-app was successfully registered

In [14]:
deploy_mxnet_model(
    clipper_conn,
    name="mxnet-mod",
    version = 1,
    input_type="doubles",
    func=predict,
    mxnet_model=mxnet_model,
    mxnet_data_shapes=train_data_shape,
    batch_size=1)


19-05-31:10:26:40 INFO     [deployer_utils.py:41] Saving function to /tmp/tmpnrclub9pclipper
19-05-31:10:26:40 INFO     [deployer_utils.py:51] Serialized and supplied predict function
19-05-31:10:26:40 INFO     [module.py:180] Saved checkpoint to "/tmp/tmpnrclub9pclipper/mxnet_model-0000.params"
19-05-31:10:26:40 INFO     [mxnet.py:250] MXNet model saved
19-05-31:10:26:40 INFO     [mxnet.py:264] Using Python 3.6 base image
19-05-31:10:26:40 INFO     [clipper_admin.py:513] [default-cluster] Building model Docker image with model data from /tmp/tmpnrclub9pclipper
19-05-31:10:26:40 INFO     [clipper_admin.py:518] [default-cluster] Step 1/2 : FROM clipper/mxnet36-container:develop
19-05-31:10:26:40 INFO     [clipper_admin.py:518] [default-cluster]  ---> c34e78406479
19-05-31:10:26:40 INFO     [clipper_admin.py:518] [default-cluster] Step 2/2 : COPY /tmp/tmpnrclub9pclipper /model/
19-05-31:10:26:40 INFO     [clipper_admin.py:518] [default-cluster]  ---> 19043a518914
19-05-31:10:26:40 INFO     [clipper_admin.py:518] [default-cluster] Successfully built 19043a518914
19-05-31:10:26:40 INFO     [clipper_admin.py:518] [default-cluster] Successfully tagged default-cluster-mxnet-mod:1
19-05-31:10:26:40 INFO     [clipper_admin.py:520] [default-cluster] Pushing model Docker image to default-cluster-mxnet-mod:1
19-05-31:10:26:42 INFO     [docker_container_manager.py:356] [default-cluster] Found 0 replicas for mxnet-mod:1. Adding 1
19-05-31:10:26:43 INFO     [clipper_admin.py:697] [default-cluster] Successfully registered model mxnet-mod:1
19-05-31:10:26:43 INFO     [clipper_admin.py:615] [default-cluster] Done deploying model mxnet-mod:1.

In [15]:
clipper_conn.link_model_to_app(
    app_name="mxnet-app",
    model_name="mxnet-mod")


19-05-31:10:26:43 INFO     [clipper_admin.py:282] [default-cluster] Model mxnet-mod is now linked to application mxnet-app

In [16]:
clipper_conn.get_all_apps()


Out[16]:
['mxnet-app']

In [17]:
# Get query address
query_address = clipper_conn.get_query_addr()

In [18]:
# Run a query
import requests, json, numpy as np
headers = {"Content-type": "application/json"}
requests.post("http://"+query_address+"/mxnet-app/predict", headers=headers, 
              data=json.dumps({"input": get_test_point()})).json()


Out[18]:
{'query_id': 0,
 'output': '\n[0.10011463 0.10053553 0.10043429 0.10027345 0.09964842 0.09943663\n 0.09980932 0.09959482 0.09990343 0.10024941]\n<NDArray 10 @cpu(0)>',
 'default': False}

In [19]:
clipper_conn.unlink_model_from_app(model_name="mxnet-mod", app_name="mxnet-app")


19-05-31:10:26:51 INFO     [clipper_admin.py:323] Model mxnet-mod is now removed to application mxnet-app

In [20]:
clipper_conn.stop_models('mxnet-mod')


19-05-31:10:27:01 INFO     [clipper_admin.py:1238] [default-cluster] Stopped all containers for these models and versions:
{'mxnet-mod': ['1']}

In [21]:
clipper_conn.delete_application('mxnet-app')


19-05-31:10:27:01 INFO     [clipper_admin.py:239] [default-cluster] Application mxnet-app was successfully deleted

In [22]:
clipper_conn.stop_all()


19-05-31:10:27:33 INFO     [clipper_admin.py:1324] [default-cluster] Stopped all Clipper cluster and all model containers

In [ ]: