軟件開發領域經常使用的A/B測試,也能用給ML模型啦

image

通常來講,開發出來的ML模型還須要不斷地完善才能提供讓人滿意的結果。然而在不少場景,例如在電子商務應用等多種實際環境中,單靠離線評估並不足以保證模型質量,咱們須要在生產期間對模型進行A/B測試,並據此作出模型更新決策。html

藉助Amazon SageMaker,你們能夠在端點之上運行多個生產模型變體,輕鬆對ML模型執行A/B測試。這些生產模型變體能夠分別對應由不一樣訓練數據集、算法以及ML框架訓練而成的ML模型,再配合不一樣的雲實例類型,便可創建起多種測試因素組合。git

===github

Amazon SageMaker是一項全託管服務,可以將快速構建、訓練以及部署機器學習(ML)模型的能力交付至每一位開發人員及數據科學家手中。目前,包括Intuit、Voodoo、ADP、Cerner、道瓊斯以及Thomson Reuters在內的成千上萬家客戶都在使用Amazon SageMaker以減輕ML流程的運營負擔。在Amazon SageMaker的幫助下,咱們能夠在託管端點上部署本身的ML模型,並實時獲取推理結果。你們也能夠經過Amazon CloudWatch輕鬆查看端點的性能指標、啓用Autoscaling以根據流量變化自動擴展端點,並在生產期間更新模型且不形成任何可用性影響。算法

如今,你們已經能夠將實際流量分發至同一端點上的各個變種當中,並由Amazon SageMaker根據指定的分發方式在各變體之間分配推理流量。對於但願控制發送至各個變體的流量的用戶,這項功能有助於擺脫指向特定變體的請求路由操做,顯著簡化實現流程。例如,咱們可能須要更新生產環境中的模型,並將部分流量定向至新模型以測試其與原有模型間的性能差別。此外,在某些特定用例中,咱們也須要使用特定模型處理推理請求,並調用系統中的特定變體。例如,你們可能但願測試並比較ML模型在不一樣客戶羣體中的性能表現,並對來自客戶的請求作出進一步細分,將其中特定部分徹底交由某一特定變體進行處理。安全

而爲了選擇使用哪一個變體處理推理請求,咱們只須要在每項推理請求上添加TargetVariant標頭,便可由Amazon SageMaker保證由指定的變體處理該項請求。session

用例:Amazon Alexaapp

Amazon Alexa使用Amazon SageMaker管理各種ML工做負載。Amazon Alexa團隊會頻繁更新其ML模型,藉此應對各類新興安全威脅。爲此,在使用Amazon SageMaker中的模型測試功能向生產環境發佈新的模型版本前,該團隊會測試、比較並肯定哪一個版本更符合其安全性、隱私性以及業務需求。關於Alexa團隊在客戶安全與隱私保護方面的更多詳細研究信息,請參閱在文本中使用分層結構表示形式保持隱私與實用程序框架

Alexa體驗與設備團隊軟件開發經理Nathanael Teissier表示,「Amazon SageMaker中提供的模型測試功能使咱們得以測試隱私保護模型的最新版本,並保證這些模型都能符合咱們在客戶隱私方面提出的最高標準。做爲一項新功能,SageMaker可以根據各項請求選擇所須要的生產變體,從而在無需修改當前設置的前提下爲A/B測試的部署策略帶來新的可能性。」機器學習

下文將向你們展現如何經過指向變體的流量分配與特定變體調用,輕鬆在Amazon SageMaker當中對ML模型執行A/B測試。咱們的測試模型已經配合不一樣訓練數據集完成訓練,且全部生產變體皆部署在Amazon SageMaker端點上。性能

使用Amazon SageMaker進行A/B測試

在生產ML工做流當中,數據科學家與工程師們常常嘗試各類方式以改進現有模型,例如執行超參數調優,或者引入更多或最新數據進行訓練或改善特徵選擇等。而對新模型以及處理生產流量的舊模型上執行A/B測試,每每是模型驗證流程中的最後一個環節。在A/B測試中,咱們須要測試模型朱同變體,並比較各個變體的相對性能。若是新版本帶來的性能優於或者等同於原有版本,便可使用新模型替換新模型。

Amazon SageMaker容許用戶經過生產變體,在同一端點以後測試多種模型或者模型的多個版本。每一個ProductionVariant都會標識一個ML模型以及託管該模型所對應的部署資源。咱們能夠爲每一個生產變體提供流量分配,或者在各項請求中直接調用目標變體以將端點調用請求分配給多個生產變體。在如下各章節中,咱們將具體介紹測試ML模型的兩種方法。

向各變體分配流量以測試模型

要經過向多個模型分配流量以測試各模型,咱們須要在端點配置中爲各生產變體指定權重,從而規劃路由至各個模型的流量百分比。Amazon SageMaker會根據你們提供的具體權重,在各生產變體之間分配流量。這也是生產變體在實際使用中的默認方式。下圖所示,詳細介紹了整個測試流程的具體實現方式。請注意,咱們還應在每一個推理響應中包含處理請求的變體名稱。
image

經過調用各變體進行模型測試

要經過調用各變體進行模型測試,咱們須要在請求當中設置TargetVariant標頭。若是已經提供了權重並指定TargetVariant以分配流量,則目標路由將覆蓋掉原有流量分發方式。下圖所示,詳細介紹了這種方法的運做方式。在這裏,咱們在推理請求中調用ProductionVariant3,你們也能夠同時在各項請求中調用不一樣的變體。
image

解決方案概述

本文將經過示例向你們介紹如何使用這項新功能。咱們能夠在Amazon SageMaker中使用Jupyter notebook以建立用於託管兩套模型的端點(使用ProductionVariant)。兩套模型皆經過Amazon SageMaker內置的XGBoost算法配合用於預測移動運營商客戶流失的數據集訓練而成。關於模型訓練的更多詳細信息,請參閱XGBoost客戶流失預測。在如下用例中,咱們將使用同一數據集中的不一樣子集進行模型訓練,並在各模型中使用不一樣的XGBoost算法版本。

經過使用Amazon SageMaker Jupyter notebook中的A/B測試示例,你們也能夠本身嘗試整個過程。咱們能夠在Amazon SageMaker Studio或者Amazon SageMaker notebook實例中實際運行。咱們使用的數據集徹底公開可用,Daniel T. Larose也曾在《從數據中發現知識(Discovering Knowledge in Data)》一書中提到這套數據集。做者稱,其爲來自加州大學爾灣分校的機器學習數據集。

本次演練包含如下操做步驟:

  • 建立並部署模型。
  • 調用已部署模型。
  • 評估變體性能。
  • 將推理流量導向您所選定的生產變體。

建立並部署模型

首先,咱們須要定義模型在Amazon Simple Storage Service(Amazon S3)中的位置。在後續模型部署步驟當中,咱們須要使用這些位置。具體請參見如下代碼:

model_url = f"s3://{path_to_model_1}"
model_url2 = f"s3://{path_to_model_2}"

接下來,使用容器鏡像與模型數據建立模型對象。咱們能夠將這些模型對象做爲生產變體部署在端點之上。模型的具體設定,能夠匹配不一樣的數據集、不一樣算法、不一樣的ML框架以及不一樣的超參數設置。具體請參見如下代碼:

from sagemaker.amazon.amazon_estimator import get_image_uri
model_name = f"DEMO-xgb-churn-pred-{datetime.now():%Y-%m-%d-%H-%M-%S}"
model_name2 = f"DEMO-xgb-churn-pred2-{datetime.now():%Y-%m-%d-%H-%M-%S}"
image_uri = get_image_uri(boto3.Session().region_name, 'xgboost', '0.90-1')
image_uri2 = get_image_uri(boto3.Session().region_name, 'xgboost', '0.90-2')
sm_session.create_model(name=model_name, role=role, container_defs={
 'Image': image_uri,
 'ModelDataUrl': model_url
})
sm_session.create_model(name=model_name2, role=role, container_defs={
 'Image': image_uri2,
 'ModelDataUrl': model_url2
})

建立2個生產變體,每一個變體都對應特定的模型與資源需求(即實例類型與數量)。要在2個變體之間平均分發推理請求,請將兩者的initial_weight設置爲0.5,具體參見如下代碼:

from sagemaker.session import production_variant
variant1 = production_variant(model_name=model_name,
 instance_type="ml.m5.xlarge",
 initial_instance_count=1,
 variant_name='Variant1',
 initial_weight=0.5)
variant2 = production_variant(model_name=model_name2,
 instance_type="ml.m5.xlarge",
 initial_instance_count=1,
 variant_name='Variant2',
 initial_weight=0.5)

使用如下代碼,將這些生產變體部署在Amazon SageMaker端點上:

endpoint_name = f"DEMO-xgb-churn-pred-{datetime.now():%Y-%m-%d-%H-%M-%S}"
print(f"EndpointName={endpoint_name}")
sm_session.endpoint_from_production_variants(
 name=endpoint_name,
 production_variants=[variant1, variant2]
)

調用部署完成的模型

如今,咱們能夠將數據發送至此端點並實時獲取推理結果。在本文中,咱們使用Amazon SageMaker支持的兩種方法進行模型測試:將流量分發至各變體,以及調用特定變體。

將流量分發至各變體

Amazon SageMaker會根據用戶在以前變體定義中配置的各項權重,在端點上的生產變體之間分配流量。具體參見如下端點調用代碼:

# get a subset of test data for a quick test
!tail -120 test_data/test-dataset-input-cols.csv > test_data/test_sample_tail_input_cols.csv
print(f"Sending test traffic to the endpoint {endpoint_name}. nPlease wait...")
with open('test_data/test_sample_tail_input_cols.csv', 'r') as f:
 for row in f:
 print(".", end="", flush=True)
 payload = row.rstrip('n')
 sm_runtime.invoke_endpoint(EndpointName=endpoint_name,
 ContentType="text/csv",
 Body=payload)
 time.sleep(0.5)
print("Done!")

Amazon SageMaker會將各變體中的延遲及調用等指標提交至Amazon CloudWatch。關於端點指標的完整列表,請參閱使用Amazon CloudWatch監控Amazon SageMaker。你們能夠查詢Amazon CloudWatch以獲取各變體的調用次數,瞭解默認狀況下如何各變體接收到的調用量。咱們得出的結果應相似於下圖:
image

調用特定變體

如下用例使用新的Amazon SageMaker變體功能以調用特定變體。在具體操做中,咱們只需使用新參數定義但願調用的特定ProductionVariant便可。如下代碼將在全部請求中調用Variant1,你們也能夠經過相同的流程調用其餘變體:

print(f"Sending test traffic to the endpoint {endpoint_name}. nPlease wait...")
with open('test_data/test_sample_tail_input_cols.csv', 'r') as f:
 for row in f:
 print(".", end="", flush=True)
 payload = row.rstrip('n')
 sm_runtime.invoke_endpoint(EndpointName=endpoint_name,
 ContentType="text/csv",
 Body=payload,
 TargetVariant="Variant1") # <- Note new parameter
 time.sleep(0.5)

要確認已經Variant1處理了全部新調用,請查詢CloudWatch以獲取每一個變體的調用次數。經過下圖能夠看到,Variant1已經完成了最近全部請求中的調用(最新時間戳),且不存在指向Variant2的調用。
image

評估變體性能

下圖評估了Variant1的準確率、精準率、召回率、F1得分以及ROC/AUC。
image
下圖評估了Variant2中的相同預測指標。

對於大多數已定義的指標,Variant2的效果都更好,所以你們能夠選擇它做爲生產環境中的推理流量處理方案。

將推理流量導向所選定的生產變體

如今,咱們已經肯定了Variant2模型比Variant1效果更好,接下來就是將更多流量轉移至Variant2。

你們固然能夠繼續使用TargetVariant調用選定的變體。但更簡單的處理方法,是使用UpdateEndpointWeightsAndCapacities對分配給各變體的權重進行更新。如此一來,無需修改端點便可更改指向各生產變體的流量分配。

你們應該還記得,以前建立模型與端點配置時,咱們在變體權重中將流量分配比例設定爲50/50。下圖所示,爲指向各變體總調用數量的CloudWatch指標,咱們能夠由此看到各變體的調用模式。
image

要將75%的流量轉移到Variant2,請使用UpdateEndpointWeightsAndCapacities爲各變體分配新的權重。具體參見如下代碼:

sm.update_endpoint_weights_and_capacities(
 EndpointName=endpoint_name,
 DesiredWeightsAndCapacities=[
 {
 "DesiredWeight": 0.25,
 "VariantName": variant1["VariantName"]
 },
 {
 "DesiredWeight": 0.75,
 "VariantName": variant2["VariantName"]
 }
 ]
)

Amazon SageMaker如今會將75%的推理請求導向Variant2,只爲Variant1保留25%請求。

下圖中的CloudWatch指標爲各變體的總調用次數,能夠看到Variant2的調用次數明顯高於Variant1。
image

咱們能夠繼續監控各項指標,並在某一變體的性能達到理想水平後將100%流量路由至該變體。在本用例中,咱們使用UpdateEndpointWeightsAndCapacities更新針對變體的流量分配。將Variant1的權重設定爲0.0,Variant2的權重設置爲1.0。如此一來,Amazon SageMaker將把全部推理請求100%發送至Variant2,參見如下代碼:

sm.update_endpoint_weights_and_capacities(
 EndpointName=endpoint_name,
 DesiredWeightsAndCapacities=[
 {
 "DesiredWeight": 0.0,
 "VariantName": variant1["VariantName"]
 },
 {
 "DesiredWeight": 1.0,
 "VariantName": variant2["VariantName"]
 }
 ]
)

下圖所示爲針對各變體的總調用量CloudWatch指標,能夠看到Variant2處理了全部推理請求,而Variant1沒有處理任何推理請求。
image

如今,咱們能夠安全地更新端點,並將Variant1從端點中刪除。你們還能夠向端點中添加新的變體,並參照本次演練中的各項步驟繼續測試生產環境下的新模型。

總結

Amazon SageMaker可幫助用戶在端點之上運行多個生產變體,從而輕鬆對生產環境中的ML模型進行A/B測試。你們可使用SageMaker提供的功能配合不一樣訓練數據集、超參數、算法以及ML框架測試由此訓練出的模型,瞭解它們在不一樣實例類型上的執行性能,並將各項因素整合起來造成不一樣搭配。

咱們還能夠在端點上的各變體之間進行流量分配,Amazon SageMaker會根據指定的分發方式將推理流量拆分並分發至各個變體。另外,若是須要面向特定客戶羣體測試模型性能,則可經過SageMaker提供的TargetVariant標頭指定負責處理特定推理請求的變體,相應請求將被自由路由至您所指定的變體處。

關於A/B測試的更多詳細信息,請參閱AWS開發者指南:在生產環境中測試模型

image

相關文章
相關標籤/搜索