近兩年,機器學習已經滲透到各行各業,各種人工智能和機器學習的應用蓬勃發展,在其背後實際上會有一個完善的機器學習平台和流水線來支撐模型的開發、測試和疊代。在本篇 Blog 中,我們将展現如果通過 AWS 的服務建構雲原生的機器學習流水線。
前言
近兩年,機器學習已經滲透到各行各業,各種人工智能和機器學習的應用蓬勃發展,在其背後實際上會有一個完善的機器學習平台和流水線來支撐模型的開發、測試和疊代。但是這樣一個系統性的平台,往往需要通過整合基礎架構層和平台層來完成,這樣的工程是非常消耗人力和物力的。
而AWS作為雲計算的上司者,在基礎架構層可以提供豐富的、充足的算力,在平台層提供全家桶式的機器學習平台服務,那麼最後一步就是需要使用一條流水線将這些機器學習中各個環節串聯在一起。
在本篇Blog中,我們将展現如果通過AWS的服務建構雲原生的機器學習流水線。本文中所有的代碼您都可以從這個Github Repo中擷取
機器學習工作流
在一個完整的機器學習工作流中,通常都包括以上幾個環節:
- 資料标注,對于監督學習來說,我們的訓練資料不僅僅需要特征資料,還需要對每一條資料的标注(label或者target),這一步往往通過大資料處理的方式得到,在AWS上有豐富的工具和服務可以幫助客戶完成此類任務。
- 資料預處理和特征工程,資料預處理是指對資料進行一些處理,比如處理缺失值和去除異常值資料等等,使資料處理一個合理分布中;而特征工程,是指将非實數的特征,轉換成模型可以了解的資料,比如one-hot和feature hashing等特征處理方法。這一步往往也是通過大資料的處理方式可以得到。
- 算法建構,這一步很好了解,就是針對不同的應用場景開發最适合的算法。
- 模型訓練,有了訓練資料和算法,那麼我們需要進行機器學習的疊代訓練。
- 評估,在訓練過程中,我們需要定期的進行評估,以确定我們的算法在向最優值進行收斂。
- 調參,如果評估的結果達不到我們的業務目标,那麼我就需要不斷調整算法超參數,進而得到一個最優的模型,這個過程是一個耗時耗算力的過程。
- 模型部署和推理,将模型部署到一個終端節點上,使其可以對外提供相應的推理服務,通常對外暴露出一個http或者grpc的API,讓用戶端進行調用。
- 推理資料監控,持續的監控推理請求的資料,檢查資料和訓練資料相比是否發生偏移,如果發生資料偏移,及時更新模型。
AWS雲原生機器學習流水線
在第2章節我們描述很多機器學習中的環節,這麼多的環節我如何一一去實作并将他們打包成一個流水線呢?在AWS上,您可以通過豐富的服務和工具快速的建構一個自動化的機器學習平台,如上圖所示,在這個方案中我們通過使用 AWS Glue(簡稱Glue) + Amazon SageMaker(簡稱SageMaker) + Step Functions的方式,完成一個serverless機器學習流水線,在這個方案中您不需要配置和維護任何一台EC2,所有的資源都是按需開啟和按需付費;在這個方案中,Glue對訓練資料進行預處理,SageMaker完成機器學習的其他環節,包括訓練、評估、模型部署等工作,而這些環節通過Step Functions串聯成一個工作流。使用這樣的方案可以實作模型的整體工程化部署,或者讓資料科學家也具有編排自己機器學習工作流的能力,提高模型開發和疊代過程。
Glue
AWS Glue 是完全托管的提取、轉換和加載 (ETL) 服務,您可以輕松地準備并加載資料以進行分析。您隻需在 AWS Glue 可視化編輯器中單擊幾次,即可建立并運作 ETL 作業。此外您也可以自己編寫Python或者Scalar的Spark應用程式,并定義ETL job所需的計算資源,之後您便可以手動或者自動的觸發ETL job,Glue會以Serverless的方式運作您的job,您可以将處理過的資料存儲到多種資料源,比如S3,RDS或者Redshift等等。
SageMaker
Amazon SageMaker是一個機器學習平台服務,它就像一個全家桶囊括了機器學習各個環節,主要包括以下元件:
- Ground Truth – 資料标注服務
- SageMaker Studio – 一個針對機器學習領域的IDE
- Training and Tuning – 支援Tensorflow、MXNet和Pytorch主流架構和以及分布式訓練任務,提供自動化超參調優的能力
- Deployment and Hosting – 部署模型到Sagemaker托管的endpoint上,支援線上和離線的推理,支援Auto Scaling
- 除此之外,SageMaker是一個對開發者友好的服務,提供非常完善的SageMaker SDK,您可以使用這個SDK友善的調用SageMaker中的元件
Step Functions
AWS Step Functions 是一個無伺服器服務編排工具,可輕松将多個 AWS 服務按順序安排到業務關鍵型應用程式中。通過其可視界面,您可以建立并運作一系列檢查點和事件驅動的工作流,以維護應用程式狀态。 每一步的輸出作為下一步的輸入。應用程式中的各個步驟根據業務邏輯定義的順序執行。
目前Step Functions已經全面的支援SageMaker及其各個元件,如果編排一個Step Functions工作流,需要掌握Amazon States Language JSON檔案的書寫方法,這對于一個初學者來說是非常難以入手的,為了簡化這方面的學習成本,提高資料科學家的工作效率,AWS提供了Step Functions Data Scientist SDK,通過簡單的API接口就可以快速建構出一個套機器學習工作流
實驗步驟
下面我們将一步步給大家示範,如何在AWS上建構上述的解決方案,在此實驗中您将使用以下幾個AWS服務:
- AWS S3 :AWS對象存儲服務,用于存放訓練資料集以及機器學習模型
- Amazon SageMaker:AWS機器學習托管服務,在實驗中主要的操作我們将在Notebook Instance中完成
- AWS Glue:無伺服器化的ETL服務,Glue的資料處理腳本已經為您準備好,對Glue的操作都會在Notebook中通過AWS SDK的方式調用
- AWS Step Functions:無伺服器服務編排工具,對AWS Step Functions的操作都會在Notebook中通過AWS Step Functions Data Science SDK的方式調用
下面我們正式開始實驗步驟
在Sagemaker中建立并配置Notebook Instance
Notebook Instance是使用Amazon SageMaker的入口,在Notebook Instance部署完成後您可以進入到熟悉的Jupyter Notebook或者Jupyter Lab的UI中,完成算法開發、互動式驗證,SageMaker服務調用等工作;在AWS配置好的Jupyter Notebook環境中,已經安裝好了常用的Tensorflow、MXNet、Pytorch、Spark和Python等Kernel,并且AWS SDK和CLI也已經配置好,使用者可以快速的開始機器學習的算法研發和驗證。
建立Notebook Instance需要進入SageMaker的Console,然後點選“Create notebook instance”
然後選擇這個Notebook Instance的配置,根據自己的需求進行選擇
此外還需要配置Notebook Instance的Role,在Jupyter中調用AWS CLI和AWS SDK的都将使用這個Role的權限,這裡選擇“Create a new role”然後按照預設的權限配置就好
然後其他配置保持預設,點選“Create notebook instance”,然後等待新的Notebook Instance的狀态變為“InService”,然後點選“Open jupyterLab”進入Jupyter Lab
進入Jupyter Lab之後,打開一個Terminal,然後運作以下指令,将Github repo下載下傳到Jupyter Lab本地:
cd SageMaker/ && git clone https://Github.com/xzy0223/SageMaker-example.git
然後導航到對應的目錄,找到SageMaker Pipeline的notebook并打開,之後的大部分操作将在這裡完成。
安裝Step Functions Data Scientist SDK和初始化
在Notebook中運作此cell,這将在環境中安裝Step Functions Data Scientist SDK,用于後面調用
然後進行一些全局參數的初始化
- session,接下來調用SageMaker元件的session
- bucket,用于存放訓練資料的S3存儲桶,需要提前建立好
- source_prefix,用于存放原始訓練資料的S3 prefix
- output_prefix,用于存放通過Glue轉換過的最終訓練資料的prefix
配置設定相應的權限
在這個實驗中,涉及到AWS之間服務的調用,是以需要給這些服務配置正确的權限才能順利完成。這些操作可以根據notebook中的描述在AWS Console中完成。
- 為Notebook Instance的Role配置設定“AWSStepFunctionsFullAccess”,以便在Jupyter notebook中Step Functions Data Scientist SDK可以有權限操作。
- 為Notebook Instance的Role配置設定可以建立Glue Job的權限,因為後邊在Jupyter notebook中會通過AWS SDK建立Glue Job。
- 為Step Functions建立一個Role,并賦予這個Role操作SageMaker和Glue的權限,因為Step Functions要和這個Role綁定去啟動Glue job和SageMaker的training job等元件
- 為Glue Job建立一個Role,Glue ETL job需要使用這個Role的權限從S3讀取和寫入訓練資料
準備原始訓練資料
從Internet下載下傳MNIST資料集
将資料分割成Train、Validation和Test資料集并存儲到S3上
建立Glue ETL Job
我們需要建立一個Glue ETL Job用于後邊Step Functions的調用,實驗目錄中包含了一個名為“train_val_norm.py”的ETL腳本,您可以打開進行檢視,這個腳本的主要作用是從S3中讀取原始訓練資料,對特征進行歸一化,最後再存儲回S3。
import sysfrom awsglue.transforms import *from awsglue.utils import getResolvedOptionsfrom pyspark.context import SparkContextfrom pyspark.sql.functions import *from awsglue.context import GlueContextfrom awsglue.job import Job 擷取Glue Job傳進來的參數args = getResolvedOptions(sys.argv, ['JOB_NAME','SOURCE_PATH', 'OUTPUT_PATH', 'TRAIN_PREFIX', 'VAL_PREFIX'])擷取Spark Context運作環境并生成Glue運作環境glueContext = GlueContext(SparkContext.getOrCreate())spark = glueContext.spark_session開始Jobjob = Job(glueContext)job.init(args['JOB_NAME'], args)'''對featurn資料進行normalization的函數參數: data_source_url:原始資料的S3路徑 data_output_url:存儲處理過的資料的S3路徑'''def norm_transform(data_source_url, data_output_url):# 讀取原始資料為dataframesource_data_frame = spark.read.load(data_source_url, format='csv', inferSchema=True, header=False) # MNIST資料集包含785列,第一列為label,剩下的為feature,選擇dataframe的第一列資料生成新的label dataframesource_label_data_frame = source_data_frame.select(source_data_frame.columns[0]) # 丢掉第一列,剩下的feature生成feature dataframesource_feature_data_frame = source_data_frame.drop(source_data_frame.columns[0]) # 獲得feature所有列的清單columns = source_feature_data_frame.columns# 周遊所有的列,對資料進行normalizationfor column in columns: source_feature_data_frame = source_feature_data_frame.withColumn(column, (source_feature_data_frame[column] / 255.)) # 對feature和label資料分别生成自增id,兩個dataframe的id是完全一樣的source_label_data_frame = source_label_data_frame.withColumn("id", monotonically_increasing_id())source_feature_data_frame = source_feature_data_frame.withColumn("id", monotonically_increasing_id()) # 通過outer join的方式将兩組dataframe在列的方向進行合并,并删除不在需要的idtarget_train_data_frame = source_label_data_frame.join(source_feature_data_frame, "id", "outer").drop("id") # 存儲資料到S3target_train_data_frame.write.save( data_output_url, format='csv', mode='overwrite')組織好訓練資料和驗證資料train_data_source_url = args['SOURCE_PATH'] + args['TRAIN_PREFIX'] + '*'train_data_output_url = args['OUTPUT_PATH'] + args['TRAIN_PREFIX']val_data_source_url = args['SOURCE_PATH'] + args['VAL_PREFIX'] + '*'val_data_output_url = args['OUTPUT_PATH'] + args['VAL_PREFIX']進行資料轉換norm_transform(train_data_source_url, train_data_output_url)norm_transform(val_data_source_url, val_data_output_url)送出Jobjob.commit()
在notebook中通過AWS SDK建立Glue ETL Job
建立Tensorflow Estimatior
SageMaker可以支援Tensorflow、Pytorch和MXNet等常見的架構,并且在SageMaker SDK中也為大家封裝了對應的類,可以通過這個類建立出一個對應架構的estimator,通過這個estimator對象可以完成從訓練、部署到推理的整個機器學習流程。在本實驗中,我們的算法基于Tensorflow開發,并且使用了腳本模式進行訓練,腳本模式允許算法工程是編寫自己的訓練腳本,而無需建構一個訓練容器鏡像,簡化了開發和驗證算法的難度。
我們需要建立一個Tensorflow Estimator,在後邊Step Funtions會使用這個Estimator完成訓練、部署模型的步驟,在建立時需要傳入一些必要的參數:
- entry_point:訓練腳本的路徑
- output_path:模型檔案存放的S3路徑
- train_instance_type:訓練模型的執行個體類型,機型配置
- train_instance_count:訓練執行個體的數量
- hyperparameters:訓練腳本需要使用的超參數
- framework_version:訓練腳本使用的Tensorflow的版本
- py_version:訓練腳本使用的python版本
- metric_definitions:訓練任務要監控的模型性能名額
- script_mode:打開腳本模式
建立并運作Step Functions流水線
Step Functions是AWS的任務編排服務,在其中最核心的概念就是Step,也就是工作流中每一步要執行的任務;另外Step Functions中每個step都會有input和output;并且可以在Step Functions中編排複雜的任務邏輯,比如并行、判斷、分支等等,在這個實驗中我們使用最簡單的串行邏輯,按照資料處理、模型訓練、模型建立到模型部署的流程順序執行。
首先import相關類庫
Step Functions的工作流是通過事件觸發的機制被啟動的,并且由于每個step都要有input,是以我們要定義一個觸發工作流的input schema,這個input會在各個step中傳遞,在其中我們定義了一些參數變量,對應的step會使用這些參數,完成對應的任務
定義Glue Job Step,定義一些Glue ETL Job需要使用的參數
定義Training Step,這裡使用了我們剛才建立的Tensorflow Estimator,還有需要傳入訓練資料的S3路徑,并等待訓練任務完成再進入下一個Step
當訓練結束後,需要建立一個SageMaker的Model
下一個Step就是要生成一個部署模型的配置資訊,比如托管模型的執行個體的配置和數量等
最後一個Step就是基于上一個Step建立的配置,部署托管模型的Endpoint,這個Endpoint就可以被client進行調用,完成線上推理的工作
[此處圖檔丢失]
各個Step已經建立完成,那麼就需要建立一個工作流将它們串聯起來
[此處圖檔丢失]
建立這個工作流
此時,來到Step Functions的console中,應該可以看到對應的工作流已經建立,并可以看到整個pipeline的圖形化展現。您可以看到左側是這個工作流的定義,在沒有Step Functions Data Scientist SDK的情況下,您需要自己編寫這個JSON文檔完成配置,如果使用了Step Functions Data Scientist SDK極大的簡化了建立機器學習工作流的難度和過程。
最後回到notebook,完成對工作流的觸發,傳入我們定義好的input參數
當工作流開始運作後,您可以在Step Functions的console中看到每個Step的執行情況和input/output
總結
在本文中,我主要講述了如何通過Step Functions編排整個機器學習工作流,使用Glue可以幫助我們完成訓練資料的ETL和特征工程等資料相關的操作,SageMaker可以完成從模型訓練、超參調優、模型生成和模型部署等機器學習流程,最後通過伺服器化的任務編排服務Step Functions将整個流程串聯,并且AWS提供了完善的UI和SDK工具,幫助算法工程師快速的建構、管理和監控機器學習工作流,大大提高了模型開發和模型驗證的效率,更好的滿足越來越多的業務需求。