From 54c883412c91bb0b051310b86199e4d24dab21b3 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Tue, 16 Oct 2018 16:49:41 -0500 Subject: [PATCH 01/25] add test service --- .../how-to-deploy-to-aci.py | 172 ++++++++++++++++++ .../sklearn_mnist_model.pkl | Bin 0 -> 63684 bytes 2 files changed, 172 insertions(+) create mode 100644 docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py create mode 100644 docs/how-to-deploy-to-aci/sklearn_mnist_model.pkl diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py new file mode 100644 index 000000000..bd57a98e4 --- /dev/null +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# coding: utf-8 + +import azureml.core +print('SDK version' + azureml.core.VERSION) + +# PREREQ: load workspace info +# import azureml.core +# +from azureml.core import Workspace +ws = Workspace.from_config() +# + +scorepy_content = "import json\nimport numpy as np\nimport os\nimport pickle\nfrom sklearn.externals import joblib\nfrom sklearn.linear_model import LogisticRegression\n\nfrom azureml.core.model import Model\n\ndef init():\n global model\n # retreive the path to the model file using the model name\n model_path = Model.get_model_path('sklearn_mnist')\n model = joblib.load(model_path)\n\ndef run(raw_data):\n data = np.array(json.loads(raw_data)['data'])\n # make prediction\n y_hat = model.predict(data)\n return json.dumps(y_hat.tolist())" +print(scorepy_content) +with open("score.py","w") as f: + f.write(scorepy_content) + + +# PREREQ: create environment file +from azureml.core.conda_dependencies import CondaDependencies + +myenv = CondaDependencies() +myenv.add_conda_package("scikit-learn") + +with open("myenv.yml","w") as f: + f.write(myenv.serialize_to_string()) + +# +from azureml.core.image import ContainerImage + +image_config = ContainerImage.image_configuration(execution_script = "score.py", + runtime = "python", + conda_file = "myenv.yml", + description = "Image with mnist model", + tags = {"data": "mnist", "type": "classification"} + ) +# + +# +from azureml.core.webservice import AciWebservice + +aciconfig = AciWebservice.deploy_configuration(cpu_cores = 1, + memory_gb = 1, + tags = {"data": "mnist", "type": "classification"}, + description = 'Handwriting recognition') +# + +# +from azureml.core.model import Model + +model_name = "sklearn_mnist" +model = Model.register(model_path = "sklearn_mnist_model.pkl", + model_name = model_name, + tags = {"data": "mnist", "type": "classification"}, + description = "Mnist handwriting recognition", + workspace = ws) +# + +# +from azureml.core.model import Model + +model_name = "sklearn_mnist" +model=Model(ws, model_name) +# + + +# ## DEPLOY FROM REGISTERED MODEL + +# +from azureml.core.webservice import Webservice + +service_name = 'aci-mnist-2' +service = Webservice.deploy_from_model(deployment_config = aciconfig, + image_config = image_config, + models = [model], # this is the registered model object + name = service_name, + workspace = ws) +service.wait_for_deployment(show_output = True) +print(service.state) +# + +service.delete() + +# ## DEPLOY FROM IMAGE + + +# +from azureml.core.image import ContainerImage + +image = ContainerImage.create(name = "myimage1", + models = [model], # this is the registered model object + image_config = image_config, + workspace = ws) + +image.wait_for_creation(show_output = True) +# + +# +from azureml.core.webservice import Webservice + +service_name = 'aci-mnist-13' +service = Webservice.deploy_from_image(deployment_config = aciconfig, + image = image, + name = service_name, + workspace = ws) +service.wait_for_deployment(show_output = True) +print(service.state) +# + +service.delete() + + +# ## DEPLOY FROM MODEL FILE +# First change score.py! + + + +scorepy_content = "import json\nimport numpy as np\nimport os\nimport pickle\nfrom sklearn.externals import joblib\nfrom sklearn.linear_model import LogisticRegression\n\nfrom azureml.core.model import Model\n\ndef init():\n global model\n # retreive the path to the model file using the model name\n model_path = Model.get_model_path('sklearn_mnist_model.pkl')\n model = joblib.load(model_path)\n\ndef run(raw_data):\n data = np.array(json.loads(raw_data)['data'])\n # make prediction\n y_hat = model.predict(data)\n return json.dumps(y_hat.tolist())" +with open("score.py","w") as f: + f.write(scorepy_content) + + + +# +from azureml.core.webservice import Webservice + +service_name = 'aci-mnist-1' +service = Webservice.deploy(deployment_config = aciconfig, + image_config = image_config, + model_paths = ['sklearn_mnist_model.pkl'], + name = service_name, + workspace = ws) + +service.wait_for_deployment(show_output = True) +print(service.state) +# + +# +# Load Data +import os +import urllib + +os.makedirs('./data', exist_ok = True) + +urllib.request.urlretrieve('http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz', filename = './data/test-images.gz') + +from utils import load_data +X_test = load_data('./data/test-images.gz', False) / 255.0 + +from sklearn import datasets +import numpy as np +import json + +# find 5 random samples from test set +n = 5 +sample_indices = np.random.permutation(X_test.shape[0])[0:n] + +test_samples = json.dumps({"data": X_test[sample_indices].tolist()}) +test_samples = bytes(test_samples, encoding = 'utf8') + +# predict using the deployed model +prediction = service.run(input_data = test_samples) +print(prediction) +# + +service.delete() + + + + + diff --git a/docs/how-to-deploy-to-aci/sklearn_mnist_model.pkl b/docs/how-to-deploy-to-aci/sklearn_mnist_model.pkl new file mode 100644 index 0000000000000000000000000000000000000000..135dd09ec8b00338ca7f62ce23142b2fdd055ea4 GIT binary patch literal 63684 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 literal 0 HcmV?d00001 From 53199d17defa8f2908fcf15fc549b573e0059fb1 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Tue, 16 Oct 2018 16:54:08 -0500 Subject: [PATCH 02/25] add delete --- docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py index bd57a98e4..0ff289d2c 100644 --- a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -164,8 +164,9 @@ print(prediction) # +# service.delete() - +# From ce3214b7c6af8b114473311bc6b2b481cc479d35 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Tue, 16 Oct 2018 17:33:24 -0500 Subject: [PATCH 03/25] fix name --- .../how-to-deploy-to-aci.py | 4 +-- docs/how-to-deploy-to-aci/utils.py | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 docs/how-to-deploy-to-aci/utils.py diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py index 0ff289d2c..13252ddd8 100644 --- a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -6,10 +6,10 @@ # PREREQ: load workspace info # import azureml.core -# +# from azureml.core import Workspace ws = Workspace.from_config() -# +# scorepy_content = "import json\nimport numpy as np\nimport os\nimport pickle\nfrom sklearn.externals import joblib\nfrom sklearn.linear_model import LogisticRegression\n\nfrom azureml.core.model import Model\n\ndef init():\n global model\n # retreive the path to the model file using the model name\n model_path = Model.get_model_path('sklearn_mnist')\n model = joblib.load(model_path)\n\ndef run(raw_data):\n data = np.array(json.loads(raw_data)['data'])\n # make prediction\n y_hat = model.predict(data)\n return json.dumps(y_hat.tolist())" print(scorepy_content) diff --git a/docs/how-to-deploy-to-aci/utils.py b/docs/how-to-deploy-to-aci/utils.py new file mode 100644 index 000000000..98170adae --- /dev/null +++ b/docs/how-to-deploy-to-aci/utils.py @@ -0,0 +1,27 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import gzip +import numpy as np +import struct + + +# load compressed MNIST gz files and return numpy arrays +def load_data(filename, label=False): + with gzip.open(filename) as gz: + struct.unpack('I', gz.read(4)) + n_items = struct.unpack('>I', gz.read(4)) + if not label: + n_rows = struct.unpack('>I', gz.read(4))[0] + n_cols = struct.unpack('>I', gz.read(4))[0] + res = np.frombuffer(gz.read(n_items[0] * n_rows * n_cols), dtype=np.uint8) + res = res.reshape(n_items[0], n_rows * n_cols) + else: + res = np.frombuffer(gz.read(n_items[0]), dtype=np.uint8) + res = res.reshape(n_items[0], 1) + return res + + +# one-hot encode a 1-D array +def one_hot_encode(array, num_of_classes): + return np.eye(num_of_classes)[array.reshape(-1)] From 96c59d5c2b966d7f849a702ea344cb3c63da5e13 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Wed, 17 Oct 2018 09:56:04 -0500 Subject: [PATCH 04/25] testing --- docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py index 13252ddd8..102ee7ac9 100644 --- a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -6,10 +6,10 @@ # PREREQ: load workspace info # import azureml.core -# +#region load-workspace from azureml.core import Workspace ws = Workspace.from_config() -# +#endregion scorepy_content = "import json\nimport numpy as np\nimport os\nimport pickle\nfrom sklearn.externals import joblib\nfrom sklearn.linear_model import LogisticRegression\n\nfrom azureml.core.model import Model\n\ndef init():\n global model\n # retreive the path to the model file using the model name\n model_path = Model.get_model_path('sklearn_mnist')\n model = joblib.load(model_path)\n\ndef run(raw_data):\n data = np.array(json.loads(raw_data)['data'])\n # make prediction\n y_hat = model.predict(data)\n return json.dumps(y_hat.tolist())" print(scorepy_content) @@ -26,7 +26,7 @@ with open("myenv.yml","w") as f: f.write(myenv.serialize_to_string()) -# +#Region config-image from azureml.core.image import ContainerImage image_config = ContainerImage.image_configuration(execution_script = "score.py", @@ -35,7 +35,7 @@ description = "Image with mnist model", tags = {"data": "mnist", "type": "classification"} ) -# +#End Region # from azureml.core.webservice import AciWebservice @@ -46,7 +46,7 @@ description = 'Handwriting recognition') # -# +# from azureml.core.model import Model model_name = "sklearn_mnist" @@ -55,7 +55,7 @@ tags = {"data": "mnist", "type": "classification"}, description = "Mnist handwriting recognition", workspace = ws) -# +# # from azureml.core.model import Model From 111f5e8d733ad9c42305a5ae66fd64d085be60b1 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Wed, 17 Oct 2018 10:46:33 -0500 Subject: [PATCH 05/25] playing around --- docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py index 102ee7ac9..b6bce7836 100644 --- a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -6,10 +6,11 @@ # PREREQ: load workspace info # import azureml.core -#region load-workspace + +# from azureml.core import Workspace ws = Workspace.from_config() -#endregion +# scorepy_content = "import json\nimport numpy as np\nimport os\nimport pickle\nfrom sklearn.externals import joblib\nfrom sklearn.linear_model import LogisticRegression\n\nfrom azureml.core.model import Model\n\ndef init():\n global model\n # retreive the path to the model file using the model name\n model_path = Model.get_model_path('sklearn_mnist')\n model = joblib.load(model_path)\n\ndef run(raw_data):\n data = np.array(json.loads(raw_data)['data'])\n # make prediction\n y_hat = model.predict(data)\n return json.dumps(y_hat.tolist())" print(scorepy_content) @@ -26,7 +27,7 @@ with open("myenv.yml","w") as f: f.write(myenv.serialize_to_string()) -#Region config-image +# # from azureml.core.webservice import AciWebservice From 3f531fd211250b9ac0ff329f41fd51cd2d753e55 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Wed, 17 Oct 2018 11:09:46 -0500 Subject: [PATCH 06/25] try camelCase --- docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py index b6bce7836..5744ae739 100644 --- a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -7,10 +7,10 @@ # PREREQ: load workspace info # import azureml.core -# +# from azureml.core import Workspace ws = Workspace.from_config() -# +# scorepy_content = "import json\nimport numpy as np\nimport os\nimport pickle\nfrom sklearn.externals import joblib\nfrom sklearn.linear_model import LogisticRegression\n\nfrom azureml.core.model import Model\n\ndef init():\n global model\n # retreive the path to the model file using the model name\n model_path = Model.get_model_path('sklearn_mnist')\n model = joblib.load(model_path)\n\ndef run(raw_data):\n data = np.array(json.loads(raw_data)['data'])\n # make prediction\n y_hat = model.predict(data)\n return json.dumps(y_hat.tolist())" print(scorepy_content) From 361b57ed29b5c49610a6acc72efd3987c2abf651 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Wed, 17 Oct 2018 11:47:09 -0500 Subject: [PATCH 07/25] change all names to camelCase --- .../how-to-deploy-to-aci.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py index 5744ae739..76ec5f8f5 100644 --- a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py +++ b/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py @@ -27,7 +27,7 @@ with open("myenv.yml","w") as f: f.write(myenv.serialize_to_string()) -# from azureml.core.image import ContainerImage image_config = ContainerImage.image_configuration(execution_script = "score.py", @@ -36,18 +36,18 @@ description = "Image with mnist model", tags = {"data": "mnist", "type": "classification"} ) -# +# -# +# from azureml.core.webservice import AciWebservice aciconfig = AciWebservice.deploy_configuration(cpu_cores = 1, memory_gb = 1, tags = {"data": "mnist", "type": "classification"}, description = 'Handwriting recognition') -# +# -# +# from azureml.core.model import Model model_name = "sklearn_mnist" @@ -56,19 +56,19 @@ tags = {"data": "mnist", "type": "classification"}, description = "Mnist handwriting recognition", workspace = ws) -# +# -# +# from azureml.core.model import Model model_name = "sklearn_mnist" model=Model(ws, model_name) -# +# # ## DEPLOY FROM REGISTERED MODEL -# +# from azureml.core.webservice import Webservice service_name = 'aci-mnist-2' @@ -79,14 +79,14 @@ workspace = ws) service.wait_for_deployment(show_output = True) print(service.state) -# +# service.delete() # ## DEPLOY FROM IMAGE -# +# from azureml.core.image import ContainerImage image = ContainerImage.create(name = "myimage1", @@ -95,9 +95,9 @@ workspace = ws) image.wait_for_creation(show_output = True) -# +# -# +# from azureml.core.webservice import Webservice service_name = 'aci-mnist-13' @@ -107,7 +107,7 @@ workspace = ws) service.wait_for_deployment(show_output = True) print(service.state) -# +# service.delete() @@ -123,7 +123,7 @@ -# +# from azureml.core.webservice import Webservice service_name = 'aci-mnist-1' @@ -135,9 +135,9 @@ service.wait_for_deployment(show_output = True) print(service.state) -# +# -# +# # Load Data import os import urllib @@ -163,11 +163,11 @@ # predict using the deployed model prediction = service.run(input_data = test_samples) print(prediction) -# +# -# +# service.delete() -# +# From 23189c6f40e2f56e97fe4d5acbe1c808507bf6a0 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Wed, 17 Oct 2018 16:24:46 -0500 Subject: [PATCH 08/25] move folder --- .../how-to-deploy-to-aci/how-to-deploy-to-aci.py | 0 .../how-to-deploy-to-aci/sklearn_mnist_model.pkl | Bin .../doc-qa}/how-to-deploy-to-aci/utils.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {docs => ignore/doc-qa}/how-to-deploy-to-aci/how-to-deploy-to-aci.py (100%) rename {docs => ignore/doc-qa}/how-to-deploy-to-aci/sklearn_mnist_model.pkl (100%) rename {docs => ignore/doc-qa}/how-to-deploy-to-aci/utils.py (100%) diff --git a/docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py b/ignore/doc-qa/how-to-deploy-to-aci/how-to-deploy-to-aci.py similarity index 100% rename from docs/how-to-deploy-to-aci/how-to-deploy-to-aci.py rename to ignore/doc-qa/how-to-deploy-to-aci/how-to-deploy-to-aci.py diff --git a/docs/how-to-deploy-to-aci/sklearn_mnist_model.pkl b/ignore/doc-qa/how-to-deploy-to-aci/sklearn_mnist_model.pkl similarity index 100% rename from docs/how-to-deploy-to-aci/sklearn_mnist_model.pkl rename to ignore/doc-qa/how-to-deploy-to-aci/sklearn_mnist_model.pkl diff --git a/docs/how-to-deploy-to-aci/utils.py b/ignore/doc-qa/how-to-deploy-to-aci/utils.py similarity index 100% rename from docs/how-to-deploy-to-aci/utils.py rename to ignore/doc-qa/how-to-deploy-to-aci/utils.py From 716c6d8bb1d5b1f7f57618efc7afc05db53986e0 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Tue, 6 Nov 2018 11:27:58 -0600 Subject: [PATCH 09/25] add quickstart code --- .../quickstart.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py diff --git a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py new file mode 100644 index 000000000..f0ea8c5a0 --- /dev/null +++ b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py @@ -0,0 +1,55 @@ +# code snippets for the quickstart-create-workspace-with-python article +# +import azureml.core +print(azureml.core.VERSION) +# + +# this is NOT a snippet. If this code changes, go fix it in the article! +from azureml.core import Workspace +ws = Workspace.create(name='myworkspace', + subscription_id='65a1016d-0f67-45d2-b838-b8f373d6d52e', + resource_group='myresourcegroup', + create_resource_group=True, + location='eastus2' # or other supported Azure region + ) + +# +ws.get_details() +# + +# +# Create the configuration file. +ws.write_config() + +# Use this code to load the workspace from +# other scripts and notebooks in this directory. +# ws = Workspace.from_config() +# + +# +from azureml.core import Experiment + +# create a new experiment +exp = Experiment(workspace=ws, name='myexp') + +# start a run +run = exp.start_logging() + +# log a number +run.log('my magic number', 42) + +# log a list (Fibonacci numbers) +run.log_list('my list', [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]) + +# finish the run +run.complete() +# + +# +print(run.get_portal_url()) +# + + +# +ws.delete(delete_dependent_resources=True) +# From e472b54f1bc0a676e98d58d2d259a41132215dae Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Mon, 17 Dec 2018 12:22:40 -0600 Subject: [PATCH 10/25] Update quickstart.py --- .../quickstart-create-workspace-with-python/quickstart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py index f0ea8c5a0..b9895215d 100644 --- a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py +++ b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py @@ -7,7 +7,7 @@ # this is NOT a snippet. If this code changes, go fix it in the article! from azureml.core import Workspace ws = Workspace.create(name='myworkspace', - subscription_id='65a1016d-0f67-45d2-b838-b8f373d6d52e', + subscription_id=' Date: Mon, 17 Dec 2018 12:23:03 -0600 Subject: [PATCH 11/25] Update quickstart.py --- .../quickstart-create-workspace-with-python/quickstart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py index b9895215d..a1a667417 100644 --- a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py +++ b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py @@ -7,7 +7,7 @@ # this is NOT a snippet. If this code changes, go fix it in the article! from azureml.core import Workspace ws = Workspace.create(name='myworkspace', - subscription_id=' Date: Thu, 3 Jan 2019 08:02:35 -0600 Subject: [PATCH 12/25] new code --- .../runconfig.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/runconfig.py diff --git a/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py b/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py new file mode 100644 index 000000000..2c32a003f --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py @@ -0,0 +1,23 @@ +# +from azureml.core.runconfig import RunConfiguration +from azureml.core.conda_dependencies import CondaDependencies + +run_system_managed = RunConfiguration() + +# Specify the conda dependencies with scikit-learn +run_system_managed.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) +# +print(run_system_managed) + + +# +from azureml.core.runconfig import RunConfiguration + +run_user_managed = RunConfiguration() +run_user_managed.environment.python.user_managed_dependencies = True + +# Choose a specific Python environment by pointing to a Python path. For example: +# run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python' +# +print(run_user_managed) + From cc688caa4e250423c65617193490f3e5dd14ec4c Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Thu, 3 Jan 2019 08:53:49 -0600 Subject: [PATCH 13/25] change names --- ignore/doc-qa/how-to-set-up-training-targets/runconfig.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py b/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py index 2c32a003f..ab0fc1e9f 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py @@ -1,4 +1,4 @@ -# +# from azureml.core.runconfig import RunConfiguration from azureml.core.conda_dependencies import CondaDependencies @@ -6,11 +6,11 @@ # Specify the conda dependencies with scikit-learn run_system_managed.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) -# +# print(run_system_managed) -# +# from azureml.core.runconfig import RunConfiguration run_user_managed = RunConfiguration() @@ -18,6 +18,6 @@ # Choose a specific Python environment by pointing to a Python path. For example: # run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python' -# +# print(run_user_managed) From 3c581b533f0e4f79fa53919f891f0602314d9aa6 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Thu, 3 Jan 2019 18:07:12 -0600 Subject: [PATCH 14/25] for local computer --- .../how-to-set-up-training-targets/Local.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/Local.py diff --git a/ignore/doc-qa/how-to-set-up-training-targets/Local.py b/ignore/doc-qa/how-to-set-up-training-targets/Local.py new file mode 100644 index 000000000..545db6a5d --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/Local.py @@ -0,0 +1,42 @@ +# Code for Local computer and Submit training run sections + +# Check core SDK version number +import azureml.core + +print("SDK version:", azureml.core.VERSION) + +# +from azureml.core.runconfig import RunConfiguration + +# Edit a run configuration property on the fly. +run_local = RunConfiguration() + +run_local.environment.python.user_managed_dependencies = True + +# Choose a specific Python environment by pointing to a Python path. For example: +# run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python' +# + +from azureml.core import Workspace +ws = Workspace.from_config() + + +# Set up an experiment +# +from azureml.core import Experiment +experiment_name = 'my_experiment' + +exp = Experiment(workspace=ws, name=experiment_name) +# + +# Submit the experiment using the run configuration +# +from azureml.core import ScriptRunConfig +import os + +script_folder = os.getcwd() +src = ScriptRunConfig(source_directory = script_folder, script = 'train.py', run_config = run_local) +run = exp.submit(src) +run.wait_for_completion(show_output = True) +# + From 80bba4c7ae1f08f537dd88347c0a452ae8f71bdb Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Thu, 3 Jan 2019 18:55:31 -0600 Subject: [PATCH 15/25] code for amlcompute section --- .../amlcompute.py | 48 +++++++++++++ .../amlcompute2.py | 72 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py diff --git a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py new file mode 100644 index 000000000..7ab08e697 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py @@ -0,0 +1,48 @@ +# Code for Azure Machine Learning Compute - Run-based creation + +# Check core SDK version number +import azureml.core + +print("SDK version:", azureml.core.VERSION) + + +from azureml.core import Workspace +ws = Workspace.from_config() + + +# Set up an experiment +from azureml.core import Experiment +experiment_name = 'my-experiment' +script_folder= "./" + +exp = Experiment(workspace=ws, name=experiment_name) + + +# +from azureml.core.compute import ComputeTarget, AmlCompute + +# First, list the supported VM families for Azure Machine Learning Compute +print(AmlCompute.supported_vmsizes(workspace=ws)) + +from azureml.core.runconfig import RunConfiguration +# Create a new runconfig object +run_temp_compute = RunConfiguration() + +# Signal that you want to use AmlCompute to execute the script +run_temp_compute.target = "amlcompute" + +# AmlCompute is created in the same region as your workspace +# Set the VM size for AmlCompute from the list of supported_vmsizes +run_temp_compute.amlcompute.vm_size = 'STANDARD_D2_V2' +# + + +# Submit the experiment using the run configuration +from azureml.core import ScriptRunConfig + +src = ScriptRunConfig(source_directory = script_folder, script = 'train.py', run_config = run_temp_compute) +run = exp.submit(src) +run.wait_for_completion(show_output = True) + + + diff --git a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py new file mode 100644 index 000000000..f8fc9d083 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py @@ -0,0 +1,72 @@ +# Code for Azure Machine Learning Compute - Persistent compute + +# Check core SDK version number +import azureml.core + +print("SDK version:", azureml.core.VERSION) + +from azureml.core import Workspace +ws = Workspace.from_config() + + +# Set up an experiment +from azureml.core import Experiment +experiment_name = 'my-experiment' +script_folder= "./" + +exp = Experiment(workspace=ws, name=experiment_name) + +# +from azureml.core.compute import ComputeTarget, AmlCompute +from azureml.core.compute_target import ComputeTargetException + +# Choose a name for your CPU cluster +cpu_cluster_name = "cpucluster" + +# Verify that cluster does not exist already +try: + cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name) + print('Found existing cluster, use it.') +except ComputeTargetException: + compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_D2_V2', + max_nodes=4) + cpu_cluster = ComputeTarget.create(ws, cpu_cluster_name, compute_config) + +cpu_cluster.wait_for_completion(show_output=True) +# + +# +from azureml.core.runconfig import RunConfiguration +from azureml.core.conda_dependencies import CondaDependencies +from azureml.core.runconfig import DEFAULT_CPU_IMAGE + +# Create a new runconfig object +run_amlcompute = RunConfiguration() + +# Use the cpu_cluster you created above. +run_amlcompute.target = cpu_cluster + +# Enable Docker +run_amlcompute.environment.docker.enabled = True + +# Set Docker base image to the default CPU-based image +run_amlcompute.environment.docker.base_image = DEFAULT_CPU_IMAGE + +# Use conda_dependencies.yml to create a conda environment in the Docker image for execution +run_amlcompute.environment.python.user_managed_dependencies = False + +# Auto-prepare the Docker image when used for execution (if it is not already prepared) +run_amlcompute.auto_prepare_environment = True + +# Specify CondaDependencies obj, add necessary packages +run_amlcompute.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) +# + +# Submit the experiment using the run configuration +# +from azureml.core import ScriptRunConfig + +src = ScriptRunConfig(source_directory = script_folder, script = 'train.py', run_config = run_amlcompute) +run = exp.submit(src) +run.wait_for_completion(show_output = True) +# From 6995c086ffad666e7678cb2fb92db7ddc7723ff2 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Thu, 3 Jan 2019 22:39:06 -0600 Subject: [PATCH 16/25] change snippet names --- ignore/doc-qa/how-to-set-up-training-targets/Local.py | 4 ++-- .../doc-qa/how-to-set-up-training-targets/amlcompute.py | 4 ++-- .../doc-qa/how-to-set-up-training-targets/amlcompute2.py | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/Local.py b/ignore/doc-qa/how-to-set-up-training-targets/Local.py index 545db6a5d..baf0d20d7 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/Local.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/Local.py @@ -5,7 +5,7 @@ print("SDK version:", azureml.core.VERSION) -# +# from azureml.core.runconfig import RunConfiguration # Edit a run configuration property on the fly. @@ -15,7 +15,7 @@ # Choose a specific Python environment by pointing to a Python path. For example: # run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python' -# +# from azureml.core import Workspace ws = Workspace.from_config() diff --git a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py index 7ab08e697..4658aab1a 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute.py @@ -18,7 +18,7 @@ exp = Experiment(workspace=ws, name=experiment_name) -# +# from azureml.core.compute import ComputeTarget, AmlCompute # First, list the supported VM families for Azure Machine Learning Compute @@ -34,7 +34,7 @@ # AmlCompute is created in the same region as your workspace # Set the VM size for AmlCompute from the list of supported_vmsizes run_temp_compute.amlcompute.vm_size = 'STANDARD_D2_V2' -# +# # Submit the experiment using the run configuration diff --git a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py index f8fc9d083..22c14c798 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py @@ -16,7 +16,7 @@ exp = Experiment(workspace=ws, name=experiment_name) -# +# from azureml.core.compute import ComputeTarget, AmlCompute from azureml.core.compute_target import ComputeTargetException @@ -33,9 +33,9 @@ cpu_cluster = ComputeTarget.create(ws, cpu_cluster_name, compute_config) cpu_cluster.wait_for_completion(show_output=True) -# +# -# +# from azureml.core.runconfig import RunConfiguration from azureml.core.conda_dependencies import CondaDependencies from azureml.core.runconfig import DEFAULT_CPU_IMAGE @@ -60,7 +60,7 @@ # Specify CondaDependencies obj, add necessary packages run_amlcompute.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) -# +# # Submit the experiment using the run configuration # From 732eecfc7c4efb60364df7f7dd91d3d28d1669a9 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Fri, 4 Jan 2019 12:45:28 -0600 Subject: [PATCH 17/25] update names --- ignore/doc-qa/how-to-set-up-training-targets/Local.py | 3 --- .../doc-qa/how-to-set-up-training-targets/runconfig.py | 10 ++++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/Local.py b/ignore/doc-qa/how-to-set-up-training-targets/Local.py index baf0d20d7..d9ccfce56 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/Local.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/Local.py @@ -12,9 +12,6 @@ run_local = RunConfiguration() run_local.environment.python.user_managed_dependencies = True - -# Choose a specific Python environment by pointing to a Python path. For example: -# run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python' # from azureml.core import Workspace diff --git a/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py b/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py index ab0fc1e9f..d0f4423ce 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/runconfig.py @@ -1,4 +1,6 @@ -# +# Code for What's a run configuration + +# from azureml.core.runconfig import RunConfiguration from azureml.core.conda_dependencies import CondaDependencies @@ -6,11 +8,11 @@ # Specify the conda dependencies with scikit-learn run_system_managed.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) -# +# print(run_system_managed) -# +# from azureml.core.runconfig import RunConfiguration run_user_managed = RunConfiguration() @@ -18,6 +20,6 @@ # Choose a specific Python environment by pointing to a Python path. For example: # run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python' -# +# print(run_user_managed) From e3a64b1f16e50ccd3da7fe68f9a312e6e4083b28 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Fri, 4 Jan 2019 12:51:11 -0600 Subject: [PATCH 18/25] code for remote vm --- .../how-to-set-up-training-targets/dsvm.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/dsvm.py diff --git a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py new file mode 100644 index 000000000..7196cb988 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py @@ -0,0 +1,28 @@ +# Code for Remote virtual machines + +compute_target_name = "attach-dsvm" + +# +import azureml.core +from azureml.core.runconfig import RunConfiguration, DEFAULT_CPU_IMAGE +from azureml.core.conda_dependencies import CondaDependencies + +run_dsvm = RunConfiguration(framework = "python") + +# Set the compute target to the Linux DSVM +run_dsvm.target = compute_target_name + +# Use Docker in the remote VM +run_dsvm.environment.docker.enabled = True + +# Use the CPU base image +# To use GPU in DSVM, you must also use the GPU base Docker image "azureml.core.runconfig.DEFAULT_GPU_IMAGE" +run_dsvm.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE +print('Base Docker image is:', run_dsvm.environment.docker.base_image) + +# Prepare the Docker and conda environment automatically when they're used for the first time +run_dsvm.prepare_environment = True + +# Specify the CondaDependencies object +run_dsvm.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) +# \ No newline at end of file From 53dbd0afcff723c57704944e70bbed67c68c2d73 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Mon, 7 Jan 2019 11:29:40 -0600 Subject: [PATCH 19/25] hdi run config code --- .amlignore | 7 ++ .vscode/settings.json | 3 + aml_config/conda_dependencies.yml | 15 +++ aml_config/docker.runconfig | 115 ++++++++++++++++++ aml_config/local.runconfig | 115 ++++++++++++++++++ aml_config/project.json | 1 + .../how-to-set-up-training-targets/.amlignore | 7 ++ .../aml_config/conda_dependencies.yml | 15 +++ .../aml_config/docker.runconfig | 115 ++++++++++++++++++ .../aml_config/local.runconfig | 115 ++++++++++++++++++ .../aml_config/project.json | 1 + .../donotupload.py | 40 ++++++ .../how-to-set-up-training-targets/dsvm.py | 2 +- .../how-to-set-up-training-targets/hdi.py | 27 ++++ .../how-to-set-up-training-targets/mylib.py | 9 ++ .../how-to-set-up-training-targets/remote.py | 52 ++++++++ .../how-to-set-up-training-targets/temp.py | 8 ++ .../how-to-set-up-training-targets/train.py | 45 +++++++ 18 files changed, 691 insertions(+), 1 deletion(-) create mode 100644 .amlignore create mode 100644 .vscode/settings.json create mode 100644 aml_config/conda_dependencies.yml create mode 100644 aml_config/docker.runconfig create mode 100644 aml_config/local.runconfig create mode 100644 aml_config/project.json create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/.amlignore create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/donotupload.py create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/hdi.py create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/mylib.py create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/remote.py create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/temp.py create mode 100644 ignore/doc-qa/how-to-set-up-training-targets/train.py diff --git a/.amlignore b/.amlignore new file mode 100644 index 000000000..616345c4d --- /dev/null +++ b/.amlignore @@ -0,0 +1,7 @@ +.ipynb_checkpoints +azureml-logs +.azureml +.git +outputs +azureml-setup +docs diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..94ae80d7a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "C:\\Users\\sgilley\\.azureml\\envs\\jan3\\python.exe" +} \ No newline at end of file diff --git a/aml_config/conda_dependencies.yml b/aml_config/conda_dependencies.yml new file mode 100644 index 000000000..5e49a89d6 --- /dev/null +++ b/aml_config/conda_dependencies.yml @@ -0,0 +1,15 @@ +# Conda environment specification. The dependencies defined in this file will +# be automatically provisioned for runs with userManagedDependencies=False. + +# Details about the Conda environment file format: +# https://conda.io/docs/user-guide/tasks/manage-environments.html#create-env-file-manually + +name: project_environment +dependencies: + # The python interpreter version. + # Currently Azure ML only supports 3.5.2 and later. +- python=3.6.2 + +- pip: + # Required packages for AzureML execution, history, and data preparation. + - azureml-defaults diff --git a/aml_config/docker.runconfig b/aml_config/docker.runconfig new file mode 100644 index 000000000..d79398c8c --- /dev/null +++ b/aml_config/docker.runconfig @@ -0,0 +1,115 @@ +# The script to run. +script: train.py +# The arguments to the script file. +arguments: [] +# The name of the compute target to use for this run. +target: local +# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch". +framework: PySpark +# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi". +communicator: None +# Automatically prepare the run environment as part of the run itself. +autoPrepareEnvironment: true +# Maximum allowed duration for the run. +maxRunDurationSeconds: +# Number of nodes to use for running job. +nodeCount: 1 +# Environment details. +environment: +# Environment variables set for the run. + environmentVariables: + EXAMPLE_ENV_VAR: EXAMPLE_VALUE +# Python details + python: +# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment. + userManagedDependencies: false +# The python interpreter path + interpreterPath: python +# Path to the conda dependencies file to use for this run. If a project +# contains multiple programs with different sets of dependencies, it may be +# convenient to manage those environments with separate files. + condaDependenciesFile: aml_config/conda_dependencies.yml +# Docker details + docker: +# Set True to perform this run inside a Docker container. + enabled: true +# Base image used for Docker-based runs. + baseImage: mcr.microsoft.com/azureml/base:0.2.0 +# Set False if necessary to work around shared volume bugs. + sharedVolumes: true +# Run with NVidia Docker extension to support GPUs. + gpuSupport: false +# Extra arguments to the Docker run command. + arguments: [] +# Image registry that contains the base image. + baseImageRegistry: +# DNS name or IP address of azure container registry(ACR) + address: +# The username for ACR + username: +# The password for ACR + password: +# Spark details + spark: +# List of spark repositories. + repositories: + - https://mmlspark.azureedge.net/maven + packages: + - group: com.microsoft.ml.spark + artifact: mmlspark_2.11 + version: '0.12' + precachePackages: true +# Databricks details + databricks: +# List of maven libraries. + mavenLibraries: [] +# List of PyPi libraries + pypiLibraries: [] +# List of RCran libraries + rcranLibraries: [] +# List of JAR libraries + jarLibraries: [] +# List of Egg libraries + eggLibraries: [] +# History details. +history: +# Enable history tracking -- this allows status, logs, metrics, and outputs +# to be collected for a run. + outputCollection: true +# whether to take snapshots for history. + snapshotProject: true +# Spark configuration details. +spark: + configuration: + spark.app.name: Azure ML Experiment + spark.yarn.maxAppAttempts: 1 +# HDI details. +hdi: +# Yarn deploy mode. Options are cluster and client. + yarnDeployMode: cluster +# Tensorflow details. +tensorflow: +# The number of worker tasks. + workerCount: 1 +# The number of parameter server tasks. + parameterServerCount: 1 +# Mpi details. +mpi: +# When using MPI, number of processes per node. + processCountPerNode: 1 +# data reference configuration details +dataReferences: {} +# Project share datastore reference. +sourceDirectoryDataStore: +# AmlCompute details. +amlcompute: +# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs + vmSize: +# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority". + vmPriority: +# A bool that indicates if the cluster has to be retained after job completion. + retainCluster: false +# Name of the cluster to be created. If not specified, runId will be used as cluster name. + name: +# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0. + clusterMaxNodeCount: 1 diff --git a/aml_config/local.runconfig b/aml_config/local.runconfig new file mode 100644 index 000000000..ccfa6195b --- /dev/null +++ b/aml_config/local.runconfig @@ -0,0 +1,115 @@ +# The script to run. +script: train.py +# The arguments to the script file. +arguments: [] +# The name of the compute target to use for this run. +target: local +# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch". +framework: Python +# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi". +communicator: None +# Automatically prepare the run environment as part of the run itself. +autoPrepareEnvironment: true +# Maximum allowed duration for the run. +maxRunDurationSeconds: +# Number of nodes to use for running job. +nodeCount: 1 +# Environment details. +environment: +# Environment variables set for the run. + environmentVariables: + EXAMPLE_ENV_VAR: EXAMPLE_VALUE +# Python details + python: +# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment. + userManagedDependencies: false +# The python interpreter path + interpreterPath: python +# Path to the conda dependencies file to use for this run. If a project +# contains multiple programs with different sets of dependencies, it may be +# convenient to manage those environments with separate files. + condaDependenciesFile: aml_config/conda_dependencies.yml +# Docker details + docker: +# Set True to perform this run inside a Docker container. + enabled: false +# Base image used for Docker-based runs. + baseImage: mcr.microsoft.com/azureml/base:0.2.0 +# Set False if necessary to work around shared volume bugs. + sharedVolumes: true +# Run with NVidia Docker extension to support GPUs. + gpuSupport: false +# Extra arguments to the Docker run command. + arguments: [] +# Image registry that contains the base image. + baseImageRegistry: +# DNS name or IP address of azure container registry(ACR) + address: +# The username for ACR + username: +# The password for ACR + password: +# Spark details + spark: +# List of spark repositories. + repositories: + - https://mmlspark.azureedge.net/maven + packages: + - group: com.microsoft.ml.spark + artifact: mmlspark_2.11 + version: '0.12' + precachePackages: true +# Databricks details + databricks: +# List of maven libraries. + mavenLibraries: [] +# List of PyPi libraries + pypiLibraries: [] +# List of RCran libraries + rcranLibraries: [] +# List of JAR libraries + jarLibraries: [] +# List of Egg libraries + eggLibraries: [] +# History details. +history: +# Enable history tracking -- this allows status, logs, metrics, and outputs +# to be collected for a run. + outputCollection: true +# whether to take snapshots for history. + snapshotProject: true +# Spark configuration details. +spark: + configuration: + spark.app.name: Azure ML Experiment + spark.yarn.maxAppAttempts: 1 +# HDI details. +hdi: +# Yarn deploy mode. Options are cluster and client. + yarnDeployMode: cluster +# Tensorflow details. +tensorflow: +# The number of worker tasks. + workerCount: 1 +# The number of parameter server tasks. + parameterServerCount: 1 +# Mpi details. +mpi: +# When using MPI, number of processes per node. + processCountPerNode: 1 +# data reference configuration details +dataReferences: {} +# Project share datastore reference. +sourceDirectoryDataStore: +# AmlCompute details. +amlcompute: +# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs + vmSize: +# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority". + vmPriority: +# A bool that indicates if the cluster has to be retained after job completion. + retainCluster: false +# Name of the cluster to be created. If not specified, runId will be used as cluster name. + name: +# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0. + clusterMaxNodeCount: 1 diff --git a/aml_config/project.json b/aml_config/project.json new file mode 100644 index 000000000..dfedb75a2 --- /dev/null +++ b/aml_config/project.json @@ -0,0 +1 @@ +{"Id": "local-compute", "Scope": "/subscriptions/65a1016d-0f67-45d2-b838-b8f373d6d52e/resourceGroups/sheri/providers/Microsoft.MachineLearningServices/workspaces/sheritestqs3/projects/local-compute"} \ No newline at end of file diff --git a/ignore/doc-qa/how-to-set-up-training-targets/.amlignore b/ignore/doc-qa/how-to-set-up-training-targets/.amlignore new file mode 100644 index 000000000..616345c4d --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/.amlignore @@ -0,0 +1,7 @@ +.ipynb_checkpoints +azureml-logs +.azureml +.git +outputs +azureml-setup +docs diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml new file mode 100644 index 000000000..5e49a89d6 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml @@ -0,0 +1,15 @@ +# Conda environment specification. The dependencies defined in this file will +# be automatically provisioned for runs with userManagedDependencies=False. + +# Details about the Conda environment file format: +# https://conda.io/docs/user-guide/tasks/manage-environments.html#create-env-file-manually + +name: project_environment +dependencies: + # The python interpreter version. + # Currently Azure ML only supports 3.5.2 and later. +- python=3.6.2 + +- pip: + # Required packages for AzureML execution, history, and data preparation. + - azureml-defaults diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig new file mode 100644 index 000000000..d79398c8c --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig @@ -0,0 +1,115 @@ +# The script to run. +script: train.py +# The arguments to the script file. +arguments: [] +# The name of the compute target to use for this run. +target: local +# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch". +framework: PySpark +# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi". +communicator: None +# Automatically prepare the run environment as part of the run itself. +autoPrepareEnvironment: true +# Maximum allowed duration for the run. +maxRunDurationSeconds: +# Number of nodes to use for running job. +nodeCount: 1 +# Environment details. +environment: +# Environment variables set for the run. + environmentVariables: + EXAMPLE_ENV_VAR: EXAMPLE_VALUE +# Python details + python: +# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment. + userManagedDependencies: false +# The python interpreter path + interpreterPath: python +# Path to the conda dependencies file to use for this run. If a project +# contains multiple programs with different sets of dependencies, it may be +# convenient to manage those environments with separate files. + condaDependenciesFile: aml_config/conda_dependencies.yml +# Docker details + docker: +# Set True to perform this run inside a Docker container. + enabled: true +# Base image used for Docker-based runs. + baseImage: mcr.microsoft.com/azureml/base:0.2.0 +# Set False if necessary to work around shared volume bugs. + sharedVolumes: true +# Run with NVidia Docker extension to support GPUs. + gpuSupport: false +# Extra arguments to the Docker run command. + arguments: [] +# Image registry that contains the base image. + baseImageRegistry: +# DNS name or IP address of azure container registry(ACR) + address: +# The username for ACR + username: +# The password for ACR + password: +# Spark details + spark: +# List of spark repositories. + repositories: + - https://mmlspark.azureedge.net/maven + packages: + - group: com.microsoft.ml.spark + artifact: mmlspark_2.11 + version: '0.12' + precachePackages: true +# Databricks details + databricks: +# List of maven libraries. + mavenLibraries: [] +# List of PyPi libraries + pypiLibraries: [] +# List of RCran libraries + rcranLibraries: [] +# List of JAR libraries + jarLibraries: [] +# List of Egg libraries + eggLibraries: [] +# History details. +history: +# Enable history tracking -- this allows status, logs, metrics, and outputs +# to be collected for a run. + outputCollection: true +# whether to take snapshots for history. + snapshotProject: true +# Spark configuration details. +spark: + configuration: + spark.app.name: Azure ML Experiment + spark.yarn.maxAppAttempts: 1 +# HDI details. +hdi: +# Yarn deploy mode. Options are cluster and client. + yarnDeployMode: cluster +# Tensorflow details. +tensorflow: +# The number of worker tasks. + workerCount: 1 +# The number of parameter server tasks. + parameterServerCount: 1 +# Mpi details. +mpi: +# When using MPI, number of processes per node. + processCountPerNode: 1 +# data reference configuration details +dataReferences: {} +# Project share datastore reference. +sourceDirectoryDataStore: +# AmlCompute details. +amlcompute: +# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs + vmSize: +# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority". + vmPriority: +# A bool that indicates if the cluster has to be retained after job completion. + retainCluster: false +# Name of the cluster to be created. If not specified, runId will be used as cluster name. + name: +# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0. + clusterMaxNodeCount: 1 diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig new file mode 100644 index 000000000..ccfa6195b --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig @@ -0,0 +1,115 @@ +# The script to run. +script: train.py +# The arguments to the script file. +arguments: [] +# The name of the compute target to use for this run. +target: local +# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch". +framework: Python +# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi". +communicator: None +# Automatically prepare the run environment as part of the run itself. +autoPrepareEnvironment: true +# Maximum allowed duration for the run. +maxRunDurationSeconds: +# Number of nodes to use for running job. +nodeCount: 1 +# Environment details. +environment: +# Environment variables set for the run. + environmentVariables: + EXAMPLE_ENV_VAR: EXAMPLE_VALUE +# Python details + python: +# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment. + userManagedDependencies: false +# The python interpreter path + interpreterPath: python +# Path to the conda dependencies file to use for this run. If a project +# contains multiple programs with different sets of dependencies, it may be +# convenient to manage those environments with separate files. + condaDependenciesFile: aml_config/conda_dependencies.yml +# Docker details + docker: +# Set True to perform this run inside a Docker container. + enabled: false +# Base image used for Docker-based runs. + baseImage: mcr.microsoft.com/azureml/base:0.2.0 +# Set False if necessary to work around shared volume bugs. + sharedVolumes: true +# Run with NVidia Docker extension to support GPUs. + gpuSupport: false +# Extra arguments to the Docker run command. + arguments: [] +# Image registry that contains the base image. + baseImageRegistry: +# DNS name or IP address of azure container registry(ACR) + address: +# The username for ACR + username: +# The password for ACR + password: +# Spark details + spark: +# List of spark repositories. + repositories: + - https://mmlspark.azureedge.net/maven + packages: + - group: com.microsoft.ml.spark + artifact: mmlspark_2.11 + version: '0.12' + precachePackages: true +# Databricks details + databricks: +# List of maven libraries. + mavenLibraries: [] +# List of PyPi libraries + pypiLibraries: [] +# List of RCran libraries + rcranLibraries: [] +# List of JAR libraries + jarLibraries: [] +# List of Egg libraries + eggLibraries: [] +# History details. +history: +# Enable history tracking -- this allows status, logs, metrics, and outputs +# to be collected for a run. + outputCollection: true +# whether to take snapshots for history. + snapshotProject: true +# Spark configuration details. +spark: + configuration: + spark.app.name: Azure ML Experiment + spark.yarn.maxAppAttempts: 1 +# HDI details. +hdi: +# Yarn deploy mode. Options are cluster and client. + yarnDeployMode: cluster +# Tensorflow details. +tensorflow: +# The number of worker tasks. + workerCount: 1 +# The number of parameter server tasks. + parameterServerCount: 1 +# Mpi details. +mpi: +# When using MPI, number of processes per node. + processCountPerNode: 1 +# data reference configuration details +dataReferences: {} +# Project share datastore reference. +sourceDirectoryDataStore: +# AmlCompute details. +amlcompute: +# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs + vmSize: +# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority". + vmPriority: +# A bool that indicates if the cluster has to be retained after job completion. + retainCluster: false +# Name of the cluster to be created. If not specified, runId will be used as cluster name. + name: +# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0. + clusterMaxNodeCount: 1 diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json new file mode 100644 index 000000000..2ad24da18 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json @@ -0,0 +1 @@ +{"Id": "my-experiment", "Scope": "/subscriptions/65a1016d-0f67-45d2-b838-b8f373d6d52e/resourceGroups/sheri/providers/Microsoft.MachineLearningServices/workspaces/sheritestqs3/projects/my-experiment"} \ No newline at end of file diff --git a/ignore/doc-qa/how-to-set-up-training-targets/donotupload.py b/ignore/doc-qa/how-to-set-up-training-targets/donotupload.py new file mode 100644 index 000000000..72ed82659 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/donotupload.py @@ -0,0 +1,40 @@ + +from azureml.core import Workspace +ws = Workspace.from_config() + +from azureml.core.compute import ComputeTarget, HDInsightCompute +from azureml.exceptions import ComputeTargetException + +try: + # if you want to connect using SSH key instead of username/password you can provide parameters private_key_file and private_key_passphrase + attach_config = HDInsightCompute.attach_configuration(address='sheri2-ssh.azurehdinsight.net', + ssh_port=22, + username='sshuser', + password='ChangePassw)rd12') + hdi_compute = ComputeTarget.attach(workspace=ws, + name='sherihdi2', + attach_configuration=attach_config) + +except ComputeTargetException as e: + print("Caught = {}".format(e.message)) + hdi_compute = ComputeTarget(workspace=ws, name='sherihdi') + + +hdi_compute.wait_for_completion(show_output=True) + +# +from azureml.core.runconfig import RunConfiguration +from azureml.core.conda_dependencies import CondaDependencies + + +# use pyspark framework +run_hdi = RunConfiguration(framework="pyspark") + +# Set compute target to the HDI cluster +run_hdi.target = hdi_compute.name + +# specify CondaDependencies object to ask system installing numpy +cd = CondaDependencies() +cd.add_conda_package('numpy') +run_hdi.environment.python.conda_dependencies = cd +# \ No newline at end of file diff --git a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py index 7196cb988..3ac411fbc 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py @@ -1,6 +1,6 @@ # Code for Remote virtual machines -compute_target_name = "attach-dsvm" +compute_target_name = "sheri-linuxvm" # import azureml.core diff --git a/ignore/doc-qa/how-to-set-up-training-targets/hdi.py b/ignore/doc-qa/how-to-set-up-training-targets/hdi.py new file mode 100644 index 000000000..ea8bc8ff3 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/hdi.py @@ -0,0 +1,27 @@ + +from azureml.core import Workspace +ws = Workspace.from_config() + +from azureml.core.compute import ComputeTarget + +# refers to an existing compute resource attached to the workspace! +hdi_compute = ComputeTarget(workspace=ws, name='sherihdi') + + +# +from azureml.core.runconfig import RunConfiguration +from azureml.core.conda_dependencies import CondaDependencies + + +# use pyspark framework +run_hdi = RunConfiguration(framework="pyspark") + +# Set compute target to the HDI cluster +run_hdi.target = hdi_compute.name + +# specify CondaDependencies object to ask system installing numpy +cd = CondaDependencies() +cd.add_conda_package('numpy') +run_hdi.environment.python.conda_dependencies = cd +# +print(run_hdi) \ No newline at end of file diff --git a/ignore/doc-qa/how-to-set-up-training-targets/mylib.py b/ignore/doc-qa/how-to-set-up-training-targets/mylib.py new file mode 100644 index 000000000..08e4d1f4a --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/mylib.py @@ -0,0 +1,9 @@ +# Copyright (c) Microsoft. All rights reserved. +# Licensed under the MIT license. + +import numpy as np + + +def get_alphas(): + # list of numbers from 0.0 to 1.0 with a 0.05 interval + return np.arange(0.0, 1.0, 0.05) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/remote.py b/ignore/doc-qa/how-to-set-up-training-targets/remote.py new file mode 100644 index 000000000..b46fdc597 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/remote.py @@ -0,0 +1,52 @@ +# Code for Remote virtual machines + +compute_target_name = "attach-dsvm" + +# +import azureml.core +from azureml.core.runconfig import RunConfiguration, DEFAULT_CPU_IMAGE +from azureml.core.conda_dependencies import CondaDependencies + +run_dsvm = RunConfiguration(framework = "python") + +# Set the compute target to the Linux DSVM +run_dsvm.target = compute_target_name + +# Use Docker in the remote VM +run_dsvm.environment.docker.enabled = True + +# Use the CPU base image +# To use GPU in DSVM, you must also use the GPU base Docker image "azureml.core.runconfig.DEFAULT_GPU_IMAGE" +run_dsvm.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE +print('Base Docker image is:', run_dsvm.environment.docker.base_image) + +# Prepare the Docker and conda environment automatically when they're used for the first time +run_dsvm.prepare_environment = True + +# Specify the CondaDependencies object +run_dsvm.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) +# +hdi_compute.name = "blah" +from azureml.core.runconfig import RunConfiguration +from azureml.core.conda_dependencies import CondaDependencies + + +# use pyspark framework +hdi_run_config = RunConfiguration(framework="pyspark") + +# Set compute target to the HDI cluster +hdi_run_config.target = hdi_compute.name + +# specify CondaDependencies object to ask system installing numpy +cd = CondaDependencies() +cd.add_conda_package('numpy') +hdi_run_config.environment.python.conda_dependencies = cd + +# +from azureml.core.runconfig import RunConfiguration +# Configure the HDInsight run +# Load the runconfig object from the myhdi.runconfig file generated in the previous attach operation +run_hdi = RunConfiguration.load(project_object = project, run_name = 'myhdi') + +# Ask the system to prepare the conda environment automatically when it's used for the first time +run_hdi.auto_prepare_environment = True> \ No newline at end of file diff --git a/ignore/doc-qa/how-to-set-up-training-targets/temp.py b/ignore/doc-qa/how-to-set-up-training-targets/temp.py new file mode 100644 index 000000000..d1fd97af3 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/temp.py @@ -0,0 +1,8 @@ +from azureml.core import Workspace +ws = Workspace.from_config() + +# +from azureml.core.compute import ComputeTarget, AmlCompute + +# First, list the supported VM families for Azure Machine Learning Compute +print(AmlCompute.supported_vmsizes(workspace=ws)) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/train.py b/ignore/doc-qa/how-to-set-up-training-targets/train.py new file mode 100644 index 000000000..42da5a6d4 --- /dev/null +++ b/ignore/doc-qa/how-to-set-up-training-targets/train.py @@ -0,0 +1,45 @@ +# Copyright (c) Microsoft. All rights reserved. +# Licensed under the MIT license. + +from sklearn.datasets import load_diabetes +from sklearn.linear_model import Ridge +from sklearn.metrics import mean_squared_error +from sklearn.model_selection import train_test_split +from azureml.core.run import Run +from sklearn.externals import joblib +import os +import numpy as np +import mylib + +os.makedirs('./outputs', exist_ok=True) + +X, y = load_diabetes(return_X_y=True) + +run = Run.get_context() + +X_train, X_test, y_train, y_test = train_test_split(X, y, + test_size=0.2, + random_state=0) +data = {"train": {"X": X_train, "y": y_train}, + "test": {"X": X_test, "y": y_test}} + +# list of numbers from 0.0 to 1.0 with a 0.05 interval +alphas = mylib.get_alphas() + +for alpha in alphas: + # Use Ridge algorithm to create a regression model + reg = Ridge(alpha=alpha) + reg.fit(data["train"]["X"], data["train"]["y"]) + + preds = reg.predict(data["test"]["X"]) + mse = mean_squared_error(preds, data["test"]["y"]) + run.log('alpha', alpha) + run.log('mse', mse) + + model_file_name = 'ridge_{0:.2f}.pkl'.format(alpha) + # save model in the outputs folder so it automatically get uploaded + with open(model_file_name, "wb") as file: + joblib.dump(value=reg, filename=os.path.join('./outputs/', + model_file_name)) + + print('alpha is {0:.2f}, and mse is {1:0.2f}'.format(alpha, mse)) From c9d018b52cc0e9a300e7a1f9756798155a7341a4 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Mon, 7 Jan 2019 12:56:54 -0600 Subject: [PATCH 20/25] remove prepare environment --- ignore/doc-qa/how-to-set-up-training-targets/dsvm.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py index 3ac411fbc..d077cdb25 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py @@ -4,7 +4,7 @@ # import azureml.core -from azureml.core.runconfig import RunConfiguration, DEFAULT_CPU_IMAGE +from azureml.core.runconfig import RunConfiguration from azureml.core.conda_dependencies import CondaDependencies run_dsvm = RunConfiguration(framework = "python") @@ -20,9 +20,7 @@ run_dsvm.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE print('Base Docker image is:', run_dsvm.environment.docker.base_image) -# Prepare the Docker and conda environment automatically when they're used for the first time -run_dsvm.prepare_environment = True - # Specify the CondaDependencies object run_dsvm.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) -# \ No newline at end of file +# +print(run_dsvm) \ No newline at end of file From a9a0713d2f8b51a759410162138e6251427a19c1 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Mon, 7 Jan 2019 12:57:58 -0600 Subject: [PATCH 21/25] Delete donotupload.py --- .../donotupload.py | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/donotupload.py diff --git a/ignore/doc-qa/how-to-set-up-training-targets/donotupload.py b/ignore/doc-qa/how-to-set-up-training-targets/donotupload.py deleted file mode 100644 index 72ed82659..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/donotupload.py +++ /dev/null @@ -1,40 +0,0 @@ - -from azureml.core import Workspace -ws = Workspace.from_config() - -from azureml.core.compute import ComputeTarget, HDInsightCompute -from azureml.exceptions import ComputeTargetException - -try: - # if you want to connect using SSH key instead of username/password you can provide parameters private_key_file and private_key_passphrase - attach_config = HDInsightCompute.attach_configuration(address='sheri2-ssh.azurehdinsight.net', - ssh_port=22, - username='sshuser', - password='ChangePassw)rd12') - hdi_compute = ComputeTarget.attach(workspace=ws, - name='sherihdi2', - attach_configuration=attach_config) - -except ComputeTargetException as e: - print("Caught = {}".format(e.message)) - hdi_compute = ComputeTarget(workspace=ws, name='sherihdi') - - -hdi_compute.wait_for_completion(show_output=True) - -# -from azureml.core.runconfig import RunConfiguration -from azureml.core.conda_dependencies import CondaDependencies - - -# use pyspark framework -run_hdi = RunConfiguration(framework="pyspark") - -# Set compute target to the HDI cluster -run_hdi.target = hdi_compute.name - -# specify CondaDependencies object to ask system installing numpy -cd = CondaDependencies() -cd.add_conda_package('numpy') -run_hdi.environment.python.conda_dependencies = cd -# \ No newline at end of file From fb760f648d3513a12385765843dab62681f27493 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Mon, 7 Jan 2019 12:58:32 -0600 Subject: [PATCH 22/25] Delete temp.py --- ignore/doc-qa/how-to-set-up-training-targets/temp.py | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/temp.py diff --git a/ignore/doc-qa/how-to-set-up-training-targets/temp.py b/ignore/doc-qa/how-to-set-up-training-targets/temp.py deleted file mode 100644 index d1fd97af3..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/temp.py +++ /dev/null @@ -1,8 +0,0 @@ -from azureml.core import Workspace -ws = Workspace.from_config() - -# -from azureml.core.compute import ComputeTarget, AmlCompute - -# First, list the supported VM families for Azure Machine Learning Compute -print(AmlCompute.supported_vmsizes(workspace=ws)) From bedfbd649ee86dc71af45e454c38881db24bc5f1 Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Mon, 7 Jan 2019 13:06:02 -0600 Subject: [PATCH 23/25] fix files --- .../how-to-set-up-training-targets/.amlignore | 7 -- .../aml_config/conda_dependencies.yml | 15 --- .../aml_config/docker.runconfig | 115 ------------------ .../aml_config/local.runconfig | 115 ------------------ .../aml_config/project.json | 1 - .../how-to-set-up-training-targets/dsvm.py | 2 +- 6 files changed, 1 insertion(+), 254 deletions(-) delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/.amlignore delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig delete mode 100644 ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json diff --git a/ignore/doc-qa/how-to-set-up-training-targets/.amlignore b/ignore/doc-qa/how-to-set-up-training-targets/.amlignore deleted file mode 100644 index 616345c4d..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/.amlignore +++ /dev/null @@ -1,7 +0,0 @@ -.ipynb_checkpoints -azureml-logs -.azureml -.git -outputs -azureml-setup -docs diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml deleted file mode 100644 index 5e49a89d6..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/conda_dependencies.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Conda environment specification. The dependencies defined in this file will -# be automatically provisioned for runs with userManagedDependencies=False. - -# Details about the Conda environment file format: -# https://conda.io/docs/user-guide/tasks/manage-environments.html#create-env-file-manually - -name: project_environment -dependencies: - # The python interpreter version. - # Currently Azure ML only supports 3.5.2 and later. -- python=3.6.2 - -- pip: - # Required packages for AzureML execution, history, and data preparation. - - azureml-defaults diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig deleted file mode 100644 index d79398c8c..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/docker.runconfig +++ /dev/null @@ -1,115 +0,0 @@ -# The script to run. -script: train.py -# The arguments to the script file. -arguments: [] -# The name of the compute target to use for this run. -target: local -# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch". -framework: PySpark -# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi". -communicator: None -# Automatically prepare the run environment as part of the run itself. -autoPrepareEnvironment: true -# Maximum allowed duration for the run. -maxRunDurationSeconds: -# Number of nodes to use for running job. -nodeCount: 1 -# Environment details. -environment: -# Environment variables set for the run. - environmentVariables: - EXAMPLE_ENV_VAR: EXAMPLE_VALUE -# Python details - python: -# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment. - userManagedDependencies: false -# The python interpreter path - interpreterPath: python -# Path to the conda dependencies file to use for this run. If a project -# contains multiple programs with different sets of dependencies, it may be -# convenient to manage those environments with separate files. - condaDependenciesFile: aml_config/conda_dependencies.yml -# Docker details - docker: -# Set True to perform this run inside a Docker container. - enabled: true -# Base image used for Docker-based runs. - baseImage: mcr.microsoft.com/azureml/base:0.2.0 -# Set False if necessary to work around shared volume bugs. - sharedVolumes: true -# Run with NVidia Docker extension to support GPUs. - gpuSupport: false -# Extra arguments to the Docker run command. - arguments: [] -# Image registry that contains the base image. - baseImageRegistry: -# DNS name or IP address of azure container registry(ACR) - address: -# The username for ACR - username: -# The password for ACR - password: -# Spark details - spark: -# List of spark repositories. - repositories: - - https://mmlspark.azureedge.net/maven - packages: - - group: com.microsoft.ml.spark - artifact: mmlspark_2.11 - version: '0.12' - precachePackages: true -# Databricks details - databricks: -# List of maven libraries. - mavenLibraries: [] -# List of PyPi libraries - pypiLibraries: [] -# List of RCran libraries - rcranLibraries: [] -# List of JAR libraries - jarLibraries: [] -# List of Egg libraries - eggLibraries: [] -# History details. -history: -# Enable history tracking -- this allows status, logs, metrics, and outputs -# to be collected for a run. - outputCollection: true -# whether to take snapshots for history. - snapshotProject: true -# Spark configuration details. -spark: - configuration: - spark.app.name: Azure ML Experiment - spark.yarn.maxAppAttempts: 1 -# HDI details. -hdi: -# Yarn deploy mode. Options are cluster and client. - yarnDeployMode: cluster -# Tensorflow details. -tensorflow: -# The number of worker tasks. - workerCount: 1 -# The number of parameter server tasks. - parameterServerCount: 1 -# Mpi details. -mpi: -# When using MPI, number of processes per node. - processCountPerNode: 1 -# data reference configuration details -dataReferences: {} -# Project share datastore reference. -sourceDirectoryDataStore: -# AmlCompute details. -amlcompute: -# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs - vmSize: -# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority". - vmPriority: -# A bool that indicates if the cluster has to be retained after job completion. - retainCluster: false -# Name of the cluster to be created. If not specified, runId will be used as cluster name. - name: -# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0. - clusterMaxNodeCount: 1 diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig deleted file mode 100644 index ccfa6195b..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/local.runconfig +++ /dev/null @@ -1,115 +0,0 @@ -# The script to run. -script: train.py -# The arguments to the script file. -arguments: [] -# The name of the compute target to use for this run. -target: local -# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch". -framework: Python -# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi". -communicator: None -# Automatically prepare the run environment as part of the run itself. -autoPrepareEnvironment: true -# Maximum allowed duration for the run. -maxRunDurationSeconds: -# Number of nodes to use for running job. -nodeCount: 1 -# Environment details. -environment: -# Environment variables set for the run. - environmentVariables: - EXAMPLE_ENV_VAR: EXAMPLE_VALUE -# Python details - python: -# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment. - userManagedDependencies: false -# The python interpreter path - interpreterPath: python -# Path to the conda dependencies file to use for this run. If a project -# contains multiple programs with different sets of dependencies, it may be -# convenient to manage those environments with separate files. - condaDependenciesFile: aml_config/conda_dependencies.yml -# Docker details - docker: -# Set True to perform this run inside a Docker container. - enabled: false -# Base image used for Docker-based runs. - baseImage: mcr.microsoft.com/azureml/base:0.2.0 -# Set False if necessary to work around shared volume bugs. - sharedVolumes: true -# Run with NVidia Docker extension to support GPUs. - gpuSupport: false -# Extra arguments to the Docker run command. - arguments: [] -# Image registry that contains the base image. - baseImageRegistry: -# DNS name or IP address of azure container registry(ACR) - address: -# The username for ACR - username: -# The password for ACR - password: -# Spark details - spark: -# List of spark repositories. - repositories: - - https://mmlspark.azureedge.net/maven - packages: - - group: com.microsoft.ml.spark - artifact: mmlspark_2.11 - version: '0.12' - precachePackages: true -# Databricks details - databricks: -# List of maven libraries. - mavenLibraries: [] -# List of PyPi libraries - pypiLibraries: [] -# List of RCran libraries - rcranLibraries: [] -# List of JAR libraries - jarLibraries: [] -# List of Egg libraries - eggLibraries: [] -# History details. -history: -# Enable history tracking -- this allows status, logs, metrics, and outputs -# to be collected for a run. - outputCollection: true -# whether to take snapshots for history. - snapshotProject: true -# Spark configuration details. -spark: - configuration: - spark.app.name: Azure ML Experiment - spark.yarn.maxAppAttempts: 1 -# HDI details. -hdi: -# Yarn deploy mode. Options are cluster and client. - yarnDeployMode: cluster -# Tensorflow details. -tensorflow: -# The number of worker tasks. - workerCount: 1 -# The number of parameter server tasks. - parameterServerCount: 1 -# Mpi details. -mpi: -# When using MPI, number of processes per node. - processCountPerNode: 1 -# data reference configuration details -dataReferences: {} -# Project share datastore reference. -sourceDirectoryDataStore: -# AmlCompute details. -amlcompute: -# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs - vmSize: -# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority". - vmPriority: -# A bool that indicates if the cluster has to be retained after job completion. - retainCluster: false -# Name of the cluster to be created. If not specified, runId will be used as cluster name. - name: -# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0. - clusterMaxNodeCount: 1 diff --git a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json b/ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json deleted file mode 100644 index 2ad24da18..000000000 --- a/ignore/doc-qa/how-to-set-up-training-targets/aml_config/project.json +++ /dev/null @@ -1 +0,0 @@ -{"Id": "my-experiment", "Scope": "/subscriptions/65a1016d-0f67-45d2-b838-b8f373d6d52e/resourceGroups/sheri/providers/Microsoft.MachineLearningServices/workspaces/sheritestqs3/projects/my-experiment"} \ No newline at end of file diff --git a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py index d077cdb25..9033d618f 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/dsvm.py @@ -1,6 +1,6 @@ # Code for Remote virtual machines -compute_target_name = "sheri-linuxvm" + compute_target_name = "sheri-linuxvm" # import azureml.core From 7db93bcb1d9db4c6e4099c83090b79fd8800f32a Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Tue, 22 Jan 2019 17:18:19 -0600 Subject: [PATCH 24/25] update comments --- .../quickstart.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py index a1a667417..54528c116 100644 --- a/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py +++ b/ignore/doc-qa/quickstart-create-workspace-with-python/quickstart.py @@ -29,19 +29,19 @@ # from azureml.core import Experiment -# create a new experiment +# Create a new experiment in your workspace. exp = Experiment(workspace=ws, name='myexp') -# start a run +# Start a run and start the logging service. run = exp.start_logging() -# log a number +# Log a single number. run.log('my magic number', 42) -# log a list (Fibonacci numbers) +# Log a list (Fibonacci numbers). run.log_list('my list', [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]) -# finish the run +# Finish the run. run.complete() # From 57b0f701f8852a42ac1ead69c64bfbafc5402c5d Mon Sep 17 00:00:00 2001 From: Sheri Gilley Date: Wed, 20 Nov 2019 17:28:44 -0600 Subject: [PATCH 25/25] remove deprecated auto_prepare_environment --- ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py index 22c14c798..bffe44328 100644 --- a/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py +++ b/ignore/doc-qa/how-to-set-up-training-targets/amlcompute2.py @@ -55,9 +55,6 @@ # Use conda_dependencies.yml to create a conda environment in the Docker image for execution run_amlcompute.environment.python.user_managed_dependencies = False -# Auto-prepare the Docker image when used for execution (if it is not already prepared) -run_amlcompute.auto_prepare_environment = True - # Specify CondaDependencies obj, add necessary packages run_amlcompute.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn']) #