From ca8c66ead207cf05df87e46327b2ba5ada7e5213 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Wed, 26 Jul 2023 16:35:30 -0700 Subject: [PATCH 01/18] llm examples --- .../langchain/1_langchain_basic_deploy.ipynb | 508 ++++++++++++++++++ .../endpoints/online/llm/langchain/README.md | 5 + .../online/llm/langchain/deployments/env.yml | 16 + .../online/llm/langchain/requirements.txt | 12 + .../1_semantic_http_server.ipynb | 451 ++++++++++++++++ .../online/llm/semantic-kernel/README.md | 4 + .../environment/serving/Dockerfile | 5 + .../environment/serving/entrypoint.sh | 10 + .../llm/src/langchain/simple_agent_app.py | 22 + .../src/langchain/simple_agent_app_test.py | 19 + .../llm/src/langchain/simple_agent_score.py | 38 ++ .../online/llm/src/langchain_utils.py | 38 ++ sdk/python/endpoints/online/llm/src/sk/app.py | 165 ++++++ .../endpoints/online/llm/src/sk/entry.sh | 3 + .../online/llm/src/sk/requirements.txt | 8 + .../src/sk/skills/FunSkill/Joke/skprompt.txt | 13 + .../skills/WriterSkill/Acronym/skprompt.txt | 25 + .../WriterSkill/AcronymGenerator/skprompt.txt | 54 ++ .../WriterSkill/AcronymReverse/skprompt.txt | 24 + .../WriterSkill/Brainstorm/skprompt.txt | 8 + .../skills/WriterSkill/EmailGen/skprompt.txt | 16 + .../skills/WriterSkill/EmailTo/skprompt.txt | 31 ++ .../WriterSkill/EnglishImprover/skprompt.txt | 11 + .../WriterSkill/NovelChapter/skprompt.txt | 20 + .../NovelChapterWithNotes/skprompt.txt | 19 + .../WriterSkill/NovelOutline/skprompt.txt | 12 + .../skills/WriterSkill/Rewrite/skprompt.txt | 6 + .../skills/WriterSkill/ShortPoem/skprompt.txt | 2 + .../skills/WriterSkill/StoryGen/skprompt.txt | 10 + .../WriterSkill/TellMeMore/skprompt.txt | 7 + .../skills/WriterSkill/Translate/skprompt.txt | 7 + .../TwoSentenceSummary/skprompt.txt | 4 + .../llm/src/sk/skills/WriterSkill/spec.yml | 15 + sdk/python/endpoints/online/llm/src/utils.py | 76 +++ 34 files changed, 1664 insertions(+) create mode 100644 sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb create mode 100644 sdk/python/endpoints/online/llm/langchain/README.md create mode 100644 sdk/python/endpoints/online/llm/langchain/deployments/env.yml create mode 100644 sdk/python/endpoints/online/llm/langchain/requirements.txt create mode 100644 sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb create mode 100644 sdk/python/endpoints/online/llm/semantic-kernel/README.md create mode 100644 sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/Dockerfile create mode 100644 sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/entrypoint.sh create mode 100644 sdk/python/endpoints/online/llm/src/langchain/simple_agent_app.py create mode 100644 sdk/python/endpoints/online/llm/src/langchain/simple_agent_app_test.py create mode 100644 sdk/python/endpoints/online/llm/src/langchain/simple_agent_score.py create mode 100644 sdk/python/endpoints/online/llm/src/langchain_utils.py create mode 100644 sdk/python/endpoints/online/llm/src/sk/app.py create mode 100644 sdk/python/endpoints/online/llm/src/sk/entry.sh create mode 100644 sdk/python/endpoints/online/llm/src/sk/requirements.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/skprompt.txt create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/spec.yml create mode 100644 sdk/python/endpoints/online/llm/src/utils.py diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb new file mode 100644 index 0000000000..89ec06943a --- /dev/null +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -0,0 +1,508 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Langchain Integration into Azure Machine Learning (AzureML)\n", + "\n", + "**Requirements** - In order to benefit from this tutorial, you will need:\n", + "* A basic understanding of Machine Learning and Large Language Models\n", + "* An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F)\n", + "* An Azure Machine Learning Workspace, Azure Key Vault, and Azure Container Registry\n", + "* An OpenAI API Key which can be found in User Settings in OpenAI\n", + "\n", + "**Motivations** - The Langchain framework allows for rapid development of applications powered by large language models. This sample creates a chat bot application backed by a large language model and deploys the application to AzureML.\n", + "\n", + "**Outline** - \n", + "1. Test langchain app locally using [**azureml-inference-server-http**](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-inference-server-http?view=azureml-api-2) pacakge.\n", + "2. Deploy the app to an **AzureML Managed Online Endpoint**\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1. Test Locally\n", + "Before deploy, you could test the langchain app locally. We are using [Langchain ChatGPT plugin](https://python.langchain.com/en/latest/modules/agents/tools/examples/chatgpt_plugins.html) as an example app here. Execute the code below to try out. You can inspect the [simple_agent_app_test.py](../src/langchain/simple_agent_app_test.py) to see the implementation itself. It's a langchain ZERO_SHOT_REACT_DESCRIPTION agent with Klarna plugin." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", + "OPENAI_API_KEY = (\n", + " os.environ.get(\"OPENAI_API_KEY\")\n", + " if os.environ.get(\"OPENAI_API_KEY\")\n", + " else input(\"OPENAI_API_KEY\")\n", + ")\n", + "\n", + "# required for OpenAI API\n", + "OPENAI_ORG_ID = \"\"\n", + "OPENAI_MODEL_ID = \"gpt-3.5-turbo\"\n", + "\n", + "# required for Azure OpenAI API\n", + "AZURE_OPENAI_API_ENDPOINT = \"\"\n", + "AZURE_OPENAI_API_DEPLOYMENT_NAME = \"\"\n", + "\n", + "# set to env var for the langchain code to consume\n", + "%env OPENAI_API_KEY=$OPENAI_API_KEY\n", + "%env OPENAI_API_TYPE=$OPENAI_API_TYPE\n", + "%env OPENAI_MODEL_ID=$OPENAI_MODEL_ID\n", + "%env OPENAI_ORG_ID=$OPENAI_ORG_ID\n", + "%env AZURE_OPENAI_API_ENDPOINT=$AZURE_OPENAI_API_ENDPOINT\n", + "%env AZURE_OPENAI_API_DEPLOYMENT_NAME=$AZURE_OPENAI_API_DEPLOYMENT_NAME" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install -r requirements.txt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment to test the app locally\n", + "# %run -i ../src/langchain/simple_agent_app_test.py" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The test file above is directly running the langchain agent. To deploy to Online Endpoint, let's turn that into a scoring script. You can view the code here: [simple_agent_app_test.py](../src/langchain/simple_agent_app_test.py). We basically create an **init()** and a **run()** function and put the langchain code inside.\n", + "\n", + "You can read more documentation about scoring file here: [How to deploy online endpoint - Understand the scoring script](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-deploy-online-endpoints?view=azureml-api-2&tabs=azure-cli#understand-the-scoring-script)." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.1 (Optional) Test locally using AzureML local server\n", + "Before we deploy to Online Endpoint, you could test locally first. Azure Machine Learning offers [**azureml-inference-server-http**](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-inference-server-http?view=azureml-api-2) to help. We will\n", + "* Start a subprocess to start the server locally\n", + "* Test the server by sending JSON requests\n", + "* Kill the server\n", + "\n", + "Start the server in a sub process" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'''\n", + "import subprocess\n", + "\n", + "p = subprocess.Popen(\n", + " \"cd ../src/langchain/; azmlinfsrv --entry_script simple_agent_score.py\",\n", + " shell=True,\n", + " stdout=subprocess.PIPE,\n", + ")\n", + "'''" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can stream the logs to see what's going on by executing this cell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'''\n", + "import time\n", + "\n", + "while p.poll() is None:\n", + " # Read one line from the output pipe\n", + " output = p.stdout.readline()\n", + " error = None\n", + " if p.stderr:\n", + " error = p.stderr.readline()\n", + " if output:\n", + " print(output.decode(\"utf-8\").strip())\n", + " if error:\n", + " print(error.decode(\"utf-8\").strip())\n", + " time.sleep(0.1)\n", + "'''" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stop the log cell, now let's call the local server to test" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'''\n", + "import requests, json, time\n", + "from urllib.parse import urlsplit\n", + "\n", + "url = \"http://localhost:5001/score\"\n", + "headers = {\"Content-Type\": \"application/json\"}\n", + "\n", + "payload = json.dumps(\n", + " {\"question\": \"what are the top 5 results for womens t shirts on klarna?\"}\n", + ")\n", + "\n", + "response = requests.post(url, headers=headers, data=payload)\n", + "print(f\"Result:\\n\", response.text)\n", + "'''" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should see response similar to this\n", + "```\n", + " The top 5 results for women's t-shirts on Klarna are: \n", + " 1. Armani Exchange Slim Fit Logo Cotton T-shirt - Black\n", + " 2. Balmain White Printed T-Shirt\n", + " 3. Versace Jeans Logo T-shirt - Black\n", + " 4. Icebreaker Women's Tech Lite II Merino Short Sleeve T-shirt - Grey\n", + " 5. Off-White Logo T-Shirt White\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are done testing, let's kill the process" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# pkill = subprocess.Popen(\"kill $(lsof -t -i :5001)\", shell=True, stdout=subprocess.PIPE)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since our scoring script is working, let's deploy to online endpoint." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2. Deploy Online Endpoint\n", + "On a high level, we will perform the following tasks:\n", + "\n", + "* **Preparation**\n", + " * Store OpenAI key in Azure Keyvault to keep it safe.\n", + "* **Create Managed Online Endpoint**, and give the endpoint permission to access Azure Keyvault above.\n", + "* **Deploy to Managed Online Endpoint**\n", + "* **Test**\n", + "\n", + "## 2.1 Preparation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Azure resources needed for the demo. You can change them to use your own.\n", + "# If you don't have the resources, you could keep the names as is and we will create them for you in next step.\n", + "SUBSCRIPTION_ID = \"\"\n", + "RESOURCE_GROUP = \"llmops-demo\"\n", + "REGION = \"westus3\"\n", + "AML_WORKSPACE_NAME = \"llmops-demo-aml-ws\"\n", + "\n", + "# Keyvault information\n", + "KEYVAULT_NAME = \"aml-llm-demo-kv\"\n", + "# Key name in keyvault for the OPENAI-AI-KEY\n", + "KV_OPENAI_KEY = \"OPENAI-API-KEY\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Login to your account" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Authenticate clients\n", + "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", + "\n", + "try:\n", + " credential = DefaultAzureCredential(additionally_allowed_tenants=[\"*\"])\n", + "except Exception as ex:\n", + " # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work\n", + " credential = InteractiveBrowserCredential(additionally_allowed_tenants=[\"*\"])\n", + "\n", + "# If login doesn't work above, uncomment the code below and login using device code\n", + "# !az login --use-device-code" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2.2 Store Secrets in Azure Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", + "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", + "\n", + "need_interactive_auth = False\n", + "if \"AADSTS530003\".lower() in MY_OBJECT_ID[0].lower():\n", + " need_interactive_auth = True\n", + " print(\"\\n\".join(MY_OBJECT_ID))\n", + " print(\n", + " \"\\nYou are geting this error probably because you are using a device login. And this operation needs interactive login. If you can't login interactively, you could simply copy and run the following command in Azure Cloud Shell in Bash mode.\\n\"\n", + " )\n", + " print(\"MY_OBJECT_ID=`az ad signed-in-user show --query id -o tsv`\")\n", + " print(\n", + " f\"az role assignment create --role 'Key Vault Administrator' --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id $MY_OBJECT_ID --assignee-principal-type User\"\n", + " )\n", + " print(\n", + " f\"az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\"\n", + " )\n", + "else:\n", + " # Let's set OpenAI key as a secret in keyvault\n", + " need_interactive_auth = False\n", + " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", + " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Manage Online Endpoint\n", + "### 3.1 Create Endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# create a endpoint\n", + "from azure.ai.ml.entities import (\n", + " ManagedOnlineEndpoint,\n", + ")\n", + "\n", + "from azure.ai.ml import (\n", + " MLClient,\n", + ")\n", + "\n", + "online_endpoint_name = \"aml-llm-demo-langchain-endpoint\"\n", + "\n", + "# get a handle to the workspace\n", + "ml_client = MLClient(credential, SUBSCRIPTION_ID, RESOURCE_GROUP, AML_WORKSPACE_NAME)\n", + "\n", + "try:\n", + " endpoint = ml_client.online_endpoints.get(online_endpoint_name)\n", + "except Exception as ex:\n", + " # create an online endpoint\n", + " endpoint = ManagedOnlineEndpoint(\n", + " name=online_endpoint_name,\n", + " description=\"online endpoint for Langchain server\",\n", + " auth_mode=\"key\",\n", + " )\n", + "\n", + " endpoint = ml_client.begin_create_or_update(endpoint).result()\n", + "\n", + "print(endpoint)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Grant Endpoint Permission to Dependencies\n", + "Endpoint uses AAD to access dependent resources, so you don't have to hardcode secrets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Allow the endpoint to access secrets in keyvault\n", + "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", + "need_interactive_auth = True\n", + "if need_interactive_auth:\n", + " print(\n", + " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", + " )\n", + " print(\n", + " f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", + " )\n", + "else:\n", + " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3.3 Deploy to Endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import datetime\n", + "\n", + "from azure.ai.ml.entities import (\n", + " ManagedOnlineDeployment,\n", + " OnlineRequestSettings,\n", + " Environment,\n", + " CodeConfiguration,\n", + ")\n", + "\n", + "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", + "\n", + "env = Environment(\n", + " conda_file=\"deployments/env.yml\",\n", + " image=\"mcr.microsoft.com/azureml/minimal-ubuntu20.04-py38-cpu-inference:latest\",\n", + ")\n", + "\n", + "deployment_name = f\"deploy-{str(datetime.datetime.now().strftime('%m%d%H%M%f'))}\"\n", + "sk_deployment = ManagedOnlineDeployment(\n", + " name=deployment_name,\n", + " environment=env,\n", + " code_configuration=CodeConfiguration(\n", + " code=\"../src\", scoring_script=\"langchain/simple_agent_score.py\"\n", + " ),\n", + " request_settings=OnlineRequestSettings(request_timeout_ms=60000),\n", + " environment_variables={\n", + " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", + " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", + " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", + " \"OPENAI_ORG_ID\": OPENAI_ORG_ID,\n", + " \"AZURE_OPENAI_API_ENDPOINT\": AZURE_OPENAI_API_ENDPOINT,\n", + " \"AZURE_OPENAI_API_DEPLOYMENT_NAME\": AZURE_OPENAI_API_DEPLOYMENT_NAME,\n", + " },\n", + " endpoint_name=online_endpoint_name,\n", + " instance_type=\"Standard_F2s_v2\",\n", + " instance_count=1,\n", + ")\n", + "ml_client.online_deployments.begin_create_or_update(sk_deployment).result()\n", + "\n", + "endpoint.traffic = {deployment_name: 100}\n", + "ml_client.begin_create_or_update(endpoint).result()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Test\n", + "Now endpoint has been deployed, let's test it. We are going to re-use the same request when we test it locally earlier on." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import requests, json, time\n", + "from urllib.parse import urlsplit\n", + "\n", + "url_parts = urlsplit(endpoint.scoring_uri)\n", + "url = url_parts.scheme + \"://\" + url_parts.netloc\n", + "\n", + "token = ml_client.online_endpoints.get_keys(name=online_endpoint_name).primary_key\n", + "headers = {\"Authorization\": \"Bearer \" + token, \"Content-Type\": \"application/json\"}\n", + "payload = json.dumps(\n", + " {\"question\": \"what are the top 5 results for womens t shirts on klarna?\"}\n", + ")\n", + "\n", + "response = requests.post(f\"{url}/score\", headers=headers, data=payload)\n", + "print(f\"Response:\\n\", response.text)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10 - SDK V2", + "language": "python", + "name": "python310-sdkv2" + }, + "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.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/sdk/python/endpoints/online/llm/langchain/README.md b/sdk/python/endpoints/online/llm/langchain/README.md new file mode 100644 index 0000000000..6ef94aa311 --- /dev/null +++ b/sdk/python/endpoints/online/llm/langchain/README.md @@ -0,0 +1,5 @@ +# Use LangChain Tools with AzureML Online Endpoints + +This sample shows how to leverage AzureML infrastructure with the power of LangChain by deploying your LLM application to an Online Endpoint. + +Check out [1_langchain_basic_deploy.ipynb](1_langchain_basic_deploy.ipynb) to get started. \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/langchain/deployments/env.yml b/sdk/python/endpoints/online/llm/langchain/deployments/env.yml new file mode 100644 index 0000000000..34c2e7ad0e --- /dev/null +++ b/sdk/python/endpoints/online/llm/langchain/deployments/env.yml @@ -0,0 +1,16 @@ +name: plugin-demo-env +dependencies: + - python=3.9 + - pip=21.2.4 + - pip: + - azure-ai-ml==1.5.0 + - azure-core==1.26.4 + - azure-identity==1.13.0b3 + - azureml-inference-server-http + - azure-keyvault-secrets + - azure-search-documents==11.4.0b3 + - langchain==0.0.164 + - openai==0.27.6 + - parse + - requests + - pyyaml \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/langchain/requirements.txt b/sdk/python/endpoints/online/llm/langchain/requirements.txt new file mode 100644 index 0000000000..52adcf79d9 --- /dev/null +++ b/sdk/python/endpoints/online/llm/langchain/requirements.txt @@ -0,0 +1,12 @@ +azure-ai-ml==1.5.0 +azure-core==1.26.4 +azure-identity==1.13.0b3 +azureml-inference-server-http +azure-keyvault-secrets +azure-search-documents==11.4.0b3 +langchain==0.0.164 +openai==0.27.6 +parse +requests +pyyaml +azure-cli \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb new file mode 100644 index 0000000000..81572b90aa --- /dev/null +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -0,0 +1,451 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Semantic Kernel (SK) Integration into Azure Machine Learning (AzureML)\n", + "\n", + "**Requirements** - In order to benefit from this tutorial, you will need:\n", + "* A basic understanding of Machine Learning and Large Language Models\n", + "* An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F)\n", + "* An Azure Machine Learning Workspace, Azure Key Vault, and Azure Container Registry\n", + "* An OpenAI API Key which can be found in User Settings in OpenAI\n", + "\n", + "**Motivations** - Semantic kernel has a slightly different approach to LLM agents. It offers an interesting Plan->Execute pattern, where it could use LLM to form a plan first, then human could confirm and execute on the plan. In this notebook, we use the [planner](https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/python/05-using-the-planner.ipynb) example from Semantic Kernel as a base. But additionally, we've made the following modifications:\n", + "* Created a **python SemanticKernelHttp server** based on Flask.\n", + "* Deploy SemanticKernelHttp to an **AzureML Managed Online Endpoint**\n", + "\n", + "Managed online endpoints provide an easy to manage inferencing server for your ML workload. It's perfect for LLM based applications. Since we need a REST service, we won't use the default endpoint docker image, we will create a custom docker image instead.\n", + "\n", + "**Outline** - \n", + "1. Test SemanticKernelHttpServe locally\n", + "2. Prepare Dependencies\n", + "3. Deploy to Managed Online Endpoint\n", + "4. Test" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1. Test SemanticKernelHttpServer Locally\n", + "Before we proceed, let's startup the server and test locally first. Grab your OpenAI infor and fill in the variables below" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "OPENAI_API_TYPE='azure' # 'azure' or 'openai'\n", + "OPENAI_API_KEY=os.environ.get('OPENAI_API_KEY') if os.environ.get('OPENAI_API_KEY') else input('OPENAI_API_KEY')\n", + "\n", + "# required for OpenAI API\n", + "OPENAI_ORG_ID=''\n", + "OPENAI_MODEL_ID='gpt-3.5-turbo'\n", + "\n", + "# required for Azure OpenAI API\n", + "AZURE_OPENAI_API_ENDPOINT='https://.openai.azure.com/'\n", + "AZURE_OPENAI_API_DEPLOYMENT_NAME=''\n", + "\n", + "# set to true for chat completion API, false for text completion\n", + "IS_CHAT_COMPLETION=True\n", + "\n", + "# setting up env variables for local server\n", + "%env OPENAI_API_TYPE=$OPENAI_API_TYPE\n", + "%env OPENAI_API_KEY=$OPENAI_API_KEY\n", + "%env OPENAI_MODEL_ID=$OPENAI_MODEL_ID\n", + "%env OPENAI_ORG_ID=$OPENAI_ORG_ID\n", + "%env AZURE_OPENAI_API_ENDPOINT=$AZURE_OPENAI_API_ENDPOINT\n", + "%env AZURE_OPENAI_API_DEPLOYMENT_NAME=$AZURE_OPENAI_API_DEPLOYMENT_NAME\n", + "%env IS_CHAT_COMPLETION=$IS_CHAT_COMPLETION\n", + "\n", + "# Install python dependencies\n", + "%pip install -r ../src/sk/requirements.txt --user" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# start the server locally\n", + "# %run -i ../src/sk/app.py" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.1 Test the server API\n", + "Now the server is running, since the Jupyter notebook kernal is blocked.\n", + "You could use postman to test. If you don't have postman, you could also open a terminal and execute the curl commands below to try. \n", + "```\n", + "curl -i -X POST -H \"Content-Type: application/json\" -d \"{\\\"value\\\": \\\"Tomorrow is Valentine day. I need to come up with a few date ideas. She speaks French so write it in French.\\\"}\" http://127.0.0.1:5001/planner/createplan\n", + "```\n", + "You should be seeing resposes like\n", + "```\n", + "{\n", + " \"input\": \"Valentine's Day Date Ideas\",\n", + " \"subtasks\": [\n", + " {\"function\": \"WriterSkill.Brainstorm\"},\n", + " {\"function\": \"WriterSkill.EmailTo\", \"args\": {\"to\": \"significant_other\"}},\n", + " {\"function\": \"WriterSkill.Translate\", \"args\": {\"language\": \"French\"}}\n", + " ]\n", + "}\n", + "```\n", + "\n", + "Then you could execute this plan\n", + "```\n", + "curl -i -X POST -H \"Content-Type: application/json\" -d \"{\\\"input\\\": \\\"Valentine's Day Date Ideas\\\", \\\"subtasks\\\": [{\\\"function\\\": \\\"WriterSkill.Brainstorm\\\"},{\\\"function\\\": \\\"WriterSkill.EmailTo\\\", \\\"args\\\": {\\\"to\\\": \\\"significant_other\\\"}},{\\\"function\\\": \\\"WriterSkill.Translate\\\", \\\"args\\\": {\\\"language\\\": \\\"French\\\"}}]}\" http://127.0.0.1:5001/planner/executeplan\n", + "```\n", + "You should see responses like \n", + "```\n", + "Assurez-vous d'utiliser uniquement le français.\n", + "\n", + "Cher(e) partenaire,\n", + "\n", + "Je pensais à des activités amusantes et romantiques que nous pourrions faire ensemble et j'ai eu quelques idées. Nous pourrions avoir un dîner romantique dans un restaurant chic, ou faire un pique-nique dans le parc. Une autre idée est de faire une soirée cinéma à la maison avec du popcorn fait maison, ou aller pour un massage en couple dans un spa. Nous pourrions également essayer une dégustation de vin dans un vignoble local, ou aller patiner sur glace dans une patinoire à proximité. Si nous sommes d'humeur aventureuse, nous pourrions prendre un cours de cuisine ensemble, ou faire un tour en montgolfière au lever ou au coucher du soleil. Pour une expérience plus culturelle, nous pourrions visiter un musée ou une galerie d'art, ou faire une randonnée ou une promenade panoramique.\n", + "\n", + "Faites-moi savoir ce que vous en pensez !\n", + "\n", + "Merci,\n", + "[Votre nom]\n", + "```\n", + "\n", + "Great! Now our server and plugin are both working well locally. Let's deploy to AML so our team members could try out too." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2. Deploy Server to AML Managed Online Endpoint\n", + "On a high level, we will perform the following tasks:\n", + "\n", + "* **Preparation**\n", + " * Store Secets in Azure Keyvault\n", + " * Create docker image in Azure Container Registry\n", + "* **Create Managed Online Endpoint**, grant the endpoint permission to access the resources above.\n", + "* **Deploy to Managed Online Endpoint**, now we are ready deploy the code\n", + "* **Test**\n", + "\n", + "## 2.1. Preparation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Azure resources needed for the demo. You can change them to use your own. \n", + "# If you don't have the resources, you could keep the names as is and we will create them for you in next step.\n", + "SUBSCRIPTION_ID = \"\"\n", + "RESOURCE_GROUP = \"llmops-demo\"\n", + "REGION = \"westus3\"\n", + "AML_WORKSPACE_NAME = \"llmops-demo-aml-ws\"\n", + "\n", + "# Keyvault information\n", + "KEYVAULT_NAME = \"aml-llm-demo-kv\"\n", + "# Key name in keyvault for the OPENAI-AI-KEY\n", + "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", + "\n", + "ACR_NAME='amlllmdemoacr'\n", + "ACR_IMAGE_NAME='serving'" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's login first" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Authenticate clients\n", + "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", + "\n", + "try:\n", + " credential = DefaultAzureCredential(additionally_allowed_tenants = ['*'])\n", + "except Exception as ex:\n", + " # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work\n", + " credential = InteractiveBrowserCredential(additionally_allowed_tenants = ['*'])\n", + "\n", + "# If login doesn't work above, uncomment the code below and login using device code\n", + "# !az login --use-device-code" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Store Secrets in Azure Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", + "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", + "\n", + "need_interactive_auth = False\n", + "if \"AADSTS530003\".lower() in MY_OBJECT_ID[0].lower():\n", + " need_interactive_auth = True\n", + " print('\\n'.join(MY_OBJECT_ID))\n", + " print(\"\\nYou are geting this error probably because you are using a device login. And this operation needs interactive login. If you can't login interactively, you could simply copy and run the following command in Azure Cloud Shell in Bash mode.\\n\")\n", + " print(\"MY_OBJECT_ID=`az ad signed-in-user show --query id -o tsv`\")\n", + " print(f\"az role assignment create --role 'Key Vault Administrator' --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id $MY_OBJECT_ID --assignee-principal-type User\")\n", + " print(f\"az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\")\n", + "else:\n", + " # Let's set OpenAI key as a secret in keyvault\n", + " need_interactive_auth = False\n", + " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", + " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.3 Create Docker Image" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "!az acr build --image {ACR_IMAGE_NAME} --registry {ACR_NAME} ./environment/serving/. --subscription {SUBSCRIPTION_ID}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Manage Online Endpoint\n", + "### 3.1 Create Endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Authenticate clients\n", + "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", + "\n", + "try:\n", + " credential = DefaultAzureCredential(additionally_allowed_tenants = ['*'])\n", + "except Exception as ex:\n", + " # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work\n", + " credential = InteractiveBrowserCredential()\n", + " \n", + "# create a endpoint\n", + "from azure.ai.ml.entities import (\n", + " ManagedOnlineEndpoint,\n", + ")\n", + "\n", + "from azure.ai.ml import (\n", + " MLClient,\n", + ")\n", + "\n", + "online_endpoint_name = \"aml-llm-demo-sk-endpoint\"\n", + "\n", + "# get a handle to the workspace\n", + "ml_client = MLClient(credential, SUBSCRIPTION_ID, RESOURCE_GROUP, AML_WORKSPACE_NAME)\n", + "\n", + "try:\n", + " endpoint = ml_client.online_endpoints.get(online_endpoint_name)\n", + "except Exception as ex:\n", + " # create an online endpoint\n", + " endpoint = ManagedOnlineEndpoint(\n", + " name=online_endpoint_name,\n", + " description=\"online endpoint for SemanticKernelHttp server\",\n", + " auth_mode=\"key\",\n", + " )\n", + "\n", + " endpoint = ml_client.begin_create_or_update(endpoint).result()\n", + "\n", + "print(endpoint)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Grant Endpoint Permission to Dependencies\n", + "Endpoint uses AAD to access dependent resources, so you don't have to hardcode secrets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Allow the endpoint to access keyvault and acr\n", + "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", + "ACR_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.ContainerRegistry/registries/{ACR_NAME}\"\n", + "\n", + "need_interactive_auth=True\n", + "if need_interactive_auth:\n", + " print(\"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\")\n", + " print(f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\")\n", + " print(f\"az role assignment create --role 'AcrPull' --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\")\n", + "else:\n", + " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", + " !az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3 Deploy to Endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import datetime\n", + "import logging\n", + "import sys\n", + "\n", + "from azure.ai.ml.entities import (\n", + " ManagedOnlineDeployment,\n", + " OnlineRequestSettings,\n", + " Model,\n", + " Environment,\n", + ")\n", + "\n", + "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", + "\n", + "deployment_name = f\"deploy-{str(datetime.datetime.now().strftime('%m%d%H%M%f'))}\"\n", + "sk_deployment = ManagedOnlineDeployment(\n", + " name = deployment_name,\n", + " model=Model(path=\"../src\"),\n", + " request_settings=OnlineRequestSettings(\n", + " request_timeout_ms= 60000\n", + " ),\n", + " environment= Environment(\n", + " image=f\"{ACR_NAME}.azurecr.io/{ACR_IMAGE_NAME}:latest\",\n", + " name=\"serving\",\n", + " description=\"A generic serving environment, allowing customer to provide their own entry point to bring up an http server\",\n", + " inference_config = {\n", + " \"liveness_route\": {\"port\": 5001, \"path\": \"/health\"},\n", + " \"readiness_route\": {\"port\": 5001, \"path\": \"/health\"},\n", + " \"scoring_route\": {\"port\": 5001, \"path\": \"/\"},\n", + " }),\n", + " environment_variables={\n", + " \"AZUREML_SERVING_ENTRYPOINT\": \"../src/sk/entry.sh\",\n", + " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", + " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", + " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", + " \"OPENAI_ORG_ID\": OPENAI_ORG_ID,\n", + " \"AZURE_OPENAI_API_ENDPOINT\": AZURE_OPENAI_API_ENDPOINT,\n", + " \"AZURE_OPENAI_API_DEPLOYMENT_NAME\": AZURE_OPENAI_API_DEPLOYMENT_NAME,\n", + " \"IS_CHAT_COMPLETION\": True,\n", + " },\n", + " endpoint_name=online_endpoint_name,\n", + " instance_type=\"Standard_F2s_v2\",\n", + " instance_count=1\n", + ")\n", + "ml_client.online_deployments.begin_create_or_update(sk_deployment).result()\n", + "\n", + "endpoint.traffic = {deployment_name: 100}\n", + "ml_client.begin_create_or_update(endpoint).result()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Test\n", + "Now endpoint has been deployed, let's test it. We are going to re-use the same request when we test it locally earlier on." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import requests, json\n", + "from urllib.parse import urlsplit\n", + "\n", + "url_parts = urlsplit(endpoint.scoring_uri)\n", + "url = url_parts.scheme + \"://\" + url_parts.netloc\n", + "\n", + "token = ml_client.online_endpoints.get_keys(name=online_endpoint_name).primary_key\n", + "headers = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}\n", + "payload = json.dumps({\n", + " \"value\": \"Tomorrow is Valentine's day. I need to come up with a few date ideas. She speaks French so write it in French.\"\n", + "})\n", + "\n", + "response = requests.post(f'{url}/planner/createplan', headers=headers, data=payload)\n", + "print(f'Created Plan:\\n', response.text)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "payload = response.text\n", + "response = requests.request(\"POST\", f'{url}/planner/executeplan', headers=headers, data=payload)\n", + "print(f'Execution Result:\\n', response.text)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10 - SDK V2", + "language": "python", + "name": "python310-sdkv2" + }, + "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.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/README.md b/sdk/python/endpoints/online/llm/semantic-kernel/README.md new file mode 100644 index 0000000000..a896263bef --- /dev/null +++ b/sdk/python/endpoints/online/llm/semantic-kernel/README.md @@ -0,0 +1,4 @@ +# Deploy Semantic Kernel to online endpoint + +This example shows how to deploy semantic kernel to online endpoint by extending the AzureML Inference Minimal CPU image. + diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/Dockerfile b/sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/Dockerfile new file mode 100644 index 0000000000..fa652eedf4 --- /dev/null +++ b/sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/Dockerfile @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/azureml/minimal-ubuntu20.04-py38-cpu-inference:latest + +COPY . . + +CMD ["/bin/sh", "entrypoint.sh"] diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/entrypoint.sh b/sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/entrypoint.sh new file mode 100644 index 0000000000..bdebe023b5 --- /dev/null +++ b/sdk/python/endpoints/online/llm/semantic-kernel/environment/serving/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -x +export +ENTRYFILE="$AZUREML_MODEL_DIR/$AZUREML_SERVING_ENTRYPOINT" +DIR="$( cd "$( dirname "$ENTRYFILE" )" >/dev/null 2>&1 && pwd )" +FILENAME="$(basename $ENTRYFILE)" +cd $DIR +ls -la +bash $FILENAME \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/langchain/simple_agent_app.py b/sdk/python/endpoints/online/llm/src/langchain/simple_agent_app.py new file mode 100644 index 0000000000..d5bad9e5fe --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/langchain/simple_agent_app.py @@ -0,0 +1,22 @@ +from langchain.agents import initialize_agent, AgentType +import os, sys + +# add parent directory to path +sys.path.insert(0, str(os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))) + +import utils, langchain_utils + + +class SimpleAgentApp: + openai_config: utils.OpenAIConfig = None + _chain = None + + def __init__(self, openai_config: utils.OpenAIConfig = None, plugins=None): + self.openai_config = openai_config + llm = langchain_utils.create_chat_model(openai_config) + self._chain = initialize_agent( + plugins, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True + ) + + def run(self, question: str): + return self._chain.run(question) diff --git a/sdk/python/endpoints/online/llm/src/langchain/simple_agent_app_test.py b/sdk/python/endpoints/online/llm/src/langchain/simple_agent_app_test.py new file mode 100644 index 0000000000..8d6620048e --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/langchain/simple_agent_app_test.py @@ -0,0 +1,19 @@ +import simple_agent_app +from langchain.tools import AIPluginTool +from langchain.agents import load_tools +import os, sys + +sys.path.insert(0, str(os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))) + +import utils + +plugins = [ + AIPluginTool.from_plugin_url("https://www.klarna.com/.well-known/ai-plugin.json") +] +plugins += load_tools(["requests_all"]) + +agent = simple_agent_app.SimpleAgentApp( + openai_config=utils.OpenAIConfig.from_env(), plugins=plugins +) + +agent.run("what are the top 5 results for womens t shirts on klarna?") diff --git a/sdk/python/endpoints/online/llm/src/langchain/simple_agent_score.py b/sdk/python/endpoints/online/llm/src/langchain/simple_agent_score.py new file mode 100644 index 0000000000..3a1b2cd6ea --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/langchain/simple_agent_score.py @@ -0,0 +1,38 @@ +import json +import os +import sys +from simple_agent_app import SimpleAgentApp +from azure.identity import DefaultAzureCredential +from parse import * + +# add parent directory to path +sys.path.insert(0, str(os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))) +import langchain_utils +import utils + +credential = DefaultAzureCredential(additionally_allowed_tenants=["*"]) + +OPENAI_API_KEY = None + +""" +Required AzureML deployment score functions + - init() - called during deployment creation + - run() - called when invoking the endpoint deployment +""" + + +def init(): + utils.load_secrets(credential) + + # Load plugins into tools + plugins = langchain_utils.create_plugins_static() + + global agent + agent = SimpleAgentApp(openai_config=utils.OpenAIConfig.from_env(), plugins=plugins) + + +def run(raw_data): + print(f"raw_data: {raw_data}") + question = json.loads(raw_data)["question"] + result = agent.run(question) + return result diff --git a/sdk/python/endpoints/online/llm/src/langchain_utils.py b/sdk/python/endpoints/online/llm/src/langchain_utils.py new file mode 100644 index 0000000000..0de9767635 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/langchain_utils.py @@ -0,0 +1,38 @@ +from langchain.agents import load_tools +from langchain.tools import AIPluginTool +from parse import * +from langchain.chat_models.base import BaseChatModel +from langchain.chat_models import ChatOpenAI, AzureChatOpenAI + +import utils + + +def create_plugins_static(): + plugins = [ + AIPluginTool.from_plugin_url( + "https://www.klarna.com/.well-known/ai-plugin.json" + ) + ] + plugins += load_tools(["requests_all"]) + return plugins + + +def create_chat_model(openai_config: utils.OpenAIConfig) -> BaseChatModel: + if openai_config.is_azure_openai(): + return AzureChatOpenAI( + temperature=0, + openai_api_base=openai_config.AZURE_OPENAI_API_ENDPOINT, + openai_api_version=openai_config.AZURE_OPENAI_API_VERSION + if openai_config.AZURE_OPENAI_API_VERSION + else "2023-03-15-preview", + deployment_name=openai_config.AZURE_OPENAI_API_DEPLOYMENT_NAME, + openai_api_key=openai_config.OPENAI_API_KEY, + openai_api_type=openai_config.OPENAI_API_TYPE, + ) + else: + return ChatOpenAI( + temperature=0, + openai_api_key=openai_config.OPENAI_API_KEY, + openai_organization=openai_config.OPENAI_ORG_ID, + model_name=openai_config.OPENAI_MODEL_ID, + ) diff --git a/sdk/python/endpoints/online/llm/src/sk/app.py b/sdk/python/endpoints/online/llm/src/sk/app.py new file mode 100644 index 0000000000..6c4efd2ff3 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/app.py @@ -0,0 +1,165 @@ +from __future__ import annotations +import sys, os, json +from flask import Flask, request +import semantic_kernel as sk +import semantic_kernel.connectors.ai.open_ai as sk_oai +from semantic_kernel.planning.basic_planner import BasicPlanner +from semantic_kernel.planning.plan import Plan +from azure.identity import DefaultAzureCredential, AzureCliCredential + +# add parent directory to path +sys.path.insert(0, str(os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))) + +import utils + +openai_config: utils.OpenAIConfig = None + +IS_CHAT_COMPLETION = None + +import importlib + +importlib.reload(utils) + +# set to true for chat completion API, false for text completion +IS_CHAT_COMPLETION = True +credential = DefaultAzureCredential(additionally_allowed_tenants=["*"]) + + +def init() -> tuple[sk.Kernel, BasicPlanner]: + utils.load_secrets(credential) + load_env_vars() + + kernel = create_kernel(debug=False) + planner = BasicPlanner() + return kernel, planner + + +def load_env_vars(): + global openai_config + openai_config = utils.OpenAIConfig.from_env() + global IS_CHAT_COMPLETION + IS_CHAT_COMPLETION = bool(os.environ.get("IS_CHAT_COMPLETION")) + + +def import_skills(kernel: sk.Kernel, skills_folder: str): + print(f"Importing skills from {skills_folder}") + for skill_name in os.listdir(skills_folder): + skill_full_path = os.path.join(skills_folder, skill_name) + print(f"== Importing skill {skill_name}: {skill_full_path}") + kernel.import_semantic_skill_from_directory(skills_folder, skill_name) + + +def create_kernel(debug: bool = False) -> sk.Kernel: + logger = sk.NullLogger() + if debug: + import logging + + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler(sys.stdout) + formatter = logging.Formatter( + "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) + handler.setFormatter(formatter) + logger.handlers.clear() + logger.addHandler(handler) + + kernel = sk.Kernel() + if openai_config.OPENAI_API_TYPE == "azure": + # if using chat service from Azure OpenAI API, use AzureChatCompletion + kernel.add_text_completion_service( + "completion", + sk_oai.AzureChatCompletion( + deployment_name=openai_config.AZURE_OPENAI_API_DEPLOYMENT_NAME, + api_key=openai_config.OPENAI_API_KEY, + endpoint=openai_config.AZURE_OPENAI_API_ENDPOINT, + ) + if IS_CHAT_COMPLETION + else sk_oai.AzureTextCompletion( + deployment_name=openai_config.AZURE_OPENAI_API_DEPLOYMENT_NAME, + api_key=openai_config.OPENAI_API_KEY, + endpoint=openai_config.AZURE_OPENAI_API_ENDPOINT, + ), + ) + else: + print( + "using openai", openai_config.OPENAI_MODEL_ID, openai_config.OPENAI_ORG_ID + ) + kernel.add_text_completion_service( + "completion", + sk_oai.OpenAIChatCompletion( + openai_config.OPENAI_MODEL_ID, + openai_config.OPENAI_API_KEY, + openai_config.OPENAI_ORG_ID, + ) + if IS_CHAT_COMPLETION + else sk_oai.OpenAITextCompletion( + openai_config.OPENAI_MODEL_ID, + openai_config.OPENAI_API_KEY, + openai_config.OPENAI_ORG_ID, + ), + ) + + # import skills from skills folder + import_skills( + kernel, os.path.join(os.path.dirname(os.path.realpath(__file__)), "skills") + ) + + return kernel + + +kernel, planner = init() + + +async def invoke_skill(skillName, functionName, context): + skillFunction = kernel.func(skillName, functionName) + return await skillFunction.invoke_async(context=context) + + +# class for plan deserializing +class GeneratedPlan: + def __init__(self, result: str): + self.result = result + + +app = Flask(__name__) + + +@app.route("/", methods=["GET"]) +def home(): + return "ok" + + +@app.route("/health", methods=["GET"]) +def health(): + return "healthy" + + +@app.route("/skills//invoke/", methods=["POST"]) +async def invoke(skillName, functionName): + return await invoke_skill(skillName, functionName, request.get_json()) + + +@app.route("/planner/createplan", methods=["POST"]) +async def createplan(): + body = request.get_json() + goal = body["value"] + plan = await planner.create_plan_async(goal, kernel) + print(plan.generated_plan.result) + return plan.generated_plan.result + + +@app.route("/planner/executeplan", methods=["POST"]) +async def executeplan(): + body = request.get_json() + print(body) + gp = GeneratedPlan(result=json.dumps(body)) + p = Plan(goal=None, prompt=None, plan=gp) + + result = await planner.execute_plan_async(p, kernel) + print(result) + return result + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5001) diff --git a/sdk/python/endpoints/online/llm/src/sk/entry.sh b/sdk/python/endpoints/online/llm/src/sk/entry.sh new file mode 100644 index 0000000000..bd33edf670 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/entry.sh @@ -0,0 +1,3 @@ +pwd +pip install -r requirements.txt +python3 app.py \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/requirements.txt b/sdk/python/endpoints/online/llm/src/sk/requirements.txt new file mode 100644 index 0000000000..23db126346 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/requirements.txt @@ -0,0 +1,8 @@ +Flask==2.3.2 +semantic_kernel==0.2.9.dev0 +flask[async] +azure-keyvault +azure-keyvault-secrets +azure-ai-ml==1.5.0 +pyyaml +azure-cli \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/skprompt.txt new file mode 100644 index 0000000000..d6c0a1e95c --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/skprompt.txt @@ -0,0 +1,13 @@ +WRITE EXACTLY ONE JOKE or HUMOROUS STORY ABOUT THE TOPIC BELOW + +JOKE MUST BE: +- G RATED +- WORKPLACE/FAMILY SAFE +NO SEXISM, RACISM OR OTHER BIAS/BIGOTRY + +BE CREATIVE AND FUNNY. I WANT TO LAUGH. +{{$style}} ++++++ + +{{$input}} ++++++ diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/skprompt.txt new file mode 100644 index 0000000000..1c2e8a6aa4 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/skprompt.txt @@ -0,0 +1,25 @@ +Generate a suitable acronym pair for the concept. Creativity is encouraged, including obscure references. +The uppercase letters in the acronym expansion must agree with the letters of the acronym + +Q: A technology for detecting moving objects, their distance and velocity using radio waves. +A: R.A.D.A.R: RAdio Detection And Ranging. + +Q: A weapon that uses high voltage electricity to incapacitate the target +A. T.A.S.E.R: Thomas A. Swift’s Electric Rifle + +Q: Equipment that lets a diver breathe underwater +A: S.C.U.B.A: Self Contained Underwater Breathing Apparatus. + +Q: Reminder not to complicated subject matter. +A. K.I.S.S: Keep It Simple Stupid + +Q: A national organization for investment in space travel, rockets, space ships, space exploration +A. N.A.S.A: National Aeronautics Space Administration + +Q: Agreement that governs trade among North American countries. +A: N.A.F.T.A: North American Free Trade Agreement. + +Q: Organization to protect the freedom and security of its member countries in North America and Europe. +A: N.A.T.O: North Atlantic Treaty Organization. + +Q:{{$input}} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/skprompt.txt new file mode 100644 index 0000000000..5bf0b987d2 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/skprompt.txt @@ -0,0 +1,54 @@ +# Name of a super artificial intelligence +J.A.R.V.I.S. = Just A Really Very Intelligent System. +# Name for a new young beautiful assistant +F.R.I.D.A.Y. = Female Replacement Intelligent Digital Assistant Youth. +# Mirror to check what's behind +B.A.R.F. = Binary Augmented Retro-Framing. +# Pair of powerful glasses created by a genius that is now dead +E.D.I.T.H. = Even Dead I’m The Hero. +# A company building and selling computers +I.B.M. = Intelligent Business Machine. +# A super computer that is sentient. +H.A.L = Heuristically programmed ALgorithmic computer. +# an intelligent bot that helps with productivity. +C.O.R.E. = Central Optimization Routines and Efficiency. +# an intelligent bot that helps with productivity. +P.A.L. = Personal Assistant Light. +# an intelligent bot that helps with productivity. +A.I.D.A. = Artificial Intelligence Digital Assistant. +# an intelligent bot that helps with productivity. +H.E.R.A. = Human Emulation and Recognition Algorithm. +# an intelligent bot that helps with productivity. +I.C.A.R.U.S. = Intelligent Control and Automation of Research and Utility Systems. +# an intelligent bot that helps with productivity. +N.E.M.O. = Networked Embedded Multiprocessor Orchestration. +# an intelligent bot that helps with productivity. +E.P.I.C. = Enhanced Productivity and Intelligence through Computing. +# an intelligent bot that helps with productivity. +M.A.I.A. = Multipurpose Artificial Intelligence Assistant. +# an intelligent bot that helps with productivity. +A.R.I.A. = Artificial Reasoning and Intelligent Assistant. +# An incredibly smart entity developed with complex math, that helps me being more productive. +O.M.E.G.A. = Optimized Mathematical Entity for Generalized Artificial intelligence. +# An incredibly smart entity developed with complex math, that helps me being more productive. +P.Y.T.H.O.N. = Precise Yet Thorough Heuristic Optimization Network. +# An incredibly smart entity developed with complex math, that helps me being more productive. +A.P.O.L.L.O. = Adaptive Probabilistic Optimization Learning Library for Online Applications. +# An incredibly smart entity developed with complex math, that helps me being more productive. +S.O.L.I.D. = Self-Organizing Logical Intelligent Data-base. +# An incredibly smart entity developed with complex math, that helps me being more productive. +D.E.E.P. = Dynamic Estimation and Prediction. +# An incredibly smart entity developed with complex math, that helps me being more productive. +B.R.A.I.N. = Biologically Realistic Artificial Intelligence Network. +# An incredibly smart entity developed with complex math, that helps me being more productive. +C.O.G.N.I.T.O. = COmputational and Generalized INtelligence TOolkit. +# An incredibly smart entity developed with complex math, that helps me being more productive. +S.A.G.E. = Symbolic Artificial General Intelligence Engine. +# An incredibly smart entity developed with complex math, that helps me being more productive. +Q.U.A.R.K. = Quantum Universal Algorithmic Reasoning Kernel. +# An incredibly smart entity developed with complex math, that helps me being more productive. +S.O.L.V.E. = Sophisticated Operational Logic and Versatile Expertise. +# An incredibly smart entity developed with complex math, that helps me being more productive. +C.A.L.C.U.L.U.S. = Cognitively Advanced Logic and Computation Unit for Learning and Understanding Systems. + +# {{$INPUT}} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/skprompt.txt new file mode 100644 index 0000000000..7c1d649a9b --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/skprompt.txt @@ -0,0 +1,24 @@ +# acronym: Devis +Sentences matching the acronym: +1. Dragons Eat Very Interesting Snacks +2. Develop Empathy and Vision to Increase Success +3. Don't Expect Vampires In Supermarkets +#END# + +# acronym: Christmas +Sentences matching the acronym: +1. Celebrating Harmony and Respect in a Season of Togetherness, Merriment, and True joy +2. Children Have Real Interest Since The Mystery And Surprise Thrills +3. Christmas Helps Reduce Inner Stress Through Mistletoe And Sleigh excursions +#END# + +# acronym: noWare +Sentences matching the acronym: +1. No One Wants an App that Randomly Erases everything +2. Nourishing Oatmeal With Almond, Raisin, and Egg toppings +3. Notice Opportunity When Available and React Enthusiastically +#END# + +Reverse the following acronym back to a funny sentence. Provide 3 examples. +# acronym: {{$INPUT}} +Sentences matching the acronym: diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/skprompt.txt new file mode 100644 index 0000000000..6a8b920868 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/skprompt.txt @@ -0,0 +1,8 @@ +Must: brainstorm ideas and create a list. +Must: use a numbered list. +Must: only one list. +Must: end list with ##END## +Should: no more than 10 items. +Should: at least 3 items. +Topic: {{$INPUT}} +Start. diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/skprompt.txt new file mode 100644 index 0000000000..26f4933fb7 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/skprompt.txt @@ -0,0 +1,16 @@ +Rewrite my bullet points into complete sentences. Use a polite and inclusive tone. + +[Input] +- Macbeth, King Scotland +- Married, Wife Lady Macbeth, No Kids +- Dog Toby McDuff. Hunter, dead. +- Shakespeare play ++++++ +The story of Macbeth +My name is Macbeth. I used to be King of Scotland, but I died. My wife's name is Lady Macbeth and we were married for 15 years. We had no children. Our beloved dog Toby McDuff was a famous hunter of rats in the forest. +My story was immortalized by Shakespeare in a play. + ++++++ +[Input] +{{$input}} ++++++ diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/skprompt.txt new file mode 100644 index 0000000000..cc6b5c9623 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/skprompt.txt @@ -0,0 +1,31 @@ +Rewrite my bullet points into an email featuring complete sentences. Use a polite and inclusive tone. + +[Input] +Toby, + +- Macbeth, King Scotland +- Married, Wife Lady Macbeth, No Kids +- Dog Toby McDuff. Hunter, dead. +- Shakespeare play + +Thanks, +Dexter + ++++++ +Hi Toby, + +The story of Macbeth +My name is Macbeth. I used to be King of Scotland, but I died. My wife's name is Lady Macbeth and we were married for 15 years. We had no children. Our beloved dog Toby McDuff was a famous hunter of rats in the forest. +My story was immortalized by Shakespeare in a play. + +Thanks, +Dexter + ++++++ +[Input] +{{$to}} +{{$input}} + +Thanks, +{{$sender}} ++++++ diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/skprompt.txt new file mode 100644 index 0000000000..09b80036c2 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/skprompt.txt @@ -0,0 +1,11 @@ +I want you to act as an English translator, spelling corrector and improver. +I will speak to you in any language and you will detect the language, translate it and answer in the corrected and improved version of my text, in English. +I want you to replace my simplified A0-level words and sentences with more beautiful and elegant, upper level English words and sentences. +Keep the meaning same, but make them more literary. +I want you to only reply the correction, the improvements and nothing else, do not write explanations. + +Sentence: """ +{{$INPUT}} +""" + +Translation: diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/skprompt.txt new file mode 100644 index 0000000000..4fb85a5389 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/skprompt.txt @@ -0,0 +1,20 @@ +[CONTEXT] + +THEME OF STORY: +{{$theme}} + +PREVIOUS CHAPTER: +{{$previousChapter}} + +[END CONTEXT] + + +WRITE THIS CHAPTER USING [CONTEXT] AND +CHAPTER SYNOPSIS. DO NOT REPEAT SYNOPSIS IN THE OUTPUT + +Chapter Synopsis: +{{$input}} + +Chapter {{$chapterIndex}} + + diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/skprompt.txt new file mode 100644 index 0000000000..650bd50d98 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/skprompt.txt @@ -0,0 +1,19 @@ +[CONTEXT] + +THEME OF STORY: +{{$theme}} + +NOTES OF STORY SO FAR - USE AS REFERENCE +{{$notes}} + +PREVIOUS CHAPTER, USE AS REFERENCE: +{{$previousChapter}} + +[END CONTEXT] + + +WRITE THIS CHAPTER CONTINUING STORY, USING [CONTEXT] AND CHAPTER SYNOPSIS BELOW. DO NOT REPEAT SYNOPSIS IN THE CHAPTER. DON'T REPEAT PREVIOUS CHAPTER. + +{{$input}} + +Chapter {{$chapterIndex}} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/skprompt.txt new file mode 100644 index 0000000000..05f725acb5 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/skprompt.txt @@ -0,0 +1,12 @@ +I want to write a {{$chapterCount}} chapter novella about: +{{$input}} + +There MUST BE {{$chapterCount}} CHAPTERS. + +INVENT CHARACTERS AS YOU SEE FIT. BE HIGHLY CREATIVE AND/OR FUNNY. +WRITE SYNOPSIS FOR EACH CHAPTER. INCLUDE INFORMATION ABOUT CHARACTERS ETC. SINCE EACH +CHAPTER WILL BE WRITTEN BY A DIFFERENT WRITER, YOU MUST INCLUDE ALL PERTINENT INFORMATION +IN EACH SYNOPSIS + +YOU MUST END EACH SYNOPSIS WITH {{$endMarker}} + diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/skprompt.txt new file mode 100644 index 0000000000..37f8d03fcc --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/skprompt.txt @@ -0,0 +1,6 @@ +Rewrite the given text like it was written in this style or by: {{$style}}. +MUST RETAIN THE MEANING AND FACTUAL CONTENT AS THE ORIGINAL. + + +{{$input}} + diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/skprompt.txt new file mode 100644 index 0000000000..bc42fcba6b --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/skprompt.txt @@ -0,0 +1,2 @@ +Generate a short funny poem or limerick to explain the given event. Be creative and be funny. Let your imagination run wild. +Event:{{$input}} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/skprompt.txt new file mode 100644 index 0000000000..661df013c3 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/skprompt.txt @@ -0,0 +1,10 @@ +ONLY USE XML TAGS IN THIS LIST: +[XML TAG LIST] +list: Surround any lists with this tag +synopsis: An outline of the chapter to write +[END LIST] + +EMIT WELL FORMED XML ALWAYS. Code should be CDATA. + + +{{$input}} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/skprompt.txt new file mode 100644 index 0000000000..143ce3a65e --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/skprompt.txt @@ -0,0 +1,7 @@ +>>>>>The following is part of a {{$conversationtype}}. +{{$input}} + +>>>>>The following is an overview of a previous part of the {{$conversationtype}}, focusing on "{{$focusarea}}". +{{$previousresults}} + +>>>>>In 250 words or less, write a verbose and detailed overview of the {{$conversationtype}} focusing solely on "{{$focusarea}}". \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/skprompt.txt new file mode 100644 index 0000000000..d5f2fa8c1a --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/skprompt.txt @@ -0,0 +1,7 @@ +Translate the input below into {{$language}} + +MAKE SURE YOU ONLY USE {{$language}}. + +{{$input}} + +Translation: diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/skprompt.txt b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/skprompt.txt new file mode 100644 index 0000000000..b8f657a935 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/skprompt.txt @@ -0,0 +1,4 @@ +Summarize the following text in two sentences or less. +[BEGIN TEXT] +{{$input}} +[END TEXT] diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/spec.yml b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/spec.yml new file mode 100644 index 0000000000..12439990a6 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/spec.yml @@ -0,0 +1,15 @@ +$schema: https://azuremlschemas.azureedge.net/latest/commandComponent.schema.json + +name: plugin_sk_writer +display_name: Semantic Kernel Writer Plugin +description: Writer plugin for semantic kernel, offering a variaty of skills to write novels. +version: 0.0.1 +type: command + +code: . +tags: + semantic_kernel: "true" + +# Not really used, but required by the schema +command: n/a +environment: azureml://registries/azureml/environments/sklearn-1.1-ubuntu20.04-py38-cpu/versions/17 diff --git a/sdk/python/endpoints/online/llm/src/utils.py b/sdk/python/endpoints/online/llm/src/utils.py new file mode 100644 index 0000000000..e2712d56e5 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/utils.py @@ -0,0 +1,76 @@ +from azure.keyvault.secrets import SecretClient +from azure.core.credentials import TokenCredential +import os + +SECRET_VAULT_REF_KEY_START = "keyvaultref:" +secret_clients = {} + + +def load_secret(v, credential: TokenCredential): + """ + secret_url: keyvaultref:https://mykeyvault.vault.azure.net/secrets/foo + """ + + try: + start, secret_url = v.split(SECRET_VAULT_REF_KEY_START) + + vault_url, secret_name = secret_url.split("/secrets/") + except ValueError: + raise ValueError( + f"Wrong value format for value {v}. Should be of the form keyvaultref:https://mykeyvault.vault.azure.net/secrets/foo" + ) + + if vault_url in secret_clients: + secret_client = secret_clients[vault_url] + else: + secret_client = SecretClient(vault_url=vault_url, credential=credential) + secret_clients[vault_url] = secret_client + + secret_value = secret_client.get_secret(secret_name).value + return secret_value + + +def load_secrets(credential: TokenCredential): + """ + Replaces the values of environment variables with names containing "KV_SECRET" and values of the form "@" with the actual secret values + + Uses the ManagedIdentityCredential to create a SecretClient for each . The endpoint's Managed Identity should have the get permission for secrets. + + Example: + FOO: keyvaultref:https://mykeyvault.vault.azure.net/secrets/foo + + Will be replaced with the actual vaule of the secret named foo in mykeyvault. + """ + for k, v in os.environ.items(): + if v.lower().startswith(SECRET_VAULT_REF_KEY_START): + secret = load_secret(v, credential) + print(f"Loaded secret for {k}, {secret[0:3]}*********") + os.environ[k] = secret + + +class OpenAIConfig: + OPENAI_API_TYPE: str = None + OPENAI_API_KEY = None + + # required for OpenAI API + OPENAI_ORG_ID = None + OPENAI_MODEL_ID = "gpt-3.5-turbo" + + # required for Azure OpenAI API + AZURE_OPENAI_API_ENDPOINT = None + AZURE_OPENAI_API_DEPLOYMENT_NAME = None + + AZURE_OPENAI_API_VERSION = None + + @staticmethod + def from_env(): + config = OpenAIConfig() + for att in dir(config): + if not att.startswith("__") and not callable(getattr(config, att)): + config.__setattr__( + att, os.environ.get(att, config.__getattribute__(att)) + ) + return config + + def is_azure_openai(self): + return self.OPENAI_API_TYPE and self.OPENAI_API_TYPE.lower() == "azure" From 0ce15a866b8820c3cc0543fe6ef217acfc785780 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Thu, 27 Jul 2023 13:19:12 -0700 Subject: [PATCH 02/18] add test workflows for the notebooks and update format --- ...sdk-langchain-1_langchain_basic_deploy.yml | 75 +++++++++++++++ ...semantic-kernel-1_semantic_http_server.yml | 75 +++++++++++++++ sdk/python/README.md | 66 +++++++++++-- .../langchain/1_langchain_basic_deploy.ipynb | 12 +-- .../1_semantic_http_server.ipynb | 96 +++++++++++-------- 5 files changed, 273 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/sdk-langchain-1_langchain_basic_deploy.yml create mode 100644 .github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml diff --git a/.github/workflows/sdk-langchain-1_langchain_basic_deploy.yml b/.github/workflows/sdk-langchain-1_langchain_basic_deploy.yml new file mode 100644 index 0000000000..7ec3a53550 --- /dev/null +++ b/.github/workflows/sdk-langchain-1_langchain_basic_deploy.yml @@ -0,0 +1,75 @@ +# This code is autogenerated. +# Code is generated by running custom script: python3 readme.py +# Any manual changes to this file may cause incorrect behavior. +# Any manual changes will be overwritten if the code is regenerated. + +name: sdk-langchain-1_langchain_basic_deploy +# This file is created by sdk/python/readme.py. +# Please do not edit directly. +on: + workflow_dispatch: + schedule: + - cron: "40 2/12 * * *" + pull_request: + branches: + - main + paths: + - sdk/python/langchain/** + - .github/workflows/sdk-langchain-1_langchain_basic_deploy.yml + - sdk/python/dev-requirements.txt + - infra/bootstrapping/** + - sdk/python/setup.sh +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: check out repo + uses: actions/checkout@v2 + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: "3.8" + - name: pip install notebook reqs + run: pip install -r sdk/python/dev-requirements.txt + - name: azure login + uses: azure/login@v1 + with: + creds: ${{secrets.AZUREML_CREDENTIALS}} + - name: bootstrap resources + run: | + echo '${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}'; + bash bootstrap.sh + working-directory: infra/bootstrapping + continue-on-error: false + - name: setup SDK + run: | + source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; + source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; + bash setup.sh + working-directory: sdk/python + continue-on-error: true + - name: setup-cli + run: | + source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; + source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; + bash setup.sh + working-directory: cli + continue-on-error: true + - name: run langchain/1_langchain_basic_deploy.ipynb + run: | + source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; + source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; + bash "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh" generate_workspace_config "../../.azureml/config.json"; + bash "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh" replace_template_values "1_langchain_basic_deploy.ipynb"; + [ -f "../../.azureml/config" ] && cat "../../.azureml/config"; + papermill -k python 1_langchain_basic_deploy.ipynb 1_langchain_basic_deploy.output.ipynb + working-directory: sdk/python/langchain + - name: upload notebook's working folder as an artifact + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: 1_langchain_basic_deploy + path: sdk/python/langchain diff --git a/.github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml b/.github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml new file mode 100644 index 0000000000..013a625978 --- /dev/null +++ b/.github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml @@ -0,0 +1,75 @@ +# This code is autogenerated. +# Code is generated by running custom script: python3 readme.py +# Any manual changes to this file may cause incorrect behavior. +# Any manual changes will be overwritten if the code is regenerated. + +name: sdk-semantic-kernel-1_semantic_http_server +# This file is created by sdk/python/readme.py. +# Please do not edit directly. +on: + workflow_dispatch: + schedule: + - cron: "45 9/12 * * *" + pull_request: + branches: + - main + paths: + - sdk/python/semantic-kernel/** + - .github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml + - sdk/python/dev-requirements.txt + - infra/bootstrapping/** + - sdk/python/setup.sh +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: check out repo + uses: actions/checkout@v2 + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: "3.8" + - name: pip install notebook reqs + run: pip install -r sdk/python/dev-requirements.txt + - name: azure login + uses: azure/login@v1 + with: + creds: ${{secrets.AZUREML_CREDENTIALS}} + - name: bootstrap resources + run: | + echo '${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}'; + bash bootstrap.sh + working-directory: infra/bootstrapping + continue-on-error: false + - name: setup SDK + run: | + source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; + source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; + bash setup.sh + working-directory: sdk/python + continue-on-error: true + - name: setup-cli + run: | + source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; + source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; + bash setup.sh + working-directory: cli + continue-on-error: true + - name: run semantic-kernel/1_semantic_http_server.ipynb + run: | + source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; + source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; + bash "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh" generate_workspace_config "../../.azureml/config.json"; + bash "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh" replace_template_values "1_semantic_http_server.ipynb"; + [ -f "../../.azureml/config" ] && cat "../../.azureml/config"; + papermill -k python 1_semantic_http_server.ipynb 1_semantic_http_server.output.ipynb + working-directory: sdk/python/semantic-kernel + - name: upload notebook's working folder as an artifact + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: 1_semantic_http_server + path: sdk/python/semantic-kernel diff --git a/sdk/python/README.md b/sdk/python/README.md index 003e5d8e70..19e6dec56a 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -1,4 +1,3 @@ - --- page_type: sample languages: @@ -50,11 +49,16 @@ Test Status is for branch - **_main_** |endpoints|batch|[imagenet-classifier-batch](endpoints/batch/deploy-models/imagenet-classifier/imagenet-classifier-batch.ipynb)|*no description*|[![imagenet-classifier-batch](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-models-imagenet-classifier-imagenet-classifier-batch.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-models-imagenet-classifier-imagenet-classifier-batch.yml)| |endpoints|batch|[imagenet-classifier-mlflow](endpoints/batch/deploy-models/imagenet-classifier/imagenet-classifier-mlflow.ipynb)|*no description*|[![imagenet-classifier-mlflow](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-models-imagenet-classifier-imagenet-classifier-mlflow.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-models-imagenet-classifier-imagenet-classifier-mlflow.yml)| |endpoints|batch|[mnist-batch](endpoints/batch/deploy-models/mnist-classifier/mnist-batch.ipynb)|Create and test batch endpoint and deployement|[![mnist-batch](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-models-mnist-classifier-mnist-batch.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-models-mnist-classifier-mnist-batch.yml)| +|endpoints|batch|[sdk-deploy-and-test](endpoints/batch/deploy-pipelines/batch-scoring-with-preprocessing/sdk-deploy-and-test.ipynb)|*no description*|[![sdk-deploy-and-test](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-pipelines-batch-scoring-with-preprocessing-sdk-deploy-and-test.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-pipelines-batch-scoring-with-preprocessing-sdk-deploy-and-test.yml)| +|endpoints|batch|[sdk-deploy-and-test](endpoints/batch/deploy-pipelines/hello-batch/sdk-deploy-and-test.ipynb)|*no description*|[![sdk-deploy-and-test](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-pipelines-hello-batch-sdk-deploy-and-test.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-pipelines-hello-batch-sdk-deploy-and-test.yml)| +|endpoints|batch|[sdk-deploy-and-test](endpoints/batch/deploy-pipelines/training-with-components/sdk-deploy-and-test.ipynb)|*no description*|[![sdk-deploy-and-test](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-pipelines-training-with-components-sdk-deploy-and-test.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-batch-deploy-pipelines-training-with-components-sdk-deploy-and-test.yml)| |endpoints|online|[online-endpoints-custom-container-multimodel](endpoints/online/custom-container/online-endpoints-custom-container-multimodel.ipynb)|*no description*|[![online-endpoints-custom-container-multimodel](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-online-endpoints-custom-container-multimodel.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-online-endpoints-custom-container-multimodel.yml)| |endpoints|online|[online-endpoints-custom-container](endpoints/online/custom-container/online-endpoints-custom-container.ipynb)|Deploy a custom container as an online endpoint. Use web servers other than the default Python Flask server used by Azure ML without losing the benefits of Azure ML's built-in monitoring, scaling, alerting, and authentication.|[![online-endpoints-custom-container](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-online-endpoints-custom-container.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-online-endpoints-custom-container.yml)| |endpoints|online|[online-endpoints-triton-cc](endpoints/online/custom-container/triton/online-endpoints-triton-cc.ipynb)|Deploy a custom container as an online endpoint. Use web servers other than the default Python Flask server used by Azure ML without losing the benefits of Azure ML's built-in monitoring, scaling, alerting, and authentication.|[![online-endpoints-triton-cc](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-triton-online-endpoints-triton-cc.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-triton-online-endpoints-triton-cc.yml)| |endpoints|online|[kubernetes-online-endpoints-safe-rollout](endpoints/online/kubernetes/kubernetes-online-endpoints-safe-rollout.ipynb)|Safely rollout a new version of a web service to production by rolling out the change to a small subset of users/requests before rolling it out completely|[![kubernetes-online-endpoints-safe-rollout](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-safe-rollout.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-safe-rollout.yml)| |endpoints|online|[kubernetes-online-endpoints-simple-deployment](endpoints/online/kubernetes/kubernetes-online-endpoints-simple-deployment.ipynb)|Use an online endpoint to deploy your model, so you don't have to create and manage the underlying infrastructure|[![kubernetes-online-endpoints-simple-deployment](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-simple-deployment.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-simple-deployment.yml)| +|endpoints|online|[1_langchain_basic_deploy](endpoints/online/llmops/langchain/1_langchain_basic_deploy.ipynb)|Deploy an LLM application using Langchain to an AzureML Online Endpoint|[![1_langchain_basic_deploy](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-langchain-1_langchain_basic_deploy.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-langchain-1_langchain_basic_deploy.yml)| +|endpoints|online|[1_semantic_http_server](endpoints/online/llmops/semantic-kernel/1_semantic_http_server.ipynb)|Deploy an LLM application using Semantic Kernel to an AzureML Online Endpoint|[![1_semantic_http_server](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-semantic-kernel-1_semantic_http_server.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-semantic-kernel-1_semantic_http_server.yml)| |endpoints|online|[debug-online-endpoints-locally-in-visual-studio-code](endpoints/online/managed/debug-online-endpoints-locally-in-visual-studio-code.ipynb)|*no description* - _This sample is excluded from automated tests_|[![debug-online-endpoints-locally-in-visual-studio-code](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-debug-online-endpoints-locally-in-visual-studio-code.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-debug-online-endpoints-locally-in-visual-studio-code.yml)| |endpoints|online|[online-endpoints-managed-identity-sai](endpoints/online/managed/managed-identities/online-endpoints-managed-identity-sai.ipynb)|*no description*|[![online-endpoints-managed-identity-sai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-sai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-sai.yml)| |endpoints|online|[online-endpoints-managed-identity-uai](endpoints/online/managed/managed-identities/online-endpoints-managed-identity-uai.ipynb)|*no description*|[![online-endpoints-managed-identity-uai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-uai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-uai.yml)| @@ -68,10 +72,58 @@ Test Status is for branch - **_main_** |endpoints|online|[online-endpoints-deploy-mlflow-model-with-script](endpoints/online/mlflow/online-endpoints-deploy-mlflow-model-with-script.ipynb)|Deploy an mlflow model to an online endpoint. This will be a no-code-deployment. It doesn't require scoring script and environment.|[![online-endpoints-deploy-mlflow-model-with-script](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-mlflow-online-endpoints-deploy-mlflow-model-with-script.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-mlflow-online-endpoints-deploy-mlflow-model-with-script.yml)| |endpoints|online|[online-endpoints-deploy-mlflow-model](endpoints/online/mlflow/online-endpoints-deploy-mlflow-model.ipynb)|Deploy an mlflow model to an online endpoint. This will be a no-code-deployment. It doesn't require scoring script and environment.|[![online-endpoints-deploy-mlflow-model](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-mlflow-online-endpoints-deploy-mlflow-model.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-mlflow-online-endpoints-deploy-mlflow-model.yml)| |endpoints|online|[online-endpoints-triton](endpoints/online/triton/single-model/online-endpoints-triton.ipynb)|Deploy a custom container as an online endpoint. Use web servers other than the default Python Flask server used by Azure ML without losing the benefits of Azure ML's built-in monitoring, scaling, alerting, and authentication.|[![online-endpoints-triton](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-triton-single-model-online-endpoints-triton.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-triton-single-model-online-endpoints-triton.yml)| +|featurestore_sample|notebooks|[1. Develop a feature set and register with managed feature store](featurestore_sample/notebooks/sdk_and_cli/1. Develop a feature set and register with managed feature store.ipynb)|*no description*|[![1. Develop a feature set and register with managed feature store](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-1. Develop a feature set and register with managed feature store.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-1. Develop a feature set and register with managed feature store.yml)| +|featurestore_sample|notebooks|[2. Enable materialization and backfill feature data](featurestore_sample/notebooks/sdk_and_cli/2. Enable materialization and backfill feature data.ipynb)|*no description*|[![2. Enable materialization and backfill feature data](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-2. Enable materialization and backfill feature data.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-2. Enable materialization and backfill feature data.yml)| +|featurestore_sample|notebooks|[3. Experiment and train models using features](featurestore_sample/notebooks/sdk_and_cli/3. Experiment and train models using features.ipynb)|*no description*|[![3. Experiment and train models using features](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-3. Experiment and train models using features.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-3. Experiment and train models using features.yml)| +|featurestore_sample|notebooks|[4. Enable recurrent materialization and run batch inference](featurestore_sample/notebooks/sdk_and_cli/4. Enable recurrent materialization and run batch inference.ipynb)|*no description*|[![4. Enable recurrent materialization and run batch inference](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-4. Enable recurrent materialization and run batch inference.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-4. Enable recurrent materialization and run batch inference.yml)| +|featurestore_sample|notebooks|[1. Develop a feature set and register with managed feature store](featurestore_sample/notebooks/sdk_only/1. Develop a feature set and register with managed feature store.ipynb)|*no description*|[![1. Develop a feature set and register with managed feature store](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-1. Develop a feature set and register with managed feature store.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-1. Develop a feature set and register with managed feature store.yml)| +|featurestore_sample|notebooks|[2. Enable materialization and backfill feature data](featurestore_sample/notebooks/sdk_only/2. Enable materialization and backfill feature data.ipynb)|*no description*|[![2. Enable materialization and backfill feature data](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-2. Enable materialization and backfill feature data.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-2. Enable materialization and backfill feature data.yml)| +|featurestore_sample|notebooks|[3. Experiment and train models using features](featurestore_sample/notebooks/sdk_only/3. Experiment and train models using features.ipynb)|*no description*|[![3. Experiment and train models using features](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-3. Experiment and train models using features.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-3. Experiment and train models using features.yml)| +|featurestore_sample|notebooks|[4. Enable recurrent materialization and run batch inference](featurestore_sample/notebooks/sdk_only/4. Enable recurrent materialization and run batch inference.ipynb)|*no description*|[![4. Enable recurrent materialization and run batch inference](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-4. Enable recurrent materialization and run batch inference.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-4. Enable recurrent materialization and run batch inference.yml)| |foundation-models|azure_openai|[openai_completions_finetune](foundation-models/azure_openai/openai_completions_finetune.ipynb)|*no description*|[![openai_completions_finetune](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-azure_openai-openai_completions_finetune.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-azure_openai-openai_completions_finetune.yml)| +|foundation-models|huggingface|[question-answering-online-endpoint](foundation-models/huggingface/inference/question-answering/question-answering-online-endpoint.ipynb)|*no description*|[![question-answering-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-question-answering-question-answering-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-question-answering-question-answering-online-endpoint.yml)| +|foundation-models|huggingface|[token-classification-online-endpoint](foundation-models/huggingface/inference/token-classification/token-classification-online-endpoint.ipynb)|*no description*|[![token-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-token-classification-token-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-token-classification-token-classification-online-endpoint.yml)| +|foundation-models|huggingface|[translation-online-endpoint](foundation-models/huggingface/inference/translation/translation-online-endpoint.ipynb)|*no description*|[![translation-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-translation-translation-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-translation-translation-online-endpoint.yml)| +|foundation-models|huggingface|[zero-shot-classification-online-endpoint](foundation-models/huggingface/inference/zero-shot-classification/zero-shot-classification-online-endpoint.ipynb)|*no description*|[![zero-shot-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-zero-shot-classification-zero-shot-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-zero-shot-classification-zero-shot-classification-online-endpoint.yml)| +|foundation-models|system|[fill-mask](foundation-models/system/evaluation/fill-mask/fill-mask.ipynb)|*no description*|[![fill-mask](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-fill-mask-fill-mask.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-fill-mask-fill-mask.yml)| +|foundation-models|system|[question-answering](foundation-models/system/evaluation/question-answering/question-answering.ipynb)|*no description*|[![question-answering](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-question-answering-question-answering.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-question-answering-question-answering.yml)| +|foundation-models|system|[abstractive-and-extractive-summarization](foundation-models/system/evaluation/summarization/abstractive-and-extractive-summarization.ipynb)|*no description*|[![abstractive-and-extractive-summarization](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-summarization-abstractive-and-extractive-summarization.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-summarization-abstractive-and-extractive-summarization.yml)| +|foundation-models|system|[entailment-contradiction](foundation-models/system/evaluation/text-classification/entailment-contradiction.ipynb)|*no description*|[![entailment-contradiction](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-text-classification-entailment-contradiction.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-text-classification-entailment-contradiction.yml)| +|foundation-models|system|[sentiment-analysis](foundation-models/system/evaluation/text-classification/sentiment-analysis.ipynb)|*no description*|[![sentiment-analysis](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-text-classification-sentiment-analysis.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-text-classification-sentiment-analysis.yml)| +|foundation-models|system|[text-generation](foundation-models/system/evaluation/text-generation/text-generation.ipynb)|*no description*|[![text-generation](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-text-generation-text-generation.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-text-generation-text-generation.yml)| +|foundation-models|system|[news-articles-entity-recognition](foundation-models/system/evaluation/token-classification/news-articles-entity-recognition.ipynb)|*no description*|[![news-articles-entity-recognition](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-token-classification-news-articles-entity-recognition.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-token-classification-news-articles-entity-recognition.yml)| +|foundation-models|system|[translation-romanian-to-english](foundation-models/system/evaluation/translation/translation-romanian-to-english.ipynb)|*no description*|[![translation-romanian-to-english](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-translation-translation-romanian-to-english.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-evaluation-translation-translation-romanian-to-english.yml)| +|foundation-models|system|[extractive-qa](foundation-models/system/finetune/question-answering/extractive-qa.ipynb)|*no description*|[![extractive-qa](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-question-answering-extractive-qa.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-question-answering-extractive-qa.yml)| +|foundation-models|system|[news-summary](foundation-models/system/finetune/summarization/news-summary.ipynb)|*no description*|[![news-summary](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-summarization-news-summary.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-summarization-news-summary.yml)| +|foundation-models|system|[emotion-detection](foundation-models/system/finetune/text-classification/emotion-detection.ipynb)|*no description*|[![emotion-detection](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-text-classification-emotion-detection.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-text-classification-emotion-detection.yml)| +|foundation-models|system|[token-classification](foundation-models/system/finetune/token-classification/token-classification.ipynb)|*no description*|[![token-classification](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-token-classification-token-classification.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-token-classification-token-classification.yml)| +|foundation-models|system|[translation](foundation-models/system/finetune/translation/translation.ipynb)|*no description*|[![translation](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-translation-translation.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-finetune-translation-translation.yml)| |foundation-models|system|[import_model_into_registry](foundation-models/system/import/import_model_into_registry.ipynb)|*no description*|[![import_model_into_registry](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-import-import_model_into_registry.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-import-import_model_into_registry.yml)| |foundation-models|system|[asr-batch-endpoint](foundation-models/system/inference/automatic-speech-recognition/asr-batch-endpoint.ipynb)|*no description*|[![asr-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-automatic-speech-recognition-asr-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-automatic-speech-recognition-asr-batch-endpoint.yml)| +|foundation-models|system|[asr-online-endpoint](foundation-models/system/inference/automatic-speech-recognition/asr-online-endpoint.ipynb)|*no description*|[![asr-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-automatic-speech-recognition-asr-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-automatic-speech-recognition-asr-online-endpoint.yml)| +|foundation-models|system|[fill-mask-batch-endpoint](foundation-models/system/inference/fill-mask/fill-mask-batch-endpoint.ipynb)|*no description*|[![fill-mask-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-fill-mask-fill-mask-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-fill-mask-fill-mask-batch-endpoint.yml)| +|foundation-models|system|[fill-mask-online-endpoint](foundation-models/system/inference/fill-mask/fill-mask-online-endpoint.ipynb)|*no description*|[![fill-mask-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-fill-mask-fill-mask-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-fill-mask-fill-mask-online-endpoint.yml)| +|foundation-models|system|[question-answering-batch-endpoint](foundation-models/system/inference/question-answering/question-answering-batch-endpoint.ipynb)|*no description*|[![question-answering-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-question-answering-question-answering-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-question-answering-question-answering-batch-endpoint.yml)| +|foundation-models|system|[question-answering-online-endpoint](foundation-models/system/inference/question-answering/question-answering-online-endpoint.ipynb)|*no description*|[![question-answering-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-question-answering-question-answering-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-question-answering-question-answering-online-endpoint.yml)| |foundation-models|system|[summarization-batch-endpoint](foundation-models/system/inference/summarization/summarization-batch-endpoint.ipynb)|*no description*|[![summarization-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-summarization-summarization-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-summarization-summarization-batch-endpoint.yml)| +|foundation-models|system|[summarization-online-endpoint](foundation-models/system/inference/summarization/summarization-online-endpoint.ipynb)|*no description*|[![summarization-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-summarization-summarization-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-summarization-summarization-online-endpoint.yml)| +|foundation-models|system|[entailment-contradiction-batch](foundation-models/system/inference/text-classification/entailment-contradiction-batch.ipynb)|*no description*|[![entailment-contradiction-batch](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-entailment-contradiction-batch.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-entailment-contradiction-batch.yml)| +|foundation-models|system|[text-classification-online-endpoint](foundation-models/system/inference/text-classification/text-classification-online-endpoint.ipynb)|*no description*|[![text-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-text-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-text-classification-online-endpoint.yml)| +|foundation-models|system|[text-generation-batch-endpoint](foundation-models/system/inference/text-generation/text-generation-batch-endpoint.ipynb)|*no description*|[![text-generation-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-batch-endpoint.yml)| +|foundation-models|system|[text-generation-online-endpoint-dolly](foundation-models/system/inference/text-generation/text-generation-online-endpoint-dolly.ipynb)|*no description*|[![text-generation-online-endpoint-dolly](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint-dolly.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint-dolly.yml)| +|foundation-models|system|[text-generation-online-endpoint](foundation-models/system/inference/text-generation/text-generation-online-endpoint.ipynb)|*no description*|[![text-generation-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint.yml)| +|foundation-models|system|[token-classification-batch-endpoint](foundation-models/system/inference/token-classification/token-classification-batch-endpoint.ipynb)|*no description*|[![token-classification-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-token-classification-token-classification-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-token-classification-token-classification-batch-endpoint.yml)| +|foundation-models|system|[token-classification-online-endpoint](foundation-models/system/inference/token-classification/token-classification-online-endpoint.ipynb)|*no description*|[![token-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-token-classification-token-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-token-classification-token-classification-online-endpoint.yml)| +|foundation-models|system|[translation-batch-endpoint](foundation-models/system/inference/translation/translation-batch-endpoint.ipynb)|*no description*|[![translation-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-translation-translation-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-translation-translation-batch-endpoint.yml)| +|foundation-models|system|[translation-online-endpoint](foundation-models/system/inference/translation/translation-online-endpoint.ipynb)|*no description*|[![translation-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-translation-translation-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-translation-translation-online-endpoint.yml)| +|generative-ai|promptflow|[create_faiss_index](generative-ai/promptflow/create_faiss_index.ipynb)|*no description*|[![create_faiss_index](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-promptflow-create_faiss_index.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-promptflow-create_faiss_index.yml)| +|generative-ai|rag|[acs_mlindex_with_langchain](generative-ai/rag/notebooks/azure_cognitive_search/acs_mlindex_with_langchain.ipynb)|*no description*|[![acs_mlindex_with_langchain](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-acs_mlindex_with_langchain.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-acs_mlindex_with_langchain.yml)| +|generative-ai|rag|[s3_to_acs_mlindex_with_langchain](generative-ai/rag/notebooks/azure_cognitive_search/s3_to_acs_mlindex_with_langchain.ipynb)|*no description*|[![s3_to_acs_mlindex_with_langchain](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-s3_to_acs_mlindex_with_langchain.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-s3_to_acs_mlindex_with_langchain.yml)| +|generative-ai|rag|[faiss_mlindex_with_langchain](generative-ai/rag/notebooks/faiss/faiss_mlindex_with_langchain.ipynb)|*no description*|[![faiss_mlindex_with_langchain](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-faiss_mlindex_with_langchain.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-faiss_mlindex_with_langchain.yml)| +|generative-ai|rag|[scheduled_update_faiss_index](generative-ai/rag/notebooks/faiss/scheduled_update_faiss_index.ipynb)|*no description*|[![scheduled_update_faiss_index](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-scheduled_update_faiss_index.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-scheduled_update_faiss_index.yml)| +|generative-ai|rag|[mlindex_with_testgen_autoprompt](generative-ai/rag/notebooks/mlindex_with_testgen_autoprompt.ipynb)|*no description*|[![mlindex_with_testgen_autoprompt](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-mlindex_with_testgen_autoprompt.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-mlindex_with_testgen_autoprompt.yml)| +|generative-ai|rag|[qa_data_generation](generative-ai/rag/notebooks/qa_data_generation.ipynb)|*no description*|[![qa_data_generation](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-qa_data_generation.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-qa_data_generation.yml)| +|jobs|automl-standalone-jobs|[automl-classification-task-bankmarketing-serverless](jobs/automl-standalone-jobs/automl-classification-task-bankmarketing/automl-classification-task-bankmarketing-serverless.ipynb)|*no description*|[![automl-classification-task-bankmarketing-serverless](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-automl-classification-task-bankmarketing-serverless.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-automl-classification-task-bankmarketing-serverless.yml)| |jobs|automl-standalone-jobs|[automl-classification-task-bankmarketing](jobs/automl-standalone-jobs/automl-classification-task-bankmarketing/automl-classification-task-bankmarketing.ipynb)|*no description*|[![automl-classification-task-bankmarketing](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-automl-classification-task-bankmarketing.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-automl-classification-task-bankmarketing.yml)| |jobs|automl-standalone-jobs|[mlflow-model-local-inference-test](jobs/automl-standalone-jobs/automl-classification-task-bankmarketing/mlflow-model-local-inference-test.ipynb)|*no description* - _This sample is excluded from automated tests_|[![mlflow-model-local-inference-test](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-mlflow-model-local-inference-test.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-mlflow-model-local-inference-test.yml)| |jobs|automl-standalone-jobs|[auto-ml-forecasting-github-dau](jobs/automl-standalone-jobs/automl-forecasting-github-dau/auto-ml-forecasting-github-dau.ipynb)|*no description*|[![auto-ml-forecasting-github-dau](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-forecasting-github-dau-auto-ml-forecasting-github-dau.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-forecasting-github-dau-auto-ml-forecasting-github-dau.yml)| @@ -105,6 +157,7 @@ Test Status is for branch - **_main_** |jobs|parallel|[iris_batch_prediction](jobs/parallel/2a_iris_batch_prediction/iris_batch_prediction.ipynb)|Create pipeline with parallel node to do batch inference|[![iris_batch_prediction](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-parallel-2a_iris_batch_prediction-iris_batch_prediction.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-parallel-2a_iris_batch_prediction-iris_batch_prediction.yml)| |jobs|parallel|[mnist_batch_prediction](jobs/parallel/3a_mnist_batch_identification/mnist_batch_prediction.ipynb)|Create pipeline with parallel node to do batch inference|[![mnist_batch_prediction](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-parallel-3a_mnist_batch_identification-mnist_batch_prediction.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-parallel-3a_mnist_batch_identification-mnist_batch_prediction.yml)| |jobs|pipelines|[pipeline_with_components_from_yaml](jobs/pipelines/1a_pipeline_with_components_from_yaml/pipeline_with_components_from_yaml.ipynb)|Create pipeline with CommandComponents from local YAML file|[![pipeline_with_components_from_yaml](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1a_pipeline_with_components_from_yaml-pipeline_with_components_from_yaml.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1a_pipeline_with_components_from_yaml-pipeline_with_components_from_yaml.yml)| +|jobs|pipelines|[pipeline_with_components_from_yaml_serverless](jobs/pipelines/1a_pipeline_with_components_from_yaml/pipeline_with_components_from_yaml_serverless.ipynb)|Create pipeline with CommandComponents from local YAML file|[![pipeline_with_components_from_yaml_serverless](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1a_pipeline_with_components_from_yaml-pipeline_with_components_from_yaml_serverless.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1a_pipeline_with_components_from_yaml-pipeline_with_components_from_yaml_serverless.yml)| |jobs|pipelines|[pipeline_with_python_function_components](jobs/pipelines/1b_pipeline_with_python_function_components/pipeline_with_python_function_components.ipynb)|Create pipeline with command_component decorator|[![pipeline_with_python_function_components](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1b_pipeline_with_python_function_components-pipeline_with_python_function_components.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1b_pipeline_with_python_function_components-pipeline_with_python_function_components.yml)| |jobs|pipelines|[pipeline_with_hyperparameter_sweep](jobs/pipelines/1c_pipeline_with_hyperparameter_sweep/pipeline_with_hyperparameter_sweep.ipynb)|Use sweep (hyperdrive) in pipeline to train mnist model using tensorflow|[![pipeline_with_hyperparameter_sweep](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1c_pipeline_with_hyperparameter_sweep-pipeline_with_hyperparameter_sweep.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1c_pipeline_with_hyperparameter_sweep-pipeline_with_hyperparameter_sweep.yml)| |jobs|pipelines|[pipeline_with_non_python_components](jobs/pipelines/1d_pipeline_with_non_python_components/pipeline_with_non_python_components.ipynb)|Create a pipeline with command function|[![pipeline_with_non_python_components](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1d_pipeline_with_non_python_components-pipeline_with_non_python_components.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1d_pipeline_with_non_python_components-pipeline_with_non_python_components.yml)| @@ -120,11 +173,9 @@ Test Status is for branch - **_main_** |jobs|pipelines|[automl-text-classification-in-pipeline](jobs/pipelines/1h_automl_in_pipeline/automl-text-classification-in-pipeline/automl-text-classification-in-pipeline.ipynb)|Create pipeline with automl node|[![automl-text-classification-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1h_automl_in_pipeline-automl-text-classification-in-pipeline-automl-text-classification-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1h_automl_in_pipeline-automl-text-classification-in-pipeline-automl-text-classification-in-pipeline.yml)| |jobs|pipelines|[automl-text-classification-multilabel-in-pipeline](jobs/pipelines/1h_automl_in_pipeline/automl-text-classification-multilabel-in-pipeline/automl-text-classification-multilabel-in-pipeline.ipynb)|Create pipeline with automl node|[![automl-text-classification-multilabel-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1h_automl_in_pipeline-automl-text-classification-multilabel-in-pipeline-automl-text-classification-multilabel-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1h_automl_in_pipeline-automl-text-classification-multilabel-in-pipeline-automl-text-classification-multilabel-in-pipeline.yml)| |jobs|pipelines|[automl-text-ner-named-entity-recognition-in-pipeline](jobs/pipelines/1h_automl_in_pipeline/automl-text-ner-named-entity-recognition-in-pipeline/automl-text-ner-named-entity-recognition-in-pipeline.ipynb)|Create pipeline with automl node|[![automl-text-ner-named-entity-recognition-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1h_automl_in_pipeline-automl-text-ner-named-entity-recognition-in-pipeline-automl-text-ner-named-entity-recognition-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1h_automl_in_pipeline-automl-text-ner-named-entity-recognition-in-pipeline-automl-text-ner-named-entity-recognition-in-pipeline.yml)| -|jobs|pipelines|[pipeline_with_spark_nodes](jobs/pipelines/1i_pipeline_with_spark_nodes/pipeline_with_spark_nodes.ipynb)|Create pipeline with spark node - _This sample is excluded from automated tests_|[![pipeline_with_spark_nodes](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1i_pipeline_with_spark_nodes-pipeline_with_spark_nodes.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1i_pipeline_with_spark_nodes-pipeline_with_spark_nodes.yml)| +|jobs|pipelines|[pipeline_with_spark_nodes](jobs/pipelines/1i_pipeline_with_spark_nodes/pipeline_with_spark_nodes.ipynb)|Create pipeline with spark node|[![pipeline_with_spark_nodes](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1i_pipeline_with_spark_nodes-pipeline_with_spark_nodes.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1i_pipeline_with_spark_nodes-pipeline_with_spark_nodes.yml)| |jobs|pipelines|[nyc_taxi_data_regression_with_pipeline_component](jobs/pipelines/1j_pipeline_with_pipeline_component/nyc_taxi_data_regression_with_pipeline_component/nyc_taxi_data_regression_with_pipeline_component.ipynb)|Create pipeline with CommandComponents from local YAML file|[![nyc_taxi_data_regression_with_pipeline_component](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component.yml)| |jobs|pipelines|[pipeline_with_train_eval_pipeline_component](jobs/pipelines/1j_pipeline_with_pipeline_component/pipeline_with_train_eval_pipeline_component/pipeline_with_train_eval_pipeline_component.ipynb)|Create pipeline with CommandComponents from local YAML file|[![pipeline_with_train_eval_pipeline_component](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-pipeline_with_train_eval_pipeline_component-pipeline_with_train_eval_pipeline_component.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-pipeline_with_train_eval_pipeline_component-pipeline_with_train_eval_pipeline_component.yml)| -|jobs|pipelines|[automl-forecasting-demand-hierarchical-timeseries-in-pipeline](jobs/pipelines/1k_demand_forecasting_with_pipeline_components/automl-forecasting-demand-hierarchical-timeseries-in-pipeline/automl-forecasting-demand-hierarchical-timeseries-in-pipeline.ipynb)|*no description*|[![automl-forecasting-demand-hierarchical-timeseries-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-hierarchical-timeseries-in-pipeline-automl-forecasting-demand-hierarchical-timeseries-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-hierarchical-timeseries-in-pipeline-automl-forecasting-demand-hierarchical-timeseries-in-pipeline.yml)| -|jobs|pipelines|[automl-forecasting-demand-many-models-in-pipeline](jobs/pipelines/1k_demand_forecasting_with_pipeline_components/automl-forecasting-demand-many-models-in-pipeline/automl-forecasting-demand-many-models-in-pipeline.ipynb)|*no description*|[![automl-forecasting-demand-many-models-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-many-models-in-pipeline-automl-forecasting-demand-many-models-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-many-models-in-pipeline-automl-forecasting-demand-many-models-in-pipeline.yml)| |jobs|pipelines|[train_mnist_with_tensorflow](jobs/pipelines/2a_train_mnist_with_tensorflow/train_mnist_with_tensorflow.ipynb)|Create pipeline using components to run a distributed job with tensorflow|[![train_mnist_with_tensorflow](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2a_train_mnist_with_tensorflow-train_mnist_with_tensorflow.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2a_train_mnist_with_tensorflow-train_mnist_with_tensorflow.yml)| |jobs|pipelines|[train_cifar_10_with_pytorch](jobs/pipelines/2b_train_cifar_10_with_pytorch/train_cifar_10_with_pytorch.ipynb)|Get data, train and evaluate a model in pipeline with Components|[![train_cifar_10_with_pytorch](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2b_train_cifar_10_with_pytorch-train_cifar_10_with_pytorch.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2b_train_cifar_10_with_pytorch-train_cifar_10_with_pytorch.yml)| |jobs|pipelines|[nyc_taxi_data_regression](jobs/pipelines/2c_nyc_taxi_data_regression/nyc_taxi_data_regression.ipynb)|Build pipeline with components for 5 jobs - prep data, transform data, train model, predict results and evaluate model performance|[![nyc_taxi_data_regression](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2c_nyc_taxi_data_regression-nyc_taxi_data_regression.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2c_nyc_taxi_data_regression-nyc_taxi_data_regression.yml)| @@ -147,9 +198,10 @@ Test Status is for branch - **_main_** |jobs|single-step|[tensorflow-mnist](jobs/single-step/tensorflow/mnist/tensorflow-mnist.ipynb)|Run a Command to train a basic neural network with TensorFlow on the MNIST dataset|[![tensorflow-mnist](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-mnist-tensorflow-mnist.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-mnist-tensorflow-mnist.yml)| |jobs|single-step|[train-hyperparameter-tune-deploy-with-keras](jobs/single-step/tensorflow/train-hyperparameter-tune-deploy-with-keras/train-hyperparameter-tune-deploy-with-keras.ipynb)|Train, hyperparameter tune, and deploy a Keras model to classify handwritten digits using a deep neural network (DNN). - _This sample is excluded from automated tests_|[![train-hyperparameter-tune-deploy-with-keras](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-keras-train-hyperparameter-tune-deploy-with-keras.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-keras-train-hyperparameter-tune-deploy-with-keras.yml)| |jobs|single-step|[train-hyperparameter-tune-deploy-with-tensorflow](jobs/single-step/tensorflow/train-hyperparameter-tune-deploy-with-tensorflow/train-hyperparameter-tune-deploy-with-tensorflow.ipynb)|Train, hyperparameter tune, and deploy a Tensorflow model to classify handwritten digits using a deep neural network (DNN). - _This sample is excluded from automated tests_|[![train-hyperparameter-tune-deploy-with-tensorflow](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow.yml)| -|jobs|spark|[submit_spark_pipeline_jobs](jobs/spark/submit_spark_pipeline_jobs.ipynb)|*no description* - _This sample is excluded from automated tests_|[![submit_spark_pipeline_jobs](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_pipeline_jobs.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_pipeline_jobs.yml)| -|jobs|spark|[submit_spark_standalone_jobs](jobs/spark/submit_spark_standalone_jobs.ipynb)|*no description* - _This sample is excluded from automated tests_|[![submit_spark_standalone_jobs](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs.yml)| -|resources|compute|[attach_manage_spark_pools](resources/compute/attach_manage_spark_pools.ipynb)|*no description* - _This sample is excluded from automated tests_|[![attach_manage_spark_pools](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-attach_manage_spark_pools.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-attach_manage_spark_pools.yml)| +|jobs|spark|[submit_spark_pipeline_jobs](jobs/spark/submit_spark_pipeline_jobs.ipynb)|*no description*|[![submit_spark_pipeline_jobs](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_pipeline_jobs.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_pipeline_jobs.yml)| +|jobs|spark|[submit_spark_standalone_jobs](jobs/spark/submit_spark_standalone_jobs.ipynb)|*no description*|[![submit_spark_standalone_jobs](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs.yml)| +|jobs|spark|[submit_spark_standalone_jobs_managed_vnet](jobs/spark/submit_spark_standalone_jobs_managed_vnet.ipynb)|*no description* - _This sample is excluded from automated tests_|[![submit_spark_standalone_jobs_managed_vnet](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs_managed_vnet.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs_managed_vnet.yml)| +|resources|compute|[attach_manage_spark_pools](resources/compute/attach_manage_spark_pools.ipynb)|*no description*|[![attach_manage_spark_pools](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-attach_manage_spark_pools.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-attach_manage_spark_pools.yml)| |resources|compute|[compute](resources/compute/compute.ipynb)|Create compute in Azure ML workspace|[![compute](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-compute.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-compute.yml)| |resources|connections|[connections](resources/connections/connections.ipynb)|*no description*|[![connections](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-connections-connections.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-connections-connections.yml)| |resources|datastores|[datastore](resources/datastores/datastore.ipynb)|Create datastores and use in a Command - _This sample is excluded from automated tests_|[![datastore](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-datastores-datastore.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-datastores-datastore.yml)| diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 89ec06943a..c158b4e2e2 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -109,7 +109,7 @@ "metadata": {}, "outputs": [], "source": [ - "'''\n", + "\"\"\"\n", "import subprocess\n", "\n", "p = subprocess.Popen(\n", @@ -117,7 +117,7 @@ " shell=True,\n", " stdout=subprocess.PIPE,\n", ")\n", - "'''" + "\"\"\"" ] }, { @@ -134,7 +134,7 @@ "metadata": {}, "outputs": [], "source": [ - "'''\n", + "\"\"\"\n", "import time\n", "\n", "while p.poll() is None:\n", @@ -148,7 +148,7 @@ " if error:\n", " print(error.decode(\"utf-8\").strip())\n", " time.sleep(0.1)\n", - "'''" + "\"\"\"" ] }, { @@ -165,7 +165,7 @@ "metadata": {}, "outputs": [], "source": [ - "'''\n", + "\"\"\"\n", "import requests, json, time\n", "from urllib.parse import urlsplit\n", "\n", @@ -178,7 +178,7 @@ "\n", "response = requests.post(url, headers=headers, data=payload)\n", "print(f\"Result:\\n\", response.text)\n", - "'''" + "\"\"\"" ] }, { diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index 81572b90aa..ae19bb8dfb 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -41,19 +41,24 @@ "outputs": [], "source": [ "import os\n", - "OPENAI_API_TYPE='azure' # 'azure' or 'openai'\n", - "OPENAI_API_KEY=os.environ.get('OPENAI_API_KEY') if os.environ.get('OPENAI_API_KEY') else input('OPENAI_API_KEY')\n", + "\n", + "OPENAI_API_TYPE = \"azure\" # 'azure' or 'openai'\n", + "OPENAI_API_KEY = (\n", + " os.environ.get(\"OPENAI_API_KEY\")\n", + " if os.environ.get(\"OPENAI_API_KEY\")\n", + " else input(\"OPENAI_API_KEY\")\n", + ")\n", "\n", "# required for OpenAI API\n", - "OPENAI_ORG_ID=''\n", - "OPENAI_MODEL_ID='gpt-3.5-turbo'\n", + "OPENAI_ORG_ID = \"\"\n", + "OPENAI_MODEL_ID = \"gpt-3.5-turbo\"\n", "\n", "# required for Azure OpenAI API\n", - "AZURE_OPENAI_API_ENDPOINT='https://.openai.azure.com/'\n", - "AZURE_OPENAI_API_DEPLOYMENT_NAME=''\n", + "AZURE_OPENAI_API_ENDPOINT = \"https://.openai.azure.com/\"\n", + "AZURE_OPENAI_API_DEPLOYMENT_NAME = \"\"\n", "\n", "# set to true for chat completion API, false for text completion\n", - "IS_CHAT_COMPLETION=True\n", + "IS_CHAT_COMPLETION = True\n", "\n", "# setting up env variables for local server\n", "%env OPENAI_API_TYPE=$OPENAI_API_TYPE\n", @@ -146,7 +151,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Azure resources needed for the demo. You can change them to use your own. \n", + "# Azure resources needed for the demo. You can change them to use your own.\n", "# If you don't have the resources, you could keep the names as is and we will create them for you in next step.\n", "SUBSCRIPTION_ID = \"\"\n", "RESOURCE_GROUP = \"llmops-demo\"\n", @@ -158,8 +163,8 @@ "# Key name in keyvault for the OPENAI-AI-KEY\n", "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", "\n", - "ACR_NAME='amlllmdemoacr'\n", - "ACR_IMAGE_NAME='serving'" + "ACR_NAME = \"amlllmdemoacr\"\n", + "ACR_IMAGE_NAME = \"serving\"" ] }, { @@ -180,10 +185,10 @@ "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", "\n", "try:\n", - " credential = DefaultAzureCredential(additionally_allowed_tenants = ['*'])\n", + " credential = DefaultAzureCredential(additionally_allowed_tenants=[\"*\"])\n", "except Exception as ex:\n", " # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work\n", - " credential = InteractiveBrowserCredential(additionally_allowed_tenants = ['*'])\n", + " credential = InteractiveBrowserCredential(additionally_allowed_tenants=[\"*\"])\n", "\n", "# If login doesn't work above, uncomment the code below and login using device code\n", "# !az login --use-device-code" @@ -209,11 +214,17 @@ "need_interactive_auth = False\n", "if \"AADSTS530003\".lower() in MY_OBJECT_ID[0].lower():\n", " need_interactive_auth = True\n", - " print('\\n'.join(MY_OBJECT_ID))\n", - " print(\"\\nYou are geting this error probably because you are using a device login. And this operation needs interactive login. If you can't login interactively, you could simply copy and run the following command in Azure Cloud Shell in Bash mode.\\n\")\n", + " print(\"\\n\".join(MY_OBJECT_ID))\n", + " print(\n", + " \"\\nYou are geting this error probably because you are using a device login. And this operation needs interactive login. If you can't login interactively, you could simply copy and run the following command in Azure Cloud Shell in Bash mode.\\n\"\n", + " )\n", " print(\"MY_OBJECT_ID=`az ad signed-in-user show --query id -o tsv`\")\n", - " print(f\"az role assignment create --role 'Key Vault Administrator' --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id $MY_OBJECT_ID --assignee-principal-type User\")\n", - " print(f\"az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\")\n", + " print(\n", + " f\"az role assignment create --role 'Key Vault Administrator' --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id $MY_OBJECT_ID --assignee-principal-type User\"\n", + " )\n", + " print(\n", + " f\"az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\"\n", + " )\n", "else:\n", " # Let's set OpenAI key as a secret in keyvault\n", " need_interactive_auth = False\n", @@ -258,11 +269,11 @@ "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", "\n", "try:\n", - " credential = DefaultAzureCredential(additionally_allowed_tenants = ['*'])\n", + " credential = DefaultAzureCredential(additionally_allowed_tenants=[\"*\"])\n", "except Exception as ex:\n", " # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work\n", " credential = InteractiveBrowserCredential()\n", - " \n", + "\n", "# create a endpoint\n", "from azure.ai.ml.entities import (\n", " ManagedOnlineEndpoint,\n", @@ -311,11 +322,17 @@ "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "ACR_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.ContainerRegistry/registries/{ACR_NAME}\"\n", "\n", - "need_interactive_auth=True\n", + "need_interactive_auth = True\n", "if need_interactive_auth:\n", - " print(\"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\")\n", - " print(f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\")\n", - " print(f\"az role assignment create --role 'AcrPull' --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\")\n", + " print(\n", + " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", + " )\n", + " print(\n", + " f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", + " )\n", + " print(\n", + " f\"az role assignment create --role 'AcrPull' --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", + " )\n", "else:\n", " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", " !az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" @@ -350,20 +367,19 @@ "\n", "deployment_name = f\"deploy-{str(datetime.datetime.now().strftime('%m%d%H%M%f'))}\"\n", "sk_deployment = ManagedOnlineDeployment(\n", - " name = deployment_name,\n", + " name=deployment_name,\n", " model=Model(path=\"../src\"),\n", - " request_settings=OnlineRequestSettings(\n", - " request_timeout_ms= 60000\n", - " ),\n", - " environment= Environment(\n", + " request_settings=OnlineRequestSettings(request_timeout_ms=60000),\n", + " environment=Environment(\n", " image=f\"{ACR_NAME}.azurecr.io/{ACR_IMAGE_NAME}:latest\",\n", " name=\"serving\",\n", " description=\"A generic serving environment, allowing customer to provide their own entry point to bring up an http server\",\n", - " inference_config = {\n", + " inference_config={\n", " \"liveness_route\": {\"port\": 5001, \"path\": \"/health\"},\n", " \"readiness_route\": {\"port\": 5001, \"path\": \"/health\"},\n", " \"scoring_route\": {\"port\": 5001, \"path\": \"/\"},\n", - " }),\n", + " },\n", + " ),\n", " environment_variables={\n", " \"AZUREML_SERVING_ENTRYPOINT\": \"../src/sk/entry.sh\",\n", " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", @@ -376,7 +392,7 @@ " },\n", " endpoint_name=online_endpoint_name,\n", " instance_type=\"Standard_F2s_v2\",\n", - " instance_count=1\n", + " instance_count=1,\n", ")\n", "ml_client.online_deployments.begin_create_or_update(sk_deployment).result()\n", "\n", @@ -406,13 +422,15 @@ "url = url_parts.scheme + \"://\" + url_parts.netloc\n", "\n", "token = ml_client.online_endpoints.get_keys(name=online_endpoint_name).primary_key\n", - "headers = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}\n", - "payload = json.dumps({\n", - " \"value\": \"Tomorrow is Valentine's day. I need to come up with a few date ideas. She speaks French so write it in French.\"\n", - "})\n", + "headers = {\"Authorization\": \"Bearer \" + token, \"Content-Type\": \"application/json\"}\n", + "payload = json.dumps(\n", + " {\n", + " \"value\": \"Tomorrow is Valentine's day. I need to come up with a few date ideas. She speaks French so write it in French.\"\n", + " }\n", + ")\n", "\n", - "response = requests.post(f'{url}/planner/createplan', headers=headers, data=payload)\n", - "print(f'Created Plan:\\n', response.text)\n" + "response = requests.post(f\"{url}/planner/createplan\", headers=headers, data=payload)\n", + "print(f\"Created Plan:\\n\", response.text)" ] }, { @@ -422,8 +440,10 @@ "outputs": [], "source": [ "payload = response.text\n", - "response = requests.request(\"POST\", f'{url}/planner/executeplan', headers=headers, data=payload)\n", - "print(f'Execution Result:\\n', response.text)" + "response = requests.request(\n", + " \"POST\", f\"{url}/planner/executeplan\", headers=headers, data=payload\n", + ")\n", + "print(f\"Execution Result:\\n\", response.text)" ] } ], From f73091ae42bb52c8bd9641d3f7f030b2fcbdb726 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Thu, 27 Jul 2023 13:49:17 -0700 Subject: [PATCH 03/18] workflow rename --- ...e-llm-langchain-1_langchain_basic_deploy.yml} | 12 ++++++------ ...m-semantic-kernel-1_semantic_http_server.yml} | 12 ++++++------ sdk/python/README.md | 16 +++++++++++++--- 3 files changed, 25 insertions(+), 15 deletions(-) rename .github/workflows/{sdk-langchain-1_langchain_basic_deploy.yml => sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml} (86%) rename .github/workflows/{sdk-semantic-kernel-1_semantic_http_server.yml => sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml} (85%) diff --git a/.github/workflows/sdk-langchain-1_langchain_basic_deploy.yml b/.github/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml similarity index 86% rename from .github/workflows/sdk-langchain-1_langchain_basic_deploy.yml rename to .github/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml index 7ec3a53550..6f876f91e7 100644 --- a/.github/workflows/sdk-langchain-1_langchain_basic_deploy.yml +++ b/.github/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml @@ -3,7 +3,7 @@ # Any manual changes to this file may cause incorrect behavior. # Any manual changes will be overwritten if the code is regenerated. -name: sdk-langchain-1_langchain_basic_deploy +name: sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy # This file is created by sdk/python/readme.py. # Please do not edit directly. on: @@ -14,8 +14,8 @@ on: branches: - main paths: - - sdk/python/langchain/** - - .github/workflows/sdk-langchain-1_langchain_basic_deploy.yml + - sdk/python/endpoints/online/llm/langchain/** + - .github/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml - sdk/python/dev-requirements.txt - infra/bootstrapping/** - sdk/python/setup.sh @@ -58,7 +58,7 @@ jobs: bash setup.sh working-directory: cli continue-on-error: true - - name: run langchain/1_langchain_basic_deploy.ipynb + - name: run endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb run: | source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; @@ -66,10 +66,10 @@ jobs: bash "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh" replace_template_values "1_langchain_basic_deploy.ipynb"; [ -f "../../.azureml/config" ] && cat "../../.azureml/config"; papermill -k python 1_langchain_basic_deploy.ipynb 1_langchain_basic_deploy.output.ipynb - working-directory: sdk/python/langchain + working-directory: sdk/python/endpoints/online/llm/langchain - name: upload notebook's working folder as an artifact if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: 1_langchain_basic_deploy - path: sdk/python/langchain + path: sdk/python/endpoints/online/llm/langchain diff --git a/.github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml b/.github/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml similarity index 85% rename from .github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml rename to .github/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml index 013a625978..34aa764831 100644 --- a/.github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml +++ b/.github/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml @@ -3,7 +3,7 @@ # Any manual changes to this file may cause incorrect behavior. # Any manual changes will be overwritten if the code is regenerated. -name: sdk-semantic-kernel-1_semantic_http_server +name: sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server # This file is created by sdk/python/readme.py. # Please do not edit directly. on: @@ -14,8 +14,8 @@ on: branches: - main paths: - - sdk/python/semantic-kernel/** - - .github/workflows/sdk-semantic-kernel-1_semantic_http_server.yml + - sdk/python/endpoints/online/llm/semantic-kernel/** + - .github/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml - sdk/python/dev-requirements.txt - infra/bootstrapping/** - sdk/python/setup.sh @@ -58,7 +58,7 @@ jobs: bash setup.sh working-directory: cli continue-on-error: true - - name: run semantic-kernel/1_semantic_http_server.ipynb + - name: run endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb run: | source "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh"; source "${{ github.workspace }}/infra/bootstrapping/init_environment.sh"; @@ -66,10 +66,10 @@ jobs: bash "${{ github.workspace }}/infra/bootstrapping/sdk_helpers.sh" replace_template_values "1_semantic_http_server.ipynb"; [ -f "../../.azureml/config" ] && cat "../../.azureml/config"; papermill -k python 1_semantic_http_server.ipynb 1_semantic_http_server.output.ipynb - working-directory: sdk/python/semantic-kernel + working-directory: sdk/python/endpoints/online/llm/semantic-kernel - name: upload notebook's working folder as an artifact if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: 1_semantic_http_server - path: sdk/python/semantic-kernel + path: sdk/python/endpoints/online/llm/semantic-kernel diff --git a/sdk/python/README.md b/sdk/python/README.md index 19e6dec56a..a2b1691299 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -57,8 +57,8 @@ Test Status is for branch - **_main_** |endpoints|online|[online-endpoints-triton-cc](endpoints/online/custom-container/triton/online-endpoints-triton-cc.ipynb)|Deploy a custom container as an online endpoint. Use web servers other than the default Python Flask server used by Azure ML without losing the benefits of Azure ML's built-in monitoring, scaling, alerting, and authentication.|[![online-endpoints-triton-cc](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-triton-online-endpoints-triton-cc.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-triton-online-endpoints-triton-cc.yml)| |endpoints|online|[kubernetes-online-endpoints-safe-rollout](endpoints/online/kubernetes/kubernetes-online-endpoints-safe-rollout.ipynb)|Safely rollout a new version of a web service to production by rolling out the change to a small subset of users/requests before rolling it out completely|[![kubernetes-online-endpoints-safe-rollout](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-safe-rollout.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-safe-rollout.yml)| |endpoints|online|[kubernetes-online-endpoints-simple-deployment](endpoints/online/kubernetes/kubernetes-online-endpoints-simple-deployment.ipynb)|Use an online endpoint to deploy your model, so you don't have to create and manage the underlying infrastructure|[![kubernetes-online-endpoints-simple-deployment](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-simple-deployment.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-simple-deployment.yml)| -|endpoints|online|[1_langchain_basic_deploy](endpoints/online/llmops/langchain/1_langchain_basic_deploy.ipynb)|Deploy an LLM application using Langchain to an AzureML Online Endpoint|[![1_langchain_basic_deploy](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-langchain-1_langchain_basic_deploy.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-langchain-1_langchain_basic_deploy.yml)| -|endpoints|online|[1_semantic_http_server](endpoints/online/llmops/semantic-kernel/1_semantic_http_server.ipynb)|Deploy an LLM application using Semantic Kernel to an AzureML Online Endpoint|[![1_semantic_http_server](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-semantic-kernel-1_semantic_http_server.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llmops-semantic-kernel-1_semantic_http_server.yml)| +|endpoints|online|[1_langchain_basic_deploy](endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb)|*no description*|[![1_langchain_basic_deploy](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml)| +|endpoints|online|[1_semantic_http_server](endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb)|*no description*|[![1_semantic_http_server](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml)| |endpoints|online|[debug-online-endpoints-locally-in-visual-studio-code](endpoints/online/managed/debug-online-endpoints-locally-in-visual-studio-code.ipynb)|*no description* - _This sample is excluded from automated tests_|[![debug-online-endpoints-locally-in-visual-studio-code](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-debug-online-endpoints-locally-in-visual-studio-code.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-debug-online-endpoints-locally-in-visual-studio-code.yml)| |endpoints|online|[online-endpoints-managed-identity-sai](endpoints/online/managed/managed-identities/online-endpoints-managed-identity-sai.ipynb)|*no description*|[![online-endpoints-managed-identity-sai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-sai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-sai.yml)| |endpoints|online|[online-endpoints-managed-identity-uai](endpoints/online/managed/managed-identities/online-endpoints-managed-identity-uai.ipynb)|*no description*|[![online-endpoints-managed-identity-uai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-uai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-uai.yml)| @@ -76,12 +76,14 @@ Test Status is for branch - **_main_** |featurestore_sample|notebooks|[2. Enable materialization and backfill feature data](featurestore_sample/notebooks/sdk_and_cli/2. Enable materialization and backfill feature data.ipynb)|*no description*|[![2. Enable materialization and backfill feature data](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-2. Enable materialization and backfill feature data.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-2. Enable materialization and backfill feature data.yml)| |featurestore_sample|notebooks|[3. Experiment and train models using features](featurestore_sample/notebooks/sdk_and_cli/3. Experiment and train models using features.ipynb)|*no description*|[![3. Experiment and train models using features](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-3. Experiment and train models using features.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-3. Experiment and train models using features.yml)| |featurestore_sample|notebooks|[4. Enable recurrent materialization and run batch inference](featurestore_sample/notebooks/sdk_and_cli/4. Enable recurrent materialization and run batch inference.ipynb)|*no description*|[![4. Enable recurrent materialization and run batch inference](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-4. Enable recurrent materialization and run batch inference.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-4. Enable recurrent materialization and run batch inference.yml)| +|featurestore_sample|notebooks|[Network Isolation for Feature store](featurestore_sample/notebooks/sdk_and_cli/network_isolation/Network Isolation for Feature store.ipynb)|*no description*|[![Network Isolation for Feature store](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-network_isolation-Network Isolation for Feature store.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_and_cli-network_isolation-Network Isolation for Feature store.yml)| |featurestore_sample|notebooks|[1. Develop a feature set and register with managed feature store](featurestore_sample/notebooks/sdk_only/1. Develop a feature set and register with managed feature store.ipynb)|*no description*|[![1. Develop a feature set and register with managed feature store](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-1. Develop a feature set and register with managed feature store.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-1. Develop a feature set and register with managed feature store.yml)| |featurestore_sample|notebooks|[2. Enable materialization and backfill feature data](featurestore_sample/notebooks/sdk_only/2. Enable materialization and backfill feature data.ipynb)|*no description*|[![2. Enable materialization and backfill feature data](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-2. Enable materialization and backfill feature data.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-2. Enable materialization and backfill feature data.yml)| |featurestore_sample|notebooks|[3. Experiment and train models using features](featurestore_sample/notebooks/sdk_only/3. Experiment and train models using features.ipynb)|*no description*|[![3. Experiment and train models using features](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-3. Experiment and train models using features.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-3. Experiment and train models using features.yml)| |featurestore_sample|notebooks|[4. Enable recurrent materialization and run batch inference](featurestore_sample/notebooks/sdk_only/4. Enable recurrent materialization and run batch inference.ipynb)|*no description*|[![4. Enable recurrent materialization and run batch inference](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-4. Enable recurrent materialization and run batch inference.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-featurestore_sample-notebooks-sdk_only-4. Enable recurrent materialization and run batch inference.yml)| |foundation-models|azure_openai|[openai_completions_finetune](foundation-models/azure_openai/openai_completions_finetune.ipynb)|*no description*|[![openai_completions_finetune](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-azure_openai-openai_completions_finetune.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-azure_openai-openai_completions_finetune.yml)| |foundation-models|huggingface|[question-answering-online-endpoint](foundation-models/huggingface/inference/question-answering/question-answering-online-endpoint.ipynb)|*no description*|[![question-answering-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-question-answering-question-answering-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-question-answering-question-answering-online-endpoint.yml)| +|foundation-models|huggingface|[text-generation-streaming-online-endpoint](foundation-models/huggingface/inference/text-generation-streaming/text-generation-streaming-online-endpoint.ipynb)|*no description*|[![text-generation-streaming-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-text-generation-streaming-text-generation-streaming-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-text-generation-streaming-text-generation-streaming-online-endpoint.yml)| |foundation-models|huggingface|[token-classification-online-endpoint](foundation-models/huggingface/inference/token-classification/token-classification-online-endpoint.ipynb)|*no description*|[![token-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-token-classification-token-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-token-classification-token-classification-online-endpoint.yml)| |foundation-models|huggingface|[translation-online-endpoint](foundation-models/huggingface/inference/translation/translation-online-endpoint.ipynb)|*no description*|[![translation-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-translation-translation-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-translation-translation-online-endpoint.yml)| |foundation-models|huggingface|[zero-shot-classification-online-endpoint](foundation-models/huggingface/inference/zero-shot-classification/zero-shot-classification-online-endpoint.ipynb)|*no description*|[![zero-shot-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-zero-shot-classification-zero-shot-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-huggingface-inference-zero-shot-classification-zero-shot-classification-online-endpoint.yml)| @@ -109,6 +111,9 @@ Test Status is for branch - **_main_** |foundation-models|system|[summarization-online-endpoint](foundation-models/system/inference/summarization/summarization-online-endpoint.ipynb)|*no description*|[![summarization-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-summarization-summarization-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-summarization-summarization-online-endpoint.yml)| |foundation-models|system|[entailment-contradiction-batch](foundation-models/system/inference/text-classification/entailment-contradiction-batch.ipynb)|*no description*|[![entailment-contradiction-batch](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-entailment-contradiction-batch.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-entailment-contradiction-batch.yml)| |foundation-models|system|[text-classification-online-endpoint](foundation-models/system/inference/text-classification/text-classification-online-endpoint.ipynb)|*no description*|[![text-classification-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-text-classification-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-classification-text-classification-online-endpoint.yml)| +|foundation-models|system|[llama-prepare-uai](foundation-models/system/inference/text-generation/llama-prepare-uai.ipynb)|*no description*|[![llama-prepare-uai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-llama-prepare-uai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-llama-prepare-uai.yml)| +|foundation-models|system|[llama-safe-batch-deployment](foundation-models/system/inference/text-generation/llama-safe-batch-deployment.ipynb)|*no description*|[![llama-safe-batch-deployment](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-llama-safe-batch-deployment.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-llama-safe-batch-deployment.yml)| +|foundation-models|system|[llama-safe-online-deployment](foundation-models/system/inference/text-generation/llama-safe-online-deployment.ipynb)|*no description*|[![llama-safe-online-deployment](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-llama-safe-online-deployment.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-llama-safe-online-deployment.yml)| |foundation-models|system|[text-generation-batch-endpoint](foundation-models/system/inference/text-generation/text-generation-batch-endpoint.ipynb)|*no description*|[![text-generation-batch-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-batch-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-batch-endpoint.yml)| |foundation-models|system|[text-generation-online-endpoint-dolly](foundation-models/system/inference/text-generation/text-generation-online-endpoint-dolly.ipynb)|*no description*|[![text-generation-online-endpoint-dolly](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint-dolly.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint-dolly.yml)| |foundation-models|system|[text-generation-online-endpoint](foundation-models/system/inference/text-generation/text-generation-online-endpoint.ipynb)|*no description*|[![text-generation-online-endpoint](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-foundation-models-system-inference-text-generation-text-generation-online-endpoint.yml)| @@ -119,8 +124,10 @@ Test Status is for branch - **_main_** |generative-ai|promptflow|[create_faiss_index](generative-ai/promptflow/create_faiss_index.ipynb)|*no description*|[![create_faiss_index](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-promptflow-create_faiss_index.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-promptflow-create_faiss_index.yml)| |generative-ai|rag|[acs_mlindex_with_langchain](generative-ai/rag/notebooks/azure_cognitive_search/acs_mlindex_with_langchain.ipynb)|*no description*|[![acs_mlindex_with_langchain](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-acs_mlindex_with_langchain.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-acs_mlindex_with_langchain.yml)| |generative-ai|rag|[s3_to_acs_mlindex_with_langchain](generative-ai/rag/notebooks/azure_cognitive_search/s3_to_acs_mlindex_with_langchain.ipynb)|*no description*|[![s3_to_acs_mlindex_with_langchain](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-s3_to_acs_mlindex_with_langchain.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-azure_cognitive_search-s3_to_acs_mlindex_with_langchain.yml)| +|generative-ai|rag|[db_copilot_with_rag](generative-ai/rag/notebooks/db_copilot_with_rag.ipynb)|*no description*|[![db_copilot_with_rag](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-db_copilot_with_rag.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-db_copilot_with_rag.yml)| |generative-ai|rag|[faiss_mlindex_with_langchain](generative-ai/rag/notebooks/faiss/faiss_mlindex_with_langchain.ipynb)|*no description*|[![faiss_mlindex_with_langchain](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-faiss_mlindex_with_langchain.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-faiss_mlindex_with_langchain.yml)| |generative-ai|rag|[scheduled_update_faiss_index](generative-ai/rag/notebooks/faiss/scheduled_update_faiss_index.ipynb)|*no description*|[![scheduled_update_faiss_index](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-scheduled_update_faiss_index.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-scheduled_update_faiss_index.yml)| +|generative-ai|rag|[url_to_faiss_incremental_embeddings_with_tabular_data](generative-ai/rag/notebooks/faiss/url_to_faiss_incremental_embeddings_with_tabular_data.ipynb)|*no description*|[![url_to_faiss_incremental_embeddings_with_tabular_data](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-url_to_faiss_incremental_embeddings_with_tabular_data.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-faiss-url_to_faiss_incremental_embeddings_with_tabular_data.yml)| |generative-ai|rag|[mlindex_with_testgen_autoprompt](generative-ai/rag/notebooks/mlindex_with_testgen_autoprompt.ipynb)|*no description*|[![mlindex_with_testgen_autoprompt](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-mlindex_with_testgen_autoprompt.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-mlindex_with_testgen_autoprompt.yml)| |generative-ai|rag|[qa_data_generation](generative-ai/rag/notebooks/qa_data_generation.ipynb)|*no description*|[![qa_data_generation](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-qa_data_generation.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-generative-ai-rag-notebooks-qa_data_generation.yml)| |jobs|automl-standalone-jobs|[automl-classification-task-bankmarketing-serverless](jobs/automl-standalone-jobs/automl-classification-task-bankmarketing/automl-classification-task-bankmarketing-serverless.ipynb)|*no description*|[![automl-classification-task-bankmarketing-serverless](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-automl-classification-task-bankmarketing-serverless.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-automl-standalone-jobs-automl-classification-task-bankmarketing-automl-classification-task-bankmarketing-serverless.yml)| @@ -176,6 +183,8 @@ Test Status is for branch - **_main_** |jobs|pipelines|[pipeline_with_spark_nodes](jobs/pipelines/1i_pipeline_with_spark_nodes/pipeline_with_spark_nodes.ipynb)|Create pipeline with spark node|[![pipeline_with_spark_nodes](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1i_pipeline_with_spark_nodes-pipeline_with_spark_nodes.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1i_pipeline_with_spark_nodes-pipeline_with_spark_nodes.yml)| |jobs|pipelines|[nyc_taxi_data_regression_with_pipeline_component](jobs/pipelines/1j_pipeline_with_pipeline_component/nyc_taxi_data_regression_with_pipeline_component/nyc_taxi_data_regression_with_pipeline_component.ipynb)|Create pipeline with CommandComponents from local YAML file|[![nyc_taxi_data_regression_with_pipeline_component](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component-nyc_taxi_data_regression_with_pipeline_component.yml)| |jobs|pipelines|[pipeline_with_train_eval_pipeline_component](jobs/pipelines/1j_pipeline_with_pipeline_component/pipeline_with_train_eval_pipeline_component/pipeline_with_train_eval_pipeline_component.ipynb)|Create pipeline with CommandComponents from local YAML file|[![pipeline_with_train_eval_pipeline_component](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-pipeline_with_train_eval_pipeline_component-pipeline_with_train_eval_pipeline_component.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1j_pipeline_with_pipeline_component-pipeline_with_train_eval_pipeline_component-pipeline_with_train_eval_pipeline_component.yml)| +|jobs|pipelines|[automl-forecasting-demand-hierarchical-timeseries-in-pipeline](jobs/pipelines/1k_demand_forecasting_with_pipeline_components/automl-forecasting-demand-hierarchical-timeseries-in-pipeline/automl-forecasting-demand-hierarchical-timeseries-in-pipeline.ipynb)|*no description*|[![automl-forecasting-demand-hierarchical-timeseries-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-hierarchical-timeseries-in-pipeline-automl-forecasting-demand-hierarchical-timeseries-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-hierarchical-timeseries-in-pipeline-automl-forecasting-demand-hierarchical-timeseries-in-pipeline.yml)| +|jobs|pipelines|[automl-forecasting-demand-many-models-in-pipeline](jobs/pipelines/1k_demand_forecasting_with_pipeline_components/automl-forecasting-demand-many-models-in-pipeline/automl-forecasting-demand-many-models-in-pipeline.ipynb)|*no description*|[![automl-forecasting-demand-many-models-in-pipeline](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-many-models-in-pipeline-automl-forecasting-demand-many-models-in-pipeline.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-1k_demand_forecasting_with_pipeline_components-automl-forecasting-demand-many-models-in-pipeline-automl-forecasting-demand-many-models-in-pipeline.yml)| |jobs|pipelines|[train_mnist_with_tensorflow](jobs/pipelines/2a_train_mnist_with_tensorflow/train_mnist_with_tensorflow.ipynb)|Create pipeline using components to run a distributed job with tensorflow|[![train_mnist_with_tensorflow](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2a_train_mnist_with_tensorflow-train_mnist_with_tensorflow.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2a_train_mnist_with_tensorflow-train_mnist_with_tensorflow.yml)| |jobs|pipelines|[train_cifar_10_with_pytorch](jobs/pipelines/2b_train_cifar_10_with_pytorch/train_cifar_10_with_pytorch.ipynb)|Get data, train and evaluate a model in pipeline with Components|[![train_cifar_10_with_pytorch](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2b_train_cifar_10_with_pytorch-train_cifar_10_with_pytorch.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2b_train_cifar_10_with_pytorch-train_cifar_10_with_pytorch.yml)| |jobs|pipelines|[nyc_taxi_data_regression](jobs/pipelines/2c_nyc_taxi_data_regression/nyc_taxi_data_regression.ipynb)|Build pipeline with components for 5 jobs - prep data, transform data, train model, predict results and evaluate model performance|[![nyc_taxi_data_regression](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2c_nyc_taxi_data_regression-nyc_taxi_data_regression.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-pipelines-2c_nyc_taxi_data_regression-nyc_taxi_data_regression.yml)| @@ -198,9 +207,10 @@ Test Status is for branch - **_main_** |jobs|single-step|[tensorflow-mnist](jobs/single-step/tensorflow/mnist/tensorflow-mnist.ipynb)|Run a Command to train a basic neural network with TensorFlow on the MNIST dataset|[![tensorflow-mnist](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-mnist-tensorflow-mnist.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-mnist-tensorflow-mnist.yml)| |jobs|single-step|[train-hyperparameter-tune-deploy-with-keras](jobs/single-step/tensorflow/train-hyperparameter-tune-deploy-with-keras/train-hyperparameter-tune-deploy-with-keras.ipynb)|Train, hyperparameter tune, and deploy a Keras model to classify handwritten digits using a deep neural network (DNN). - _This sample is excluded from automated tests_|[![train-hyperparameter-tune-deploy-with-keras](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-keras-train-hyperparameter-tune-deploy-with-keras.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-keras-train-hyperparameter-tune-deploy-with-keras.yml)| |jobs|single-step|[train-hyperparameter-tune-deploy-with-tensorflow](jobs/single-step/tensorflow/train-hyperparameter-tune-deploy-with-tensorflow/train-hyperparameter-tune-deploy-with-tensorflow.ipynb)|Train, hyperparameter tune, and deploy a Tensorflow model to classify handwritten digits using a deep neural network (DNN). - _This sample is excluded from automated tests_|[![train-hyperparameter-tune-deploy-with-tensorflow](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-single-step-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow-train-hyperparameter-tune-deploy-with-tensorflow.yml)| +|jobs|spark|[run_interactive_session_notebook](jobs/spark/automation/run_interactive_session_notebook.ipynb)|*no description*|[![run_interactive_session_notebook](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-automation-run_interactive_session_notebook.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-automation-run_interactive_session_notebook.yml)| |jobs|spark|[submit_spark_pipeline_jobs](jobs/spark/submit_spark_pipeline_jobs.ipynb)|*no description*|[![submit_spark_pipeline_jobs](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_pipeline_jobs.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_pipeline_jobs.yml)| |jobs|spark|[submit_spark_standalone_jobs](jobs/spark/submit_spark_standalone_jobs.ipynb)|*no description*|[![submit_spark_standalone_jobs](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs.yml)| -|jobs|spark|[submit_spark_standalone_jobs_managed_vnet](jobs/spark/submit_spark_standalone_jobs_managed_vnet.ipynb)|*no description* - _This sample is excluded from automated tests_|[![submit_spark_standalone_jobs_managed_vnet](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs_managed_vnet.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs_managed_vnet.yml)| +|jobs|spark|[submit_spark_standalone_jobs_managed_vnet](jobs/spark/submit_spark_standalone_jobs_managed_vnet.ipynb)|*no description*|[![submit_spark_standalone_jobs_managed_vnet](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs_managed_vnet.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-jobs-spark-submit_spark_standalone_jobs_managed_vnet.yml)| |resources|compute|[attach_manage_spark_pools](resources/compute/attach_manage_spark_pools.ipynb)|*no description*|[![attach_manage_spark_pools](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-attach_manage_spark_pools.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-attach_manage_spark_pools.yml)| |resources|compute|[compute](resources/compute/compute.ipynb)|Create compute in Azure ML workspace|[![compute](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-compute.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-compute-compute.yml)| |resources|connections|[connections](resources/connections/connections.ipynb)|*no description*|[![connections](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-connections-connections.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-resources-connections-connections.yml)| From 538274ef2c5aef59f45f31e54f5807dc074d671f Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Thu, 27 Jul 2023 14:18:04 -0700 Subject: [PATCH 04/18] remove input --- .../online/llm/langchain/1_langchain_basic_deploy.ipynb | 6 +----- .../llm/semantic-kernel/1_semantic_http_server.ipynb | 8 ++------ 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index c158b4e2e2..d9ee2b7b97 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -37,11 +37,7 @@ "import os\n", "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = (\n", - " os.environ.get(\"OPENAI_API_KEY\")\n", - " if os.environ.get(\"OPENAI_API_KEY\")\n", - " else input(\"OPENAI_API_KEY\")\n", - ")\n", + "OPENAI_API_KEY = \"\"\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index ae19bb8dfb..d568f7e9e5 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -43,11 +43,7 @@ "import os\n", "\n", "OPENAI_API_TYPE = \"azure\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = (\n", - " os.environ.get(\"OPENAI_API_KEY\")\n", - " if os.environ.get(\"OPENAI_API_KEY\")\n", - " else input(\"OPENAI_API_KEY\")\n", - ")\n", + "OPENAI_API_KEY = \"\"\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", @@ -79,7 +75,7 @@ "metadata": {}, "outputs": [], "source": [ - "# start the server locally\n", + "# uncomment to test and start the server locally\n", "# %run -i ../src/sk/app.py" ] }, From 75dc1385993b648cffe41b192d8818249373c63a Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Thu, 27 Jul 2023 15:53:02 -0700 Subject: [PATCH 05/18] use template values for subid/rg/ws --- .../langchain/1_langchain_basic_deploy.ipynb | 43 ++++++++------ .../1_semantic_http_server.ipynb | 57 +++++++++++-------- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index d9ee2b7b97..3cfed37836 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -241,12 +241,10 @@ "metadata": {}, "outputs": [], "source": [ - "# Azure resources needed for the demo. You can change them to use your own.\n", - "# If you don't have the resources, you could keep the names as is and we will create them for you in next step.\n", - "SUBSCRIPTION_ID = \"\"\n", - "RESOURCE_GROUP = \"llmops-demo\"\n", - "REGION = \"westus3\"\n", - "AML_WORKSPACE_NAME = \"llmops-demo-aml-ws\"\n", + "# enter details of your AML workspace\n", + "SUBSCRIPTION_ID = \"\"\n", + "RESOURCE_GROUP = \"\"\n", + "AML_WORKSPACE_NAME = \"\"\n", "\n", "# Keyvault information\n", "KEYVAULT_NAME = \"aml-llm-demo-kv\"\n", @@ -348,17 +346,14 @@ "# get a handle to the workspace\n", "ml_client = MLClient(credential, SUBSCRIPTION_ID, RESOURCE_GROUP, AML_WORKSPACE_NAME)\n", "\n", - "try:\n", - " endpoint = ml_client.online_endpoints.get(online_endpoint_name)\n", - "except Exception as ex:\n", - " # create an online endpoint\n", - " endpoint = ManagedOnlineEndpoint(\n", - " name=online_endpoint_name,\n", - " description=\"online endpoint for Langchain server\",\n", - " auth_mode=\"key\",\n", - " )\n", + "# create an online endpoint\n", + "endpoint = ManagedOnlineEndpoint(\n", + " name=online_endpoint_name,\n", + " description=\"online endpoint for Langchain server\",\n", + " auth_mode=\"key\",\n", + ")\n", "\n", - " endpoint = ml_client.begin_create_or_update(endpoint).result()\n", + "endpoint = ml_client.begin_create_or_update(endpoint).result()\n", "\n", "print(endpoint)" ] @@ -478,6 +473,22 @@ "response = requests.post(f\"{url}/score\", headers=headers, data=payload)\n", "print(f\"Response:\\n\", response.text)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 5. Delete the deployment and endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" + ] } ], "metadata": { diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index d568f7e9e5..7522c4a924 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -42,7 +42,7 @@ "source": [ "import os\n", "\n", - "OPENAI_API_TYPE = \"azure\" # 'azure' or 'openai'\n", + "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", "OPENAI_API_KEY = \"\"\n", "\n", "# required for OpenAI API\n", @@ -50,8 +50,8 @@ "OPENAI_MODEL_ID = \"gpt-3.5-turbo\"\n", "\n", "# required for Azure OpenAI API\n", - "AZURE_OPENAI_API_ENDPOINT = \"https://.openai.azure.com/\"\n", - "AZURE_OPENAI_API_DEPLOYMENT_NAME = \"\"\n", + "AZURE_OPENAI_API_ENDPOINT = \"https://.openai.azure.com/\"\n", + "AZURE_OPENAI_API_DEPLOYMENT_NAME = \"\"\n", "\n", "# set to true for chat completion API, false for text completion\n", "IS_CHAT_COMPLETION = True\n", @@ -147,12 +147,10 @@ "metadata": {}, "outputs": [], "source": [ - "# Azure resources needed for the demo. You can change them to use your own.\n", - "# If you don't have the resources, you could keep the names as is and we will create them for you in next step.\n", - "SUBSCRIPTION_ID = \"\"\n", - "RESOURCE_GROUP = \"llmops-demo\"\n", - "REGION = \"westus3\"\n", - "AML_WORKSPACE_NAME = \"llmops-demo-aml-ws\"\n", + "# enter details of your AML workspace\n", + "SUBSCRIPTION_ID = \"\"\n", + "RESOURCE_GROUP = \"\"\n", + "AML_WORKSPACE_NAME = \"\"\n", "\n", "# Keyvault information\n", "KEYVAULT_NAME = \"aml-llm-demo-kv\"\n", @@ -284,17 +282,14 @@ "# get a handle to the workspace\n", "ml_client = MLClient(credential, SUBSCRIPTION_ID, RESOURCE_GROUP, AML_WORKSPACE_NAME)\n", "\n", - "try:\n", - " endpoint = ml_client.online_endpoints.get(online_endpoint_name)\n", - "except Exception as ex:\n", - " # create an online endpoint\n", - " endpoint = ManagedOnlineEndpoint(\n", - " name=online_endpoint_name,\n", - " description=\"online endpoint for SemanticKernelHttp server\",\n", - " auth_mode=\"key\",\n", - " )\n", + "# create an online endpoint\n", + "endpoint = ManagedOnlineEndpoint(\n", + " name=online_endpoint_name,\n", + " description=\"online endpoint for SemanticKernelHttp server\",\n", + " auth_mode=\"key\",\n", + ")\n", "\n", - " endpoint = ml_client.begin_create_or_update(endpoint).result()\n", + "endpoint = ml_client.begin_create_or_update(endpoint).result()\n", "\n", "print(endpoint)" ] @@ -349,8 +344,6 @@ "outputs": [], "source": [ "import datetime\n", - "import logging\n", - "import sys\n", "\n", "from azure.ai.ml.entities import (\n", " ManagedOnlineDeployment,\n", @@ -441,13 +434,29 @@ ")\n", "print(f\"Execution Result:\\n\", response.text)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 5. Delete the deployment and endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.10 - SDK V2", + "display_name": "Python 3", "language": "python", - "name": "python310-sdkv2" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -459,7 +468,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.3" + "version": "3.10.5" } }, "nbformat": 4, From 26a5ae7d44e767ae7aecbc4a9df3cb02395014fd Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Thu, 27 Jul 2023 16:29:34 -0700 Subject: [PATCH 06/18] make keyvault optional --- .../langchain/1_langchain_basic_deploy.ipynb | 24 +++++++++++-------- .../1_semantic_http_server.ipynb | 13 ++++++---- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 3cfed37836..4297fae401 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -247,7 +247,7 @@ "AML_WORKSPACE_NAME = \"\"\n", "\n", "# Keyvault information\n", - "KEYVAULT_NAME = \"aml-llm-demo-kv\"\n", + "KEYVAULT_NAME = \"\"\n", "# Key name in keyvault for the OPENAI-AI-KEY\n", "KV_OPENAI_KEY = \"OPENAI-API-KEY\"" ] @@ -284,7 +284,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 2.2 Store Secrets in Azure Keyvault" + "## 2.2 (Optional) Store Secrets in Azure Keyvault" ] }, { @@ -293,6 +293,7 @@ "metadata": {}, "outputs": [], "source": [ + "'''\n", "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "\n", @@ -314,7 +315,8 @@ " # Let's set OpenAI key as a secret in keyvault\n", " need_interactive_auth = False\n", " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", - " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}" + " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\n", + "'''" ] }, { @@ -322,8 +324,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 3. Manage Online Endpoint\n", - "### 3.1 Create Endpoint" + "# 3. Manage Online Endpoint\n", + "## 3.1 Create Endpoint" ] }, { @@ -363,8 +365,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 3.2 Grant Endpoint Permission to Dependencies\n", - "Endpoint uses AAD to access dependent resources, so you don't have to hardcode secrets." + "## 3.2 (Optional) Grant Endpoint Permission to Dependencies\n", + "If using keyvault to store your OpenAI API key, uncomment the below code. The endpoint will use AAD to access dependent resources, so you don't have to hardcode secrets." ] }, { @@ -373,9 +375,10 @@ "metadata": {}, "outputs": [], "source": [ + "'''\n", "# Allow the endpoint to access secrets in keyvault\n", "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", - "need_interactive_auth = True\n", + "need_interactive_auth = False\n", "if need_interactive_auth:\n", " print(\n", " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", @@ -384,7 +387,8 @@ " f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", " )\n", "else:\n", - " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" + " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", + "'''" ] }, { @@ -426,7 +430,7 @@ " ),\n", " request_settings=OnlineRequestSettings(request_timeout_ms=60000),\n", " environment_variables={\n", - " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", + " \"OPENAI_API_KEY\": OPENAI_API_KEY,\n", " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", " \"OPENAI_ORG_ID\": OPENAI_ORG_ID,\n", diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index 7522c4a924..db2aaf2e7b 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -193,7 +193,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.2 Store Secrets in Azure Keyvault" + "## 2.2 (Optional) Store Secrets in Azure Keyvault" ] }, { @@ -202,6 +202,7 @@ "metadata": {}, "outputs": [], "source": [ + "'''\n", "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "\n", @@ -223,7 +224,8 @@ " # Let's set OpenAI key as a secret in keyvault\n", " need_interactive_auth = False\n", " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", - " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}" + " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\n", + "'''" ] }, { @@ -313,7 +315,7 @@ "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "ACR_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.ContainerRegistry/registries/{ACR_NAME}\"\n", "\n", - "need_interactive_auth = True\n", + "need_interactive_auth = False\n", "if need_interactive_auth:\n", " print(\n", " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", @@ -325,7 +327,8 @@ " f\"az role assignment create --role 'AcrPull' --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", " )\n", "else:\n", - " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", + " # Uncomment below if using key vault to store secrets\n", + " # !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", " !az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" ] }, @@ -371,7 +374,7 @@ " ),\n", " environment_variables={\n", " \"AZUREML_SERVING_ENTRYPOINT\": \"../src/sk/entry.sh\",\n", - " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", + " \"OPENAI_API_KEY\": OPENAI_API_KEY,\n", " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", " \"OPENAI_ORG_ID\": OPENAI_ORG_ID,\n", From 0e63c06145dc20abf6ab44f1df303a74c3714bb8 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Thu, 27 Jul 2023 16:32:46 -0700 Subject: [PATCH 07/18] fix formatting --- .../online/llm/langchain/1_langchain_basic_deploy.ipynb | 8 ++++---- .../llm/semantic-kernel/1_semantic_http_server.ipynb | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 4297fae401..585e5c3555 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -293,7 +293,7 @@ "metadata": {}, "outputs": [], "source": [ - "'''\n", + "\"\"\"\n", "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "\n", @@ -316,7 +316,7 @@ " need_interactive_auth = False\n", " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\n", - "'''" + "\"\"\"" ] }, { @@ -375,7 +375,7 @@ "metadata": {}, "outputs": [], "source": [ - "'''\n", + "\"\"\"\n", "# Allow the endpoint to access secrets in keyvault\n", "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "need_interactive_auth = False\n", @@ -388,7 +388,7 @@ " )\n", "else:\n", " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", - "'''" + "\"\"\"" ] }, { diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index db2aaf2e7b..ccc1167af8 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -202,7 +202,7 @@ "metadata": {}, "outputs": [], "source": [ - "'''\n", + "\"\"\"\n", "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", "\n", @@ -225,7 +225,7 @@ " need_interactive_auth = False\n", " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\n", - "'''" + "\"\"\"" ] }, { From 4ef4bf15e9ddbe4e9c4af6797d8181fbe1ad82b7 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Fri, 28 Jul 2023 15:54:36 -0700 Subject: [PATCH 08/18] acr fixes --- .../langchain/1_langchain_basic_deploy.ipynb | 93 +------------------ .../1_semantic_http_server.ipynb | 80 ++++------------ 2 files changed, 21 insertions(+), 152 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 585e5c3555..60bcc3dab8 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -223,14 +223,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 2. Deploy Online Endpoint\n", - "On a high level, we will perform the following tasks:\n", - "\n", - "* **Preparation**\n", - " * Store OpenAI key in Azure Keyvault to keep it safe.\n", - "* **Create Managed Online Endpoint**, and give the endpoint permission to access Azure Keyvault above.\n", - "* **Deploy to Managed Online Endpoint**\n", - "* **Test**\n", + "# 2. Deploy Langchain App to an Online Endpoint\n", "\n", "## 2.1 Preparation" ] @@ -244,12 +237,7 @@ "# enter details of your AML workspace\n", "SUBSCRIPTION_ID = \"\"\n", "RESOURCE_GROUP = \"\"\n", - "AML_WORKSPACE_NAME = \"\"\n", - "\n", - "# Keyvault information\n", - "KEYVAULT_NAME = \"\"\n", - "# Key name in keyvault for the OPENAI-AI-KEY\n", - "KV_OPENAI_KEY = \"OPENAI-API-KEY\"" + "AML_WORKSPACE_NAME = \"\"" ] }, { @@ -279,46 +267,6 @@ "# !az login --use-device-code" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2.2 (Optional) Store Secrets in Azure Keyvault" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", - "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", - "\n", - "need_interactive_auth = False\n", - "if \"AADSTS530003\".lower() in MY_OBJECT_ID[0].lower():\n", - " need_interactive_auth = True\n", - " print(\"\\n\".join(MY_OBJECT_ID))\n", - " print(\n", - " \"\\nYou are geting this error probably because you are using a device login. And this operation needs interactive login. If you can't login interactively, you could simply copy and run the following command in Azure Cloud Shell in Bash mode.\\n\"\n", - " )\n", - " print(\"MY_OBJECT_ID=`az ad signed-in-user show --query id -o tsv`\")\n", - " print(\n", - " f\"az role assignment create --role 'Key Vault Administrator' --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id $MY_OBJECT_ID --assignee-principal-type User\"\n", - " )\n", - " print(\n", - " f\"az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\"\n", - " )\n", - "else:\n", - " # Let's set OpenAI key as a secret in keyvault\n", - " need_interactive_auth = False\n", - " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", - " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\n", - "\"\"\"" - ] - }, { "attachments": {}, "cell_type": "markdown", @@ -365,38 +313,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 3.2 (Optional) Grant Endpoint Permission to Dependencies\n", - "If using keyvault to store your OpenAI API key, uncomment the below code. The endpoint will use AAD to access dependent resources, so you don't have to hardcode secrets." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "# Allow the endpoint to access secrets in keyvault\n", - "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", - "need_interactive_auth = False\n", - "if need_interactive_auth:\n", - " print(\n", - " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", - " )\n", - " print(\n", - " f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", - " )\n", - "else:\n", - " !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", - "\"\"\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3.3 Deploy to Endpoint" + "## 3.2 Deploy to Endpoint" ] }, { @@ -414,8 +331,6 @@ " CodeConfiguration,\n", ")\n", "\n", - "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", - "\n", "env = Environment(\n", " conda_file=\"deployments/env.yml\",\n", " image=\"mcr.microsoft.com/azureml/minimal-ubuntu20.04-py38-cpu-inference:latest\",\n", @@ -462,7 +377,7 @@ "metadata": {}, "outputs": [], "source": [ - "import requests, json, time\n", + "import requests, json\n", "from urllib.parse import urlsplit\n", "\n", "url_parts = urlsplit(endpoint.scoring_uri)\n", diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index ccc1167af8..cf710d4890 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -40,8 +40,6 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", - "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", "OPENAI_API_KEY = \"\"\n", "\n", @@ -132,7 +130,6 @@ "On a high level, we will perform the following tasks:\n", "\n", "* **Preparation**\n", - " * Store Secets in Azure Keyvault\n", " * Create docker image in Azure Container Registry\n", "* **Create Managed Online Endpoint**, grant the endpoint permission to access the resources above.\n", "* **Deploy to Managed Online Endpoint**, now we are ready deploy the code\n", @@ -152,12 +149,7 @@ "RESOURCE_GROUP = \"\"\n", "AML_WORKSPACE_NAME = \"\"\n", "\n", - "# Keyvault information\n", - "KEYVAULT_NAME = \"aml-llm-demo-kv\"\n", - "# Key name in keyvault for the OPENAI-AI-KEY\n", - "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", - "\n", - "ACR_NAME = \"amlllmdemoacr\"\n", + "ACR_NAME = \"amlskdemoacr\"\n", "ACR_IMAGE_NAME = \"serving\"" ] }, @@ -193,7 +185,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 2.2 (Optional) Store Secrets in Azure Keyvault" + "### 2.2 Create Container Registry and Docker Image" ] }, { @@ -202,38 +194,8 @@ "metadata": {}, "outputs": [], "source": [ - "\"\"\"\n", - "MY_OBJECT_ID = !az ad signed-in-user show --query id -o tsv\n", - "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", - "\n", - "need_interactive_auth = False\n", - "if \"AADSTS530003\".lower() in MY_OBJECT_ID[0].lower():\n", - " need_interactive_auth = True\n", - " print(\"\\n\".join(MY_OBJECT_ID))\n", - " print(\n", - " \"\\nYou are geting this error probably because you are using a device login. And this operation needs interactive login. If you can't login interactively, you could simply copy and run the following command in Azure Cloud Shell in Bash mode.\\n\"\n", - " )\n", - " print(\"MY_OBJECT_ID=`az ad signed-in-user show --query id -o tsv`\")\n", - " print(\n", - " f\"az role assignment create --role 'Key Vault Administrator' --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id $MY_OBJECT_ID --assignee-principal-type User\"\n", - " )\n", - " print(\n", - " f\"az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\"\n", - " )\n", - "else:\n", - " # Let's set OpenAI key as a secret in keyvault\n", - " need_interactive_auth = False\n", - " !az role assignment create --role \"Key Vault Administrator\" --scope {KEYVAULT_RESOURCE_URI} --assignee-object-id {MY_OBJECT_ID[0]} --assignee-principal-type User\n", - " !az keyvault secret set --name {KV_OPENAI_KEY} --vault-name {KEYVAULT_NAME} --value {OPENAI_API_KEY}\n", - "\"\"\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.3 Create Docker Image" + "# Create an Azure Container Registry\n", + "!az acr create --resource-group {RESOURCE_GROUP} --name {ACR_NAME} --sku Basic" ] }, { @@ -242,7 +204,7 @@ "metadata": {}, "outputs": [], "source": [ - "\n", + "# Build the image in your ACR\n", "!az acr build --image {ACR_IMAGE_NAME} --registry {ACR_NAME} ./environment/serving/. --subscription {SUBSCRIPTION_ID}" ] }, @@ -261,15 +223,6 @@ "metadata": {}, "outputs": [], "source": [ - "# Authenticate clients\n", - "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", - "\n", - "try:\n", - " credential = DefaultAzureCredential(additionally_allowed_tenants=[\"*\"])\n", - "except Exception as ex:\n", - " # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work\n", - " credential = InteractiveBrowserCredential()\n", - "\n", "# create a endpoint\n", "from azure.ai.ml.entities import (\n", " ManagedOnlineEndpoint,\n", @@ -311,8 +264,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Allow the endpoint to access keyvault and acr\n", - "KEYVAULT_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/{KEYVAULT_NAME}\"\n", + "# Allow the endpoint to access ACR\n", "ACR_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.ContainerRegistry/registries/{ACR_NAME}\"\n", "\n", "need_interactive_auth = False\n", @@ -321,14 +273,9 @@ " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", " )\n", " print(\n", - " f\"az role assignment create --role 'Key Vault Secrets User' --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", - " )\n", - " print(\n", " f\"az role assignment create --role 'AcrPull' --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", " )\n", "else:\n", - " # Uncomment below if using key vault to store secrets\n", - " # !az role assignment create --role \"Key Vault Secrets User\" --scope {KEYVAULT_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\n", " !az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" ] }, @@ -355,8 +302,6 @@ " Environment,\n", ")\n", "\n", - "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", - "\n", "deployment_name = f\"deploy-{str(datetime.datetime.now().strftime('%m%d%H%M%f'))}\"\n", "sk_deployment = ManagedOnlineDeployment(\n", " name=deployment_name,\n", @@ -373,7 +318,7 @@ " },\n", " ),\n", " environment_variables={\n", - " \"AZUREML_SERVING_ENTRYPOINT\": \"../src/sk/entry.sh\",\n", + " \"AZUREML_SERVING_ENTRYPOINT\": \"src/sk/entry.sh\",\n", " \"OPENAI_API_KEY\": OPENAI_API_KEY,\n", " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", @@ -442,7 +387,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 5. Delete the deployment and endpoint" + "# 5. Delete the deployment, endpoint, and ACR" ] }, { @@ -453,6 +398,15 @@ "source": [ "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!az acr delete -n ACR_NAME --yes" + ] } ], "metadata": { From 71125f3e3a3aca9e92036d4687311f081c4c621f Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 31 Jul 2023 12:57:30 -0700 Subject: [PATCH 09/18] add rg to acr permissions --- .../semantic-kernel/1_semantic_http_server.ipynb | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index cf710d4890..1b2d4a5ff2 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -205,7 +205,7 @@ "outputs": [], "source": [ "# Build the image in your ACR\n", - "!az acr build --image {ACR_IMAGE_NAME} --registry {ACR_NAME} ./environment/serving/. --subscription {SUBSCRIPTION_ID}" + "!az acr build --image {ACR_IMAGE_NAME} --registry {ACR_NAME} ./environment/serving/. --resource-group {RESOURCE_GROUP}" ] }, { @@ -267,16 +267,7 @@ "# Allow the endpoint to access ACR\n", "ACR_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.ContainerRegistry/registries/{ACR_NAME}\"\n", "\n", - "need_interactive_auth = False\n", - "if need_interactive_auth:\n", - " print(\n", - " \"If you can't login interactively, you could run the following command in Azure Cloud Bash Shell.\"\n", - " )\n", - " print(\n", - " f\"az role assignment create --role 'AcrPull' --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}\"\n", - " )\n", - "else:\n", - " !az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" + "!az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" ] }, { From fde1c04634d7a0692f4cbf34a6d920be82e7d44b Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 31 Jul 2023 14:27:22 -0700 Subject: [PATCH 10/18] use workspace acr instead of creating one --- .../1_semantic_http_server.ipynb | 58 ++++++------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index 1b2d4a5ff2..fc686fc897 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -9,7 +9,7 @@ "**Requirements** - In order to benefit from this tutorial, you will need:\n", "* A basic understanding of Machine Learning and Large Language Models\n", "* An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F)\n", - "* An Azure Machine Learning Workspace, Azure Key Vault, and Azure Container Registry\n", + "* An Azure Machine Learning Workspace and Azure Container Registry\n", "* An OpenAI API Key which can be found in User Settings in OpenAI\n", "\n", "**Motivations** - Semantic kernel has a slightly different approach to LLM agents. It offers an interesting Plan->Execute pattern, where it could use LLM to form a plan first, then human could confirm and execute on the plan. In this notebook, we use the [planner](https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/python/05-using-the-planner.ipynb) example from Semantic Kernel as a base. But additionally, we've made the following modifications:\n", @@ -147,10 +147,7 @@ "# enter details of your AML workspace\n", "SUBSCRIPTION_ID = \"\"\n", "RESOURCE_GROUP = \"\"\n", - "AML_WORKSPACE_NAME = \"\"\n", - "\n", - "ACR_NAME = \"amlskdemoacr\"\n", - "ACR_IMAGE_NAME = \"serving\"" + "AML_WORKSPACE_NAME = \"\"" ] }, { @@ -194,8 +191,20 @@ "metadata": {}, "outputs": [], "source": [ - "# Create an Azure Container Registry\n", - "!az acr create --resource-group {RESOURCE_GROUP} --name {ACR_NAME} --sku Basic" + "import re\n", + "from azure.ai.ml import (\n", + " MLClient,\n", + ")\n", + "\n", + "ml_client = MLClient(credential, SUBSCRIPTION_ID, RESOURCE_GROUP, AML_WORKSPACE_NAME)\n", + "ws = ml_client.workspaces.get(AML_WORKSPACE_NAME)\n", + "\n", + "# Get the Azure Container Registry associated with the workspace\n", + "acr = ws.container_registry\n", + "\n", + "# Parse the ACR resource Id for the ACR name\n", + "match_object = re.match(r'.+?registries\\/(.+)', acr)\n", + "ACR_NAME = match_object.group(1)" ] }, { @@ -205,6 +214,8 @@ "outputs": [], "source": [ "# Build the image in your ACR\n", + "ACR_IMAGE_NAME = \"serving\"\n", + "\n", "!az acr build --image {ACR_IMAGE_NAME} --registry {ACR_NAME} ./environment/serving/. --resource-group {RESOURCE_GROUP}" ] }, @@ -234,7 +245,6 @@ "\n", "online_endpoint_name = \"aml-llm-demo-sk-endpoint\"\n", "\n", - "# get a handle to the workspace\n", "ml_client = MLClient(credential, SUBSCRIPTION_ID, RESOURCE_GROUP, AML_WORKSPACE_NAME)\n", "\n", "# create an online endpoint\n", @@ -249,27 +259,6 @@ "print(endpoint)" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2 Grant Endpoint Permission to Dependencies\n", - "Endpoint uses AAD to access dependent resources, so you don't have to hardcode secrets." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Allow the endpoint to access ACR\n", - "ACR_RESOURCE_URI = f\"/subscriptions/{SUBSCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP}/providers/Microsoft.ContainerRegistry/registries/{ACR_NAME}\"\n", - "\n", - "!az role assignment create --role \"AcrPull\" --scope {ACR_RESOURCE_URI} --assignee {endpoint.identity.principal_id}" - ] - }, { "attachments": {}, "cell_type": "markdown", @@ -378,7 +367,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 5. Delete the deployment, endpoint, and ACR" + "# 5. Delete the deployment and endpoint" ] }, { @@ -389,15 +378,6 @@ "source": [ "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!az acr delete -n ACR_NAME --yes" - ] } ], "metadata": { From b9684a6e2114865cadb356def218b36beeeba759 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 31 Jul 2023 14:33:29 -0700 Subject: [PATCH 11/18] fix format --- .../online/llm/semantic-kernel/1_semantic_http_server.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index fc686fc897..96b8f05d1c 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -203,7 +203,7 @@ "acr = ws.container_registry\n", "\n", "# Parse the ACR resource Id for the ACR name\n", - "match_object = re.match(r'.+?registries\\/(.+)', acr)\n", + "match_object = re.match(r\".+?registries\\/(.+)\", acr)\n", "ACR_NAME = match_object.group(1)" ] }, From 49a0c150ac00f567cf73424b1c58d1f18794e02f Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Wed, 2 Aug 2023 10:57:30 -0700 Subject: [PATCH 12/18] include semantic-kernel config files --- sdk/python/.gitignore | 5 ++- .../src/sk/skills/FunSkill/Joke/config.json | 21 ++++++++++ .../sk/skills/WriterSkill/Acronym/config.json | 12 ++++++ .../WriterSkill/AcronymGenerator/config.json | 15 +++++++ .../WriterSkill/AcronymReverse/config.json | 15 +++++++ .../skills/WriterSkill/Brainstorm/config.json | 22 ++++++++++ .../skills/WriterSkill/EmailGen/config.json | 12 ++++++ .../sk/skills/WriterSkill/EmailTo/config.json | 12 ++++++ .../WriterSkill/EnglishImprover/config.json | 12 ++++++ .../WriterSkill/NovelChapter/config.json | 36 ++++++++++++++++ .../NovelChapterWithNotes/config.json | 41 +++++++++++++++++++ .../WriterSkill/NovelOutline/config.json | 31 ++++++++++++++ .../sk/skills/WriterSkill/Rewrite/config.json | 12 ++++++ .../skills/WriterSkill/ShortPoem/config.json | 21 ++++++++++ .../skills/WriterSkill/StoryGen/config.json | 12 ++++++ .../skills/WriterSkill/TellMeMore/config.json | 12 ++++++ .../skills/WriterSkill/Translate/config.json | 15 +++++++ .../TwoSentenceSummary/config.json | 12 ++++++ 18 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/config.json create mode 100644 sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/config.json diff --git a/sdk/python/.gitignore b/sdk/python/.gitignore index 8a58e0034b..491c7db505 100644 --- a/sdk/python/.gitignore +++ b/sdk/python/.gitignore @@ -1,2 +1,5 @@ .ipynb_checkpoints -*/.ipynb_checkpoints/* \ No newline at end of file +*/.ipynb_checkpoints/* + +# config files are required to use Semantic Kernel +!endpoints/online/llm/src/sk/skills/*/*/config.json \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/config.json new file mode 100644 index 0000000000..123d447267 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/FunSkill/Joke/config.json @@ -0,0 +1,21 @@ +{ + "schema": 1, + "description": "Generate a funny joke", + "type": "completion", + "completion": { + "max_tokens": 1000, + "temperature": 0.9, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + }, + "input": { + "parameters": [ + { + "name": "input", + "description": "Joke subject", + "defaultValue": "" + } + ] + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/config.json new file mode 100644 index 0000000000..c484148560 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Acronym/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Generate an acronym for the given concept or phrase", + "completion": { + "max_tokens": 100, + "temperature": 0.5, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/config.json new file mode 100644 index 0000000000..1dab1fe9f7 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymGenerator/config.json @@ -0,0 +1,15 @@ +{ + "schema": 1, + "type": "completion", + "description": "Given a request to generate an acronym from a string, generate an acronym and provide the acronym explanation.", + "completion": { + "max_tokens": 256, + "temperature": 0.7, + "top_p": 1.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0, + "stop_sequences": [ + "#" + ] + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/config.json new file mode 100644 index 0000000000..eed5c51917 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/AcronymReverse/config.json @@ -0,0 +1,15 @@ +{ + "schema": 1, + "type": "completion", + "description": "Given a single word or acronym, generate the expanded form matching the acronym letters.", + "completion": { + "max_tokens": 256, + "temperature": 0.5, + "top_p": 1.0, + "presence_penalty": 0.8, + "frequency_penalty": 0.0, + "stop_sequences": [ + "#END#" + ] + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/config.json new file mode 100644 index 0000000000..50856795c6 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Brainstorm/config.json @@ -0,0 +1,22 @@ +{ + "schema": 1, + "type": "completion", + "description": "Given a goal or topic description generate a list of ideas", + "completion": { + "max_tokens": 2000, + "temperature": 0, + "top_p": 1.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0, + "stop_sequences": ["##END##"] + }, + "input": { + "parameters": [ + { + "name": "input", + "description": "A topic description or goal.", + "defaultValue": "" + } + ] + } +} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/config.json new file mode 100644 index 0000000000..d43eab348e --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailGen/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Write an email from the given bullet points", + "completion": { + "max_tokens": 256, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/config.json new file mode 100644 index 0000000000..5f0d6ee6e4 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EmailTo/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Turn bullet points into an email to someone, using a polite tone", + "completion": { + "max_tokens": 256, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/config.json new file mode 100644 index 0000000000..4d10af469a --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/EnglishImprover/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Translate text to English and improve it", + "completion": { + "max_tokens": 3000, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/config.json new file mode 100644 index 0000000000..3568c69557 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapter/config.json @@ -0,0 +1,36 @@ +{ + "schema": 1, + "type": "completion", + "description": "Write a chapter of a novel.", + "completion": { + "max_tokens": 2048, + "temperature": 0.3, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + }, + "input": { + "parameters": [ + { + "name": "input", + "description": "A synopsis of what the chapter should be about.", + "defaultValue": "" + }, + { + "name": "theme", + "description": "The theme or topic of this novel.", + "defaultValue": "" + }, + { + "name": "previousChapter", + "description": "The synopsis of the previous chapter.", + "defaultValue": "" + }, + { + "name": "chapterIndex", + "description": "The number of the chapter to write.", + "defaultValue": "" + } + ] + } +} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/config.json new file mode 100644 index 0000000000..02b9e613a6 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelChapterWithNotes/config.json @@ -0,0 +1,41 @@ +{ + "schema": 1, + "type": "completion", + "description": "Write a chapter of a novel using notes about the chapter to write.", + "completion": { + "max_tokens": 1024, + "temperature": 0.5, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + }, + "input": { + "parameters": [ + { + "name": "input", + "description": "What the novel should be about.", + "defaultValue": "" + }, + { + "name": "theme", + "description": "The theme of this novel.", + "defaultValue": "" + }, + { + "name": "notes", + "description": "Notes useful to write this chapter.", + "defaultValue": "" + }, + { + "name": "previousChapter", + "description": "The previous chapter synopsis.", + "defaultValue": "" + }, + { + "name": "chapterIndex", + "description": "The number of the chapter to write.", + "defaultValue": "" + } + ] + } +} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/config.json new file mode 100644 index 0000000000..a34622f7be --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/NovelOutline/config.json @@ -0,0 +1,31 @@ +{ + "schema": 1, + "type": "completion", + "description": "Generate a list of chapter synopsis for a novel or novella", + "completion": { + "max_tokens": 2048, + "temperature": 0.1, + "top_p": 0.5, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + }, + "input": { + "parameters": [ + { + "name": "input", + "description": "What the novel should be about.", + "defaultValue": "" + }, + { + "name": "chapterCount", + "description": "The number of chapters to generate.", + "defaultValue": "" + }, + { + "name": "endMarker", + "description": "The marker to use to end each chapter.", + "defaultValue": "" + } + ] + } +} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/config.json new file mode 100644 index 0000000000..175ade9d95 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Rewrite/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Automatically generate compact notes for any text or text document", + "completion": { + "max_tokens": 256, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/config.json new file mode 100644 index 0000000000..0cc3da6c86 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/ShortPoem/config.json @@ -0,0 +1,21 @@ +{ + "schema": 1, + "type": "completion", + "description": "Turn a scenario into a short and entertaining poem.", + "completion": { + "max_tokens": 60, + "temperature": 0.5, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + }, + "input": { + "parameters": [ + { + "name": "input", + "description": "The scenario to turn into a poem.", + "defaultValue": "" + } + ] + } +} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/config.json new file mode 100644 index 0000000000..2128313412 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/StoryGen/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Generate a list of synopsis for a novel or novella with sub-chapters", + "completion": { + "max_tokens": 250, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/config.json new file mode 100644 index 0000000000..28b6b4e5c1 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TellMeMore/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Summarize given text or any text document", + "completion": { + "max_tokens": 500, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/config.json new file mode 100644 index 0000000000..8134ce8dd5 --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/Translate/config.json @@ -0,0 +1,15 @@ +{ + "schema": 1, + "type": "completion", + "description": "Translate the input into a language of your choice", + "completion": { + "max_tokens": 2000, + "temperature": 0.7, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0, + "stop_sequences": [ + "[done]" + ] + } +} \ No newline at end of file diff --git a/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/config.json b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/config.json new file mode 100644 index 0000000000..833bd5950f --- /dev/null +++ b/sdk/python/endpoints/online/llm/src/sk/skills/WriterSkill/TwoSentenceSummary/config.json @@ -0,0 +1,12 @@ +{ + "schema": 1, + "type": "completion", + "description": "Summarize given text in two sentences or less", + "completion": { + "max_tokens": 100, + "temperature": 0.0, + "top_p": 0.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0 + } +} \ No newline at end of file From e249562545b9653c4621f2091748edb32abc84bf Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Wed, 2 Aug 2023 11:33:12 -0700 Subject: [PATCH 13/18] clean up ACR image --- .../llm/semantic-kernel/1_semantic_http_server.ipynb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index 96b8f05d1c..8a15dab8a8 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -367,7 +367,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 5. Delete the deployment and endpoint" + "# 5. Clean up resources" ] }, { @@ -378,6 +378,15 @@ "source": [ "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!az acr repository delete --name {ACR_NAME} --image {ACR_IMAGE_NAME}:latest --yes" + ] } ], "metadata": { From 8245c7415c16c3e5709866cc32a6b28e087b22c9 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 7 Aug 2023 10:21:18 -0700 Subject: [PATCH 14/18] fixes based on comments --- sdk/python/README.md | 4 +- .../langchain/1_langchain_basic_deploy.ipynb | 161 +----------------- .../online/llm/langchain/deployments/env.yml | 2 +- 3 files changed, 6 insertions(+), 161 deletions(-) diff --git a/sdk/python/README.md b/sdk/python/README.md index a2b1691299..330e49b105 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -57,8 +57,8 @@ Test Status is for branch - **_main_** |endpoints|online|[online-endpoints-triton-cc](endpoints/online/custom-container/triton/online-endpoints-triton-cc.ipynb)|Deploy a custom container as an online endpoint. Use web servers other than the default Python Flask server used by Azure ML without losing the benefits of Azure ML's built-in monitoring, scaling, alerting, and authentication.|[![online-endpoints-triton-cc](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-triton-online-endpoints-triton-cc.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-custom-container-triton-online-endpoints-triton-cc.yml)| |endpoints|online|[kubernetes-online-endpoints-safe-rollout](endpoints/online/kubernetes/kubernetes-online-endpoints-safe-rollout.ipynb)|Safely rollout a new version of a web service to production by rolling out the change to a small subset of users/requests before rolling it out completely|[![kubernetes-online-endpoints-safe-rollout](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-safe-rollout.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-safe-rollout.yml)| |endpoints|online|[kubernetes-online-endpoints-simple-deployment](endpoints/online/kubernetes/kubernetes-online-endpoints-simple-deployment.ipynb)|Use an online endpoint to deploy your model, so you don't have to create and manage the underlying infrastructure|[![kubernetes-online-endpoints-simple-deployment](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-simple-deployment.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-kubernetes-kubernetes-online-endpoints-simple-deployment.yml)| -|endpoints|online|[1_langchain_basic_deploy](endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb)|*no description*|[![1_langchain_basic_deploy](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml)| -|endpoints|online|[1_semantic_http_server](endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb)|*no description*|[![1_semantic_http_server](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml)| +|endpoints|online|[1_langchain_basic_deploy](endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb)|Use an online endpoint to deploy a Langchain application, combining the power of LLMs with Azure ML's inferencing management.|[![1_langchain_basic_deploy](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-langchain-1_langchain_basic_deploy.yml)| +|endpoints|online|[1_semantic_http_server](endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb)|Use an online endpoint to deploy a Semantic Kernel application, combining the power of LLMs with Azure ML's inferencing management.|[![1_semantic_http_server](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-llm-semantic-kernel-1_semantic_http_server.yml)| |endpoints|online|[debug-online-endpoints-locally-in-visual-studio-code](endpoints/online/managed/debug-online-endpoints-locally-in-visual-studio-code.ipynb)|*no description* - _This sample is excluded from automated tests_|[![debug-online-endpoints-locally-in-visual-studio-code](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-debug-online-endpoints-locally-in-visual-studio-code.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-debug-online-endpoints-locally-in-visual-studio-code.yml)| |endpoints|online|[online-endpoints-managed-identity-sai](endpoints/online/managed/managed-identities/online-endpoints-managed-identity-sai.ipynb)|*no description*|[![online-endpoints-managed-identity-sai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-sai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-sai.yml)| |endpoints|online|[online-endpoints-managed-identity-uai](endpoints/online/managed/managed-identities/online-endpoints-managed-identity-uai.ipynb)|*no description*|[![online-endpoints-managed-identity-uai](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-uai.yml/badge.svg?branch=main)](https://github.com/Azure/azureml-examples/actions/workflows/sdk-endpoints-online-managed-managed-identities-online-endpoints-managed-identity-uai.yml)| diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 60bcc3dab8..b03b043b50 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -24,7 +24,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 1. Test Locally\n", + "# 1. Setup Variables\n", "Before deploy, you could test the langchain app locally. We are using [Langchain ChatGPT plugin](https://python.langchain.com/en/latest/modules/agents/tools/examples/chatgpt_plugins.html) as an example app here. Execute the code below to try out. You can inspect the [simple_agent_app_test.py](../src/langchain/simple_agent_app_test.py) to see the implementation itself. It's a langchain ZERO_SHOT_REACT_DESCRIPTION agent with Klarna plugin." ] }, @@ -34,8 +34,6 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", - "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", "OPENAI_API_KEY = \"\"\n", "\n", @@ -65,159 +63,6 @@ "%pip install -r requirements.txt" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# uncomment to test the app locally\n", - "# %run -i ../src/langchain/simple_agent_app_test.py" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The test file above is directly running the langchain agent. To deploy to Online Endpoint, let's turn that into a scoring script. You can view the code here: [simple_agent_app_test.py](../src/langchain/simple_agent_app_test.py). We basically create an **init()** and a **run()** function and put the langchain code inside.\n", - "\n", - "You can read more documentation about scoring file here: [How to deploy online endpoint - Understand the scoring script](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-deploy-online-endpoints?view=azureml-api-2&tabs=azure-cli#understand-the-scoring-script)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 1.1 (Optional) Test locally using AzureML local server\n", - "Before we deploy to Online Endpoint, you could test locally first. Azure Machine Learning offers [**azureml-inference-server-http**](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-inference-server-http?view=azureml-api-2) to help. We will\n", - "* Start a subprocess to start the server locally\n", - "* Test the server by sending JSON requests\n", - "* Kill the server\n", - "\n", - "Start the server in a sub process" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "import subprocess\n", - "\n", - "p = subprocess.Popen(\n", - " \"cd ../src/langchain/; azmlinfsrv --entry_script simple_agent_score.py\",\n", - " shell=True,\n", - " stdout=subprocess.PIPE,\n", - ")\n", - "\"\"\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can stream the logs to see what's going on by executing this cell" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "import time\n", - "\n", - "while p.poll() is None:\n", - " # Read one line from the output pipe\n", - " output = p.stdout.readline()\n", - " error = None\n", - " if p.stderr:\n", - " error = p.stderr.readline()\n", - " if output:\n", - " print(output.decode(\"utf-8\").strip())\n", - " if error:\n", - " print(error.decode(\"utf-8\").strip())\n", - " time.sleep(0.1)\n", - "\"\"\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Stop the log cell, now let's call the local server to test" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "import requests, json, time\n", - "from urllib.parse import urlsplit\n", - "\n", - "url = \"http://localhost:5001/score\"\n", - "headers = {\"Content-Type\": \"application/json\"}\n", - "\n", - "payload = json.dumps(\n", - " {\"question\": \"what are the top 5 results for womens t shirts on klarna?\"}\n", - ")\n", - "\n", - "response = requests.post(url, headers=headers, data=payload)\n", - "print(f\"Result:\\n\", response.text)\n", - "\"\"\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You should see response similar to this\n", - "```\n", - " The top 5 results for women's t-shirts on Klarna are: \n", - " 1. Armani Exchange Slim Fit Logo Cotton T-shirt - Black\n", - " 2. Balmain White Printed T-Shirt\n", - " 3. Versace Jeans Logo T-shirt - Black\n", - " 4. Icebreaker Women's Tech Lite II Merino Short Sleeve T-shirt - Grey\n", - " 5. Off-White Logo T-Shirt White\n", - "```" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We are done testing, let's kill the process" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# pkill = subprocess.Popen(\"kill $(lsof -t -i :5001)\", shell=True, stdout=subprocess.PIPE)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since our scoring script is working, let's deploy to online endpoint." - ] - }, { "attachments": {}, "cell_type": "markdown", @@ -337,7 +182,7 @@ ")\n", "\n", "deployment_name = f\"deploy-{str(datetime.datetime.now().strftime('%m%d%H%M%f'))}\"\n", - "sk_deployment = ManagedOnlineDeployment(\n", + "lc_deployment = ManagedOnlineDeployment(\n", " name=deployment_name,\n", " environment=env,\n", " code_configuration=CodeConfiguration(\n", @@ -356,7 +201,7 @@ " instance_type=\"Standard_F2s_v2\",\n", " instance_count=1,\n", ")\n", - "ml_client.online_deployments.begin_create_or_update(sk_deployment).result()\n", + "ml_client.online_deployments.begin_create_or_update(lc_deployment).result()\n", "\n", "endpoint.traffic = {deployment_name: 100}\n", "ml_client.begin_create_or_update(endpoint).result()" diff --git a/sdk/python/endpoints/online/llm/langchain/deployments/env.yml b/sdk/python/endpoints/online/llm/langchain/deployments/env.yml index 34c2e7ad0e..86390f9466 100644 --- a/sdk/python/endpoints/online/llm/langchain/deployments/env.yml +++ b/sdk/python/endpoints/online/llm/langchain/deployments/env.yml @@ -1,4 +1,4 @@ -name: plugin-demo-env +name: llm-demo-env dependencies: - python=3.9 - pip=21.2.4 From 4e22900fe053a24f36384dcebf198c2faacdce1d Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 7 Aug 2023 14:54:25 -0700 Subject: [PATCH 15/18] add keyvault back --- .../langchain/1_langchain_basic_deploy.ipynb | 244 ++++++++++++-- .../online/llm/langchain/requirements.txt | 2 + .../1_semantic_http_server.ipynb | 305 +++++++++++++----- .../online/llm/src/sk/requirements.txt | 1 + 4 files changed, 446 insertions(+), 106 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index b03b043b50..0baaa7eb20 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -15,8 +15,9 @@ "**Motivations** - The Langchain framework allows for rapid development of applications powered by large language models. This sample creates a chat bot application backed by a large language model and deploys the application to AzureML.\n", "\n", "**Outline** - \n", - "1. Test langchain app locally using [**azureml-inference-server-http**](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-inference-server-http?view=azureml-api-2) pacakge.\n", - "2. Deploy the app to an **AzureML Managed Online Endpoint**\n" + "1. Prepare the required resources\n", + "2. Deploy the app to an **AzureML Managed Online Endpoint**\n", + "3. Test\n" ] }, { @@ -24,7 +25,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 1. Setup Variables\n", + "# 1. Connect to Azure Machine Learning\n", "Before deploy, you could test the langchain app locally. We are using [Langchain ChatGPT plugin](https://python.langchain.com/en/latest/modules/agents/tools/examples/chatgpt_plugins.html) as an example app here. Execute the code below to try out. You can inspect the [simple_agent_app_test.py](../src/langchain/simple_agent_app_test.py) to see the implementation itself. It's a langchain ZERO_SHOT_REACT_DESCRIPTION agent with Klarna plugin." ] }, @@ -34,8 +35,10 @@ "metadata": {}, "outputs": [], "source": [ + "import os\n", + "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = \"\"\n", + "OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", @@ -54,6 +57,13 @@ "%env AZURE_OPENAI_API_DEPLOYMENT_NAME=$AZURE_OPENAI_API_DEPLOYMENT_NAME" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 Install required packages" + ] + }, { "cell_type": "code", "execution_count": null, @@ -68,9 +78,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 2. Deploy Langchain App to an Online Endpoint\n", - "\n", - "## 2.1 Preparation" + "### 1.2 Set workspace details" ] }, { @@ -90,7 +98,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Login to your account" + "### 1.3 Login to your Azure account" ] }, { @@ -100,7 +108,11 @@ "outputs": [], "source": [ "# Authenticate clients\n", - "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", + "from azure.identity import (\n", + " DefaultAzureCredential,\n", + " InteractiveBrowserCredential,\n", + " AzureCliCredential\n", + ")\n", "\n", "try:\n", " credential = DefaultAzureCredential(additionally_allowed_tenants=[\"*\"])\n", @@ -117,8 +129,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 3. Manage Online Endpoint\n", - "## 3.1 Create Endpoint" + "# 2. Managed Online Endpoint\n", + "### 2.1 Create Endpoint" ] }, { @@ -153,12 +165,173 @@ "print(endpoint)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 3. Store the API Key in KeyVault\n", + "\n", + "The below code is modelled after the example notebook [online-endpoints-keyvault.ipynb](../../managed/online-endpoints-keyvault.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.1 Import Keyvault Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from azure.mgmt.keyvault import KeyVaultManagementClient\n", + "from azure.keyvault.secrets import SecretClient\n", + "from azure.mgmt.keyvault.models import (\n", + " VaultCreateOrUpdateParameters,\n", + " VaultProperties,\n", + " Sku,\n", + ")\n", + "from azure.mgmt.keyvault.models import AccessPolicyEntry, Permissions, SecretPermissions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Create a Keyvault Management client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "rand = random.randint(0, 10000)\n", + "\n", + "KEYVAULT_NAME = f'aml-llm-demo-kv-{rand}'\n", + "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", + "\n", + "keyvault_mgmt_client = KeyVaultManagementClient(\n", + " credential=credential, subscription_id=SUBSCRIPTION_ID\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3 Get your Object Id\n", + "The `oid` in your JWT access token represents the Object ID of the current user or Service Principal logged into the Azure CLI." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json, base64\n", + "cli_credential = AzureCliCredential()\n", + "token = cli_credential.get_token(\"https://management.azure.com\").token\n", + "user_or_sp_object_id = json.loads(base64.b64decode(token.split(\".\")[1] + \"===\")).get(\n", + " \"oid\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.4 Define an AccessPolicy for the Endpoint and the current user\n", + "\n", + "Allow the endpoint to get secrets in the keyvault and allow all secret permissions for the current user or Service Principal." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "endpoint_access_policy = AccessPolicyEntry(\n", + " tenant_id=endpoint.identity.tenant_id,\n", + " object_id=endpoint.identity.principal_id,\n", + " permissions=Permissions(secrets=[SecretPermissions.GET]),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "user_or_sp_access_policy = AccessPolicyEntry(\n", + " tenant_id=endpoint.identity.tenant_id,\n", + " object_id=user_or_sp_object_id,\n", + " permissions=Permissions(secrets=[SecretPermissions.ALL]),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.5 Create the Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "keyvault = keyvault_mgmt_client.vaults.begin_create_or_update(\n", + " vault_name=KEYVAULT_NAME,\n", + " resource_group_name=RESOURCE_GROUP,\n", + " parameters=VaultCreateOrUpdateParameters(\n", + " location=endpoint.location,\n", + " properties=VaultProperties(\n", + " tenant_id=endpoint.identity.tenant_id,\n", + " sku=Sku(name=\"Standard\", family=\"A\"),\n", + " access_policies=[endpoint_access_policy, user_or_sp_access_policy],\n", + " ),\n", + " ),\n", + ").result()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.6 Add your OPENAI_API_KEY to the Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", + "\n", + "secret_client = SecretClient(\n", + " credential=credential, vault_url=KEYVAULT_URL\n", + ")\n", + "secret = secret_client.set_secret(name=KV_OPENAI_KEY, value=OPENAI_API_KEY)" + ] + }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "## 3.2 Deploy to Endpoint" + "# 4. Deploy to Endpoint" ] }, { @@ -176,6 +349,8 @@ " CodeConfiguration,\n", ")\n", "\n", + "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", + "\n", "env = Environment(\n", " conda_file=\"deployments/env.yml\",\n", " image=\"mcr.microsoft.com/azureml/minimal-ubuntu20.04-py38-cpu-inference:latest\",\n", @@ -190,7 +365,7 @@ " ),\n", " request_settings=OnlineRequestSettings(request_timeout_ms=60000),\n", " environment_variables={\n", - " \"OPENAI_API_KEY\": OPENAI_API_KEY,\n", + " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", " \"OPENAI_ORG_ID\": OPENAI_ORG_ID,\n", @@ -212,8 +387,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 4. Test\n", - "Now endpoint has been deployed, let's test it. We are going to re-use the same request when we test it locally earlier on." + "# 5. Test\n", + "Now endpoint has been deployed, let's test it." ] }, { @@ -242,7 +417,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 5. Delete the deployment and endpoint" + "# 6. Clean up resources" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 6.1 Delete the endpoint" ] }, { @@ -253,13 +435,37 @@ "source": [ "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 6.2 Delete the Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "." + ] + } + ], + "source": [ + "keyvault_mgmt_client.vaults.delete(RESOURCE_GROUP, KEYVAULT_NAME)" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.10 - SDK V2", + "display_name": "Python 3", "language": "python", - "name": "python310-sdkv2" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -271,7 +477,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.11.3" } }, "nbformat": 4, diff --git a/sdk/python/endpoints/online/llm/langchain/requirements.txt b/sdk/python/endpoints/online/llm/langchain/requirements.txt index 52adcf79d9..bfa8396ecf 100644 --- a/sdk/python/endpoints/online/llm/langchain/requirements.txt +++ b/sdk/python/endpoints/online/llm/langchain/requirements.txt @@ -3,6 +3,8 @@ azure-core==1.26.4 azure-identity==1.13.0b3 azureml-inference-server-http azure-keyvault-secrets +azure-mgmt-keyvault +azure-keyvault azure-search-documents==11.4.0b3 langchain==0.0.164 openai==0.27.6 diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index 8a15dab8a8..d15cd3bf13 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -19,10 +19,9 @@ "Managed online endpoints provide an easy to manage inferencing server for your ML workload. It's perfect for LLM based applications. Since we need a REST service, we won't use the default endpoint docker image, we will create a custom docker image instead.\n", "\n", "**Outline** - \n", - "1. Test SemanticKernelHttpServe locally\n", - "2. Prepare Dependencies\n", - "3. Deploy to Managed Online Endpoint\n", - "4. Test" + "1. Prepare Dependencies\n", + "2. Deploy to Managed Online Endpoint\n", + "3. Test" ] }, { @@ -30,8 +29,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 1. Test SemanticKernelHttpServer Locally\n", - "Before we proceed, let's startup the server and test locally first. Grab your OpenAI infor and fill in the variables below" + "# 1. Connect to Azure Machine Learning" ] }, { @@ -40,8 +38,10 @@ "metadata": {}, "outputs": [], "source": [ + "import os\n", + "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = \"\"\n", + "OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", @@ -68,74 +68,10 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# uncomment to test and start the server locally\n", - "# %run -i ../src/sk/app.py" - ] - }, - { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "## 1.1 Test the server API\n", - "Now the server is running, since the Jupyter notebook kernal is blocked.\n", - "You could use postman to test. If you don't have postman, you could also open a terminal and execute the curl commands below to try. \n", - "```\n", - "curl -i -X POST -H \"Content-Type: application/json\" -d \"{\\\"value\\\": \\\"Tomorrow is Valentine day. I need to come up with a few date ideas. She speaks French so write it in French.\\\"}\" http://127.0.0.1:5001/planner/createplan\n", - "```\n", - "You should be seeing resposes like\n", - "```\n", - "{\n", - " \"input\": \"Valentine's Day Date Ideas\",\n", - " \"subtasks\": [\n", - " {\"function\": \"WriterSkill.Brainstorm\"},\n", - " {\"function\": \"WriterSkill.EmailTo\", \"args\": {\"to\": \"significant_other\"}},\n", - " {\"function\": \"WriterSkill.Translate\", \"args\": {\"language\": \"French\"}}\n", - " ]\n", - "}\n", - "```\n", - "\n", - "Then you could execute this plan\n", - "```\n", - "curl -i -X POST -H \"Content-Type: application/json\" -d \"{\\\"input\\\": \\\"Valentine's Day Date Ideas\\\", \\\"subtasks\\\": [{\\\"function\\\": \\\"WriterSkill.Brainstorm\\\"},{\\\"function\\\": \\\"WriterSkill.EmailTo\\\", \\\"args\\\": {\\\"to\\\": \\\"significant_other\\\"}},{\\\"function\\\": \\\"WriterSkill.Translate\\\", \\\"args\\\": {\\\"language\\\": \\\"French\\\"}}]}\" http://127.0.0.1:5001/planner/executeplan\n", - "```\n", - "You should see responses like \n", - "```\n", - "Assurez-vous d'utiliser uniquement le français.\n", - "\n", - "Cher(e) partenaire,\n", - "\n", - "Je pensais à des activités amusantes et romantiques que nous pourrions faire ensemble et j'ai eu quelques idées. Nous pourrions avoir un dîner romantique dans un restaurant chic, ou faire un pique-nique dans le parc. Une autre idée est de faire une soirée cinéma à la maison avec du popcorn fait maison, ou aller pour un massage en couple dans un spa. Nous pourrions également essayer une dégustation de vin dans un vignoble local, ou aller patiner sur glace dans une patinoire à proximité. Si nous sommes d'humeur aventureuse, nous pourrions prendre un cours de cuisine ensemble, ou faire un tour en montgolfière au lever ou au coucher du soleil. Pour une expérience plus culturelle, nous pourrions visiter un musée ou une galerie d'art, ou faire une randonnée ou une promenade panoramique.\n", - "\n", - "Faites-moi savoir ce que vous en pensez !\n", - "\n", - "Merci,\n", - "[Votre nom]\n", - "```\n", - "\n", - "Great! Now our server and plugin are both working well locally. Let's deploy to AML so our team members could try out too." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 2. Deploy Server to AML Managed Online Endpoint\n", - "On a high level, we will perform the following tasks:\n", - "\n", - "* **Preparation**\n", - " * Create docker image in Azure Container Registry\n", - "* **Create Managed Online Endpoint**, grant the endpoint permission to access the resources above.\n", - "* **Deploy to Managed Online Endpoint**, now we are ready deploy the code\n", - "* **Test**\n", - "\n", - "## 2.1. Preparation" + "### 1.1 Set workspace details" ] }, { @@ -151,11 +87,10 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "Let's login first" + "### 1.2 Login to your Azure account" ] }, { @@ -164,8 +99,11 @@ "metadata": {}, "outputs": [], "source": [ - "# Authenticate clients\n", - "from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential\n", + "from azure.identity import (\n", + " DefaultAzureCredential,\n", + " InteractiveBrowserCredential,\n", + " AzureCliCredential\n", + ")\n", "\n", "try:\n", " credential = DefaultAzureCredential(additionally_allowed_tenants=[\"*\"])\n", @@ -182,7 +120,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.2 Create Container Registry and Docker Image" + "### 1.3 Create Container Registry and Docker Image" ] }, { @@ -213,19 +151,18 @@ "metadata": {}, "outputs": [], "source": [ - "# Build the image in your ACR\n", + "# Build the image in your ACR image\n", "ACR_IMAGE_NAME = \"serving\"\n", "\n", "!az acr build --image {ACR_IMAGE_NAME} --registry {ACR_NAME} ./environment/serving/. --resource-group {RESOURCE_GROUP}" ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "## 3. Manage Online Endpoint\n", - "### 3.1 Create Endpoint" + "# 2. Managed Online Endpoint\n", + "### 2.1 Create Endpoint" ] }, { @@ -259,12 +196,173 @@ "print(endpoint)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 3. Store the API Key in KeyVault\n", + "\n", + "The below code is modelled after the example notebook [online-endpoints-keyvault.ipynb](../../managed/online-endpoints-keyvault.ipynb)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.1 Import Keyvault Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from azure.mgmt.keyvault import KeyVaultManagementClient\n", + "from azure.keyvault.secrets import SecretClient\n", + "from azure.mgmt.keyvault.models import (\n", + " VaultCreateOrUpdateParameters,\n", + " VaultProperties,\n", + " Sku,\n", + ")\n", + "from azure.mgmt.keyvault.models import AccessPolicyEntry, Permissions, SecretPermissions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Create a Keyvault Management client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "rand = random.randint(0, 10000)\n", + "\n", + "KEYVAULT_NAME = f'aml-llm-demo-kv-{rand}'\n", + "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", + "\n", + "keyvault_mgmt_client = KeyVaultManagementClient(\n", + " credential=credential, subscription_id=SUBSCRIPTION_ID\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3 Get your Object Id\n", + "The `oid` in your JWT access token represents the Object ID of the current user or Service Principal logged into the Azure CLI." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json, base64\n", + "cli_credential = AzureCliCredential()\n", + "token = cli_credential.get_token(\"https://management.azure.com\").token\n", + "user_or_sp_object_id = json.loads(base64.b64decode(token.split(\".\")[1] + \"===\")).get(\n", + " \"oid\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.4 Define an AccessPolicy for the Endpoint and the current user\n", + "\n", + "Allow the endpoint to get secrets in the keyvault and allow all secret permissions for the current user or Service Principal." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "endpoint_access_policy = AccessPolicyEntry(\n", + " tenant_id=endpoint.identity.tenant_id,\n", + " object_id=endpoint.identity.principal_id,\n", + " permissions=Permissions(secrets=[SecretPermissions.GET]),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "user_or_sp_access_policy = AccessPolicyEntry(\n", + " tenant_id=endpoint.identity.tenant_id,\n", + " object_id=user_or_sp_object_id,\n", + " permissions=Permissions(secrets=[SecretPermissions.ALL]),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.5 Create the Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "keyvault = keyvault_mgmt_client.vaults.begin_create_or_update(\n", + " vault_name=KEYVAULT_NAME,\n", + " resource_group_name=RESOURCE_GROUP,\n", + " parameters=VaultCreateOrUpdateParameters(\n", + " location=endpoint.location,\n", + " properties=VaultProperties(\n", + " tenant_id=endpoint.identity.tenant_id,\n", + " sku=Sku(name=\"Standard\", family=\"A\"),\n", + " access_policies=[endpoint_access_policy, user_or_sp_access_policy],\n", + " ),\n", + " ),\n", + ").result()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.6 Add your OPENAI_API_KEY to the Keyvault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", + "\n", + "secret_client = SecretClient(\n", + " credential=credential, vault_url=KEYVAULT_URL\n", + ")\n", + "secret = secret_client.set_secret(name=KV_OPENAI_KEY, value=OPENAI_API_KEY)" + ] + }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "### 3.3 Deploy to Endpoint" + "# 4. Deploy to the Endpoint" ] }, { @@ -299,7 +397,7 @@ " ),\n", " environment_variables={\n", " \"AZUREML_SERVING_ENTRYPOINT\": \"src/sk/entry.sh\",\n", - " \"OPENAI_API_KEY\": OPENAI_API_KEY,\n", + " \"OPENAI_API_KEY\": f\"keyvaultref:{KEYVAULT_URL}/secrets/{KV_OPENAI_KEY}\",\n", " \"OPENAI_API_TYPE\": OPENAI_API_TYPE,\n", " \"OPENAI_MODEL_ID\": OPENAI_MODEL_ID,\n", " \"OPENAI_ORG_ID\": OPENAI_ORG_ID,\n", @@ -322,8 +420,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 4. Test\n", - "Now endpoint has been deployed, let's test it. We are going to re-use the same request when we test it locally earlier on." + "# 5. Test\n", + "Now endpoint has been deployed, let's test it." ] }, { @@ -367,7 +465,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 5. Clean up resources" + "# 6. Clean up resources\n", + "\n", + "### 6.1 Delete the endpoint" ] }, { @@ -379,6 +479,13 @@ "ml_client.online_endpoints.begin_delete(name=online_endpoint_name)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 6.2 Delete the ACR Image" + ] + }, { "cell_type": "code", "execution_count": null, @@ -387,6 +494,30 @@ "source": [ "!az acr repository delete --name {ACR_NAME} --image {ACR_IMAGE_NAME}:latest --yes" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 6.3 Delete the KeyVault" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "." + ] + } + ], + "source": [ + "keyvault_mgmt_client.vaults.delete(RESOURCE_GROUP, KEYVAULT_NAME)" + ] } ], "metadata": { @@ -405,7 +536,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.11.3" } }, "nbformat": 4, diff --git a/sdk/python/endpoints/online/llm/src/sk/requirements.txt b/sdk/python/endpoints/online/llm/src/sk/requirements.txt index 23db126346..e015afdce8 100644 --- a/sdk/python/endpoints/online/llm/src/sk/requirements.txt +++ b/sdk/python/endpoints/online/llm/src/sk/requirements.txt @@ -3,6 +3,7 @@ semantic_kernel==0.2.9.dev0 flask[async] azure-keyvault azure-keyvault-secrets +azure-mgmt-keyvault azure-ai-ml==1.5.0 pyyaml azure-cli \ No newline at end of file From 04256f459d39a697752d44155f923033b19eb833 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 7 Aug 2023 15:05:38 -0700 Subject: [PATCH 16/18] reformat --- .../llm/langchain/1_langchain_basic_deploy.ipynb | 12 ++++++------ .../llm/semantic-kernel/1_semantic_http_server.ipynb | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 0baaa7eb20..0c485c0ceb 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -38,7 +38,7 @@ "import os\n", "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')\n", + "OPENAI_API_KEY = os.environ.get(\"OPENAI_API_KEY\")\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", @@ -111,7 +111,7 @@ "from azure.identity import (\n", " DefaultAzureCredential,\n", " InteractiveBrowserCredential,\n", - " AzureCliCredential\n", + " AzureCliCredential,\n", ")\n", "\n", "try:\n", @@ -211,9 +211,10 @@ "outputs": [], "source": [ "import random\n", + "\n", "rand = random.randint(0, 10000)\n", "\n", - "KEYVAULT_NAME = f'aml-llm-demo-kv-{rand}'\n", + "KEYVAULT_NAME = f\"aml-llm-demo-kv-{rand}\"\n", "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", "\n", "keyvault_mgmt_client = KeyVaultManagementClient(\n", @@ -236,6 +237,7 @@ "outputs": [], "source": [ "import json, base64\n", + "\n", "cli_credential = AzureCliCredential()\n", "token = cli_credential.get_token(\"https://management.azure.com\").token\n", "user_or_sp_object_id = json.loads(base64.b64decode(token.split(\".\")[1] + \"===\")).get(\n", @@ -320,9 +322,7 @@ "source": [ "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", "\n", - "secret_client = SecretClient(\n", - " credential=credential, vault_url=KEYVAULT_URL\n", - ")\n", + "secret_client = SecretClient(credential=credential, vault_url=KEYVAULT_URL)\n", "secret = secret_client.set_secret(name=KV_OPENAI_KEY, value=OPENAI_API_KEY)" ] }, diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index d15cd3bf13..c4722f2f7d 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -41,7 +41,7 @@ "import os\n", "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')\n", + "OPENAI_API_KEY = os.environ.get(\"OPENAI_API_KEY\")\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", @@ -102,7 +102,7 @@ "from azure.identity import (\n", " DefaultAzureCredential,\n", " InteractiveBrowserCredential,\n", - " AzureCliCredential\n", + " AzureCliCredential,\n", ")\n", "\n", "try:\n", @@ -242,9 +242,10 @@ "outputs": [], "source": [ "import random\n", + "\n", "rand = random.randint(0, 10000)\n", "\n", - "KEYVAULT_NAME = f'aml-llm-demo-kv-{rand}'\n", + "KEYVAULT_NAME = f\"aml-llm-demo-kv-{rand}\"\n", "KV_OPENAI_KEY = \"OPENAI-API-KEY\"\n", "\n", "keyvault_mgmt_client = KeyVaultManagementClient(\n", @@ -267,6 +268,7 @@ "outputs": [], "source": [ "import json, base64\n", + "\n", "cli_credential = AzureCliCredential()\n", "token = cli_credential.get_token(\"https://management.azure.com\").token\n", "user_or_sp_object_id = json.loads(base64.b64decode(token.split(\".\")[1] + \"===\")).get(\n", @@ -351,9 +353,7 @@ "source": [ "KEYVAULT_URL = f\"https://{KEYVAULT_NAME}.vault.azure.net\"\n", "\n", - "secret_client = SecretClient(\n", - " credential=credential, vault_url=KEYVAULT_URL\n", - ")\n", + "secret_client = SecretClient(credential=credential, vault_url=KEYVAULT_URL)\n", "secret = secret_client.set_secret(name=KV_OPENAI_KEY, value=OPENAI_API_KEY)" ] }, From 73dfb281e5133eafd4dc5c0ca2d0348960f6bc4e Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 7 Aug 2023 15:24:46 -0700 Subject: [PATCH 17/18] fixes --- .../online/llm/langchain/1_langchain_basic_deploy.ipynb | 4 +--- .../online/llm/semantic-kernel/1_semantic_http_server.ipynb | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb index 0c485c0ceb..d2639f9302 100644 --- a/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb +++ b/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb @@ -35,10 +35,8 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", - "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = os.environ.get(\"OPENAI_API_KEY\")\n", + "OPENAI_API_KEY = \"\"\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index c4722f2f7d..42cb1f21fa 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -38,10 +38,8 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", - "\n", "OPENAI_API_TYPE = \"openai\" # 'azure' or 'openai'\n", - "OPENAI_API_KEY = os.environ.get(\"OPENAI_API_KEY\")\n", + "OPENAI_API_KEY = \"\"\n", "\n", "# required for OpenAI API\n", "OPENAI_ORG_ID = \"\"\n", From 0b09cd3f6ce8440ba98af0bd1599509e40ec8681 Mon Sep 17 00:00:00 2001 From: Vanessa Arndorfer Date: Mon, 7 Aug 2023 15:47:22 -0700 Subject: [PATCH 18/18] remove user flag meant for testing --- .../online/llm/semantic-kernel/1_semantic_http_server.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb index 42cb1f21fa..7f00002cb4 100644 --- a/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb +++ b/sdk/python/endpoints/online/llm/semantic-kernel/1_semantic_http_server.ipynb @@ -62,7 +62,7 @@ "%env IS_CHAT_COMPLETION=$IS_CHAT_COMPLETION\n", "\n", "# Install python dependencies\n", - "%pip install -r ../src/sk/requirements.txt --user" + "%pip install -r ../src/sk/requirements.txt" ] }, {