chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
FROM python:3.8
|
||||
|
||||
RUN pip install mlflow azure-storage-blob numpy scipy pandas scikit-learn cloudpickle
|
||||
|
||||
COPY train.py .
|
||||
COPY wine-quality.csv .
|
||||
@@ -0,0 +1,11 @@
|
||||
name: docker-example
|
||||
|
||||
docker_env:
|
||||
image: mlflow-docker-example
|
||||
|
||||
entry_points:
|
||||
main:
|
||||
parameters:
|
||||
alpha: float
|
||||
l1_ratio: {type: float, default: 0.1}
|
||||
command: "python train.py --alpha {alpha} --l1-ratio {l1_ratio}"
|
||||
@@ -0,0 +1,71 @@
|
||||
Dockerized Model Training with MLflow
|
||||
-------------------------------------
|
||||
This directory contains an MLflow project that trains a linear regression model on the UC Irvine
|
||||
Wine Quality Dataset. The project uses a Docker image to capture the dependencies needed to run
|
||||
training code. Running a project in a Docker environment (as opposed to Conda) allows for capturing
|
||||
non-Python dependencies, e.g. Java libraries. In the future, we also hope to add tools to MLflow
|
||||
for running Dockerized projects e.g. on a Kubernetes cluster for scale out.
|
||||
|
||||
Structure of this MLflow Project
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This MLflow project contains a ``train.py`` file that trains a scikit-learn model and uses
|
||||
MLflow Tracking APIs to log the model and its metadata (e.g., hyperparameters and metrics)
|
||||
for later use and reference. ``train.py`` operates on the Wine Quality Dataset, which is included
|
||||
in ``wine-quality.csv``.
|
||||
|
||||
Most importantly, the project also includes an ``MLproject`` file, which specifies the Docker
|
||||
container environment in which to run the project using the ``docker_env`` field:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
docker_env:
|
||||
image: mlflow-docker-example
|
||||
|
||||
Here, ``image`` can be any valid argument to ``docker run``, such as the tag, ID or URL of a Docker
|
||||
image (see `Docker docs <https://docs.docker.com/engine/reference/run/#general-form>`_). The above
|
||||
example references a locally-stored image (``mlflow-docker-example``) by tag.
|
||||
|
||||
Finally, the project includes a ``Dockerfile`` that is used to build the image referenced by the
|
||||
``MLproject`` file. The ``Dockerfile`` specifies library dependencies required by the project, such
|
||||
as ``mlflow`` and ``scikit-learn``.
|
||||
|
||||
Running this Example
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
First, install MLflow (via ``pip install mlflow``) and install
|
||||
`Docker <https://www.docker.com/get-started>`_.
|
||||
|
||||
Then, build the image for the project's Docker container environment. You must use the same image
|
||||
name that is given by the ``docker_env.image`` field of the MLproject file. In this example, the
|
||||
image name is ``mlflow-docker-example``. Issue the following command to build an image with this
|
||||
name:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker build -t mlflow-docker-example -f Dockerfile .
|
||||
|
||||
Note that the name if the image used in the ``docker build`` command, ``mlflow-docker-example``,
|
||||
matches the name of the image referenced in the ``MLproject`` file.
|
||||
|
||||
Finally, run the example project using ``mlflow run examples/docker -P alpha=0.5``.
|
||||
|
||||
.. note::
|
||||
If running this example on a Mac with Apple silicon, ensure that Docker Desktop is running and
|
||||
that you are logged in to the Docker Desktop service.
|
||||
If you are modifying the example ``DockerFile`` to specify older versions of ``scikit-learn``,
|
||||
you should enable `Rosetta compatibility <https://docs.docker.com/desktop/settings/mac/#features-in-development>`_
|
||||
in the Docker Desktop configuration settings to ensure that the appropriate ``cython`` compiler is used.
|
||||
|
||||
What happens when the project is run?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Running ``mlflow run examples/docker`` builds a new Docker image based on ``mlflow-docker-example``
|
||||
that also contains our project code. The resulting image is tagged as
|
||||
``mlflow-docker-example-<git-version>`` where ``<git-version>`` is the git commit ID. After the image is
|
||||
built, MLflow executes the default (main) project entry point within the container using ``docker run``.
|
||||
|
||||
Environment variables, such as ``MLFLOW_TRACKING_URI``, are propagated inside the container during
|
||||
project execution. When running against a local tracking URI, MLflow mounts the host system's
|
||||
tracking directory (e.g., a local ``mlruns`` directory) inside the container so that metrics and
|
||||
params logged during project execution are accessible afterwards.
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"kube-context": "docker-for-desktop",
|
||||
"kube-job-template-path": "examples/docker/kubernetes_job_template.yaml",
|
||||
"repository-uri": "username/mlflow-kubernetes-example"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{replaced with MLflow Project name}"
|
||||
namespace: mlflow
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 100
|
||||
backoffLimit: 0
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: "{replaced with MLflow Project name}"
|
||||
image: "{replaced with URI of Docker image created during Project execution}"
|
||||
command: ["{replaced with MLflow Project entry point command}"]
|
||||
resources:
|
||||
limits:
|
||||
memory: 512Mi
|
||||
requests:
|
||||
memory: 256Mi
|
||||
restartPolicy: Never
|
||||
@@ -0,0 +1,70 @@
|
||||
# The data set used in this example is from http://archive.ics.uci.edu/ml/datasets/Wine+Quality
|
||||
# P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis.
|
||||
# Modeling wine preferences by data mining from physicochemical properties. In Decision Support Systems, Elsevier, 47(4):547-553, 2009.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from sklearn.linear_model import ElasticNet
|
||||
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
|
||||
from sklearn.model_selection import train_test_split
|
||||
|
||||
import mlflow
|
||||
import mlflow.sklearn
|
||||
|
||||
|
||||
def eval_metrics(actual, pred):
|
||||
rmse = np.sqrt(mean_squared_error(actual, pred))
|
||||
mae = mean_absolute_error(actual, pred)
|
||||
r2 = r2_score(actual, pred)
|
||||
return rmse, mae, r2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
warnings.filterwarnings("ignore")
|
||||
np.random.seed(40)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--alpha")
|
||||
parser.add_argument("--l1-ratio")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read the wine-quality csv file (make sure you're running this from the root of MLflow!)
|
||||
wine_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "wine-quality.csv")
|
||||
data = pd.read_csv(wine_path)
|
||||
|
||||
# Split the data into training and test sets. (0.75, 0.25) split.
|
||||
train, test = train_test_split(data)
|
||||
|
||||
# The predicted column is "quality" which is a scalar from [3, 9]
|
||||
train_x = train.drop(["quality"], axis=1)
|
||||
test_x = test.drop(["quality"], axis=1)
|
||||
train_y = train[["quality"]]
|
||||
test_y = test[["quality"]]
|
||||
|
||||
alpha = float(args.alpha)
|
||||
l1_ratio = float(args.l1_ratio)
|
||||
|
||||
with mlflow.start_run():
|
||||
lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
|
||||
lr.fit(train_x, train_y)
|
||||
|
||||
predicted_qualities = lr.predict(test_x)
|
||||
|
||||
(rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)
|
||||
|
||||
print(f"Elasticnet model (alpha={alpha:f}, l1_ratio={l1_ratio:f}):")
|
||||
print(f" RMSE: {rmse}")
|
||||
print(f" MAE: {mae}")
|
||||
print(f" R2: {r2}")
|
||||
|
||||
mlflow.log_param("alpha", alpha)
|
||||
mlflow.log_param("l1_ratio", l1_ratio)
|
||||
mlflow.log_metric("rmse", rmse)
|
||||
mlflow.log_metric("r2", r2)
|
||||
mlflow.log_metric("mae", mae)
|
||||
|
||||
mlflow.sklearn.log_model(lr, name="model")
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user