{ "cells": [ { "cell_type": "markdown", "id": "a1ab3402-ec4c-4012-b5a9-27b78fdee532", "metadata": {}, "source": [ "\"Oasis\n", "


\n", "\n", "Exercise 2: Model Installation \n", "===============================\n", "\n" ] }, { "cell_type": "markdown", "id": "3078919c-fe61-4fc0-8c54-e14e3e82b439", "metadata": {}, "source": [ "This version of the OasisPlatform differs from the existing oasis releases, model workers build from the existing oasis versions, such as [1.26.3](https://github.com/OasisLMF/OasisPlatform/releases/tag/1.26.3), [1.23.13](https://github.com/OasisLMF/OasisPlatform/releases/tag/1.23.13-lts) and [1.15.26](https://github.com/OasisLMF/OasisPlatform/releases/tag/1.15.26-lts) are not directly compatible with Enterprise Platform components which are tag with `2.x.x` version numbers. To port models from the `1.x.x` platform to `2.x.x`, the base worker needs to be build from [Dockerfile.model_worker](https://raw.githubusercontent.com/OasisLMF/OasisPlatform/platform-2.0-develop/Dockerfile.model_worker) on the [platform-2.0-develop](https://github.com/OasisLMF/OasisPlatform/tree/platform-2.0-develop) branch in the OasisPlatform Github repository. \n", "\n", "Both the example models, `PiWind` and `CHAZ`, in this workshop are data driven. Since all of the components are 'Vanilla oasis' and don't require custom supplier components or code, the installation process is straightforward. Part of the platform installation script pushes a version `2.x.x` Oasis worker to the [Azure container registry](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-intro) two run either of the data driven models we just need to make sure that this image is referenced in the deployment yaml configuration (covered in section 2.2.3) \n", "\n", "\"Azure
\n", "\n", "\n", "\n", "### Migrating models (rule of thumb) \n", "* **Data driven models (low effort):** change the default `model_worker` docker image. \n", "* **Custom components (medium effort):** requires rebuilding a new supplier image based on `2.x.x` worker\n", "* **Complex models (case by case):** This depends on the complexity of the custom components and how practical it is to parallelize a custom GUL across multiple worker nodes. \n", "\n", "\n", "### Pipeline Automation for Model deployment \n", "The platform and model deployment scripts were written for [Azure DevOps pipeline](https://learn.microsoft.com/en-us/azure/devops/pipelines/get-started/what-is-azure-pipelines?view=azure-devops). While we won't be covering Pipelines in this workshop, there is [pipeline how-to guide](https://github.com/OasisLMF/OasisAzureDeployment#22-prepare-devops-pipeline) in the OasisAzureDeployment Readme file." ] }, { "cell_type": "markdown", "id": "9e913b2f-7c09-431e-8b2b-89f37c6b13d0", "metadata": { "tags": [] }, "source": [ "## 2.1 Install PiWind using [OasisAzureDeployment](https://github.com/OasisLMF/OasisAzureDeployment)\n" ] }, { "cell_type": "markdown", "id": "a8571146-823b-408b-afbc-846a9a4d7312", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### 2.1.1 Git clone \n", "\n", "Start an azure cloud shell session and Git clone the following GitHub repositories. The terminal icons followed by `some text` are command line which should work 'as is' by copying into https://shell.azure.com/ \n", "\n", "1. [OasisAzureDeployment](https://github.com/OasisLMF/OasisAzureDeployment) \n", "> \"Azure `git clone https://github.com/OasisLMF/OasisAzureDeployment.git -b develop`\n", "\n", "2. [OasisPlatform](https://github.com/OasisLMF/OasisPlatform) \n", "> \"Azure `git clone --depth 1 https://github.com/OasisLMF/OasisPlatform.git -b platform-2.0-develop ~/OasisPlatform`\n", " \n", "\n", "3. [OasisPiWind](https://github.com/OasisLMF/OasisPiWind) \n", "> \"Azure `git clone --depth 1 https://github.com/OasisLMF/OasisPiWind.git -b develop ~/OasisPiWind`\n" ] }, { "cell_type": "markdown", "id": "b4eca294-3735-4543-891d-fb39fd2093ad", "metadata": {}, "source": [ "### 2.1.2 Update the `settings/settings.sh` file\n", "There are shell variables that need to be set for the **OasisAzureDeployment** scripts to work, paste and execute the folloing commands into the shell. \n", "While these arn't strictly needed for the PiWind deployment command to work, the script will throw an error without these set correctly;. \n", "\n", "\n", "1. Set **DNS_LABEL_NAME** \n", "> \"Azure `sed -i \"s|^DNS_LABEL_NAME.*|DNS_LABEL_NAME=oasis-workshop-$(echo $USER | tr -dc '0-9')|\" ~/OasisAzureDeployment/settings/settings.sh`\n", "\n", "2. Set **RESOURCE_GROUP** \n", "> \"Azure `sed -i \"s|^RESOURCE_GROUP.*|RESOURCE_GROUP=oasis-workshop-$(echo $USER | tr -dc '0-9')|\" ~/OasisAzureDeployment/settings/settings.sh`\n", "\n", "3. Set **LETSENCRYPT_EMAIL** \n", "> \"Azure `sed -i \"s|^LETSENCRYPT_EMAIL.*|LETSENCRYPT_EMAIL=workshop$(echo $USER | tr -dc '0-9')@oasislmfenterprise.onmicrosoft.com|\" ~/OasisAzureDeployment/settings/settings.sh`\n" ] }, { "cell_type": "markdown", "id": "df9e1768-4d8c-4871-b9fa-dbc7ea74d45f", "metadata": {}, "source": [ "### 2.1.3 Run the PiWind installation command \n", "\n", "1. Double check the **deploy.sh** script works with the added variables by running the help command. If set correctly, you should see the following list of available commands \n", "\n", "> \"Azure `cd ~/OasisAzureDeployment && ./deploy.sh --help`\n", "\n", "\n", "\n", "```\n", "Usage: ./deploy.sh \n", "\n", "Available commands:\n", " resource-group Create the resource group in Azure to be used for the Oasis platform\n", " ...\n", "```\n", "\n", "\n", "2. Run the Deploy PiWind command, this will push files to the Azure file share mounted to worker pods and create a [Kubernetes deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) for PiWind. Part of the deployment process includes testing, where the example portfolios are executed to check that the deployment was successful. \n", "\n", "> \"Azure `./deploy.sh piwind`" ] }, { "cell_type": "markdown", "id": "f53574c3-b28d-45a0-a51a-22ef0eaf54aa", "metadata": {}, "source": [ "### 2.1.4 Fetch Data from the API to check installation\n", "\n", "The following python fetches data from https://oasis-workshop-{id}.northcentralus.cloudapp.azure.com/api/ \n", "and presents the json returns as tables. \n", "\n", "> **Alternative method:** accessing OasisUI directly from https://oasis-workshop-{id}.northcentralus.cloudapp.azure.com/ (replace `{id}` with your workshop number)" ] }, { "cell_type": "code", "execution_count": null, "id": "e5ef5090-d762-4f1f-91c0-176630ece0f7", "metadata": {}, "outputs": [], "source": [ "# Edit this value to match your workshop ID, if your username is `workshop6@oasislmfenterprise.onmicrosoft.com` set 'WORKSHOP_ID=6'\n", "WORKSHOP_ID=\n", "\n", "# Install of workshop package \n", "!pip install oasis-workshop==1.0.0\n", " \n", "# Clear cell output\n", "from IPython.display import clear_output\n", "clear_output(wait=False) " ] }, { "cell_type": "code", "execution_count": null, "id": "dde35988-7c6f-4ab4-aa92-27e6338ab17a", "metadata": {}, "outputs": [], "source": [ "# Python imports and setup \n", "import time \n", "import json \n", "import tabulate\n", "\n", "from oasis_workshop.client import APIClient\n", "from oasis_workshop.funcs import tabulate_endpoint, tabulate_json\n", "from IPython.display import display, clear_output, HTML, Markdown \n", " \n", "# Start API client session \n", "oasis_server = APIClient(\n", " api_url=f'https://oasis-workshop-{WORKSHOP_ID}.northcentralus.cloudapp.azure.com/api/',\n", " username='admin', \n", " password='password'\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "8451f384-3a8e-47f7-8db5-0f965a5bfd38", "metadata": {}, "outputs": [], "source": [ "models = tabulate_endpoint(oasis_server.models, ['id', 'supplier_id', 'model_id', 'version_id'])\n", "portfolios = tabulate_endpoint(oasis_server.portfolios, ['id', 'name', 'location_file', 'accounts_file', 'reinsurance_info_file', 'reinsurance_scope_file'])\n", "analyses = tabulate_endpoint(oasis_server.analyses, ['id', 'name', 'model', 'portfolio', 'status', 'input_file', 'output_file', 'run_log_file'])\n", "\n", "display(Markdown(f'### Installed Models'))\n", "display(HTML(models))\n", "\n", "display(Markdown(f'### Portfolios Table'))\n", "display(HTML(portfolios))\n", "\n", "display(Markdown(f'### Analyses Table'))\n", "display(HTML(analyses))" ] }, { "cell_type": "markdown", "id": "92811a74-e179-428f-848d-f323c8efe8a3", "metadata": {}, "source": [ "## 2.2 Install and configure CHAZ (Columbia - Tropical Cyclone)" ] }, { "cell_type": "markdown", "id": "b770096b-7f5b-436c-899c-ada9bacdf9d3", "metadata": {}, "source": [ "### 2.2.1 Download a local copy of the CHAZ model data to Azure Cloud Shell\n", "\n", "There is a copy of the CHAZ model data stored in [Azure Blob storage](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-overview), in this exercise the idea is to deploy this to the cluster, via a more manual process than the piwind installation. \n", "\n", "\n", "\"Azure
\n", "\n", "\n", "* **Step 1** - Open Azure cloud shell and login with the [az utility](https://learn.microsoft.com/en-us/cli/azure/what-is-azure-cli) this is a command line tool to interact with Azure resources.\n", "\n", "> \"Azure `az login --identity`\n", "\n", "```\n", " {\n", " \"environmentName\": \"AzureCloud\",\n", " \"homeTenantId\": \"812eb12f-c995-45ef-bfea-eac7aeca0755\",\n", " \"id\": \"da90aaa5-0e0f-4362-bb41-422887865d0f\",\n", " \"isDefault\": true,\n", " \"managedByTenants\": [],\n", " \"name\": \"Oasis-Infrastructure\",\n", " \"state\": \"Enabled\",\n", " \"tenantId\": \"812eb12f-c995-45ef-bfea-eac7aeca0755\",\n", " \"user\": {\n", " \"cloudShellID\": true,\n", " \"name\": \"workshop1@oasislmfenterprise.onmicrosoft.com\",\n", " \"type\": \"user\"\n", " }\n", "```\n", "\n", "\n", "* **Step 2** - Issue a [SAS token](https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview) which grants access to download the CHAZ model data\n", "\n", "> \"Azure `CONTAINER_SAS_TOKEN=$(az storage container generate-sas --account-name oasismodelstore --name columbia-chaz --permissions acdlrw --expiry $(date -u -d \"300 minutes\" '+%Y-%m-%dT%H:%MZ') | tr -d '\"')\n", "`\n", "\n", "Echo out the `CONTAINER_SAS_TOKEN` shell variable to double check the SAS token was created \n", "```\n", "workshop1 [ ~ ]$ echo $CONTAINER_SAS_TOKEN\n", "se=2022-09-23T14%3A26Z&sp=racwdl&sv=2021-06-08&sr=c&sig=3c5F7iyp%2BCVy%2BK1hbN8kAQOl7dRNA4mAMsYE0clOE9k%3D\n", "```\n", "\n", "\n", "\n", "* **Step 3** - Use the [azcopy](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-v10) tool to download a localy copy of the CHAZ data. \n", "\n", "> \"Azure `azcopy copy \"https://oasismodelstore.blob.core.windows.net/columbia-chaz/*?$CONTAINER_SAS_TOKEN\" \"~/chaz-data\" --recursive=true --overwrite=ifSourceNewer`\n", "\n", "\n", "**Example Output**\n", "```\n", "true --overwrite=ifSourceNewer\n", "INFO: Scanning...\n", "INFO: Any empty folders will not be processed, because source and/or destination doesn't have full folder support\n", "INFO: azcopy: A newer version 10.16.0 is available to download\n", "\n", "\n", "Job 0675edeb-80ba-7443-5fd1-1177122a44c9 has started\n", "Log file is located at: /home/workshop1/.azcopy/0675edeb-80ba-7443-5fd1-1177122a44c9.log\n", "\n", "100.0 %, 14 Done, 0 Failed, 0 Pending, 0 Skipped, 14 Total, \n", "\n", "\n", "Job 0675edeb-80ba-7443-5fd1-1177122a44c9 summary\n", "Elapsed Time (Minutes): 0.0667\n", "Number of File Transfers: 14\n", "Number of Folder Property Transfers: 0\n", "Total Number of Transfers: 14\n", "Number of Transfers Completed: 14\n", "Number of Transfers Failed: 0\n", "Number of Transfers Skipped: 0\n", "TotalBytesTransferred: 125452308\n", "Final Job Status: Completed\n", "```" ] }, { "cell_type": "markdown", "id": "f97160a6-0a96-445a-9e33-61513ad333c4", "metadata": {}, "source": [ "### 2.2.2 Edit the meta-data files and upload to cluster \n", "\n", "You should now have a local copy of the CHAZ model data downloaded to `~/chaz-data`, if not ask for assisstance! \n", "\n", "\"Azure
\n", "\n", "Next, using either [nano](https://www.nano-editor.org/dist/latest/cheatsheet.html) or [vim](https://vim.rtorr.com/) make the following edits to the `chunking_configuration.json` and `scaling_configuration.json` files. This needs to happen before uploading these to the cluster file share. \n", "\n", "\n", "**Editing - chunking_configuration.json** - Update the default chunking config values, this affects how many pieces (or chunks) an analysis is broken up into (these options are covered in the next notebook)\n", "\n", "```\n", "\"lookup_strategy\": \"DYNAMIC_CHUNKS\",\n", "\"loss_strategy\": \"DYNAMIC_CHUNKS\",\n", "\"dynamic_locations_per_lookup\": 11000,\n", "\"dynamic_events_per_analysis\": 4800,\n", "```\n", "\n", "> \"Azure `nano ~/chaz-data/chunking_configuration.json`\n", "\n", "> **Hint:** the shortcut `Ctrl-X` saves changes to the file and exits nano\n", "\n", "\n", "\n", "\"Azure
\n", "\n", "\n", "**Editing - scaling_configuration.json** -Update the auto-scaling defaults, this changes how many workers are created to process each of the the job chunks in parallel (these options are covered in the next notebook) \n", "\n", "```\n", " \"worker_count_fixed\": 4,\n", "```\n", "> \"Azure `nano ~/chaz-data/scaling_configuration.json`\n", "\n", "\"Azure
\n", "\n", "### 2.2.3 Upload the model data \n", "\n", "Using the `upload_model_data.sh` from **OasisAzureDeployment** upload the modified model files to the cluster fileshare. This is a file system which gets mounted to the worker containers on startup. \n", "\n", "> \"Azure `~/OasisAzureDeployment/scripts/upload_model_data.sh -C ~/chaz-data/ columbia/chaz/1 $(ls ~/chaz-data/)`\n", "\n", "\"Azure
\n", "\n", "\n", "If the command was successful you should be able to see the files in the clusters file share, located under `models/columbia/chaz/1`\n", "\n", "\"Azure
\n", "\n" ] }, { "cell_type": "markdown", "id": "95fe1755-5f7e-4568-bd54-ec370ee26faa", "metadata": { "tags": [] }, "source": [ "### 2.2.3 Create a deployment YML and run the model deployment command \n", "\n", "Each model requires its own [kubernetes deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), to set this up we'll need to define that deployment with a YAML configuration file. The configuration for PiWind looks like this [oasislmf-piwind-1.yaml](https://raw.githubusercontent.com/OasisLMF/OasisAzureDeployment/master/settings/helm/workers/oasislmf-piwind-1.yaml) to adapt this file for CHAZ, all that needs to change is the top section specifying the model's name. \n", "\n", "**FROM:**\n", "```\n", "workers:\n", " oasislmf_piwind_1: # A name that is unique among all workers\n", " supplierId: OasisLMF # Must be identical to supplier in the model data file share\n", " modelId: PiWind # Must be identical to name in the model data file share\n", " modelVersionId: \"1\" # Must be identical to version in the model data file share\n", " ... \n", "```\n", "\n", "**TO:**\n", "```\n", "workers:\n", " columbia_chaz_1: # A name that is unique among all workers\n", " supplierId: columbia # Must be identical to supplier in the model data file share\n", " modelId: chaz # Must be identical to name in the model data file share\n", " modelVersionId: \"1\" \n", " ...\n", "```\n", "\n", "* To skip editing this file you can use the shortcut below to download an example directly. \n", "\n", "\n", "> \"Azure `wget https://raw.githubusercontent.com/OasisLMF/Workshop2022/main/examples/columbia-chaz-1.yaml -O ~/columbia-chaz-1.yaml`\n", "\n", "\n", "\n", "* Once this file is ready move it to the worker deployment subfolder of **OasisAzureDeployment**\n", "\n", "> \"Azure `mv columbia-chaz-1.yaml ~/OasisAzureDeployment/settings/helm/workers/`\n", "\n", "\n", "\n", "* Running the deploy models command will automaticlly pickup and deploy all model YAML files from the [settings/helm/workers/](https://github.com/OasisLMF/OasisAzureDeployment/tree/master/settings/helm/workers) directory \n", "\n", "\n", "> \"Azure `~/OasisAzureDeployment/deploy.sh models`\n", "\n", "\n", "**Example output**\n", "```\n", "Deploying models...\n", "Updating kubectl cluster\n", "Helm chart upgrade...\n", "Release \"models\" has been upgraded. Happy Helming!\n", "NAME: models\n", "LAST DEPLOYED: Fri Sep 23 11:37:44 2022\n", "NAMESPACE: default\n", "STATUS: deployed\n", "REVISION: 3\n", "TEST SUITE: None\n", "NOTES:\n", "Model(s) registered and worker(s) deployed.\n", "Helm finished\n", "Waiting for models to be registered: \n", "chaz.../home/workshop1/OasisAzureDeployment/deploy.sh: line 189: kill: (819) - No such process\n", "\n", "PiWind...\n", "Models deployed\n", "```\n" ] }, { "cell_type": "markdown", "id": "20e1f511-571e-45c4-af2a-9d6cfa379cce", "metadata": {}, "source": [ "### 2.2.4 check the model registration worked \n", "\n", "If the above commands worked, you should see two model deployments via kubectl. \n", "* `kubectl get deployments | grep ^worker` \n", "\n", "\n", "\"Azure
\n", "\n", "* `kubectl describe deployment worker-columbia-chaz-1`\n", "\n", "\"Azure
\n", "\n", "\n", "\n", "\n", "If something fails you will see that in the **model-registration** pod execution, if for example, the `model_settings.json` file is invalid it would show up as an error. \n", "\n", "\n", "\n", "* `kubectl get pods | grep model-registration`\n", "\n", "\"Azure
\n", "\n", "* `kubectl logs model-registration-ac0tij-5ht5n`\n", "\n", "\"Azure
\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ee6bf3e3-34bd-4d96-b503-a8c8dbeb6532", "metadata": {}, "outputs": [], "source": [ "models = tabulate_endpoint(oasis_server.models, ['id', 'supplier_id', 'model_id', 'version_id'])\n", "display(Markdown(f'### Installed Models'))\n", "display(HTML(models))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "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.10.4" } }, "nbformat": 4, "nbformat_minor": 5 }