Skip to content
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

Add run_pyfunc_model() to build and run pyfunc model locally #514

Merged
merged 13 commits into from
Jan 15, 2024

Conversation

ariefrahmansyah
Copy link
Contributor

@ariefrahmansyah ariefrahmansyah commented Jan 3, 2024

Description

To improve the user experience in developing the PyFunc model, I'm adding a new merlin.run_pyfunc_model() helper function to build and run the PyFunc model's Docker image locally. The new function has the similar arguments as merlin.log_pyfunc_model().

Currently, merlin-sdk has (outdated) ModelVersion.start_server() that also can be used to run standard and PyFunc models locally. However, there are some drawbacks to the current implementation:

  1. To use start_server() function, users need to connect to the Merlin server, create a project (if not created yet), create a new model version, and log the model artifacts to the remote MLflow tracking server. This could lead to some unfinished model versions getting uploaded onto the Merlin and MLflow servers.
  2. The implementation of start_server() will download the artifacts from the MLflow tracking server first to be used to build the Docker image locally.
# Before:
from merlin
from merlin.model import ModelType, PyFuncModel

# Implement PyFuncModel
class MyModel(PyFuncModel):
    ....

# Connecting to Merlin server
merlin.set_url("...")
merlin.set_project("...")
merlin.set_model("my-model", ModelType.PYFUNC)

# Create new model version, log it, and run server:
with merlin.new_model_version() as v:
    v.log_pyfunc_model(
        model_instance=MyModel(),
        ...
    )

    # run pyfunc server
    v.start_server(...)

# Or, if users already have logged existing model version on Merlin,
# they can get the latest model version and run it locally:
versions = merlin.active_model().list_version()
versions.sort(key=lambda v: v.id, reverse=True)
last_version = versions[0]
last_version.start_server()

The new merlin.run_pyfunc_model() is more straightforward as it can build and run the pyfunc model without creating a new model version and uploading the model artifact:

# After:
from merlin
from merlin.model import ModelType, PyFuncModel

# Implement PyFuncModel
class MyModel(PyFuncModel):
        ....

# Run pyfunc server
merlin.run_pyfunc_model(
    model_instance=MyModel(),
    ...
)

Modifications

  1. Introduce run_pyfunc_model() in pyfunc package
  2. Import pyfunc.run_pyfunc_model() into merlin's __all__ so it can be called via merlin.run_pyfunc_model()
  3. Refactor ModelVersion.start_server() to use pyfunc.run_pyfunc_model() for PyFunc model
  4. Add an example of how to run the PyFunc model locally on PyFunc notebook example
  5. Add some simple PyFunc model examples in pyfunc/examples folder

Tests

  1. Add test_examples.py in pyfunc-server package

Checklist

  • Added PR label
  • Added unit test, integration, and/or e2e tests
  • Tested locally
  • Updated documentation
  • Update Swagger spec if the PR introduce API changes
  • Regenerated Golang and Python client if the PR introduces API changes

Release Notes

Add merlin.run_pyfunc_model() function to build and run the PyFunc model locally.

@ariefrahmansyah ariefrahmansyah changed the title Add run_pyfunc_server() to build and run pyfunc model …locally Add run_pyfunc_server() to build and run pyfunc model locally Jan 3, 2024
@ghost
Copy link

ghost commented Jan 3, 2024

👇 Click on the image for a new way to code review

Review these changes using an interactive CodeSee Map

Legend

CodeSee Map legend

@ariefrahmansyah ariefrahmansyah changed the title Add run_pyfunc_server() to build and run pyfunc model locally Add run_pyfunc_model() to build and run pyfunc model locally Jan 3, 2024
@ariefrahmansyah ariefrahmansyah added the enhancement New feature or request label Jan 4, 2024
@ariefrahmansyah ariefrahmansyah requested review from tiopramayudi, tkpd-hafizhan and leonlnj and removed request for tkpd-hafizhan January 5, 2024 06:38
@ariefrahmansyah ariefrahmansyah marked this pull request as ready for review January 5, 2024 06:39
@ariefrahmansyah ariefrahmansyah self-assigned this Jan 5, 2024
@leonlnj
Copy link
Contributor

leonlnj commented Jan 9, 2024

left a bunch of question, mostly around UX.

No major concern and overall it LGTM. With these, user should be able to run docker build + deploy pyfunc locally to test.

Just to confirm, does this works for pyfunc v1/3?

python/pyfunc-server/examples/iris/iris.py Outdated Show resolved Hide resolved
python/pyfunc-server/setup.py Show resolved Hide resolved
python/pyfunc-server/examples/iris/iris.py Outdated Show resolved Hide resolved
python/sdk/merlin/docker/pyfunc.Dockerfile Show resolved Hide resolved
@ariefrahmansyah
Copy link
Contributor Author

-> Just to confirm, does this works for pyfunc v1/3?

Yes, run_pyfunc_model works for pyfunc v1 and v3.

Copy link
Contributor

@leonlnj leonlnj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let one more comment if we can hide start_server from the example at least, so user are only expose to

merlin.run_pyfunc_model(model) #local
merlin.deploy(version) #remote

@ariefrahmansyah ariefrahmansyah merged commit 904a894 into main Jan 15, 2024
32 checks passed
@ariefrahmansyah ariefrahmansyah deleted the local-pyfunc branch January 15, 2024 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants