Getting Started with Predictive Services

In this notebook we show how to set up a GraphLab Predictive Service deployment, to enable low-latency REST queries of trained machine learning models from a cluster of EC2 instances. For more information, see the Predictive Services section of the User Guide.

We show how easy it is to:

  1. Launch a Predictive Service deployment
  2. Add new Predictive Objects
  3. Update existing Predictive Objects
  4. Monitor deployment status
  5. Query deployed Predictive Objects
  6. Integrate deployment into an application
  7. Terminate the Predictive Service deployment

In [ ]:
import graphlab

Define EC2 Configuration

To launch a Predictive Service deployment we need to specify an Ec2Config object for this deployment. This configuration includes the region (defaults to us-west-2), instance type (defaults to m3.xlarge), and your aws credentials (if needed).


In [ ]:
env = graphlab.deploy.Ec2Config(region='us-west-2',
                                instance_type='m3.xlarge',
                                aws_access_key_id='YOUR_ACCESS_KEY', 
                                aws_secret_access_key='YOUR_SECRET_KEY')

Launch the Predictive Service Deployment

To launch a Predictive Service Deployment the API is graphlab.deploy.predictive_service.create. The required parameters are a name for the deployment, the EC2 configuration we defined in the previous step, and an S3 path for the root 'working directory' for this Predictive Service. This path is where the models and predictive objects will be uploaded, and where logs will be written for this Predictive Service.

When this command is executed the EC2 instances will be launched immediately, then a load balancer will be launched, configured, and finally the load balancer will add the instances into the cluster as they pass health checks. The Predictive Service object will also be added to the workbench, so the deployment can be easily loaded in a later Python session.


In [ ]:
deployment = graphlab.deploy.predictive_service.create('sample-service-onefive', env, 's3://gl-rajat-testing/pred-root/sample-service')
deployment.save()


[INFO] Launching Predictive Service with 1 hosts, as specified by num_hosts parameter
[INFO] Launching Predictive Service, with name: sample-service-onefive
[INFO] [Step 0/5]: Initializing S3 locations.
[INFO] [Step 1/5]: Launching EC2 instances.
[INFO] This commercial license of GraphLab Create is assigned to engr@turi.com.

[INFO] Launching an m3.xlarge instance in the us-west-2a availability zone, with id: i-7ed516b7. You will be responsible for the cost of this instance.
[INFO] WARNING: Launching Predictive Service without SSL certificate!
[INFO] [Step 2/5]: Launching Load Balancer.
[INFO] [Step 3/5]: Configuring Load Balancer.
[INFO] [Step 4/5]: Waiting for Load Balancer to put all instances into service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster not fully operational yet, [0/1] instances currently in service.
[INFO] Cluster is fully operational, [1/1] instances currently in service.
[INFO] [Step 5/5]: Finalizing Configuration.
[INFO] Cache enabled successfully!

There are other parameters which are optional, like specifying an SSL credential pair for HTTPS, specifying API keys and Admin keys (API keys enable REST queries, Admin keys enable adding/modifying the deployment), and the number of hosts in the cluster.

Print the deployment to see the details about this deployment. This shows the information necessary to connect to the deployment from an application, which predictive objects (models) are deployed, and whether there are any pending changes.


In [ ]:
deployment


Out[ ]:
Name                  : sample-service-onefive
State Path            : s3://gl-rajat-testing/pred-root/sample-service
Description           : None
API Key               : 806fc046-62da-4e5b-ab9d-0dc6ac2ff549
CORS origin           : 
Global Cache State    : enabled
Load Balancer DNS Name: sample-service-onefive-137425129.us-west-2.elb.amazonaws.com

Deployed predictive objects:
No Pending changes.

Visualize Predictive Service

GraphLab Canvas shows the details of this Predictive Service, and provides the introductory monitoring dashboard for the cluster. See the API documentation here.


In [ ]:
deployment.show()


Canvas is accessible via web browser at the URL: http://localhost:59585/index.html
Opening Canvas in default web browser.
[INFO] retrieving metrics from predictive service...

Prepare a Predictive Object (train a Model)

Now that the cluster is ready, let's quickly train a Model to upload to this deployment. Each GraphLab Model is a Predictive Object. Custom Predictive Objects can also be specified by writing a function in Python, see the User Guide for more information.


In [ ]:
data_url = 'https://static.turi.com/datasets/movie_ratings/sample.small'
data = graphlab.SFrame.read_csv(data_url,delimiter='\t',column_type_hints={'rating':int})
(train_set, test_set) = data.random_split(0.8)
model = graphlab.popularity_recommender.create(train_set, 'user', 'movie', 'rating')


PROGRESS: Downloading https://static.turi.com/datasets/movie_ratings/sample.small to /var/tmp/graphlab-rajat/42160/000005.small
PROGRESS: Finished parsing file https://static.turi.com/datasets/movie_ratings/sample.small
PROGRESS: Parsing completed. Parsed 100 lines in 2.10975 secs.
PROGRESS: Read 1549015 lines. Lines per second: 652272
PROGRESS: Finished parsing file https://static.turi.com/datasets/movie_ratings/sample.small
PROGRESS: Parsing completed. Parsed 4000000 lines in 4.33449 secs.
PROGRESS: Recsys training: model = popularity
PROGRESS: Preparing data set.
PROGRESS:     Data has 3200435 observations with 12020 users and 17188 items.
PROGRESS:     Data prepared in: 4.25899s
PROGRESS: 3200435 observations to process; with 17188 unique items.

Add the Predictive Object to the deployment, then apply changes

Adding a Predictive Object stages this Predictive Object to be deployed to the cluster. To add a predictive object specify a name (which will be used in the URI to query the model in the REST API), and then specify the model object (or a path to the model). See the API documentation here.


In [ ]:
deployment.add('recs', model, description='Sample Recommender')


[INFO] New predictive object 'recs' added, use apply_changes() to deploy all pending changes, or continue other modification.

Now if you print the deployment there will be a pending predictive object that was just added.


In [ ]:
deployment


Out[ ]:
Name                  : sample-service-onefive
State Path            : s3://gl-rajat-testing/pred-root/sample-service
Description           : None
API Key               : 806fc046-62da-4e5b-ab9d-0dc6ac2ff549
CORS origin           : 
Global Cache State    : enabled
Load Balancer DNS Name: sample-service-onefive-137425129.us-west-2.elb.amazonaws.com

Deployed predictive objects:
Pending changes: 
	Adding: recs, description: 

Updating an existing model

To update an existing model or predictive object, use the update method. Update will increment the version of an existing predictive object. When published, the updated model will be proactively warmed in the distributed cache, and existing cached entries for this model will be expired in 15 minutes.

To complete the publishing of this Predictive Object (model), call the apply_changes method. By calling this API the pending predictive objects will be uploaded to S3, and the cluster will be notified to download them from S3.


In [ ]:
deployment.apply_changes()


[INFO] Uploading local path /var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT to s3 path: s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_719dbd25102195e0.sidx to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_719dbd25102195e0.sidx
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_ade2c73172c7342b.sidx to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_ade2c73172c7342b.sidx
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/dir_archive.ini to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/dir_archive.ini
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_719dbd25102195e0.frame_idx to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_719dbd25102195e0.frame_idx
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/version to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/version
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/pickle_archive to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/pickle_archive
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_719dbd25102195e0.0000 to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_719dbd25102195e0.0000
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/objects.bin to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/objects.bin
Completed 11 of 11 part(s) with 1 file(s) remaining
[INFO] Successfully uploaded to s3 path s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1
[INFO] Notifying: ec2-52-27-212-78.us-west-2.compute.amazonaws.com
upload: ../../../../var/folders/g3/n0zyc7612mdfs9bmp4h5vn180000gn/T/predictive_object_YzaqGT/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_ade2c73172c7342b.0000 to s3://gl-rajat-testing/pred-root/sample-service/predictive_objects/recs/1/a8287914-0dc2-4a8a-b0d3-8122d5d12fdb/m_ade2c73172c7342b.0000

To see the status of the deployment, call the get_status API.


In [ ]:
deployment.get_status()


Out[ ]:
[{'cache': {u'healthy': True, u'num_keys': 1, u'type': u'local'},
  'dns_name': u'ec2-52-27-212-78.us-west-2.compute.amazonaws.com',
  'id': u'i-7ed516b7',
  'models': [{u'cache_enabled': True,
    u'description': u'',
    u'name': u'recs',
    u'reason': u'N/A',
    u'status': u'Loaded successfully',
    u'version': 1}],
  'reason': u'N/A',
  'state': u'InService'}]

Query service (using deployment object)

To test this Predictive Object deployed to the Predictive Service, use the query function from the deployment object.


In [ ]:
recs = deployment.query('recs', method='recommend', data={'users':['Jacob Smith']})
recs


Out[ ]:
{u'response': [{u'movie': u'Bellydance Fitness Fusion for Beginners with Suhaila: Buns',
   u'rank': 1,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u"Stephen Sondheim's Putting It Together",
   u'rank': 2,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'Strange Relations',
   u'rank': 3,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'Celebrating Bird: The Triumph of Charlie Parker',
   u'rank': 4,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'Kiddy Grade',
   u'rank': 5,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'Loves of Carmen',
   u'rank': 6,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'The Bob Newhart Show: Season 2',
   u'rank': 7,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'Dragon Ball Z: Great Saiyaman: Declaration',
   u'rank': 8,
   u'score': 5.0,
   u'user': u'Jacob Smith'},
  {u'movie': u'Sangam', u'rank': 9, u'score': 5.0, u'user': u'Jacob Smith'},
  {u'movie': u'Hart to Hart: Season 1',
   u'rank': 10,
   u'score': 5.0,
   u'user': u'Jacob Smith'}],
 u'uuid': u'fc605592-de0e-43ac-b4f8-8df361d18b8d',
 u'version': 1}

Query service (using a client library)

Now to integrate this Predictive Service deployment into an application, next step is to query the REST API on the cluster. Below are the available client libraries for Predictive Service. One can also use curl, which can be modified for any programming language needed.

Please follow the instructions to install and use these client libraries.

cURL


In [ ]:
!curl -X POST -d '{"api key": "806fc046-62da-4e5b-ab9d-0dc6ac2ff549", "data":{"method":"recommend", "data": {"users":["Jacob Smith"]}}}' http://sample-service-onefive-137425129.us-west-2.elb.amazonaws.com/query/recs

Terminate Predictive Services Deployment

To terminate a Predictive Service, call the terminate_service() API. There are options to delete the logs and predictive objects as well.


In [ ]:
deployment.terminate_service(remove_logs=True, remove_state=True)


[INFO] Deleting load balancer: sample-service-onefive
[INFO] Terminating EC2 host(s) [u'i-7ed516b7'] in us-west-2
[INFO] Deleting log files.
[INFO] Deleting state data.
[INFO] Deleting s3 state data.
[INFO] Deleted reference to PredictiveService('sample-service-onefive') from current session.

There is a lot more you can do with a Predictive Service. Spin one up for yourself and see how easy it is to consume a Model, or define your own Custom Predictive Object.