In case of doubts refer to the documentation on https://clipper.ai.
In [2]:
import torch
import torch.nn as nn
import numpy as np
In [3]:
# Hyper-parameters
input_size = 1
output_size = 1
num_epochs = 60
learning_rate = 0.001
# Toy dataset
x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],
[9.779], [6.182], [7.59], [2.167], [7.042],
[10.791], [5.313], [7.997], [3.1]], dtype=np.float32)
y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573],
[3.366], [2.596], [2.53], [1.221], [2.827],
[3.465], [1.65], [2.904], [1.3]], dtype=np.float32)
# Linear regression model
model = nn.Linear(input_size, output_size)
# Loss and optimizer
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# Train the model
for epoch in range(num_epochs):
# Convert numpy arrays to torch tensors
inputs = torch.from_numpy(x_train)
targets = torch.from_numpy(y_train)
# Forward pass
outputs = model(inputs)
loss = criterion(outputs, targets)
# Backward and optimize
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) % 5 == 0:
print ('Epoch [{}/{}], Loss: {:.4f}'.format(
epoch+1, num_epochs, loss.item()))
In [4]:
# Create a directory for the model
%mkdir -p /tmp/pytorch
In [5]:
# Save the model to a file and remove it, we will reload it in the next step
torch.save(model.state_dict(), "/tmp/pytorch/model.pt")
print("Model saved")
del(model)
# Let's check if the model variable is really gone
try:
model
except NameError:
print("Model variable removal successful")
In [6]:
# Load the model from the file, remember you must define the model type first
# (for example nn.Linear)
model = nn.Linear(input_size, output_size)
model.load_state_dict(torch.load("/tmp/pytorch/model.pt"))
# Check model type
model.eval()
Out[6]:
In [7]:
# Predict function needs the model variable and inputs
def predict(model, inputs):
pred = torch.from_numpy(np.array(inputs, dtype=np.float32))
pred = model(pred)
pred = pred.data.numpy()
return [str(x) for x in pred]
# Test on 2 values
predict(model, [[2.0], [4.0]])
Out[7]:
In [8]:
from clipper_admin import ClipperConnection, DockerContainerManager
from clipper_admin.deployers.pytorch import deploy_pytorch_model
clipper_conn = ClipperConnection(DockerContainerManager())
In [9]:
clipper_conn.start_clipper()
In [10]:
# You can see some Clipper containers by simply running:
!docker ps
In [13]:
clipper_conn.connect()
In [14]:
# List all applications
clipper_conn.get_all_apps()
Out[14]:
In [15]:
# List all models
clipper_conn.get_all_models()
Out[15]:
In [16]:
# Add an application with a name and an input type
clipper_conn.register_application(name="pytorch-app", input_type="doubles", default_output="-1.0", slo_micros=100000)
In [17]:
# Deploy a model, to check what arguments you need run
# "?deploy_pytorch_model" to let the notebook show you the definition of the method
deploy_pytorch_model(
clipper_conn,
name="pytorch-mod",
version=1,
input_type="doubles",
func=predict,
pytorch_model=model)
In [18]:
# Link the model and the app
clipper_conn.link_model_to_app(
app_name="pytorch-app",
model_name="pytorch-mod")
In [19]:
# Show the apps again, should list one
clipper_conn.get_all_apps()
Out[19]:
In [20]:
# Get query address
query_address = clipper_conn.get_query_addr()
print(query_address)
In [21]:
# Run a query
import requests, json, numpy as np
headers = {"Content-type": "application/json"}
requests.post("http://"+query_address+"/pytorch-app/predict", headers=headers, data=json.dumps({
"input": [2.0]})).json()
# The result is the same as in the local prediction!
Out[21]:
In [22]:
# Unlink the model and the app
clipper_conn.unlink_model_from_app(model_name="pytorch-mod", app_name="pytorch-app")
In [23]:
# Stop the model
clipper_conn.stop_models('pytorch-mod')
In [24]:
# Remove the app
clipper_conn.delete_application('pytorch-app')
In [25]:
# Stop Clipper
clipper_conn.stop_all()
In [26]:
# Check that all docker processes are stopped
!docker ps
In [ ]: