案例研究:亞馬遜廣告使用 PyTorch 和 Amazon Inferentia 擴充套件廣告處理模型

亞馬遜雲開發者發表於2022-03-22

作者:Yashal Kanungo – 應用科學家,Kamran Khan – 高階技術產品經理,Shubha Kumbadakone – ML 框架高階專家

亞馬遜廣告使用 PyTorch、TorchServe 和 Amazon Inferentia 將推理成本降低 71% 的同時推動橫向擴充套件。

亞馬遜廣告(Amazon Ads)通過在亞馬遜商店內外展示的廣告(包括超過 15 個國家/地區的網站、應用和流媒體電視內容)幫助公司建立品牌並與購物者建立聯絡。 各種規模的企業和品牌,包括註冊賣家、供應商、圖書供應商、Kindle Direct Publishing (KDP) 作者、應用程式開發人員和代理機構都可以上傳自己的廣告創意,其中可以包括影像、視訊、音訊,當然,還有在亞馬遜上銷售的商品。

image.png

為了推廣準確、安全和愉悅的購物體驗,這些廣告必須遵守內容準則。 例如,廣告閃爍開啟或關閉,產品必須在適當的上下文中展示,圖片和文字應適合普通受眾。為了幫助確保廣告符合所需的政策和標準,我們需要開發可擴充套件的機制和工具。

作為解決方案,我們使用機器學習 (ML) 模型來展示可能需要修改的廣告。隨著深度神經網路在過去十年中蓬勃發展,我們的資料科學團隊開始探索更通用的深度學習 (DL) 方法,這些方法能夠以最少的人工干預處理文字、影像、音訊或視訊。為此,我們使用 PyTorch 構建了計算機視覺(CV)和自然語言處理(NLP)模型,這些模型會自動標記可能不合規的廣告。PyTorch 直觀,靈活且使用者友好,並且已經使我們無縫過渡到使用 DL 模型。在基於 Amazon Inferentia 的 Amazon EC2 Inf1 例項而不是基於 GPU 的例項上部署這些新模型,對於相同的工作負載,我們的推理延遲降低了 30%,推理成本降低了 71%。

向深度學習過渡

我們的機器學習系統將經典模型與詞嵌入配對以評估廣告文字。 但是我們的需求在不斷變化,隨著提交量的不斷擴大,我們需要一種足夠靈活的方法來隨著我們的業務擴充套件。此外,我們的模型必須快速並在幾毫秒內投放廣告,以提供最佳的客戶體驗。

在過去的十年中,深度學習在許多領域都非常流行,包括自然語言、視覺和音訊。由於深度神經網路通過多層傳輸資料集——逐步提取更高層次的特徵——它們可以比經典的ML模型做出更細微的推斷。例如,深度學習模型可以拒絕做出虛假宣告的廣告,而不是簡單地檢測被禁止的語言。

此外,深度學習技術是可轉移的——為一項任務訓練的模型可以適應執行相關任務。例如,可以優化預訓練的神經網路以檢測影像中的物件,然後進行微調以識別不允許在廣告中顯示的特定物件。

深度神經網路可以自動執行經典ML最耗時的兩個步驟:特徵工程和資料標記與需要探索性資料分析和手工設計特徵的傳統監督學習方法不同,深度神經網路直接從資料中學習相關特徵。DL 模型還可以分析非結構化資料,例如文字和影像,而無需 ML 中所需的預處理。深度神經網路可以有效地擴充套件更多資料,並且在涉及大型資料集的應用程式中表現得特別好。

我們選擇了 PyTorch 來開發我們的模型,因為它幫助我們最大限度地提高了系統的效能。藉助於 PyTorch,我們可以更好地為客戶服務,同時利用 Python 最直觀的概念。PyTorch 中的程式設計是物件導向的:它將處理函式與它們修改的資料組合在一起。因此,我們的程式碼庫是模組化的,我們可以在不同的應用程式中重用程式碼片段。此外,PyTorch 的 Eager 模式允許迴圈和控制結構,因此模型中的操作更復雜。Eager 模式可以很容易地對我們的模型進行原型設計和迭代,並且我們可以使用各種資料結構。這種靈活性有助於我們快速更新模型以滿足不斷變化的業務需求。

“在此之前,我們嘗試了其他‘Pythonic’框架,但 PyTorch 在我們這裡顯然是贏家。” 應用科學家 Yashal Kanungo 談到。 “使用PyTorch很容易,因為這種結構感覺是 Python 程式設計的原生結構,而資料科學家對此非常熟悉”。

訓練管道

今天,我們完全在 PyTorch 中構建我們的文字模型。為了節省時間和金錢,我們經常通過微調預訓練的 NLP 模型來跳過訓練的早期階段以進行語言分析。 如果我們需要一個新模型來評估影像或視訊,我們首先瀏覽 PyTorch 的 torchvision 庫,該庫為影像和視訊分類、物件檢測、例項分割和姿勢估計提供了預訓練選項。對於專門的任務,我們從頭開始構建自定義模型。PyTorch 非常適合這一點,因為 Eager 模式和使用者友好的前端使嘗試不同的架構變得容易。

要了解如何在 PyTorch 中微調神經網路,請參閱本教程

在開始訓練之前,我們會優化模型的超引數、定義網路架構的變數(例如隱藏層的數量)和訓練機制(例如學習率和批量大小)。選擇適當的超引數值至關重要,因為它們將塑造模型的訓練行為。在這一步中,我們依賴亞馬遜雲科技的 ML 平臺 SageMaker 中的貝葉斯搜尋功能。 貝葉斯搜尋將超引數調整視為迴歸問題:它提出可能產生最佳結果的超引數組合並執行訓練作業來測試這些值。每次試驗後,迴歸演算法會確定下一組要測試的超引數值,並且效能會逐步提高。

我們使用 SageMaker Notebooks 對我們的模型進行原型設計和迭代。Eager 模式讓我們通過為每個訓練批次構建一個新的計算圖來快速原型模型;操作的順序可以在迭代之間改變,以適應不同的資料結構或與中間結果相結合。這使我們可以在訓練期間調整網路,而無需從頭開始。這些動態圖對於基於可變序列長度的遞迴計算特別有價值,例如使用 NLP 分析的廣告中的單詞、句子和段落。

當我們完成模型架構後,我們會在 SageMaker 上部署訓練作業。 PyTorch 通過同時執行大量訓練作業幫助我們更快地開發大型模型。 PyTorch 的分散式資料並行 (DDP) 模組在 SageMaker 內的多臺互連機器上覆制單個模型,並且所有程式在資料集自己獨特的部分上同時向前執行。在反向傳播過程中,模組對所有過程的梯度進行平均,因此每個區域性模型都使用相同的引數值進行更新。

模型部署管道

當我們在生產中部署模型時,我們希望確保在不影響預測準確性的情況下降低推理成本。PyTorch 的多項功能和亞馬遜雲科技服務幫助我們應對了這一挑戰。

動態圖形的靈活性豐富了訓練,但在部署中,我們希望最大限度地提高效能和可移植性。在 PyTorch 中開發 NLP 模型的其中一個優點是開箱即用,它們可以被 TorchScript 追蹤到靜態操作序列中,TorchScript 是專門用於ML應用程式的 Python子集。Torchscript 將 PyTorch 模型轉換為更高效、更易於編譯的生產友好型中間表示 (IR) 圖。我們通過模型執行一個示例輸入,TorchScript 記錄在前向傳遞期間執行的操作。生成的 IR 圖可以在高效能環境中執行,包括 C++和其他無 Python 的多執行緒上下文,並且諸如運算子融合之類的優化可以加快執行時。

Neuron SDK 和 Amazon Inferentia 驅動的計算

我們將模型部署在由 Amazon Inferentia 提供支援的 Amazon EC2 Inf1 例項上,這是 Amazon 的第一個 ML 晶片,旨在加速深度學習推理工作負載。與基於 Amazon EC2 GPU 的例項相比,Inferentia 已證明可將推理成本降低多達 70%。我們使用 Amazon Neuron SDK(一組與Inferentia一起使用的軟體工具)來編譯和優化我們的模型,以便在 EC2 Inf1 例項上進行部署。

以下的程式碼片段展示瞭如何使用 Neuron 編譯 Hugging Face BERT 模型。與 torch.jit.trace() 一樣,neuron.trace() 在前向傳遞期間記錄模型對示例輸入的操作,以構建靜態 IR 圖。

import torch

from transformers import BertModel, BertTokenizer

import torch.neuron

tokenizer = BertTokenizer.from_pretrained("path to saved vocab")

model = BertModel.from_pretrained("path to the saved model", returned_dict=False)

inputs = tokenizer ("sample input", return_tensor="pt")

neuron_model = torch.neuron.trace(model,

                                  example_inputs = (inputs['input_ids'], inputs['attention_mask']),

                                  verbose = 1)

output = neuron_model(*(inputs['input_ids'], inputs['attention_mask']))

自動轉換和重新校準

在底層,Neuron 通過將模型自動轉換為更小的資料型別來優化模型的效能。 預設情況下,大多數應用程式以 32 位單精度浮點 (FP32) 數字格式表示神經網路值。將模型自動轉換為 16 位格式——半精度浮點 (FP16) 或大腦浮點 (BF16)——減少了模型的記憶體佔用和執行時間。在我們的案例中,我們決定使用 FP16來優化效能,同時保持高精度。

在某些情況下,自動轉換為較小的資料型別會觸發模型預測的細微差異。 為了確保模型的準確性不受影響,Neuron 比較了 FP16 和 FP32 模型的效能指標和預測。當自動轉換降低模型的準確性時,我們可以告訴神經元編譯器僅將權重和某些資料輸入轉換為 FP16,將其餘中間結果保留在 FP32 中。此外,我們經常對訓練資料進行幾次迭代,以重新校準我們的自動鑄造模型。這個過程比原來的訓練要少得多。

部署

為了分析多媒體廣告,我們執行了一組 DL 模型。上傳到亞馬遜的所有廣告都通過專門的模型執行,這些模型評估它們包括的每種型別的內容:影像、視訊和音訊、標題、文字、背景,甚至語構、語法和可能不恰當的語言。 我們從這些模型收到的訊號表明廣告是否符合我們的標準。

部署和監控多個模型異常複雜,因此我們依賴於 SageMaker 的預設 PyTorch 模型服務庫 TorchServe。TorchServe 由Facebook 的 PyTorch 團隊和亞馬遜雲科技聯合開發,旨在簡化從原型設計到生產的過渡,幫助我們大規模部署訓練有素的 PyTorch 模型,而無需編寫自定義程式碼。它為推理、管理、度量和解釋提供了一組安全的 REST API。TorchServe 具有多模型服務、模型版本控制、整合支援和自動批處理等功能,非常適合支援我們巨大的工作量。您可以在這篇博文中閱讀更多關於在 SageMaker上部署 Pytorch 模型並整合原生 TorchServe 的資訊。

在某些用例中,我們利用PyTorch的物件導向程式設計正規化將多個 DL 模型包裝到一個父物件(PyTorch nn.Module)中,並將它們作為一個整體服務。在其他情況下,我們使用 TorchServe 在單獨的 SageMaker 終端節點上為單獨的模型提供服務,這些終端節點在 Amazon Inf1 例項上執行。

自定義處理程式

我們特別讚賞 TorchServe 允許我們將模型初始化,預處理,推理和後處理程式碼嵌入到伺服器上的單個 Python 指令碼 handler.py 中。此指令碼(處理程式)預處理廣告中未標記的資料,通過我們的模型執行該資料,並將結果推斷提供給下游系統。TorchServe 提供了多個預設處理程式,用於載入權重和體系結構,並準備模型以在特定裝置上執行。我們可以將所有需要的附加工件(如詞彙表檔案或標籤對映)與模型捆綁在一個存檔檔案中。

當我們需要部署具有複雜初始化過程或源自第三方庫的模型時,我們會在 TorchServe 中設計自定義處理程式。這讓我們可以使用任何所需的過程從任何庫載入任何模型。以下程式碼段顯示了一個簡單的處理程式,它可以在任何 SageMaker託管端點例項上為 Hugging Face BERT 模型提供服務。

import torchimport torch.neuronfrom ts.torch_handler.base_handler import BaseHandlerimport transformersfrom transformers import AutoModelForSequenceClassification,AutoTokenizer

class MyModelHandler(BaseHandler):def initialize(self, context):self.manifest = ctx.manifestproperties = ctx.system_propertiesmodel_dir = properties.get("model_dir")serialized_file = self.manifest["model"]["serializedFile"]model_pt_path = os.path.join(model_dir, serialized_file)

    self.tokenizer = AutoTokenizer.from_pretrained(
            model_dir, do_lower_case=True
        )
    self.model = AutoModelForSequenceClassification.from_pretrained(
                model_dir
            )

def preprocess(self, data):

    input_text = data.get("data")
    if input_text is None:
        input_text = data.get("body")
        inputs = self.tokenizer.encode_plus(input_text, max_length=int(max_length), pad_to_max_length=True, add_special_tokens=True, return_tensors='pt')
    return inputs

def inference(self,inputs):
    predictions = self.model(**inputs)
    return predictions

def postprocess(self, output):
    return output

批處理

硬體加速器針對並行性進行了優化,批處理(在一個步驟中為模型提供多個輸入)有助於使所有可用容量飽和,通常會導致更高的吞吐量。然而,過高的批量大小會增加延遲,而吞吐量的提升卻很小。嘗試不同的批量大小有助於我們確定模型和硬體加速器的最佳位置。我們進行實驗以確定模型大小、有效負載大小和請求流量模式的最佳批量大小。

Neuron 編譯器現在支援可變批量大小。以前,跟蹤模型硬編碼了預定義的批量大小,因此我們必須填充資料,這會浪費計算、降低吞吐量並加劇延遲。 Inferentia 經過優化,可最大限度地提高小批量的吞吐量,通過減輕系統負載來減少延遲。

批處理

硬體加速器針對並行性進行了優化,批處理(在一個步驟中為模型提供多個輸入)有助於使所有可用容量飽和,通常會導致更高的吞吐量。然而,過高的批量大小會增加延遲,而吞吐量的提升卻很小。嘗試不同的批量大小有助於我們確定模型和硬體加速器的最佳位置。我們進行實驗以確定模型大小、有效負載大小和請求流量模式的最佳批量大小。

Neuron 編譯器現在支援可變批量大小。以前,跟蹤模型硬編碼了預定義的批量大小,因此我們必須填充資料,這會浪費計算、降低吞吐量並加劇延遲。 Inferentia 經過優化,可最大限度地提高小批量的吞吐量,通過減輕系統負載來減少延遲。

並行性

多核上的模型並行性還提高了吞吐量和延遲,這對於我們繁重的工作負載至關重要。每個 Inferentia 晶片包含四個 NeuronCore,它們既可以同時執行單獨的模型,也可以形成流水線來傳輸單個模型。在我們的用例中,資料並行配置以最低的成本提供最高的吞吐量,因為它擴充套件了併發處理請求。

資料並行:

image.png

模型並行:

image.png

監控

在生產過程中監控推理的準確性至關重要。最初做出良好預測的模型最終會在部署中退化,因為它們暴露在更多種類的資料中。這種現象稱為模型漂移,通常發生在輸入資料分佈或預測目標發生變化時。

We use SageMaker Model Monitor to track parity between the training and production data. Model Monitor notifies us when predictions in production begin to deviate from the training and validation results. Thanks to this early warning, we can restore accuracy — by retraining the model if necessary — before our advertisers are affected. To track performance in real time, Model Monitor also sends us metrics about the quality of predictions, such as accuracy, F-scores, and the distribution of the predicted classes.

我們使用 SageMaker 模型監控器來跟蹤訓練和生產資料之間的奇偶校驗。當生產中的預測開始偏離訓練和驗證結果時,模型監控器會通知我們。多虧了這種早期預警方式,我們可以在我們的廣告商受到影響之前恢復準確性——必要時可以重新訓練模型。為了實時跟蹤效能,模型監控器還會向我們傳送有關預測質量的指標,例如準確度、F 分數和預測類別的分佈。

為了確定我們的應用程式是否需要擴充套件,TorchServe 會定期記錄 CPU、記憶體和磁碟的資源利用率指標;它還記錄收到的請求數量與服務數量。對於自定義指標,TorchServe 提供了一個 Metrics API

一種有益的結果

我們的深度學習模型在 PyTorch 中開發並部署在 Inferentia 上,在降低成本的同時加快了廣告分析的速度。從我們在 DL 中的第一次探索開始,在 PyTorch 中程式設計感覺是非常自然的。它的使用者友好型功能有助於從我們早期的實驗到多模態整合的部署。PyTorch 讓我們能夠快速製作原型和構建模型,這在我們的廣告服務發展和擴充套件過程中至關重要。為了獲得額外的好處,PyTorch 與 Inferentia 和我們的亞馬遜雲科技機器學習堆疊無縫協作。我們期待使用 PyTorch 構建更多用例,以便我們能夠繼續為客戶提供準確,實時的結果。

相關文章