Kubeflow是一款流行的開源機器學習(ML)工具包,適用於但願構建自定義機器學習管道的Kubernetes用戶。Kubeflow Pipelines屬於Kubeflow提供的附加組件,可幫助咱們構建並部署具有良好可移植性與可擴展性的端到端機器學習工做流。但在使用Kubeflow Pipelines時,數據科學家每每須要耗費很多精力以實現各種生產力工具,例如數據標記工做流與模型調優工具。html
另外,在使用Kubeflow Pipelines的過程當中,MLOps團隊還須要管理Kubernetes集羣中的CPU與GPU實例,考慮如何保持資源的高利用率,最終實現最佳投資回報。在數據科學團隊當中,充分利用集羣資源是一項極爲艱鉅的挑戰,同時也極大增長了MLOps團隊的運營壓力。例如,咱們須要保證僅使用GPU實例處理深度學習訓練及推理等性能要求較高的任務,並將CPU實例用於執行數據預處理以及Kubeflow管道控制平面等性能要求相對較低的任務。python
最近,AWS正式公佈了適用於Kubeflow Pipelines的Amazon SageMaker Components。藉此,Amazon SageMaker Components可以幫助咱們在Kubeflow Pipelines上實現強大的Amazon SageMaker功能,以全託管服務的形式支持數據標記、大規模超參數調優以及分佈式訓練做業、一鍵式安全可擴展模型部署,並經過Amazon Elastic Compute Cloud (Amazon EC2)競價實例進行高成本效益訓練等目標。git
下文將介紹如何經過Kubeflow Pipelines SDK,使用Amazon SageMaker Components構建出一個Kubeflow管道。github
咱們能夠在Kubeflow Pipelines中使用SageMaker Components,在機器學習工做流中的各個階段調用相應SageMaker做業,且無需擔憂其在後臺的具體運行方式。做爲數據科學家或機器學習開發人員,咱們能夠藉此將精力集中在經過可移植、可擴展管道內構建及運行機器學習實驗身上。所謂管道組件,是指可以在容器化應用程序中實現複用的代碼,你們能夠根據需求進行代碼共享以提升生產效率。算法
若是但願使用Amazon SageMaker中的超參考調優功能,則可使用超參數優化組件。在管道做業的運行過程當中,相應的超參數調優步驟將在Amazon SageMaker全託管基礎設施之上進行。在下一節中,咱們將具體介紹其工做方式;本節先來介紹Amazon SageMaker Components的基本原理。docker
在一條典型的Kubeflow管道中,各個組件負責將您的邏輯封裝在容器鏡像當中。做爲開發人員或數據科學家,咱們須要將訓練、數據預處理、模型服務或者其餘邏輯打包在Kubeflow Pipelines ContainerOp函數中,由該函數將代碼構建至新容器內。或者也可將代碼放置在自定義容器鏡像中,然後將鏡像推送至容器註冊表(如Amazon Elastic Container Registry,簡稱Amazon ECR)。在管道運行時,負責運行Kubeflow的Kubernetes集羣將指定一個工做節點對組件容器進行實例化,進而執行相關邏輯。管道組件可讀取先前組件的輸出,並生成管道中下一組件可使用的輸出。下圖所示,爲此管道工做流的基本架構。
在Kubeflow Pipelines中使用Amazon SageMaker Components時,你們再也不須要將邏輯封裝在自定義容器以內,而能夠直接加載對應組件並使用Kubeflow Pipelines SDK描述管道。在管道運行時,其中的指令將被轉換爲Amazon SageMaker做業或部署。然後,工做負載將在Amazon SageMaker全託管基礎設施之上運行,保證咱們充分享受Amazon SageMaker的各項典型優點,包括Managed Spot Training、端點自動規模伸縮等。下圖爲這類加強管道的基本架構。json
隨着時間推移,AWS將繼續推出更多功能,建議你們在官方Kubeflow Pipelines GitHub repo中收收藏Amazon SageMaker Components目錄連接。 )ubuntu
爲了說明如何在Kubeflow中使用Amazon SageMaker Components,讓咱們按下圖所示構建一條小型管道。
實際場景中的管道每每更爲高級,並且涉及數據攝取、數據預處理、數據轉換等其餘步驟。但爲簡便起見,這裏只使用最簡單的管道設計。安全
你們能夠在YouTube上觀看本演練的視頻版本:《在Kubernetes與Kubeflow上使用SageMaker實現機器學習規模擴展》(Scaling Machine Learning on Kubernetes and Kubeflow with SageMaker)。服務器
下面來看管道中各個步驟的具體做用:
組件1:超參數調優做業;
第一個組件,負責運行Amazon SageMaker超參數調優做業以優化如下超參數:
輸入:N/A
輸出:最佳超參數
組件2:選擇最佳超參數
在上一步的超參數搜索過程當中,模型只須要訓練10個輪次便可肯定最佳性能超參數。而在第二步中,爲了獲取最佳超參數,咱們須要進行80輪更新,以保證最佳超參數可以進一步提高模型準確率。
輸入:最佳超參數
輸出:通過80輪更新的最佳超參數
組件3:使用最佳超參數執行訓練做業
第三個組件將使用輪次最高的最佳超參數運行Amazon SageMaker訓練做業。
輸入:通過80輪更新的最佳超參數
輸出:訓練做業名稱
組件4:建立一套待部署模型
第四個組件將建立一套Amazon SageMaker模型工件。
輸入:訓練做業名稱
輸出:模型工件名稱
組件5:部署推理端點
最終組件將使用Amazon SageMaker完成模型部署。
輸入:模型工件名稱
輸出:N/A
要運行如下用例,須要作好以下準備:
r_components_for_kubeflow_pipelines.html)。咱們須要如下兩個IAM角色:
你們能夠經過筆記本電腦、臺式機、EC2實例或者Amazon SageMaker notebook實例啓動Amazon EKS集羣。不管如何選擇,咱們一般將該實例稱爲「網關實例」。這是由於Amazon EKS提供徹底託管的控制平面,咱們只須要使用網關實例便可與Kubernetes API以及工做節點進行交互。在本示例中,咱們使用一個c5.xlarge EC2實例做爲網關實例。
GitHub上提供了本文中使用的代碼、配置文件、Jupyter notebook以及Dockerfile。咱們將經過如下演示逐步解釋其中涉及的各項核心概念。請不要在各步驟中複製代碼,建議你們直接運行GitHub上提供的現成Jupyter notebook。
打開終端並經過SSH接入咱們用於建立Amazon EKS集羣的Amazon EC2網關實例。在登陸後,克隆該示例Repo以訪問示例Jupyter notebook。詳見如下代碼:
cd
git clone https://github.com/shashankpr...
cd kubeflow-pipelines-sagemaker-examples
要在網關實例上打開Jupyter notebook,請完成如下操做步驟:
l 在網關實例上啓動Jupyter,並使用如下代碼經過本地設備訪問Jupyter:
jupyter-lab
若是是在EC2實例上運行Jupyterlab服務器,請設置一條指向該EC2實例的通道,藉此經過本地筆記本或者臺式機訪問Jupyterlab客戶端。詳見如下代碼:
ssh -N -L 0.0.0.0:8081:localhost:8081 -L 0.0.0.0:8888:localhost:8888 -i ~/.ssh/<key_pair>.pem ubuntu@<IP_ADDRESS>
若是使用Amazon Linux而非Ubuntu,則必須使用ec2-user這一用戶名。更新EC2實例的IP地址,並使用對應的密鑰對。
至此,應該已經能夠在本地設備上經過http://localhost:8888訪問Jupyterlab了。
l 在網關實例上運行如下代碼以訪問Kubeflow儀表板:
kubectl port-forward svc/istio-ingressgateway -n istio-system 8081:80
至此,應該已經能夠經過http://localhost:8081訪問Kubeflow儀表板了。
l 打開示例Jupyter notebook。
Amazon SageMaker支持兩種訓練做業模式(GitHub Repo中分別爲兩種模式提供對應的Jupyter notebook):
Ø 自帶Docker容器鏡像 —— 在這種模式下,咱們能夠提供本身的Docker容器以執行訓練。使用訓練腳本構建容器,然後將其推送至Amazon ECR容器註冊表。Amazon SageMaker會提取該容器鏡像,進行實例化,然後開始訓練。kfp-sagemaker-custom-container.ipynb Jupyter notebook採用的便是這種方法。
Ø 自帶訓練腳本(即腳本模式)—— 在這種模式下,無需使用Docker容器。只要將機器學習訓練腳本導入TensorFlow、PyTorch、MXNet或XGBoost等流行框架中,然後將框架上傳至Amazon S3便可。Amazon SageMaker會自動提取適當容器、下載訓練腳本然後加以運行。若是不想使用Docker容器,那麼這種模式明顯更爲適用。kfp-sagemaker-script-mode.ipynb Jupyter notebook採用的就是這種方法。
如下示例主要探討第一種方法(自帶Docker容器鏡像)。本演練將帶你們瞭解kfp-sagemaker-custom-container.ipynb Jupyter notebook中的各個重要步驟。在將其打開後,咱們便可輕鬆完成後續操做。
如下截屏所示,即kfp-sagemaker-custom-container.ipynb notebook:
要安裝SDK並加載各管道組件,請完成如下操做步驟:
l 使用如下表明安裝 Kubeflow Pipelines SDK:
pip install kfp --upgrade
l 使用如下代碼在Python中導入Kubeflow Pipelines軟件包:
import kfp
from kfp import components
from kfp.components import func_to_container_op
from kfp import dsl
l 使用如下代碼在Python中加載Kubeflow Pipelines Components:
sagemaker_hpo_op = components.load_component_from_url('https://raw.githubusercontent...')
sagemaker_train_op = components.load_component_from_url('https://raw.githubusercontent...')
sagemaker_model_op = components.load_component_from_url('https://raw.githubusercontent...')
sagemaker_deploy_op = components.load_component_from_url('https://raw.githubusercontent...')
在生產工做流中,建議將組件固定至特定提交操做當中,而非直接使用Master。這樣能夠保證任何可能致使兼容性破壞的變動都不會對生產流程形成影響。
例如,要使用特定的提交版本,請在各加載組件中使用提交哈希替換掉Master部分:
sagemaker_train_op = components.load_component_from_url(‘https://raw.githubusercontent...’)
要準備並上傳數據集,請輸入如下代碼:
import sagemaker
import boto3
sess = boto3.Session()
account = boto3.client('sts').get_caller_identity().get('Account')
sm = sess.client('sagemaker')
role = sagemaker.get_execution_role()
sagemaker_session = sagemaker.Session(boto_session=sess)
bucket_name = sagemaker_session.default_bucket()
job_folder = 'jobs'
dataset_folder = 'datasets'
local_dataset = 'cifar10'
!python generate_cifar10_tfrecords.py —data-dir {local_dataset}
datasets = sagemaker_session.upload_data(path='cifar10', key_prefix='datasets/cifar10-dataset')
在以上代碼中,咱們首先導入Sagemaker與Boto3軟件包,藉此訪問當前計算機的IAM角色與默認的S3存儲桶。Python腳本generate_cifar10_tfrecords.py使用TensorFlow下載相應數據,將其轉換爲TFRecord格式,然後上傳至Amazon S3。
Build_docker_push_to_ecr.ipynb Jupyter notebook負責執行建立容器並將其推送至Amazon ECR的所有操做步驟。
Docker目錄中還包含Dockerfile、訓練與推理Python腳本,以及保存在需求文件中的各依賴項。如下截屏所示,爲Docker文件夾的具體內容 —— Dockerfile以及build_docker_push_to_ecr.ipynb Jupyter notebook。
關於如何使用Amazon SageMaker運行自定義容器的更多詳細信息,請參閱在Amazon SageMaker中使用您的自有算法或模型。
若是不打算構建本身的容器,能夠指定由Amazon SageMaker替咱們管理容器。在這種方法下,咱們能夠將訓練腳本上傳至Amazon S3,如kfp-sagemaker-script-mode.ipynb notebook中所示。
咱們可將Kubeflow管道表示爲由@dsl.pipeline裝飾的函數,參見如下代碼及kfp-sagemaker-custom-container.ipynb所示。關於更多詳細信息,請參閱Kubeflow Pipelines概述。
@dsl.pipeline(
name='cifar10 hpo train deploy pipeline',
description='cifar10 hpo train deploy pipeline using sagemaker'
)
def cifar10_hpo_train_deploy(region='us-west-2',
training_input_mode='File',
train_image=f'{account}.dkr.ecr.us-west-2.amazonaws.com/sagemaker-kubernetes:latest',
serving_image='763104351884.dkr.ecr.us-west-2.amazonaws.com/tensorflow-inference:1.15.2-cpu',
volume_size='50',
max_run_time='86400',
instance_type='ml.p3.2xlarge',
network_isolation='False',
traffic_encryption='False',
...
在本文的示例代碼中,咱們建立一項名爲cifar10_hpo_training_deploy ()的新函數,由其定義管道中各步驟間共通的參數。在該函數內,咱們還將定義如下五項管道組件。
此組件描述了超參數調優做業中的相關選項。詳見如下代碼:
hpo = sagemaker_hpo_op(
region=region,
image=train_image,
training_input_mode=training_input_mode,
strategy='Bayesian',
metric_name='val_acc',
metric_definitions='{"val_acc": "val_acc: ([0-9.]+)"}',
metric_type='Maximize',
static_parameters='{
"epochs": "1",
"momentum": "0.9",
"weight-decay": "0.0002",
"model_dir":"s3://'+bucket_name+'/jobs",
"sagemaker_region": "us-west-2"
}',
continuous_parameters='[
{"Name": "learning-rate", "MinValue": "0.0001", "MaxValue": "0.1", "ScalingType": "Logarithmic"}
]',
categorical_parameters='[
{"Name": "optimizer", "Values": ["sgd", "adam"]},
{"Name": "batch-size", "Values": ["32", "128", "256"]},
{"Name": "model-type", "Values": ["resnet", "custom"]}
]',
channels=channels,
output_location=f's3://{bucket_name}/jobs',
instance_type=instance_type,
instance_count='1',
volume_size=volume_size,
max_num_jobs='16',
max_parallel_jobs='4'
...
這些選項包括調優策略(貝葉斯)、優化指標(驗證準確率)、連續超參數(學習率)、分類超參數(優化器、批次大小與模型類型)以及保持不變的靜態超參數(例如輪次數=10)。
咱們將做業數量指定爲16。Amazon SageMaker會配置16個GPU實例以運行這項超參數調優做業。
組件1的輸出將被捕捉在hpo變量中。組件2則採用最佳超參數並更新輪次數,具體參見如下代碼:
training_hyp = get_best_hyp_op(hpo.outputs[‘best_hyperparameters’])
爲此,咱們須要定義一項自定義函數,由其獲取此項輸出並將輪次數更新爲80。這意味着咱們須要經歷更長的訓練時間,但能夠憑藉最佳超參數提高訓練效果。具體參見如下代碼:
def update_best_model_hyperparams(hpo_results, best_model_epoch = "80") -> str:
import json
r = json.loads(str(hpo_results))
return json.dumps(dict(r,epochs=best_model_epoch))
get_best_hyp_op = func_to_container_op(update_best_model_hyperparams)
此組件負責描述Amazon SageMaker訓練做業,此做業將使用最佳超參數與先前步驟中通過更新的輪次數。詳見如下代碼:
training = sagemaker_train_op(
region=region,
image=train_image,
training_input_mode=training_input_mode,
hyperparameters=training_hyp.output,
channels=channels,
instance_type=instance_type,
instance_count='1',
volume_size=volume_size,
max_run_time=max_run_time,
model_artifact_path=f's3://{bucket_name}/jobs',
network_isolation=network_isolation,
traffic_encryption=traffic_encryption,
spot_instance=spot_instance,
role=role,
)
此組件負責建立一套Amazon SageMaker模型工件,供你們做爲推理端點進行部署與託管。詳見如下代碼:
create_model = sagemaker_model_op(
region=region,
model_name=training.outputs['job_name'],
image=serving_image,
model_artifact_url=training.outputs['model_artifact_url'],
network_isolation=network_isolation,
role=role
)
最後,此組件負責模型部署,詳見如下代碼:
prediction = sagemaker_deploy_op(
region=region,
model_name_1=create_model.output,
instance_type_1='ml.m5.large'
)
使用Kubeflow管道編譯器,你們能夠編譯此管道、建立實驗並運行管道。詳見如下代碼:
kfp.compiler.Compiler().compile(cifar10_hpo_train_deploy,'sm-hpo-train-deploy-pipeline.zip')
client = kfp.Client()
aws_experiment = client.create_experiment(name='sm-kfp-experiment')
exp_name = f'cifar10-hpo-train-deploy-kfp-{time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())}'
my_run = client.run_pipeline(aws_experiment.id, exp_name, 'sm-hpo-train-deploy-pipeline.zip')
如下截屏所示,爲Kubeflow管道執行完成以後的結果(帶有註釋)。除了「自定義函數以更新輪次(Custom function to update epochs)」步驟以外,其他全部步驟皆由Amazon SageMaker在Kubeflow管道中實現。
咱們還能夠在Amazon SageMaker控制檯上監控各個步驟的當前進度。如下截屏所示,爲用於執行超參數調優做業的Amazon SageMaker控制檯。
在管道總體運行完畢以後,咱們的模型將做爲推理端點接受託管,如如下截屏所示。
要測試該端點,請複製端點名稱並使用Boto3 SDK獲取預測結果:
import json, boto3, numpy as np
client = boto3.client('runtime.sagemaker')
file_name = '1000_dog.png'
with open(file_name, 'rb') as f:
payload = f.read()
response = client.invoke_endpoint(EndpointName='Endpoint-20200522021801-DR5P',
ContentType='application/x-image',
Body=payload)
pred = json.loads(response['Body'].read())['predictions']
labels = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']
for l,p in zip(labels, pred[0]):
print(l,"{:.4f}".format(p*100))
在對包含小狗的圖片進行分析時,咱們應得出以下輸出結果:
airplane 0.0000
automobile 0.0000
bird 0.0001
cat 0.0115
deer 0.0000
dog 99.9883
frog 0.0000
horse 0.0000
ship 0.0000
truck 0.0000
本文介紹瞭如何配置Kubeflow Pipelines以經過Amazon SageMaker運行機器學習做業。Kubeflow Pipelines是一套開源機器學習編排平臺,在但願立足Kubernetes構建並管理自定義機器學習工做流的開發者羣體中廣受歡迎。但很多開發人員及MLOps團隊在Kubeflow Pipelines的實際運營中遭遇挑戰,發現本身難以管理Kubernetes集羣的機器學習優化工做,沒法得到良好的投資回報率或者承擔極高的整體擁有成本。
在面向Kubeflow Pipelines的SageMaker Components幫助下,咱們能夠繼續在Kubeflow Pipelines中管理自有管道,並依靠Amazon SageMaker的託管功能執行具體的機器學習任務。數據科學家與機器學習開發人員還可使用Amazon SageMaker中的最新創新成果,例如全託管超參數調優、分佈式訓練、Managed Spot Training、自動規模伸縮等功能。咱們還展現瞭如何使用Amazon SageMaker Components建立並運行一條端到端Kubeflow示例管道。完整示例請參閱GitHub。