-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #59 from truefoundry/js-restore
Restored train-model directory files
- Loading branch information
Showing
4 changed files
with
438 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,385 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "KPsrbcty6JfS" | ||
}, | ||
"source": [ | ||
"##### This notebook demonstrates a demo of how you can deploy your first job with TrueFoundry.\n", | ||
"\n", | ||
"---\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "Q9eRIwP76rBv" | ||
}, | ||
"source": [ | ||
"After you complete the notebook, you will have a successful deployed a job to train a model on the iris dataser. Your jobs deployment dashboard will look like this:\n", | ||
"\n", | ||
"![](https://files.readme.io/2f6871c-Screenshot_2022-11-16_at_11.43.31_PM.png)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "RbdHA8sf6qm4" | ||
}, | ||
"source": [ | ||
"## Project structure\n", | ||
"\n", | ||
"To complete this guide, you are going to create the following **files**:\n", | ||
"\n", | ||
"- `train.py` : contains our training code\n", | ||
"- `requirements.txt` : contains our dependencies\n", | ||
"- `deploy.py` contains our deployment code ( you can also use a deployment configuration for deploying using a YAML file)\n", | ||
"\n", | ||
"Your **final file structure** is going to look like this:\n", | ||
"\n", | ||
"```\n", | ||
".\n", | ||
"├── train.py\n", | ||
"├── deploy.py\n", | ||
"└── requirements.txt\n", | ||
"```\n", | ||
"\n", | ||
"As you can see, all the following files are created in the same folder/directory\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "1ag-WSEf642R" | ||
}, | ||
"source": [ | ||
"# Setup\n", | ||
"\n", | ||
"Let's first setup all the things we need to deploy our service.\n", | ||
"\n", | ||
"- Signup or Login on TrueFoundry\n", | ||
"- Setup Workspace\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "Vr3iFsrv67Mc" | ||
}, | ||
"source": [ | ||
"Let's start with installing `truefoundry`.\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"colab": { | ||
"base_uri": "https://localhost:8080/" | ||
}, | ||
"id": "x5HP_7Qt6pqw", | ||
"outputId": "8bcd94b9-537f-4399-e958-d6e29a3a99c0" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"%pip install -U \"truefoundry>=0.4.1,<0.5.0\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"**Login into TrueFoundry**\n", | ||
"\n", | ||
"In order to login run the cell below. Host can be found from the TrueFoundry UI as shown below like https://app.truefoundry.com\n", | ||
"\n", | ||
"![image.png](../common/images/host.png)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"id": "0QL_ZCes6nEz" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"!tfy login --host \"<Host name of TrueFoundry UI. e.g. https://company.truefoundry.cloud>\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "5eDM6Z6r6q8G" | ||
}, | ||
"source": [ | ||
"**Select the `Workspace` in which you want to deploy your application.**\n", | ||
"\n", | ||
"Once you run the cell below you will get a prompt to enter your Workspace FQN. Follow the docs to\n", | ||
"\n", | ||
"**Create a Workspace**: https://docs.truefoundry.com/docs/key-concepts#creating-a-workspace\n", | ||
"\n", | ||
"**Get Existing Workspace FQN**: https://docs.truefoundry.com/docs/key-concepts#getting-workspace-fqn" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import click" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"id": "4AU4ufGu6tpT" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"WORKSPACE_FQN = click.prompt(\n", | ||
" \"Enter the Workspace FQN\",\n", | ||
" type=str,\n", | ||
")\n", | ||
"print(f\"\\nWorkspace FQN set to {WORKSPACE_FQN!r}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "IgTqSS3Q7J46" | ||
}, | ||
"source": [ | ||
"# Step 1: Implement the training code\n", | ||
"\n", | ||
"The first step is to create a job that trains a scikit learn model on iris dataset\n", | ||
"\n", | ||
"We start with a `train.py` containing our training code and `requirements.txt` with our dependencies.\n", | ||
"\n", | ||
"```\n", | ||
".\n", | ||
"├── train.py\n", | ||
"└── requirements.txt\n", | ||
"```\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "ewNT1fG07tRY" | ||
}, | ||
"source": [ | ||
"### **`train.py`**\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"colab": { | ||
"base_uri": "https://localhost:8080/" | ||
}, | ||
"id": "LuU9kOzv7Ci7", | ||
"outputId": "002753bd-6b23-48ff-aff6-9fa5c0f380d6" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"%%writefile train.py\n", | ||
"from sklearn.datasets import load_iris\n", | ||
"from sklearn.model_selection import train_test_split\n", | ||
"from sklearn.linear_model import LogisticRegression\n", | ||
"from sklearn.metrics import classification_report\n", | ||
"\n", | ||
"# load the dataset\n", | ||
"X, y = load_iris(as_frame=True, return_X_y=True)\n", | ||
"X = X.rename(columns={\n", | ||
" \"sepal length (cm)\": \"sepal_length\",\n", | ||
" \"sepal width (cm)\": \"sepal_width\",\n", | ||
" \"petal length (cm)\": \"petal_length\",\n", | ||
" \"petal width (cm)\": \"petal_width\",\n", | ||
"})\n", | ||
"\n", | ||
"# NOTE:- You can pass these configurations via command line\n", | ||
"# arguments, config file, environment variables.\n", | ||
"X_train, X_test, y_train, y_test = train_test_split(\n", | ||
" X, y, test_size=0.2, random_state=42, stratify=y\n", | ||
")\n", | ||
"\n", | ||
"# Initialize the model\n", | ||
"clf = LogisticRegression(solver=\"liblinear\")\n", | ||
"# Fit the model\n", | ||
"clf.fit(X_train, y_train)\n", | ||
"\n", | ||
"preds = clf.predict(X_test)\n", | ||
"print(classification_report(y_true=y_test, y_pred=preds))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "Exa3CI-T7jnR" | ||
}, | ||
"source": [ | ||
"Click on this [link](https://docs.truefoundry.com/v0.1.1/recipes/training-a-scikit-learn-model) to understand the **`app.py`**:\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "c1zqWidl7yTS" | ||
}, | ||
"source": [ | ||
"### **`requirements.txt`**\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"colab": { | ||
"base_uri": "https://localhost:8080/" | ||
}, | ||
"id": "vHJts2tR7bfw", | ||
"outputId": "7b4c8cbb-2e42-4e6c-e265-d7acf59ffc6a" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"%%writefile requirements.txt\n", | ||
"pandas==1.5.3\n", | ||
"numpy==1.23.2\n", | ||
"scikit-learn==1.5.0" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "vtwCrPGJ750K" | ||
}, | ||
"source": [ | ||
"# Step 2: Deploying as a Job\n", | ||
"\n", | ||
"You can deploy services on TrueFoundry programmatically via our **Python SDK**.\n", | ||
"\n", | ||
"Create the `deploy.py`, after which our file structure will look like this:\n", | ||
"\n", | ||
"**File Structure**\n", | ||
"\n", | ||
"```Text\n", | ||
".\n", | ||
"├── train.py\n", | ||
"├── deploy.py\n", | ||
"└── requirements.txt\n", | ||
"```\n", | ||
"\n", | ||
"### **`deploy.py`**\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"colab": { | ||
"base_uri": "https://localhost:8080/" | ||
}, | ||
"id": "jc-yRSkE7xdD", | ||
"outputId": "ffa6fcc8-f43d-4238-8138-ed5131b2322c" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"%%writefile deploy.py\n", | ||
"import argparse\n", | ||
"import logging\n", | ||
"\n", | ||
"from truefoundry.deploy import Build, Job, PythonBuild, LocalSource\n", | ||
"\n", | ||
"logging.basicConfig(\n", | ||
" level=logging.INFO, format=\"%(asctime)s [%(name)s] %(levelname)-8s %(message)s\"\n", | ||
")\n", | ||
"\n", | ||
"parser = argparse.ArgumentParser()\n", | ||
"parser.add_argument(\"--workspace_fqn\", required=True, type=str)\n", | ||
"args = parser.parse_args()\n", | ||
"\n", | ||
"job = Job(\n", | ||
" name=\"iris-train-job\",\n", | ||
" image=Build(\n", | ||
" build_source=LocalSource(local_build=False),\n", | ||
" build_spec=PythonBuild(\n", | ||
" python_version=\"3.11\",\n", | ||
" command=\"python train.py\",\n", | ||
" requirements_path=\"requirements.txt\",\n", | ||
" )\n", | ||
" )\n", | ||
")\n", | ||
"job.deploy(workspace_fqn=args.workspace_fqn, wait=False)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "Ac89hU5U8tUy" | ||
}, | ||
"source": [ | ||
"Click on this [link](https://docs.truefoundry.com/recipes/deploy-training-code-as-a-job) to understand the **`deploy.py`**:\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"id": "6bjVtz5v829H" | ||
}, | ||
"source": [ | ||
"Now to deploy our Job run the command below\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"colab": { | ||
"base_uri": "https://localhost:8080/" | ||
}, | ||
"id": "OBNeK70h85L1", | ||
"outputId": "58c98c1d-9622-46b3-e977-8eb9e195d22b" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"!python deploy.py --workspace_fqn $WORKSPACE_FQN" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"colab": { | ||
"provenance": [] | ||
}, | ||
"kernelspec": { | ||
"display_name": "jupyter-base", | ||
"language": "python", | ||
"name": "jupyter-base" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.9" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
Oops, something went wrong.