-
Notifications
You must be signed in to change notification settings - Fork 20
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
added snippets for Connection, Model Registry #160
base: main
Are you sure you want to change the base?
Changes from all commits
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,127 @@ | ||
# Hopsworks Model Management | ||
|
||
<p align="center"> | ||
<a href="https://community.hopsworks.ai"><img | ||
src="https://img.shields.io/discourse/users?label=Hopsworks%20Community&server=https%3A%2F%2Fcommunity.hopsworks.ai" | ||
alt="Hopsworks Community" | ||
/></a> | ||
<a href="https://docs.hopsworks.ai"><img | ||
src="https://img.shields.io/badge/docs-HSML-orange" | ||
alt="Hopsworks Model Management Documentation" | ||
/></a> | ||
<a href="https://pypi.org/project/hsml/"><img | ||
src="https://img.shields.io/pypi/v/hsml?color=blue" | ||
alt="PyPiStatus" | ||
/></a> | ||
<a href="https://archiva.hops.works/#artifact/com.logicalclocks/hsml"><img | ||
src="https://img.shields.io/badge/java-HSML-green" | ||
alt="Scala/Java Artifacts" | ||
/></a> | ||
<a href="https://pepy.tech/project/hsml/month"><img | ||
src="https://pepy.tech/badge/hsml/month" | ||
alt="Downloads" | ||
/></a> | ||
<a href="https://github.com/psf/black"><img | ||
src="https://img.shields.io/badge/code%20style-black-000000.svg" | ||
alt="CodeStyle" | ||
/></a> | ||
<a><img | ||
src="https://img.shields.io/pypi/l/hsml?color=green" | ||
alt="License" | ||
/></a> | ||
</p> | ||
|
||
HSML is the library to interact with the Hopsworks Model Registry and Model Serving. The library makes it easy to export, manage and deploy models. | ||
|
||
The library automatically configures itself based on the environment in which it runs. | ||
However, to connect from an external Python environment additional connection information, such as the Hopsworks hostname (or IP address) and port (if it is not port 443), is required. For more information about the setup from external environments, see the setup section. | ||
|
||
## Getting Started On Hopsworks | ||
|
||
Instantiate a connection and get the project model registry and serving handles | ||
```python | ||
import hsml | ||
|
||
# Create a connection | ||
connection = hsml.connection() | ||
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. put the hostname and project in the example here: connection = hsml.connection(host="my.cluster.com", project="fraud") |
||
# or connection = hsml.connection(host="my.hopsworks.cluster", project="my_project") | ||
|
||
# Get the model registry handle for the project's model registry | ||
mr = connection.get_model_registry() | ||
|
||
# Get the model serving handle for the current model registry | ||
ms = connection.get_model_serving() | ||
``` | ||
|
||
Create a new model | ||
```python | ||
import tensorflow as tf | ||
|
||
|
||
export_path = "/tmp/model_directory" | ||
tf.saved_model.save(model, export_path) | ||
model = mr.tensorflow.create_model( | ||
name="my_model", | ||
metrics=metrics_dict, | ||
model_schema=model_schema, | ||
input_example=input_example, | ||
description="Iris Flower Classifier" | ||
) | ||
|
||
model.save(export_path) # "/tmp/model_directory" or "/tmp/model_file" | ||
``` | ||
|
||
Download a model | ||
```python | ||
model = mr.get_model("my_model", version=1) | ||
|
||
model_path = model.download() | ||
``` | ||
|
||
Delete a model | ||
```python | ||
model.delete() | ||
``` | ||
|
||
Get best performing model | ||
```python | ||
best_model = mr.get_best_model('my_model', 'accuracy', 'max') | ||
|
||
``` | ||
|
||
Deploy a model | ||
```python | ||
deployment = model.deploy() | ||
``` | ||
|
||
Start a deployment | ||
```python | ||
deployment.start() | ||
|
||
# Get the logs from a running deployment | ||
deployment.logs() | ||
``` | ||
|
||
javierdlrm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Make predictions with a deployed model | ||
```python | ||
data = { "instances": model.input_example } | ||
|
||
predictions = deployment.predict(data) | ||
``` | ||
|
||
You can find more examples on how to use the library in [examples.hopsworks.ai](https://examples.hopsworks.ai). | ||
|
||
## Documentation | ||
|
||
Documentation is available at [Hopsworks Model Management Documentation](https://docs.hopsworks.ai/). | ||
|
||
## Issues | ||
|
||
For general questions about the usage of Hopsworks Machine Learning please open a topic on [Hopsworks Community](https://community.hopsworks.ai/). | ||
|
||
Please report any issue using [Github issue tracking](https://github.com/logicalclocks/machine-learning-api/issues). | ||
|
||
|
||
## Contributing | ||
|
||
If you would like to contribute to this library, please see the [Contribution Guidelines](CONTRIBUTING.md). |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -61,8 +61,8 @@ class Connection: | |||||
api_key_file='modelregistry.key', # The file containing the API key generated above | ||||||
hostname_verification=True) # Disable for self-signed certificates | ||||||
) | ||||||
mr = conn.get_model_registry() # Get the project's default model registry | ||||||
ms = conn.get_model_serving() # Uses the previous model registry | ||||||
mr = conn.get_model_registry() | ||||||
ms = conn.get_model_serving() | ||||||
``` | ||||||
|
||||||
Clients in external clusters need to connect to the Hopsworks Model Registry and Model Serving using an | ||||||
|
@@ -119,6 +119,12 @@ def get_model_registry(self, project: str = None): | |||||
"""Get a reference to a model registry to perform operations on, defaulting to the project's default model registry. | ||||||
Shared model registries can be retrieved by passing the `project` argument. | ||||||
|
||||||
!!! example | ||||||
```python | ||||||
mr = conn.get_model_registry() # Get the project's default model registry | ||||||
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.
Suggested change
|
||||||
``` | ||||||
|
||||||
|
||||||
# Arguments | ||||||
project: The name of the project that owns the shared model registry, | ||||||
the model registry must be shared with the project the connection was established for, defaults to `None`. | ||||||
|
@@ -131,6 +137,11 @@ def get_model_registry(self, project: str = None): | |||||
def get_model_serving(self): | ||||||
"""Get a reference to model serving to perform operations on. Model serving operates on top of a model registry, defaulting to the project's default model registry. | ||||||
|
||||||
!!! example | ||||||
```python | ||||||
ms = conn.get_model_serving() | ||||||
``` | ||||||
|
||||||
# Returns | ||||||
`ModelServing`. A model serving handle object to perform operations on. | ||||||
""" | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -84,18 +84,40 @@ def __init__( | |||||||
self._model_engine = model_engine.ModelEngine() | ||||||||
|
||||||||
def save(self, model_path, await_registration=480): | ||||||||
"""Persist this model including model files and metadata to the model registry.""" | ||||||||
"""Persist this model including model files and metadata to the model registry. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
model.save('model.pkl') | ||||||||
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.
Suggested change
|
||||||||
``` | ||||||||
|
||||||||
""" | ||||||||
return self._model_engine.save( | ||||||||
self, model_path, await_registration=await_registration | ||||||||
) | ||||||||
|
||||||||
def download(self): | ||||||||
"""Download the model files to a local folder.""" | ||||||||
"""Download the model files to a local folder. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
model_dir = model.download() | ||||||||
``` | ||||||||
|
||||||||
""" | ||||||||
return self._model_engine.download(self) | ||||||||
|
||||||||
def delete(self): | ||||||||
"""Delete the model | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
# get model object of a specific version | ||||||||
model = mr.get_model("my_model", version=1) | ||||||||
# delete the model version | ||||||||
model.delete() | ||||||||
``` | ||||||||
|
||||||||
!!! danger "Potentially dangerous operation" | ||||||||
This operation drops all metadata associated with **this version** of the | ||||||||
model **and** deletes the model files. | ||||||||
|
@@ -370,6 +392,11 @@ def set_tag(self, name: str, value: Union[str, dict]): | |||||||
A tag consists of a <name,value> pair. Tag names are unique identifiers across the whole cluster. | ||||||||
The value of a tag can be any valid json - primitives, arrays or json objects. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
model.set_tag(name="tag_name", value=42) | ||||||||
``` | ||||||||
|
||||||||
# Arguments | ||||||||
name: Name of the tag to be added. | ||||||||
value: Value of the tag to be added. | ||||||||
|
@@ -382,6 +409,11 @@ def set_tag(self, name: str, value: Union[str, dict]): | |||||||
def delete_tag(self, name: str): | ||||||||
"""Delete a tag attached to a model. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
model.delete_tag("tag_name") | ||||||||
``` | ||||||||
|
||||||||
# Arguments | ||||||||
name: Name of the tag to be removed. | ||||||||
# Raises | ||||||||
|
@@ -392,6 +424,11 @@ def delete_tag(self, name: str): | |||||||
def get_tag(self, name: str): | ||||||||
"""Get the tags of a model. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
tag_value = model.get_tag("tag_name") | ||||||||
``` | ||||||||
|
||||||||
# Arguments | ||||||||
name: Name of the tag to get. | ||||||||
# Returns | ||||||||
|
@@ -404,6 +441,11 @@ def get_tag(self, name: str): | |||||||
def get_tags(self): | ||||||||
"""Retrieves all tags attached to a model. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
tags = model.get_tags() | ||||||||
``` | ||||||||
|
||||||||
# Returns | ||||||||
`Dict[str, obj]` of tags. | ||||||||
# Raises | ||||||||
|
@@ -415,6 +457,14 @@ def __repr__(self): | |||||||
return f"Model(name: {self._name!r}, version: {self._version!r})" | ||||||||
|
||||||||
def get_url(self): | ||||||||
"""Returns URL of the specific model. | ||||||||
|
||||||||
!!! example | ||||||||
```python | ||||||||
model_url = model.get_url() | ||||||||
``` | ||||||||
|
||||||||
""" | ||||||||
path = ( | ||||||||
"/p/" | ||||||||
+ str(client.get_instance()._project_id) | ||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -63,6 +63,20 @@ def get_model(self, name: str, version: int = None): | |||||
Getting a model from the Model Registry means getting its metadata handle | ||||||
so you can subsequently download the model directory. | ||||||
|
||||||
!!! example | ||||||
```python | ||||||
import hsml | ||||||
|
||||||
# connect with Hopsworks | ||||||
conn = hsml.connection() | ||||||
|
||||||
# get Hopsworks Model Registry | ||||||
mr = conn.get_model_registry(project="my_project") | ||||||
|
||||||
# get model object | ||||||
model = mr.get_model("my_model", version=1) | ||||||
``` | ||||||
|
||||||
# Arguments | ||||||
name: Name of the model to get. | ||||||
version: Version of the model to retrieve, defaults to `None` and will | ||||||
|
@@ -94,6 +108,11 @@ def get_models(self, name: str): | |||||
Getting all models from the Model Registry for a given name returns a list of model entities, one for each version registered under | ||||||
the specified model name. | ||||||
|
||||||
!!! example | ||||||
```python | ||||||
models = mr.get_models("my_model") | ||||||
``` | ||||||
|
||||||
# Arguments | ||||||
name: Name of the model to get. | ||||||
# Returns | ||||||
|
@@ -114,6 +133,17 @@ def get_best_model(self, name: str, metric: str, direction: str): | |||||
name corresponding to one of the keys in the training_metrics dict of the model and a direction. For example to | ||||||
get the model version with the highest accuracy, specify metric='accuracy' and direction='max'. | ||||||
|
||||||
!!! example | ||||||
```python | ||||||
EVALUATION_METRIC = "r2_score" | ||||||
SORT_METRICS_BY = "max" # your sorting criteria | ||||||
|
||||||
# get best model based on custom metrics | ||||||
best_model = mr.get_best_model("citibike_mlp_model", | ||||||
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.
Suggested change
|
||||||
EVALUATION_METRIC, | ||||||
SORT_METRICS_BY) | ||||||
|
||||||
``` | ||||||
# Arguments | ||||||
name: Name of the model to get. | ||||||
metric: Name of the key in the training metrics field to compare. | ||||||
|
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 we can keep the first sentence as