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

0.2.0 fix (part 1) #9

Merged
merged 5 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ body:
- label: Other issue
validations:
required: true
- type: checkboxes
attributes:
label: OS/Platform(s) Used
description: \
What OS or platform(s) did you encounter this issue? Specify
exact version or distro in the Problem Brief if needed.
options:
- label: Windows (local)
- label: MacOS Intel (local)
- label: MacOS Apple Silicon (local)
- label: Linux (local)
- label: Coder
- label: Run:ai VSCode
- label: Run:ai JupyterLab
validations:
required: true
- type: textarea
attributes:
label: Problem Brief
Expand Down
7 changes: 6 additions & 1 deletion {{cookiecutter.repo_name}}/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
default:
tags:
- dind
- on-prem

variables:
Expand Down Expand Up @@ -40,6 +39,8 @@ build:data-prep-image:
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
before_script:
- "[[ -z ${HARBOR_ROBOT_CREDS_JSON} ]] && exit 1"
script:
- mkdir -p /kaniko/.docker
- cat $HARBOR_ROBOT_CREDS_JSON > /kaniko/.docker/config.json
Expand All @@ -63,6 +64,8 @@ build:model-training-image:
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
before_script:
- "[[ -z ${HARBOR_ROBOT_CREDS_JSON} ]] && exit 1"
script:
- mkdir -p /kaniko/.docker
- cat $HARBOR_ROBOT_CREDS_JSON > /kaniko/.docker/config.json
Expand All @@ -86,6 +89,8 @@ build:retag-images:
image:
name: gcr.io/go-containerregistry/crane:debug
entrypoint: [""]
before_script:
- "[[ -z ${HARBOR_ROBOT_CREDS_JSON} ]] && exit 1"
script:
- cat $HARBOR_ROBOT_CREDS_JSON > /root/.docker/config.json
- crane tag {{cookiecutter.registry_project_path}}/data-prep:${CI_COMMIT_SHORT_SHA} ${CI_COMMIT_TAG}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ MLflow Tracking server.
=== "Linux/macOS"

```bash
$ conda create -n mlflow-test python=3.10.11
$ conda create -n mlflow-test python=3.11.7
$ conda activate mlflow-test
$ pip install boto3==1.34.17 mlflow==2.9.2
$ export MLFLOW_TRACKING_USERNAME=<MLFLOW_TRACKING_USERNAME>
Expand All @@ -844,7 +844,7 @@ MLflow Tracking server.
=== "Windows PowerShell"

```powershell
$ conda create -n mlflow-test python=3.10.11
$ conda create -n mlflow-test python=3.11.7
$ conda activate mlflow-test
$ pip install boto3==1.34.17 mlflow==2.9.2
$ $MLFLOW_TRACKING_USERNAME=<MLFLOW_TRACKING_USERNAME>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Now, let's clone your repository from the remote:
=== "VSCode Server Terminal"

```bash
$ cd /{{cookiecutter.proj_name}}/workspaces/<YOUR_HYPHENATED_NAME>
$ cd /<PVC_LOCATION>/workspaces/<YOUR_HYPHENATED_NAME>
$ git clone <REMOTE_URL_HTTPS>
$ cd {{cookiecutter.repo_name}}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ workspace directory:
(base) $ echo 'alias {{cookiecutter.repo_name}}-conda="conda activate /<NAME_OF_DATA_SOURCE>/workspaces/<YOUR_HYPHENATED_NAME>/conda_envs/{{cookiecutter.repo_name}}"' >> ~/.bashrc
(base) $ source ~/.bashrc
(base) $ {{cookiecutter.repo_name}}-conda
({{cookiecutter.repo_name}}-conda) $ # conda environment has been activated
({{cookiecutter.repo_name}}) $ # conda environment has been activated
```

!!! tip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ autolog). With that, we have the following pointers to take note of:
convention similar to the following:
`<MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>/artifacts`.
- With this path/URI, we can use the AWS CLI to download the predictive
model from ECS into a mounted volume when we run the Docker image for
model from ECS. Alternatively, we can utilise the MLFlow Client
library to retrieve the predictive model. This model can then be
propagated into a mounted volume when we run the Docker image for
the REST APIs.

Here's how you can quickly retrieve the artifact location of a
specific MLflow experiment within your VSCode server:
Here's how you can quickly retrieve the artifact of a specific MLflow
Run within your VSCode server with the MLFlow Client library:

=== "Linux/macOS"

```bash
$ export MLFLOW_TRACKING_URI=<MLFLOW_TRACKING_URI>
$ export MLFLOW_TRACKING_USERNAME=<MLFLOW_TRACKING_USERNAME>
$ export MLFLOW_TRACKING_PASSWORD=<MLFLOW_TRACKING_PASSWORD>
$ python -c "import mlflow; mlflow_experiment = mlflow.get_experiment_by_name('<NAME_OF_DEFAULT_MLFLOW_EXPERIMENT>'); print(mlflow_experiment.artifact_location)"
s3://<BUCKET_NAME>/subdir/paths
$ python -c "import mlflow; mlflow.artifacts.download_artifact(artifact_uri='runs:/<MLFLOW_RUN_UUID>/', dst_path='models/<MLFLOW_RUN_UUID')"
Downloading artifacts: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00, 1.18it/s]
```

=== "Windows PowerShell"
Expand All @@ -54,57 +56,12 @@ specific MLflow experiment within your VSCode server:
$ $Env:MLFLOW_TRACKING_URI=<MLFLOW_TRACKING_URI>
$ $Env:MLFLOW_TRACKING_USERNAME=<MLFLOW_TRACKING_USERNAME>
$ $Env:MLFLOW_TRACKING_PASSWORD=<MLFLOW_TRACKING_PASSWORD>
$ python -c "import mlflow; mlflow_experiment = mlflow.get_experiment_by_name('<NAME_OF_DEFAULT_MLFLOW_EXPERIMENT>'); print(mlflow_experiment.artifact_location)"
s3://<BUCKET_NAME>/subdir/paths
$ python -c "import mlflow; mlflow.artifacts.download_artifact(artifact_uri='runs:/<MLFLOW_RUN_UUID>/', dst_path='models/<MLFLOW_RUN_UUID')"
Downloading artifacts: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00, 1.18it/s]
```

To list the contents of the artifact location, you can use the AWS CLI
(installed within the VSCOde server by default) like so:

=== "Linux/macOS"

```bash
$ export AWS_ACCESS_KEY_ID=<AWS_ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<AWS_SECRET_ACCESS_KEY>
$ aws s3 ls --endpoint-url "https://necs.nus.edu.sg" <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/
PRE XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/
PRE YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY/
PRE ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ/
```

=== "Windows PowerShell"

```powershell
$ $Env:AWS_ACCESS_KEY_ID=<AWS_ACCESS_KEY_ID>
$ $Env:AWS_SECRET_ACCESS_KEY=<AWS_SECRET_ACCESS_KEY>
$ aws s3 ls --endpoint-url "https://necs.nus.edu.sg" <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/
PRE XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/
PRE YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY/
PRE ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ/
```

What would be listed are subdirectories named after MLflow experiment
unique IDs. Within each of these subdirectories, we will find the
artifacts uploaded to ECS.To list the artifacts of a specific run,
we can run a command like the following:

=== "Linux/macOS"

```bash
$ aws s3 ls --recursive --endpoint-url "https://necs.nus.edu.sg" <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>
YYYY-MM-DD hh:mm:ss XXXXXXXX <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>/artifacts/model/model.pt
YYYY-MM-DD hh:mm:ss XXXXXXXX <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>/artifacts/train_model_config.json
```

=== "Windows PowerShell"

```powershell
$ aws s3 ls --recursive --endpoint-url "https://necs.nus.edu.sg" <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>
YYYY-MM-DD hh:mm:ss XXXXXXXX <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>/artifacts/model/model.pt
YYYY-MM-DD hh:mm:ss XXXXXXXX <MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/<MLFLOW_RUN_UUID>/artifacts/train_model_config.json
```

Now that we have established on how we are to obtain the models for the
Now that we have established on how we are to obtain a specific model for the
API server, let's look into the servers themselves.

## Model Serving (FastAPI)
Expand All @@ -116,7 +73,7 @@ among other things. These factors have made it a popular framework
within AI Singapore across many projects.

If you were to inspect the `src` folder, you would notice that there
exist more than one package:
exists more than one package:

- `{{cookiecutter.src_package_name}}`
- `{{cookiecutter.src_package_name}}_fastapi`
Expand Down Expand Up @@ -150,16 +107,20 @@ following commands:

```bash
$ export PRED_MODEL_UUID=<MLFLOW_RUN_UUID>
$ export PRED_MODEL_ECS_S3_URI=<MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/$PRED_MODEL_UUID
$ aws s3 cp --recursive --endpoint-url "https://necs.nus.edu.sg" $PRED_MODEL_ECS_S3_URI ./models/$PRED_MODEL_UUID
$ export MLFLOW_TRACKING_URI=<MLFLOW_TRACKING_URI>
$ export MLFLOW_TRACKING_USERNAME=<MLFLOW_TRACKING_USERNAME>
$ export MLFLOW_TRACKING_PASSWORD=<MLFLOW_TRACKING_PASSWORD>
$ python -c "import mlflow; mlflow.artifacts.download_artifact(artifact_uri='runs:/$PRED_MODEL_UUID/', dst_path='models/$PRED_MODEL_UUID')"
```

=== "Windows PowerShell"

```powershell
$ $Env:PRED_MODEL_UUID=<MLFLOW_RUN_UUID>
$ $Env:PRED_MODEL_ECS_S3_URI=<MLFLOW_EXPERIMENT_ARTIFACT_LOCATION>/$Env:MLFLOW_RUN_UUID
$ aws s3 cp --recursive --endpoint-url "https://necs.nus.edu.sg" $Env:PRED_MODEL_ECS_S3_URI .\models\$Env:PRED_MODEL_UUID
$ $Env:MLFLOW_TRACKING_URI=<MLFLOW_TRACKING_URI>
$ $Env:MLFLOW_TRACKING_USERNAME=<MLFLOW_TRACKING_USERNAME>
$ $Env:MLFLOW_TRACKING_PASSWORD=<MLFLOW_TRACKING_PASSWORD>
$ python -c "import mlflow; mlflow.artifacts.download_artifact(artifact_uri='runs:/$PRED_MODEL_UUID/', dst_path='models/$PRED_MODEL_UUID')"
```

Executing the commands above will download the artifacts related to the
Expand Down Expand Up @@ -203,7 +164,7 @@ Run the FastAPI server using [Gunicorn](https://gunicorn.org)
```bash
$ conda activate {{cookiecutter.repo_name}}
$ cd src
$ gunicorn {{cookiecutter.src_package_name}}_fastapi.main:APP -b 0.0.0.0:8080 -w 4 -k uvicorn.workers.UvicornWorker
$ gunicorn {{cookiecutter.src_package_name}}_fastapi.main:APP -b 0.0.0.0:8080 -w 2 -k uvicorn.workers.UvicornWorker -t 90
```

See
Expand Down Expand Up @@ -264,7 +225,7 @@ the environment variables.
`src/{{cookiecutter.src_package_name}}_fastapi/config.py`:
```python
...
class Settings(pydantic.BaseSettings):
class Settings(pydantic_settings.BaseSettings):

API_NAME: str = "{{cookiecutter.src_package_name}}_fastapi"
API_V1_STR: str = "/api/v1"
Expand All @@ -280,8 +241,29 @@ class Settings(pydantic.BaseSettings):
FastAPI automatically generates interactive API documentation for
easy viewing of all the routers/endpoints you have made available for
the server. You can view the documentation through
`<API_SERVER_URL>:<PORT>/docs`. In our case here, it is viewable through
[`localhost:8080/docs`](http://localhost:8080/docs). It will look like
`<API_SERVER_URL>:<PORT>/docs`.

It's optional, but let's view the labour of our hard work:

> The following steps assumes you have installed coder on your machine.
> Else, follow the installation steps [here](https://coder.com/docs/v2/latest/install#install-coder)
> and login via `coder login <CODER_URL>`

=== "Linux/macOS"

```bash
$ coder port-forward <WORKSPACE_NAME> --tcp 8080:8080
```

=== "Windows PowerShell"

```powershell

$ coder port-forward <WORKSPACE_NAME> --tcp 8080:8080
```

And with that, our document site for our server is viewable through
[`localhost:8080/docs`](http://localhost:8080/docs) and will look as
such:

![FastAPI - OpenAPI Docs](assets/screenshots/fastapi-openapi-docs.png)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ Let's look at the job defined for the `test`stage first:
before_script:
- conda env create -f {{cookiecutter.repo_name}}-conda-env.yaml
- source activate {{cookiecutter.repo_name}}
- pip install -r dev-requirements.txt
script:
- pylint src --fail-under=7.0 --ignore=tests --disable=W1202
- pytest src/tests
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,23 @@ channels:
- pytorch
- conda-forge
dependencies:
- torch=2.1.2
- torchvision=0.16.2
- cpuonly=2.0
- python=3.11.7
- pip=23.3.2
- pip:
- torch==2.1.2
- mlflow==2.9.2
- boto3==1.34.17
- mlflow-skinny==2.9.2
- hydra-core==1.3.2
- hydra-optuna-sweeper==1.2.0
- torchvision==0.16.2
- python-json-logger==2.0.7
- fastapi==0.109.0
- uvicorn[standard]==0.25.0
- python-multipart==0.0.6
#- python-json-logger==2.0.7
#- pytest==7.4.0
#- pandas==2.0.3
#- torch==2.0.1
#- torchdata==0.6.1
#- torchvision==0.15.2
#- hydra-core==1.3.2
#- hydra-optuna-sweeper==1.2.0
#- pre-commit==3.3.3
#- black==23.3.0
#- scipy==1.11.1
#- Pillow==10.0.0
#- mlflow==2.6.0
#- boto3==1.28.2
#- scikit-learn==1.3.0
#- pylint==2.17.4
#- pydocstyle==6.3.0
#- pygments==2.15.1
#- semgrep==1.33.2
#- ipykernel==6.25.1
#- fastapi==0.103.0
#- uvicorn[standard]==0.23.2
#- gunicorn==21.2.0
#- pydantic==1.10.12
#- python-multipart==0.0.6
#- jsonlines==3.1.0
#- sphinx==4.3.2
- jsonlines==4.0.0
- pandas==2.1.4
- gunicorn==21.2.0
- pydantic==2.5.3
- pydantic-settings==2.1.0
- ipykernel==6.25.0
- sphinx==7.2.5