自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

新聞 機(jī)器學(xué)習(xí)
本文重點(diǎn)關(guān)注了基于無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí)的最新研究進(jìn)展,并通過四篇研究論文表明了無服務(wù)器 ML 框架在執(zhí)行機(jī)器學(xué)習(xí)任務(wù)時(shí)性能遠(yuǎn)優(yōu)于經(jīng)典的基于粗粒度的 VM 集群的ML框架。

 一、機(jī)器學(xué)習(xí)和無服務(wù)器學(xué)習(xí)

1.1、機(jī)器學(xué)習(xí)(ML)在應(yīng)用場(chǎng)景中遇到了什么問題?

近年來,機(jī)器學(xué)習(xí)(Machine Learning,ML)在圖像識(shí)別、文本和語音處理等領(lǐng)域中廣泛應(yīng)用,改變了人們工作、生活的方式,帶來了巨大的便利性。但同時(shí),ML 用戶也面臨著幾個(gè)巨大的挑戰(zhàn),這些挑戰(zhàn)極大地阻礙了 ML 的生產(chǎn)力和效率。首先,用戶通常需要手動(dòng)配置許多系統(tǒng)級(jí)參數(shù),例如工作服務(wù)器 / 參數(shù)服務(wù)器的數(shù)量、內(nèi)存分配、cpu 數(shù)量、物理拓?fù)涞?。其次,用戶需要指定大量與 ML 相關(guān)的參數(shù),如學(xué)習(xí)率、學(xué)習(xí)算法、神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)等,這些參數(shù)與系統(tǒng)級(jí)參數(shù)之間還存在各種交互作用。第三,ML 工作流通常由多個(gè)階段組成,包括預(yù)處理、訓(xùn)練、超參數(shù)搜索等等,每個(gè)階段都有 ML 用戶必須考慮的不同計(jì)算需求。

由于 ML 的這些特點(diǎn),在實(shí)際應(yīng)用中經(jīng)常會(huì)導(dǎo)致兩個(gè)問題:

一是,ML 工作流中不同任務(wù)的異構(gòu)性導(dǎo)致了訓(xùn)練工作流執(zhí)行過程中資源的嚴(yán)重不平衡。ML 用戶需要單獨(dú)考慮每個(gè)階段的異構(gòu)資源需求,常常會(huì)導(dǎo)致資源過度配置(Resource Overprovisioning)。當(dāng)前的 ML 框架通常是基于粗粒度的 VM 集群的,而這些集群并不具備 ML 相關(guān)工作負(fù)載所需的靈活性。CPU 總利用率低至 20% 的情況并不少見[1]。在實(shí)踐中,開發(fā)人員在工作流的不同階段反復(fù)使用不同的 ML 參數(shù)進(jìn)行實(shí)驗(yàn)會(huì)進(jìn)一步加劇資源過度配置的問題;

二是,ML 用戶需要應(yīng)對(duì)復(fù)雜的管理問題,他們面臨著為每個(gè) ML 工作負(fù)載提供、配置和管理這些資源的挑戰(zhàn)。利用 VMs 進(jìn)行機(jī)器學(xué)習(xí)工作負(fù)載的系統(tǒng)通常需要用戶重復(fù)執(zhí)行一系列繁重的任務(wù),表 1 中展示了一些任務(wù)。這種管理復(fù)雜性阻礙了交互和迭代用例,降低了用戶生產(chǎn)力和模型的有效性。

在實(shí)踐中,過度資源調(diào)配和顯式資源管理負(fù)擔(dān)這兩個(gè)問題是緊密耦合的:ML 用戶在遇到工作流不同階段所需資源精確分配所帶來的難度和人工成本的問題時(shí),通常會(huì)采用過度資源調(diào)配的方式來應(yīng)對(duì)。

那究竟用什么辦法應(yīng)對(duì) ML 在實(shí)踐中應(yīng)用的這些問題呢?在這篇文章中我們一起來探討一個(gè)目前廣泛應(yīng)用且獲得了非常好效果的辦法:無服務(wù)器計(jì)算(Serverless Computing)

表 1. ML 用戶在使用 VM 集群時(shí)遇到的任務(wù)挑戰(zhàn)。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

1.2、無服務(wù)器計(jì)算(Serverless Computing)

無服務(wù)器計(jì)算是云原生計(jì)算模型的一種落地狀態(tài)。云計(jì)算的發(fā)展在經(jīng)歷了基礎(chǔ)設(shè)施即服務(wù)(Infrastructure as a Service-IaaS)、平臺(tái)即服務(wù)(Platform as a Service-PaaS)、軟件即服務(wù)(Software as a Service-SaaS)幾個(gè)階段后,逐漸進(jìn)入了無服務(wù)器計(jì)算的階段。從與之前幾個(gè)階段所能提供的服務(wù)進(jìn)行比較的角度分析,無服務(wù)器計(jì)算可以提供以下一種或兩種服務(wù):

1. 函數(shù)即服務(wù) (Functions-as-a-Service-FaaS)。開發(fā)人員使用由事件(event) 或 HTTP 請(qǐng)求觸發(fā)的函數(shù)運(yùn)行和管理應(yīng)用程序代碼,開發(fā)人員將這些小的代碼單元部署到 FaaS 中,F(xiàn)aaS 按需執(zhí)行和擴(kuò)展,開發(fā)人員則無需管理服務(wù)器或任何其他底層基礎(chǔ)設(shè)施。

2. 后端即服務(wù)(Backend-as-a-Service-BaaS)。提供第三方的基于 API 的服務(wù)用于替換應(yīng)用程序中的核心功能子集。對(duì)于開發(fā)人員來說,這些 API 是作為一個(gè)自動(dòng)擴(kuò)縮容和透明操作的服務(wù)提供的,所以對(duì)于開發(fā)人員來說,這種服務(wù)方式也是無服務(wù)器的。

從技術(shù)實(shí)現(xiàn)的角度分析,無服務(wù)器計(jì)算依靠云基礎(chǔ)設(shè)施而不是用戶來自動(dòng)解決資源調(diào)配和管理的挑戰(zhàn)。這種方法依賴于一個(gè)更受限制的計(jì)算單元,例如 AWS Lambda 的無狀態(tài) Lambda 函數(shù)(the Stateless Lambda Function),該計(jì)算單元由開發(fā)人員提交,并由云基礎(chǔ)設(shè)施安排執(zhí)行。因此,用戶無需手動(dòng)配置、部署和管理長(zhǎng)期計(jì)算單元(例如 VM)。無服務(wù)器模式的優(yōu)勢(shì)促進(jìn)了數(shù)據(jù)中心、云提供商和開放源代碼平臺(tái)的快速應(yīng)用。

無服務(wù)器計(jì)算所提供的服務(wù)包括:一種有時(shí)間限制的無狀態(tài)函數(shù)作為執(zhí)行程序邏輯的服務(wù) API,以及,一種管理程序狀態(tài)的對(duì)象存儲(chǔ)系統(tǒng)。通過使用服務(wù) API,用戶可以運(yùn)行代碼函數(shù) (也稱為操作) 并返回每個(gè)函數(shù)的結(jié)果。無服務(wù)器計(jì)算還提供 HTTPS 終端,允許開發(fā)人員檢索函數(shù)結(jié)果,開發(fā)人員可以通過 HTTPS 終端輸入?yún)?shù)后生成相關(guān)函數(shù)的觸發(fā)事件(或鏈接)。對(duì)于能夠清晰地分離程序狀態(tài)和邏輯的應(yīng)用程序設(shè)計(jì)人員來說,無服務(wù)器計(jì)算平臺(tái)提供了對(duì)大型計(jì)算能力的即時(shí)訪問,使得程序設(shè)計(jì)人員無需進(jìn)行復(fù)雜的集群部署。

在無服務(wù)器計(jì)算平臺(tái)中,云服務(wù)提供商提供了按需執(zhí)行函數(shù)的能力,并對(duì)最終用戶隱藏了集群配置和管理開銷。除了可用性方面的好處外,這種模式還提高了效率:云提供商可以以比傳統(tǒng)集群計(jì)算更精細(xì)的粒度復(fù)用資源,并且用戶不需要為空閑資源付費(fèi)。然而,為了有效地管理資源,云服務(wù)提供商對(duì)每種資源的使用進(jìn)行了限制。

計(jì)算(computation)。無服務(wù)器計(jì)算平臺(tái)中提供的計(jì)算資源通常僅限于一個(gè) CPU 核和一個(gè)較短的計(jì)算窗口。例如,AWS Lambda 在單個(gè) AVX 內(nèi)核上提供 900 秒的計(jì)算時(shí)間,可以訪問高達(dá) 3GB 的內(nèi)存和 512MB 的磁盤存儲(chǔ)。用戶可以執(zhí)行許多并行函數(shù),并且這些執(zhí)行的聚合計(jì)算性能幾乎呈線性擴(kuò)展。函數(shù)執(zhí)行中的線性可伸縮性只在單個(gè) worker 之間沒有通信的情況下對(duì)并行計(jì)算有用。在實(shí)際應(yīng)用中,由于單個(gè) worker 只是瞬時(shí)存在的,他們的啟動(dòng)時(shí)間可能是錯(cuò)開的,因此傳統(tǒng)的類似 MPI 的點(diǎn)對(duì)點(diǎn)通信模型無法在這種環(huán)境中工作。我們可以考慮利用存儲(chǔ)作為 worker 之間的間接通信通道。

存儲(chǔ)(Storage)。云服務(wù)提供商提供了多種存儲(chǔ)選項(xiàng),從鍵值存儲(chǔ)到關(guān)系型數(shù)據(jù)庫。有些服務(wù)不完全是彈性的,因?yàn)樗鼈冃枰A(yù)先提供資源。然而,像 Amazon S3 或 Google Cloud Storage 這樣的分布式對(duì)象存儲(chǔ)系統(tǒng)提供了無限存儲(chǔ),用戶只需按存儲(chǔ)的數(shù)據(jù)量付費(fèi)。我們可以考慮潛在地將計(jì)算期間的中間狀態(tài)存儲(chǔ)在分布式對(duì)象存儲(chǔ)中,并且仍然可以獲得與從其他節(jié)點(diǎn)的 RAM 訪問時(shí)相同的帶寬。

控制面(Control Plane)。除了存儲(chǔ)服務(wù),云服務(wù)提供商還提供發(fā)布 - 訂閱服務(wù),如 Amazon SQS 或 Google Task Queue。這些服務(wù)通常不支持高數(shù)據(jù)訪問帶寬,但提供一致性保證,如至少一次傳遞,并且可以用于 “控制平面” 狀態(tài):所有無服務(wù)器函數(shù)調(diào)用之間共享的任務(wù)隊(duì)列。云服務(wù)提供商還提供一致的鍵值存儲(chǔ)(例如 DynamoDB),可用于跨無服務(wù)器函數(shù)調(diào)用存儲(chǔ)和操作控制平面狀態(tài)。

由于無服務(wù)器計(jì)算存在上述約束條件,在實(shí)際應(yīng)用中,無服務(wù)器計(jì)算也不是 “完美無缺” 的,應(yīng)用無服務(wù)器計(jì)算也面臨很多問題。以 AWS Lambda 為例,利用無服務(wù)器計(jì)算的主要挑戰(zhàn)是與 Lambda 函數(shù)相關(guān)聯(lián)的非常小的本地資源約束(內(nèi)存、cpu、存儲(chǔ)、網(wǎng)絡(luò)),這是無服務(wù)器計(jì)算的基礎(chǔ),正因?yàn)檫@些細(xì)粒度的計(jì)算單元實(shí)現(xiàn)了可伸縮性和靈活性。具體的,無服務(wù)器計(jì)算面臨著如下問題:

本地內(nèi)存和存儲(chǔ)空間?。⊿mall local memory and storage)。由于存在計(jì)算資源限制,阻止了使用任何未使用這些資源設(shè)計(jì)的計(jì)算框架。例如,我們無法在 AWS Lambda 或具有此類資源受限配置的 VM 上運(yùn)行 Tensorflow 或 Spark。

低帶寬以及缺乏 P2P 通信(Low bandwidth and lack of P2P communication)。與常規(guī) VM 相比,Lambda 函數(shù)的可用帶寬有限。我們發(fā)現(xiàn),最大的 AWS Lambda 只能維持 60MB/s 的帶寬,即使在中型 VM 中,也遠(yuǎn)遠(yuǎn)低于 1GB/s 的可用帶寬。此外,無服務(wù)器計(jì)算對(duì)通信拓?fù)涫┘恿诉M(jìn)一步的限制。諸如 AWS Lambda 之類的無服務(wù)器計(jì)算單元不允許對(duì)等通信。因此,傳統(tǒng)的用于數(shù)據(jù)中心 ML 的通用通信策略,例如樹結(jié)構(gòu)或環(huán)結(jié)構(gòu) AllReduce 通信等等,在這樣的環(huán)境中都無法有效實(shí)現(xiàn)。

短暫且不可預(yù)測(cè)的加載時(shí)間(Short-lived and unpredictable launch times)。Lambda 函數(shù)的壽命很短,且啟動(dòng)時(shí)間非常多變。例如,AWS Lambda 在加載后可能需要幾分鐘的時(shí)間來啟動(dòng)。這意味著在訓(xùn)練過程中,Lambda 會(huì)在不可預(yù)知的時(shí)間開始,并且有可能在訓(xùn)練中途結(jié)束。這就要求 Lambda 的 ML 運(yùn)行時(shí)能夠容忍 worker 的頻繁離開和到達(dá)。

缺乏快速共享存儲(chǔ)(Lack of fast shared storage)。因?yàn)?Lambda 函數(shù)之間不能連接,所以需要使用共享存儲(chǔ)。由于 ML 算法有嚴(yán)格的性能要求,這種共享存儲(chǔ)需要低延遲、高吞吐量,并針對(duì) ML 工作負(fù)載中的通信類型進(jìn)行優(yōu)化。然而,到目前為止,還沒有能夠?yàn)樵铺峁┧羞@些屬性的快速無服務(wù)器存儲(chǔ)。

不過,目前已經(jīng)有不少無服務(wù)器計(jì)算的落地應(yīng)用案例。其中,有代表性的公有云無服務(wù)器平臺(tái)有:

AWS Lambda。亞馬遜的 AWS Lambda,借助 Lambda,幾乎可以為任何類型的應(yīng)用程序或后端服務(wù)運(yùn)行代碼,而且完全無需管理。只需上傳代碼,Lambda 會(huì)處理運(yùn)行和擴(kuò)展高可用性代碼所需的一切工作。開發(fā)人員可以將代碼設(shè)置為自動(dòng)從其他 AWS 服務(wù)觸發(fā),或者直接從任何 Web 或移動(dòng)應(yīng)用程序調(diào)用。https://aws.amazon.com/cn/lambda/。

Microsoft Azure Functions。微軟的 Azure 是一個(gè)事件驅(qū)動(dòng)(Event-drive)的無服務(wù)器計(jì)算平臺(tái),可以解決復(fù)雜的編排問題。本地構(gòu)建和調(diào)試,無需額外設(shè)置,在云中大規(guī)模部署和操作,并使用觸發(fā)器和綁定集成服務(wù)。https://azure.microsoft.com/en-us/services/functions/。

Google Cloud Functions。Google 的 Cloud Functions 是一種事件驅(qū)動(dòng)的計(jì)算服務(wù)。它具有自動(dòng)擴(kuò)展、運(yùn)行代碼以響應(yīng)事件的能力,僅在代碼運(yùn)行時(shí)付費(fèi)的能力,并且不需要任何服務(wù)器管理。用例包括無服務(wù)器應(yīng)用程序后端,實(shí)時(shí)數(shù)據(jù)處理和智能應(yīng)用程序,如虛擬助手,聊天機(jī)器人和情緒分析。https://cloud.google.com/functions/

阿里云函數(shù)計(jì)算(Function Compute)。阿里的函數(shù)計(jì)算是一個(gè)事件驅(qū)動(dòng)的全托管無服務(wù)器計(jì)算服務(wù),無需管理服務(wù)器等基礎(chǔ)設(shè)施,只需編寫代碼并上傳,函數(shù)計(jì)算會(huì)準(zhǔn)備好計(jì)算資源,并以彈性、可靠的方式運(yùn)行代碼。所有客戶,函數(shù)計(jì)算都將提供每月 100 萬次函數(shù)調(diào)用、400,000 個(gè)函數(shù)實(shí)例資源的免費(fèi)無服務(wù)器算力支持。https://www.aliyun.com/product/fc?spm=5176.10695662.1112509.1.3b6768bc2OOWFL。

有代表性的私有云無服務(wù)器框架有:

Fission 。Fission 使用 Kubernetes 構(gòu)建函數(shù)。它允許程序員使用任何編程語言編寫函數(shù),并將其與任何事件觸發(fā)器 (如 HTTP 請(qǐng)求) 進(jìn)行映射。https://fission.io/。

Funktion 。Funktion 是一個(gè)開源的容器本地化服務(wù)器平臺(tái),使用 Kubernetes 構(gòu)建函數(shù)。它允許程序員用任何編程語言編寫函數(shù),可以在任何地方、任何云上或在本地運(yùn)行。https://github.com/funktionio/funktion。

Kubeless 。是一個(gè) kubernets 原生的無服務(wù)器計(jì)算框架。它利用 Kubernetes 資源提供自動(dòng)縮放、API 路由、監(jiān)控、故障恢復(fù)等功能。https://github.com/kubeless/kubeless。

Apache OpenWhisk 。OpenWhisk 使用 Docker 構(gòu)建函數(shù),它允許程序員使用 Scala 語言編寫函數(shù),允許在任何規(guī)模的事件響應(yīng)中執(zhí)行代碼??蚣茼憫?yīng)類似 HTTP 請(qǐng)求這樣的觸發(fā)事件,然后運(yùn)行 JavaScript 或 Swift 代碼片段。https://openwhisk.apache.org/。

Iron Functions 。Iron 使用 Docker、Swarm、Kubernetes 構(gòu)建函數(shù),它允許程序員使用 Go 語言編寫函數(shù)。https://github.com/iron-io/functions。

OpenLambda。OpenLambda 是一個(gè) Apache 許可的無服務(wù)器計(jì)算項(xiàng)目,用 Go 編寫,基于 Linux 容器。OpenLambda 的主要目標(biāo)是探索無服務(wù)器計(jì)算的新方法。https://github.com/open-lambda/open-lambda。

OpenFaas 。OpenFaaS 是一個(gè)使用 Docker 構(gòu)建無服務(wù)器 (Serverless) 功能的框架,它擁有對(duì)指標(biāo)的一級(jí)支持。任何流程都可以打包為一個(gè)函數(shù),使你能夠使用一系列 web 事件,而無需重復(fù)的樣板化編碼。https://www.oschina.net/p/openfaas?hmsr=aladdin1e1。

有代表性的無服務(wù)器平臺(tái)的包裝框架有:

Zappa(Python,AWS)。Zappa 極大的簡(jiǎn)化了在 AWS Lambda + API 網(wǎng)關(guān)上發(fā)布所有 Python WSGI 應(yīng)用。相當(dāng)于是無服務(wù)器的部署運(yùn)行 Python Web 應(yīng)用。這意味著無限伸縮、零宕機(jī)、零維護(hù)。https://www.oschina.net/p/python-zappa。

Chalice(Python,AWS)。Chalice 允許開發(fā)者快速創(chuàng)建和部署應(yīng)用,采用 Amazon API 網(wǎng)關(guān)和 AWS Lambda 。https://www.oschina.net/p/chalice?hmsr=aladdin1e1。

Claudia.js(Node,AWS)。方便快速部署 Node.js 項(xiàng)目到 AWS Lambda 和 API 網(wǎng)關(guān)。它自動(dòng)化了所有容易出錯(cuò)的部署和配置任務(wù),并按照 JavaScript 開發(fā)人員所期望的開箱即用的方式設(shè)置了一切。開發(fā)人員可以輕松地開始使用 Lambda 和 API 網(wǎng)關(guān),并專注于解決重要的業(yè)務(wù)問題,而不是處理 AWS 部署工作流。https://github.com/claudiajs/claudia。

二、引入 ML 的無服務(wù)器計(jì)算最新研究情況介紹

由上一節(jié)的介紹我們知道,目前已經(jīng)有很多公有云、私有云無服務(wù)器計(jì)算平臺(tái),也有一些無服務(wù)器平臺(tái)的包裝框架??梢哉f,我們想在日常的應(yīng)用實(shí)踐中嘗試無服務(wù)器化,已經(jīng)是比較容易的一件事了。不過,具體到機(jī)器學(xué)習(xí)的問題,這些無服務(wù)器計(jì)算平臺(tái)在 ML 應(yīng)用場(chǎng)景下都或多或少存在一些問題。

由第一章中的介紹我們可以看到,無服務(wù)器計(jì)算非常適用于離散化數(shù)據(jù)中心(Disaggregated Datacenters),但對(duì)許多性能關(guān)鍵型應(yīng)用(Performance critical applications)卻不是非常適用,因?yàn)闊o服務(wù)器計(jì)算方式切斷了傳統(tǒng)的性能優(yōu)化途徑,例如利用數(shù)據(jù)局部性進(jìn)行優(yōu)化或分層通信等,因此會(huì)直接影響性能關(guān)鍵型應(yīng)用的效果。目前無服務(wù)器平臺(tái)主要用于簡(jiǎn)單的事件驅(qū)動(dòng)應(yīng)用程序,如物聯(lián)網(wǎng)自動(dòng)化、前端 web 服務(wù)和日志處理等等。

最近,一些研究人員將無服務(wù)器計(jì)算應(yīng)用在更廣泛的場(chǎng)景中,如并行數(shù)據(jù)分析和分布式視頻編碼。然而,這些工作負(fù)載要么只能簡(jiǎn)單并行,要么只能跨函數(shù)使用簡(jiǎn)單的通信模式。復(fù)雜的通信模式和工作負(fù)載如何有效地適應(yīng)無服務(wù)器計(jì)算仍然是一個(gè)有待研究的問題。我們這篇文章中重點(diǎn)關(guān)注的是用于 ML 的無服務(wù)器計(jì)算。我們知道,ML 包含大量的參數(shù)、復(fù)雜的處理流程,是典型的 “性能關(guān)鍵型應(yīng)用”,我們將在這一節(jié)中介紹最新的關(guān)于“如何將 ML 引入無服務(wù)器計(jì)算” 這一問題的研究進(jìn)展。

2.1、A Case for Serverless Machine Learning [2]

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

本文是來自 Berkeley 的研究人員發(fā)表在 NIPS2018 中的一篇文章,具體分析了 ML 工作負(fù)載環(huán)境下的資源管理問題,探討了利用無服務(wù)器基礎(chǔ)設(shè)施實(shí)現(xiàn) ML 工作流資源管理自動(dòng)化的研究方向。作者提出了一個(gè)無服務(wù)器機(jī)器學(xué)習(xí)框架,該框架專門用于無服務(wù)器基礎(chǔ)設(shè)施和 ML 工作流。

本文所討論的無服務(wù)器計(jì)算依賴于 Amazon S3 的無狀態(tài) Lambda 函數(shù),這些函數(shù)由開發(fā)人員提交,并由云基礎(chǔ)設(shè)施自動(dòng)調(diào)度。因此,它們避免了開發(fā)人員顯式配置、部署和管理長(zhǎng)期計(jì)算單元(例如 VM)的需要。與一般的無服務(wù)器計(jì)算平臺(tái)不同,無服務(wù)器機(jī)器學(xué)習(xí)框架需要滿足三個(gè)關(guān)鍵目標(biāo)。首先,它的 API 需要支持廣泛的 ML 任務(wù):數(shù)據(jù)預(yù)處理、訓(xùn)練和超參數(shù)優(yōu)化。為了簡(jiǎn)化從現(xiàn)有 ML 系統(tǒng)的轉(zhuǎn)換所涉及的工作量,應(yīng)該用 Python 之類的高級(jí)語言開發(fā)這樣的 API。第二,為了為無狀態(tài)工作者之間的中間數(shù)據(jù)和消息傳遞提供存儲(chǔ),它需要提供一個(gè)具有豐富接口的低延遲可伸縮數(shù)據(jù)存儲(chǔ)。第三,要在資源受限的 Lambda 上高效運(yùn)行,它的 Runtime 必須是輕量級(jí)和高性能的。

為了滿足這些條件,作者構(gòu)建了一個(gè)專門用于 ML 的無服務(wù)器框架。

首先,該框架為 ML 工作流的所有階段提供了一個(gè) API,該 API 實(shí)用且易于更廣泛的 ML 社區(qū)使用。(1)API 完全包含在 Python 包中,允許 ML 開發(fā)人員輕松調(diào)用。(2) API 提供了一個(gè)抽象底層系統(tǒng)級(jí)資源的高級(jí)接口。(3) Python 包提供了一個(gè)用戶界面,開發(fā)人員可以通過該界面可視化工作進(jìn)度。

然后,該框架包含 Python 前端提供到客戶端后端的接口。這個(gè)后端負(fù)責(zé)管理臨時(shí)計(jì)算資源和調(diào)度任務(wù)。在這個(gè)后端中,不同的子模塊為 ML 工作流的每個(gè)特定階段的邏輯(例如預(yù)處理)進(jìn)行編碼處理。這些子模塊啟動(dòng) Lambda 上的 worker,跟蹤計(jì)算進(jìn)度,并在計(jì)算完成后將結(jié)果返回到 Python 前端??蛻舳撕蠖耸褂脙?nèi)部低級(jí)調(diào)度程序,該調(diào)度程序封裝了與啟動(dòng)、終止和重新生成在無服務(wù)器 Lambda 上運(yùn)行的任務(wù)相關(guān)的所有邏輯。這個(gè)調(diào)度程序還跟蹤所有任務(wù)的狀態(tài)。

第三,該框架提供一個(gè)輕量級(jí) Runtime,它封裝了系統(tǒng)支持的不同計(jì)算之間共享的所有函數(shù),從而簡(jiǎn)化了新算法的開發(fā)。Worker runtime 提供兩個(gè)接口。首先,它提供了一個(gè)智能迭代器來訓(xùn)練存儲(chǔ)在 S3 中的數(shù)據(jù)集。這個(gè)迭代器在 Lambda 的本地內(nèi)存中預(yù)取和緩沖 mini-batch,與 worker 的計(jì)算并行,以減輕訪問 S3 的高延遲(>10ms)。它為分布式數(shù)據(jù)存儲(chǔ)提供了一個(gè) API。

最后,該框架為 workers 之間的中間數(shù)據(jù)和通信提供具有豐富接口的共享存儲(chǔ)。此接口有兩種類型的 API:(1)用于一般消息傳遞、中間數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)縮減的鍵值存儲(chǔ),以及(2)參數(shù)服務(wù)器接口。為了達(dá)到所需的低延遲,將該數(shù)據(jù)存儲(chǔ)部署在云 VMs 上。為了有效地利用稀缺的網(wǎng)絡(luò)資源,對(duì)數(shù)據(jù)存儲(chǔ)接口進(jìn)行優(yōu)化處理,例如:數(shù)據(jù)壓縮、稀疏數(shù)據(jù)結(jié)構(gòu)、異步通信等。

為了實(shí)現(xiàn)簡(jiǎn)化機(jī)器學(xué)習(xí)工作流執(zhí)行的目標(biāo),理想的系統(tǒng)應(yīng)該提供一個(gè)簡(jiǎn)單但足夠通用的 API。這個(gè) API 需要讓用戶在一個(gè)單一的、集成的框架內(nèi)執(zhí)行 ML 任務(wù),例如:(1)數(shù)據(jù)集加載,支持常用的數(shù)據(jù)格式,(2)數(shù)據(jù)預(yù)處理,(3)模型訓(xùn)練,(4)大規(guī)模的超參數(shù)調(diào)整。

作者給出了一個(gè)例子來展示這個(gè) API 的功能——圖 1 中給出基于 Criteo Kaggle 競(jìng)爭(zhēng)開發(fā)模型的過程,該模型用于預(yù)測(cè)用戶點(diǎn)擊顯示廣告數(shù)據(jù)集的廣告的概率。工作流的第一步是加載數(shù)據(jù)集并將其上載到 Amazon S3。例如,用戶可以調(diào)用 load_libsvm 方法來加載以 LIBSVM 格式存儲(chǔ)的數(shù)據(jù)集,解析數(shù)據(jù)后自動(dòng)為其創(chuàng)建分區(qū),然后將其上載到 Amazon S3。第二步,一旦數(shù)據(jù)加載到 Amazon S3 中,就可以立即進(jìn)行預(yù)處理。系統(tǒng)應(yīng)該提供一些開發(fā)人員常用的預(yù)處理方法。例如,用戶可以通過使用 Amazon S3 中數(shù)據(jù)集的路徑調(diào)用 normalize 函數(shù)來規(guī)范化數(shù)據(jù)集。一旦加載了數(shù)據(jù),用戶就可以通過查看系統(tǒng)的測(cè)試損失來訓(xùn)練不同的模型并查看它們的性能。一旦用戶對(duì)某個(gè)特定的模型獲得了合理的損失,他們就可以通過超參數(shù)搜索對(duì)其進(jìn)行微調(diào)。此外,作者設(shè)想這樣一個(gè)系統(tǒng)允許用戶在每個(gè)階段的執(zhí)行過程中進(jìn)行多次交互。例如,當(dāng)超參數(shù)搜索任務(wù)正在運(yùn)行時(shí),用戶應(yīng)該能夠監(jiān)視每個(gè)單獨(dú)實(shí)驗(yàn)的測(cè)試損失。對(duì)于表現(xiàn)不好的實(shí)驗(yàn)(例如,測(cè)試損失發(fā)散(test loss is diverging)),用戶應(yīng)該能夠終止它們。這個(gè)特性可以通過交互環(huán)境(比如 Jupyter)中的用戶界面來實(shí)現(xiàn)。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 1. API 示例。無服務(wù)器 ML 的 API 應(yīng)該支持 ML 開發(fā)工作流的不同階段:(a)預(yù)處理,(b)訓(xùn)練,和(c)超參數(shù)調(diào)優(yōu)。

為了評(píng)估對(duì) ML 無服務(wù)器框架的需求,作者引入兩個(gè)框架進(jìn)行性能比對(duì):PyWren[3]和 Bosen[4]。PyWren 是一個(gè)專門用于無服務(wù)器架構(gòu)的 Map-reduce 框架。PyWren 提供了可縮放到數(shù)千個(gè) workers 的 map 和 reduce 原語。Bosen 是一個(gè)分布參數(shù)框架,專門用于基于 VM 的 ML 算法。為了進(jìn)行評(píng)估,作者在 PyWren 上實(shí)現(xiàn)了一個(gè)異步 SGD 訓(xùn)練算法。在 PyWren 基線實(shí)現(xiàn)的基礎(chǔ)上,作者還進(jìn)行了一組優(yōu)化。作者使用了來自 Criteo Kaggle 競(jìng)賽的 Criteo 展示廣告數(shù)據(jù)集進(jìn)行實(shí)驗(yàn)。作者在 10 個(gè)最大的 AWS Lambda(3GB 內(nèi)存)上運(yùn)行 PyWren,在單個(gè) VM(m5.2xlarge1)中的 8 個(gè)內(nèi)核上運(yùn)行 Bosen。

作者通過記錄隨時(shí)間變化的測(cè)試損失來測(cè)量這兩個(gè)系統(tǒng)的性能(圖 2)。對(duì)于 PyWren,作者在實(shí)現(xiàn)每個(gè)優(yōu)化之后報(bào)告這個(gè)值。作者累計(jì)實(shí)現(xiàn)了以下優(yōu)化:(1)跨迭代重用 Lambda;(2)使用異步 SGD 進(jìn)行小批量預(yù)取;(3)使用低延遲存儲(chǔ)(Redis)代替 Amazon S3;(4)使用具有多 get 操作的稀疏數(shù)據(jù)傳輸。我們觀察到這些優(yōu)化顯著改善了 Pyren 在 600 秒后實(shí)現(xiàn)的最終測(cè)試損失(從 0.61 到 0.57)。盡管有了這些改進(jìn),PyWren 仍然比 Bosen 慢得多。進(jìn)一步的性能分析表明,PyWren 存在一些開銷,例如序列化 / 反序列化數(shù)據(jù),以及使用接口不適合 ML 工作負(fù)載的遠(yuǎn)程存儲(chǔ)(例如 Redis 或 S3)。這一結(jié)果表明,在設(shè)計(jì)無服務(wù)器計(jì)算框架的早期,需要仔細(xì)考慮 ML 工作負(fù)載的性能需求。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 2. PyWren 和 Bosen 在 Criteo-Kaggle 邏輯回歸任務(wù)中的表現(xiàn)。PyWren 基線通過重用 Lambda、添加預(yù)取、切換到異步計(jì)算、用更高性能的 Redis 存儲(chǔ)后端替換 S3 以及支持在單個(gè) RPC 上獲取多個(gè)密鑰而得到了增量改進(jìn)。

此外,作者還構(gòu)建了本文所提出的框架的原型,包括:(1)具有參數(shù)服務(wù)器接口的高性能數(shù)據(jù)存儲(chǔ),(2)mini-batch 數(shù)據(jù)的循環(huán)緩沖區(qū)預(yù)取,(3)邏輯回歸 SGD 訓(xùn)練算法。為了充分驗(yàn)證這種設(shè)計(jì)的好處,作者在相同的邏輯回歸任務(wù)中對(duì)其進(jìn)行了評(píng)估。作者測(cè)量了每個(gè) worker 的平均 SGD 迭代時(shí)間(見圖 3)。這個(gè)時(shí)間是 worker 性能的一個(gè)指標(biāo);較低的迭代時(shí)間意味著更頻繁的模型更新和更快的收斂。作者還將這一次的 SGD 算法分解為四個(gè)主要步驟:(1)從數(shù)據(jù)存儲(chǔ)中獲取最新模型,(2)從遠(yuǎn)程存儲(chǔ)(例如 S3)中獲取一個(gè) minibatch,(3)計(jì)算 SGD 梯度,以及(4)將梯度發(fā)送到數(shù)據(jù)存儲(chǔ)。作者發(fā)現(xiàn),盡管無服務(wù)器計(jì)算具有固有的開銷,本文所提出的框架原型還是實(shí)現(xiàn)了較低的每次迭代時(shí)間( 500 μs)--- 與 Bosen 這樣的系統(tǒng)不相上下。這種性能源于兩種機(jī)制:(1)遠(yuǎn)程 mini-batch 的有效預(yù)取和緩沖,以及(2)盡可能與數(shù)據(jù)存儲(chǔ)通信。首先,minibatch 預(yù)取機(jī)制通過與計(jì)算并行進(jìn)行,有效地掩蓋了從 S3 獲取 minibatch 所需的時(shí)間。實(shí)際上,對(duì)于中型 / 大型 Lambda,在新的 minibatch 上開始計(jì)算所需的時(shí)間可以忽略不計(jì),因?yàn)榇蠖鄶?shù)情況下,這些數(shù)據(jù)都是在 worker 需要之前緩存在內(nèi)存中的。即使從 S3 獲取一個(gè) mini-batch 需要 10ms 也是這樣的。其次,作者發(fā)現(xiàn)與數(shù)據(jù)存儲(chǔ)的通信是有效的(例如,發(fā)送梯度的時(shí)間可以忽略不計(jì))。由于能夠與數(shù)據(jù)存儲(chǔ)異步通信,進(jìn)一步提升了該框架的性能。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 3. 本文所提出原型每次 SGD 迭代的時(shí)間。具體細(xì)分為四個(gè)主要步驟:(1)將梯度發(fā)送到數(shù)據(jù)存儲(chǔ),(2)計(jì)算梯度,(3)從數(shù)據(jù)存儲(chǔ)獲取模型,(4)從 S3 獲取 minibatch。

2.2、Cirrus: a Serverless Framework for End-to-end ML Workflows [5]

這篇文章也是節(jié) 2.1 中所介紹的 Berkeley 研究小組的研究成果,是對(duì)節(jié) 2.1 中分析的 NIPS’18 中文章所涉及工作的擴(kuò)展和延伸。在專門用于無服務(wù)器基礎(chǔ)設(shè)施和 ML 工作流的無服務(wù)器 ML 框架原型的基礎(chǔ)上,將其封裝為一個(gè)實(shí)現(xiàn)端到端管理的分布式 ML 訓(xùn)練框架 Cirrus,可以直接調(diào)用使用(https://github.com/ucbrise/cirrus),并將相關(guān)工作內(nèi)容發(fā)表在發(fā)表在 SoCC ’19 中。Cirrus 專門用于無服務(wù)器云基礎(chǔ)設(shè)施(如 Amazon AWS Lambda)中的 ML 訓(xùn)練。它提供高級(jí)原語來支持 ML 工作流中的一系列任務(wù):數(shù)據(jù)集預(yù)處理、訓(xùn)練和超參數(shù)優(yōu)化。Cirrus 結(jié)合了無服務(wù)器接口的簡(jiǎn)單性和無服務(wù)器基礎(chǔ)設(shè)施(具體是指 AWS Lambda 和 S3)的可伸縮性,以最小化用戶的工作。

Cirrus 的設(shè)計(jì)原則是:

自適應(yīng)的細(xì)粒度資源分配。為了避免由于過度配置而造成的資源浪費(fèi),Cirrus 應(yīng)該靈活地調(diào)整為每個(gè)工作流階段保留的細(xì)粒度資源量。

無狀態(tài)服務(wù)器端后端。為了確保無服務(wù)器計(jì)算資源的健壯和高效管理,Cirrus 設(shè)計(jì)了一個(gè)無狀態(tài)的服務(wù)器端后端。有關(guān)當(dāng)前部署的函數(shù)以及 ML 工作流任務(wù)和計(jì)算單元之間的映射的信息由客戶端后端管理。因此,即使所有云端資源變得不可用,ML 訓(xùn)練工作流也不會(huì)失敗,并且可以在資源再次可用時(shí)恢復(fù)其操作。

端到端無服務(wù)器 API。模型訓(xùn)練不是 ML 研究人員的唯一任務(wù),數(shù)據(jù)集預(yù)處理、特征工程和參數(shù)調(diào)整等對(duì)于最終生成一個(gè)好的模型同樣重要。Cirrus 應(yīng)該提供一個(gè)完整的 API,允許開發(fā)人員以最小的工作量端到端的大規(guī)模地運(yùn)行這些任務(wù)。

高可擴(kuò)展性。ML 任務(wù)是高度計(jì)算密集型的,在沒有有效并行化的情況下需要很長(zhǎng)時(shí)間才能完成。因此,Cirrus 應(yīng)該能夠同時(shí)運(yùn)行數(shù)千個(gè) workers 和數(shù)百個(gè)實(shí)驗(yàn)。

與節(jié) 2.1 中所介紹的工作類似,Cirrus 利用四個(gè)系統(tǒng)模塊來實(shí)現(xiàn)上述原則。首先,Cirrus 為 ML 開發(fā)人員提供了 Python 前端。這個(gè)前端有兩個(gè)功能:a)為 ML 訓(xùn)練的所有階段提供豐富的 API;b)在無服務(wù)器的基礎(chǔ)設(shè)施中執(zhí)行和管理大規(guī)模計(jì)算。其次,Cirrus 提供了一個(gè)客戶端后端。第三,為了克服低延遲無服務(wù)器存儲(chǔ)的不足,Cirrus 為 worker 共享的所有中間數(shù)據(jù)提供了低延遲分布式數(shù)據(jù)存儲(chǔ)。第四,Cirrus 提供了一個(gè)在無服務(wù)器 Lambda 上運(yùn)行的 worker 運(yùn)行時(shí)(runtime)。該運(yùn)行時(shí)提供了訪問 S3 中的訓(xùn)練數(shù)據(jù)集和分布式數(shù)據(jù)存儲(chǔ)中的中間數(shù)據(jù)的有效接口。Cirrus 的完整結(jié)構(gòu)見圖 4。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 4. Cirrus 系統(tǒng)結(jié)構(gòu)。系統(tǒng)由(有狀態(tài)的)客戶端(左)和(無狀態(tài)的)服務(wù)器端(右)組成。預(yù)處理和面向用戶的訓(xùn)練包含一個(gè)前端的 API??蛻舳撕蠖斯芾碓乒δ芎拖蚝瘮?shù)分配任務(wù)。服務(wù)器端由 Lambda Worker 和高性能數(shù)據(jù)存儲(chǔ)組件組成。Lambda worker 將數(shù)據(jù)迭代器 API 導(dǎo)出到客戶端后端,并包含許多迭代訓(xùn)練算法的有效實(shí)現(xiàn)。數(shù)據(jù)存儲(chǔ)用于存儲(chǔ)梯度、模型和中間預(yù)處理結(jié)果。

Cirrus 的整體結(jié)構(gòu)與節(jié) 2.1 中是類似的。Cirrus 的前端和客戶端后端是用 Python 實(shí)現(xiàn)的,方便 Cirrus 與現(xiàn)有的機(jī)器學(xué)習(xí)方法相結(jié)合。為了提高效率,分布式數(shù)據(jù)存儲(chǔ)和 worker runtime 用 C++ 實(shí)現(xiàn)。表 2 列出了實(shí)現(xiàn)的不同組件以及它們的大小和實(shí)現(xiàn)語言。Worker runtime 代碼包括迭代器接口和數(shù)據(jù)存儲(chǔ)客戶端實(shí)現(xiàn)。worker runtime 和數(shù)據(jù)存儲(chǔ)通過 TCP 連接進(jìn)行通信。作者實(shí)現(xiàn)了一個(gè)共享組件庫,其中包括線性代數(shù)庫、通用實(shí)用程序和 ML 算法,這些組件被所有系統(tǒng)組件共享。作者已經(jīng)公開發(fā)布了 Apache 2 開源許可的實(shí)現(xiàn)(https://github.com/ucbrise/cirrus)。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

表 2. Cirrus 組件。

首先,Cirrus 為 ML 工作流的所有階段提供了一個(gè) Python 前端 API。前端是一個(gè)高度靈活的 thin Python API,默認(rèn)情況下,它從開發(fā)人員那里抽象出所有的細(xì)節(jié),同時(shí)提供了通過 API 的參數(shù)覆蓋內(nèi)部配置參數(shù)(例如,優(yōu)化算法)的能力。前端還提供了一個(gè)運(yùn)行在 Plotly 上的用戶界面,供用戶監(jiān)控工作負(fù)載的進(jìn)度和啟動(dòng) / 停止任務(wù)。Cirrus Python API 分為三個(gè)子模塊。每個(gè)子模塊都打包了與工作流的每個(gè)階段相關(guān)的所有函數(shù)和類。(1)預(yù)處理。預(yù)處理子模塊允許用戶對(duì)存儲(chǔ)在 S3 中的訓(xùn)練數(shù)據(jù)集進(jìn)行預(yù)處理。此子模塊允許不同類型的數(shù)據(jù)集轉(zhuǎn)換:最小 - 最大縮放、標(biāo)準(zhǔn)化和特征散列。(2)訓(xùn)練。Cirrus 的訓(xùn)練子模塊支持 ML 模型,這些模型可以通過隨機(jī)梯度下降進(jìn)行訓(xùn)練。目前 Cirrus 支持稀疏 Logistic 回歸、潛在 Dirichlet 分配、Softmax 和協(xié)同過濾。(3)超參數(shù)優(yōu)化。超參數(shù)優(yōu)化子模塊允許用戶在給定的參數(shù)集上運(yùn)行網(wǎng)格搜索。Cirrus 允許用戶改變 ML 訓(xùn)練參數(shù)(例如,學(xué)習(xí)率、正則化率、小批量大?。┮约跋到y(tǒng)參數(shù)(例如,Lambda 函數(shù)大小、并發(fā) worker 數(shù)量、梯度過濾)。

其次,Cirrus 的 Python 前端提供了一個(gè)到 Cirrus 客戶端后端的接口。這個(gè)后端的功能和能夠完成的任務(wù)與節(jié) 2.1 中介紹的框架完全相同??蛻舳撕蠖藦那岸怂惴ㄖ谐橄蟪?Lambda 的管理??蛻舳撕笈_(tái)會(huì)保存一個(gè)當(dāng)前活動(dòng)的 Lambda 列表,以及一個(gè) AWS Lambda API 的連接列表(每個(gè)連接用于啟動(dòng)一個(gè) Lambda)。在訓(xùn)練期間加載的 Lambda 在其生存期結(jié)束時(shí)自動(dòng)重新加載(每 15 分鐘一次)。由于 Lambda API 的特殊性,從一臺(tái)服務(wù)器上快速加載數(shù)百個(gè) Lambda 是非常困難的。為了解決這個(gè)問題,后端保留一個(gè)線程池,可用于響應(yīng)新 Lambda 任務(wù)的請(qǐng)求。

第三,Cirrus 提供了分布式存儲(chǔ)模塊。Cirrus 的數(shù)據(jù)存儲(chǔ)用于存儲(chǔ)所有 workers 共享的中間數(shù)據(jù)。由于現(xiàn)有產(chǎn)品中不允許 Lambda 之間進(jìn)行交互通信,因此 Lambda 需要共享存儲(chǔ)。無服務(wù)器 Lambda 的存儲(chǔ)需要滿足三個(gè)條件:首先,它需要低延遲(本文實(shí)現(xiàn)低至 300μs),以便能夠適應(yīng)延遲敏感的工作負(fù)載,例如用于 ML 訓(xùn)練的工作負(fù)載(迭代 SGD)。其次,它需要擴(kuò)展到數(shù)百個(gè) workers,以利用無服務(wù)器基礎(chǔ)架構(gòu)幾乎線性的可擴(kuò)展性。第三,它需要一個(gè)豐富的接口來支持不同的 ML 用例。例如,數(shù)據(jù)存儲(chǔ)必須支持 multiget(§6.5)、常規(guī)鍵 / 值的 put/get 操作和參數(shù)服務(wù)器接口。為了實(shí)現(xiàn)低延遲,將數(shù)據(jù)存儲(chǔ)部署在云 VMs 中。它實(shí)現(xiàn)了低至 300μs 的延遲,而 AWS S3 的延遲約為 10ms。此延遲對(duì)于訓(xùn)練階段最大化模型的更新至關(guān)重要。作者使用稀疏表示來表征梯度和模型以實(shí)現(xiàn)高達(dá) 100 倍的壓縮比,以便與存儲(chǔ)和批處理請(qǐng)求進(jìn)行數(shù)據(jù)交換。為了實(shí)現(xiàn)高可伸縮性,Cirrus 包括以下機(jī)制:(1)分片存儲(chǔ),(2)高度多線程,(3)數(shù)據(jù)壓縮,(4)梯度濾波器和(5)異步通信。Cirrus 的分布式數(shù)據(jù)存儲(chǔ)提供了一個(gè)接口,支持所有在 ML 工作流中存儲(chǔ)中間數(shù)據(jù)的用例。該接口支持鍵值存儲(chǔ)接口(set/get)和參數(shù)服務(wù)器接口(send 果然啊 dient/get model)。

最后,Cirrus 提供了一個(gè)運(yùn)行時(shí)(Runtime),它封裝了系統(tǒng)支持的不同計(jì)算之間共享的所有函數(shù)。如圖 5,Cirrus 的 Runtime 為 ML 計(jì)算提供了通用抽象(General abstractions)和基本數(shù)據(jù)類型(Data primitives)用于訪問訓(xùn)練數(shù)據(jù)、參數(shù)模型和中間結(jié)果。這些可用于向 Cirrus 添加新的 ML 模型。為了簡(jiǎn)化新算法的開發(fā),Runtime 提供了一組線性代數(shù)庫。Cirrus 的初始版本使用外部線性代數(shù)庫如 Eigen 進(jìn)行梯度計(jì)算。為了減少 Eigen 處理序列化和反序列化數(shù)據(jù)的時(shí)間,作者最終開發(fā)了自己的線性代數(shù)庫。對(duì)于數(shù)據(jù)訪問,Runtime 提供了一個(gè)由本地循環(huán)緩沖區(qū)支持的基于 minibatch 的迭代器,允許 worker 以低延遲訪問訓(xùn)練 minibatch。此外,它還提供了一個(gè)高效的 API 來與分布式數(shù)據(jù)存儲(chǔ)進(jìn)行通信。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 5. Cirrus Runtime。minibatch 是異步預(yù)取的,并在每個(gè) Lambda 的內(nèi)存中本地緩存(取決于使用的 Lambda 的大?。⑻荻犬惒桨l(fā)送至參數(shù)服務(wù)器,每次迭代模型同步從參數(shù)服務(wù)器中進(jìn)行檢索。

作者給出了 Cirrus 在不同階段的詳細(xì)工作方式。

(1)數(shù)據(jù)加載和預(yù)處理。Cirrus 假設(shè)訓(xùn)練數(shù)據(jù)存儲(chǔ)在一個(gè)全局存儲(chǔ)中,比如 S3。因此,使用 Cirrus 的第一步就是將數(shù)據(jù)集上傳到云端。用戶將數(shù)據(jù)集的路徑傳遞給系統(tǒng),然后由系統(tǒng)負(fù)責(zé)解析和上載數(shù)據(jù)集。在此過程中,Cirrus 將數(shù)據(jù)集從其原始格式(如 csv)轉(zhuǎn)換為二進(jìn)制格式。這種壓縮消除了在訓(xùn)練和超參數(shù)調(diào)優(yōu)階段進(jìn)行反序列化的需要,這有助于減少 Lambda 工作進(jìn)程中的計(jì)算負(fù)載。其次,Cirrus 生成數(shù)據(jù)集大小相似的分區(qū),并將其上傳到 S3 存儲(chǔ)桶(S3 Bucket)。

Cirrus 還可以應(yīng)用變換(Transformations)來提高模型的性能。例如,對(duì)于 Cirrus 實(shí)現(xiàn)的異步 SGD 優(yōu)化方法,對(duì)數(shù)據(jù)集中的特征進(jìn)行規(guī)范化處理能夠提高訓(xùn)練的效果。對(duì)于這些 transformations,Cirrus 啟動(dòng)了一個(gè)大型 Map Reduce 作業(yè):每個(gè)輸入分區(qū)一個(gè) worker。在 map 階段,每個(gè) worker 計(jì)算其分區(qū)的統(tǒng)計(jì)信息(例如,平均值和標(biāo)準(zhǔn)差)。在 reduce 階段,這些局部統(tǒng)計(jì)信息被聚合以計(jì)算全局統(tǒng)計(jì)信息。在最后的映射階段,worker 轉(zhuǎn)換每個(gè)分區(qū)樣本,給出最終的每列統(tǒng)計(jì)信息。對(duì)于大型數(shù)據(jù)集,map 和 reduce 階段會(huì)跨大量 worker 和列來聚合每列的統(tǒng)計(jì)信息。這會(huì)造成每秒生成大量新的寫操作和讀操作,而超出了 S3 支持的事務(wù)吞吐量?;谶@個(gè)原因,作者使用 Cirrus 的低延遲分布式數(shù)據(jù)存儲(chǔ)來存儲(chǔ)映射的中間結(jié)果,并減少了計(jì)算量。

(2)模型訓(xùn)練。Cirrus 使用分布式 SGD 算法進(jìn)行模型訓(xùn)練。在訓(xùn)練期間,worker 運(yùn)行 Lambda 函數(shù),并迭代計(jì)算梯度步長(zhǎng)。每個(gè)梯度計(jì)算需要兩個(gè)輸入:一個(gè) minibatch 和最新的模型。minibatch 是 Cirrus 的運(yùn)行時(shí)通過迭代器從 S3 獲取的。因?yàn)榈髟诠ぷ鲀?nèi)存中緩沖 minibatch,所以檢索 minibatch 的延遲非常低。使用數(shù)據(jù)存儲(chǔ) API(get_sparse_model_X)從數(shù)據(jù)存儲(chǔ)中同步檢索最新的模型。對(duì)于每個(gè)迭代,每個(gè) worker 都計(jì)算一個(gè)新的梯度。然后將此梯度異步發(fā)送到數(shù)據(jù)存儲(chǔ)(send_gradient_X)以更新模型。

(3)超參數(shù)優(yōu)化。超參數(shù)優(yōu)化是一種模型參數(shù)的搜索方式,該模型參數(shù)能夠保證生成最佳準(zhǔn)確度。典型的做法是在多維參數(shù)空間上執(zhí)行網(wǎng)格搜索。搜索可以是暴力破解(Brute-force)搜索或自適應(yīng)搜索。常見的做法是讓網(wǎng)格搜索完整地運(yùn)行,然后對(duì)結(jié)果進(jìn)行后處理,以找到最佳配置。這是一種代價(jià)高昂的資源浪費(fèi)。Cirrus 通過提供超參數(shù)搜索儀表板(Hyperparameter search dashboard),來解決這種超時(shí)過度配置問題(over-provisioning over time)。Cirrus 超參數(shù)儀表板提供了一個(gè)統(tǒng)一的界面,用于監(jiān)控模型隨時(shí)間變化的損失收斂情況。它允許用戶選擇單個(gè)損失曲線并終止相應(yīng)的訓(xùn)練實(shí)驗(yàn)。因此,Cirrus 提供了:?jiǎn)?dòng)超參數(shù)搜索的 API 和執(zhí)行后端;監(jiān)控模型精度收斂的儀表板;終止單個(gè)調(diào)優(yōu)實(shí)驗(yàn)的能力,并節(jié)省了過度配置成本。

在文獻(xiàn) [2] 工作的基礎(chǔ)上,Cirrus 為 ML 用戶提供了一個(gè)輕量級(jí)的 Python API。作者同樣給出了一個(gè)例子來展示這個(gè) API 的功能。如圖 6 所示,這個(gè) API 與圖 1 中給出的文獻(xiàn) [2] 中的 API 幾乎相同。區(qū)別在于本文已經(jīng)將 Cirrus 封裝為模塊“cirrus”,可直接在 python 中進(jìn)行 import。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 6. Cirrus API 示例。Cirrus 支持 ML 開發(fā)工作流的不同階段:(a)預(yù)處理,(b)訓(xùn)練,和(c)超參數(shù)調(diào)優(yōu)。

作者利用稀疏邏輯回歸任務(wù)對(duì)比 Cirrus 和兩個(gè)專門用于基于 VM 的 ML 訓(xùn)練框架:TensorFlow[6]和 Bosen[4]。TensorFlow 是一個(gè)用于 ML 計(jì)算的通用數(shù)據(jù)流引擎。Bosen 是一個(gè)分布式和多線程參數(shù)服務(wù)器,由 CMU 開發(fā) Petuum 商業(yè)化,它針對(duì)大規(guī)模分布式集群和機(jī)器學(xué)習(xí)算法的陳舊更新進(jìn)行了優(yōu)化。邏輯回歸是計(jì)算任何給定樣本屬于兩個(gè)感興趣的類的概率問題。本文實(shí)驗(yàn)中作者計(jì)算網(wǎng)站廣告被點(diǎn)擊的概率,并利用時(shí)間函數(shù)評(píng)估學(xué)習(xí)收斂性。使用 Criteo 顯示廣告數(shù)據(jù)集[7]。這個(gè)數(shù)據(jù)集包含 45M 個(gè)樣本,大小為 11GB。每個(gè)樣本包含 13 個(gè)數(shù)字特征和 26 個(gè)分類特征。在訓(xùn)練之前,對(duì)數(shù)據(jù)集進(jìn)行了歸一化處理,將分類特征哈希為一個(gè)大小為 2^20 的稀疏向量。為了評(píng)估 Bosen,作者使用 1、2 和 4 個(gè) m5.2xlarge 亞馬遜 AWS 實(shí)例(每個(gè)實(shí)例有 8 個(gè) CPU 和 32GB 內(nèi)存)。對(duì)于 Bosen 實(shí)驗(yàn),作者將數(shù)據(jù)集分區(qū)到所有機(jī)器上。為了評(píng)估 Cirrus,作者使用 Amazon AWS Lambda 作為 worker,m5.large 實(shí)例(2 個(gè) CPU,8GB 內(nèi)存,10Gbps 網(wǎng)絡(luò))作為參數(shù)服務(wù)器,AWS S3 存儲(chǔ)用于訓(xùn)練數(shù)據(jù)和定期備份型。作者報(bào)告了嘗試兩個(gè)系統(tǒng)的學(xué)習(xí)率范圍后得到的最佳結(jié)果。對(duì)于 Bosen,只改變學(xué)習(xí)率和工人數(shù)量。所有其他配置參數(shù)都保留默認(rèn)值。

圖 7a 顯示了不同數(shù)量的服務(wù)器(對(duì)于 Bosen)和 AWS Lambda(對(duì)于 Cirrus)在一段時(shí)間內(nèi)實(shí)現(xiàn)的邏輯測(cè)試損失。通過對(duì)一個(gè)包含 50K 樣本的數(shù)據(jù)集上的訓(xùn)練模型評(píng)估以得到損失值。作者發(fā)現(xiàn),Cirrus 的收斂速度明顯快于 Bosen。Bosen 的性能因?yàn)?worker 相互競(jìng)爭(zhēng)共享本地緩存受到影響,該緩存在將梯度發(fā)送到參數(shù)服務(wù)器之前聚合梯度。這種設(shè)計(jì)最終導(dǎo)致了 Bosen 收斂速度較慢。在圖 7b 中,作者使用相同的數(shù)據(jù)集和相同的預(yù)處理步驟將 Cirrus 與 TensorFlow 進(jìn)行了比較。同樣地,Cirrus 性能優(yōu)于 TensorFlow。

圖 7c 中的實(shí)驗(yàn)對(duì)比的是 Cirrus 和 Spark 完成協(xié)同過濾任務(wù)的性能,該實(shí)驗(yàn)中使用的是 Netflix 數(shù)據(jù)庫[8]。由圖 7c,Cirrus 比 Spark 收斂得更快,測(cè)試損耗更低。此外,作者還觀察到 Spark 的 ALS 實(shí)現(xiàn)受到昂貴的 RDD 開銷的影響,因?yàn)?Spark 需要將整個(gè)數(shù)據(jù)集加載到內(nèi)存中。這導(dǎo)致 Spark 花了超過 94% 的時(shí)間來做與訓(xùn)練模型不直接相關(guān)的工作。相比之下,Cirrus 從 S3 連續(xù)向 worker 流式傳輸數(shù)據(jù),這使得他們可以立即開始計(jì)算。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 7. (a) Bosen 和 Cirrus 之間不同設(shè)置的時(shí)間損失比較。Bosen 達(dá)到的最佳損失為 0.485,Cirrus 達(dá)到最佳損失的速度至少快了 5 倍(200 秒 vs 1000 秒)。與最先進(jìn)的 ML 訓(xùn)練框架相比,Cirrus 可以在一個(gè)或兩個(gè) Lambda 的壽命內(nèi)(300-600 秒)更快地收斂,并且損失更低。(b) Tensorflow Criteo_tft 基準(zhǔn)和 Cirrus 的收斂與時(shí)間曲線。Tensorflow 是在 32 核節(jié)點(diǎn)上執(zhí)行的,Cirrus 在 10 個(gè) Lambda 中運(yùn)行。(c) 運(yùn)行 Netflix 數(shù)據(jù)集時(shí),Spark (ALS)和 Cirrus 的 RMSE 隨時(shí)間變化曲線。Spark 在運(yùn)行 Netflix 數(shù)據(jù)集時(shí),前 4 分鐘處理數(shù)據(jù),并在 ALS 的 5 次迭代中收斂(RMSE=0.85)后終止。Cirrus 能夠更快收斂到較低的 RMSE(0.833)。

圖 8 中的實(shí)驗(yàn)驗(yàn)證的是 Cirrus 的可擴(kuò)展性(Scalability)。通過設(shè)計(jì)該系統(tǒng)以實(shí)現(xiàn) 3 個(gè)維度的擴(kuò)展:用 S3 存儲(chǔ)訓(xùn)練數(shù)據(jù),用 Lambda 計(jì)算,以及用分布式參數(shù)服務(wù)器共享內(nèi)存,來實(shí)現(xiàn)擴(kuò)展性。

存儲(chǔ)擴(kuò)展性:Cirrus 通過將 S3 中的訓(xùn)練數(shù)據(jù)集分割成中等大小的對(duì)象來解決這個(gè)問題。作者使用 10MB 的對(duì)象,因?yàn)樽髡甙l(fā)現(xiàn)這個(gè)大小可以實(shí)現(xiàn)良好的網(wǎng)絡(luò)利用率,同時(shí)對(duì)于最小尺寸的 Lambda 來說也足夠小。通過使用大型對(duì)象,減少了每秒的請(qǐng)求數(shù)量。因此,當(dāng)每個(gè) worker 從 S3 消耗 30MB/s 的訓(xùn)練數(shù)據(jù)時(shí),能夠?qū)?S3 的吞吐量線性擴(kuò)展到 1000 個(gè) Cirrus workers(圖 8a)。

計(jì)算擴(kuò)展性:由圖 8b,沒有模型和參數(shù)的同步得情況下 Cirrus 可以通過并行傳輸輸入訓(xùn)練數(shù)據(jù)和計(jì)算梯度來實(shí)現(xiàn)線性計(jì)算可伸縮性。

參數(shù)服務(wù)器擴(kuò)展性:在參數(shù)服務(wù)器層面,主要挑戰(zhàn)來自于每個(gè)虛擬機(jī) VM 有限的網(wǎng)絡(luò)帶寬,以及更新模型和 worker 請(qǐng)求服務(wù)器所需的計(jì)算。Cirrus 通過 1)模型分片,2)稀疏梯度 / 模型,3)數(shù)據(jù)壓縮,4)異步通信來解決這個(gè)問題。Cirrus 實(shí)現(xiàn)了線性可擴(kuò)展性,最高可達(dá) 600 個(gè) worker(圖 8c)。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 8. AWS 存儲(chǔ)(GB / 秒)、AWS 無服務(wù)器計(jì)算(梯度 / 秒)和 Cirrus 數(shù)據(jù)存儲(chǔ)(樣本 / 秒)的可擴(kuò)展性。每個(gè) worker 消耗 30MB/s 的訓(xùn)練數(shù)據(jù)。

最后,作者對(duì)比了專門的 ML 系統(tǒng) PyWren 與 Cirrus。PyWren 是一個(gè)運(yùn)行在無服務(wù)器 Lambda 上的 map-reduce 框架。它提供了可擴(kuò)展至數(shù)千名 worker 的 map 和 reduce 原語。PyWren 的 Runtime 經(jīng)過優(yōu)化可以在 AWS Lambda 上運(yùn)行,AWS Lambda 也是本文用于 Cirrus 實(shí)驗(yàn)的無服務(wù)器平臺(tái)。作者在實(shí)驗(yàn)中對(duì) PyWren 進(jìn)行了優(yōu)化,使其每次模型更新的平均時(shí)間提高了 700 倍(從 14 秒到 0.02),但其模型每秒更新次數(shù)仍然遠(yuǎn)低于 Cirrus(圖 9b),并且收斂速度明顯慢于 Cirrus(圖 9a)。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 9. PyWren 和 Cirrus 在 10 個(gè) Lambda 上運(yùn)行時(shí)在稀疏邏輯回歸工作負(fù)載上的性能。由于結(jié)合了預(yù)取、在模型訓(xùn)練迭代中重復(fù)使用 Lambda 以及通過 Cirrus 的快速數(shù)據(jù)存儲(chǔ)進(jìn)行高效的模型共享,Cirrus 實(shí)現(xiàn)了 2 個(gè)數(shù)量級(jí)的模型更新數(shù)量增長(zhǎng)。訓(xùn)練數(shù)據(jù)預(yù)取解決了 S3 的高訪問延遲問題,從而使更新速度增加了 10 倍 / 秒。

2.3、Distributed Machine Learning with a Serverless Architecture [9]

本文作者介紹了一個(gè)完全基于無服務(wù)器架構(gòu)的分布式機(jī)器學(xué)習(xí)新框架:SIREN。SIREN 由本地客戶端和無服務(wù)器云平臺(tái)(例如 Amazon Lambda)組成,前者使用深度強(qiáng)化學(xué)習(xí)(Deep Reinforcement Learning,DRL)agent 進(jìn)行資源調(diào)度決策,后者根據(jù)這些調(diào)度決策為 ML 訓(xùn)練作業(yè)加載無狀態(tài)函數(shù)(Stateless Functions)。SIREN 的完整結(jié)構(gòu)框架如圖 10。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 10.SIREN 結(jié)構(gòu)

首先,將一個(gè)代碼包部署到無服務(wù)器云平臺(tái)中,其中包含用戶定義的 ML 模型及其所依賴的庫。然后,根據(jù)初始資源方案(即函數(shù)的數(shù)量和內(nèi)存大?。┘虞d無狀態(tài)函數(shù)群,進(jìn)行基于 SGD 的第一個(gè) epoch 訓(xùn)練。在第一個(gè) epoch 結(jié)束時(shí),收集作業(yè)的函數(shù)狀態(tài)和統(tǒng)計(jì)數(shù)據(jù),并以狀態(tài)(States)的形式反饋給本地客戶端的 DRL agent,DRL agent 將采取行動(dòng)為下一個(gè) epoch 做出資源調(diào)度決策。SIREN 會(huì)隨著訓(xùn)練作業(yè)的 epoch 推進(jìn)自適應(yīng)調(diào)整資源調(diào)度決策:在不同的 epoch 中,可以啟動(dòng)不同數(shù)量、不同內(nèi)存配置的函數(shù)。

SIREN 采用的是 SGD 算法,使用 mini-batches 并在多個(gè) Lambda 函數(shù)上運(yùn)行。每個(gè) Lambda 函數(shù)的作用就類似于傳統(tǒng)參數(shù)服務(wù)器架構(gòu)中的 worker。SIREN 與參數(shù)服務(wù)器架構(gòu)的一個(gè)主要區(qū)別是,在 SIREN 中不存在參數(shù)服務(wù)器來處理模型參數(shù)更新。相反,數(shù)據(jù)和模型都存儲(chǔ)在一個(gè)共同的數(shù)據(jù)存儲(chǔ)中(例如 Amazon S3),所有函數(shù)都可以訪問。每個(gè)函數(shù)從公共存儲(chǔ)中讀取當(dāng)前模型,根據(jù) mini-batches 訓(xùn)練數(shù)據(jù)計(jì)算梯度,然后直接用新計(jì)算的梯度更新公共存儲(chǔ)中的模型。因此,整個(gè)架構(gòu)是無服務(wù)器的。在 SIREN 中,作者提出了一種混合同步并行(Hybrid synchronous parallel,HSP)計(jì)算模式。如圖 11 所示,在每個(gè) epoch 內(nèi),所有的函數(shù)都可以異步更新模型,同時(shí)在每個(gè) epoch 結(jié)束時(shí)施加一個(gè)同步屏障(Synchronization barrier),以便完成下一個(gè) epoch 的資源調(diào)度。

已知 epoch 為 t,第 k 個(gè) mini-batch 為Ξ_t,k,更新模型為:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

在 epoch t-1 結(jié)束時(shí)的模型ω與ω_t,0 相同。HSP 在無服務(wù)器架構(gòu)中是高效的,因?yàn)榧虞d的函數(shù)是同質(zhì)的,從而導(dǎo)致每個(gè) epoch 的同步代價(jià)都很低。在無服務(wù)器云平臺(tái)中,調(diào)用和終止函數(shù)也是輕量級(jí)的。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 11. 無服務(wù)器云上的混合同步并行(HSP)處理。

作者使用 Python 代碼實(shí)現(xiàn)了 SIREN,支持 AWS Lambda 之上的 ML 模型訓(xùn)練,并全面支持 MXNet APIs。機(jī)器學(xué)習(xí)開發(fā)人員可以在 SIREN 上運(yùn)行他們的傳統(tǒng) MXNet 項(xiàng)目,而無需重構(gòu)現(xiàn)有代碼。如圖 10 所示,SIREN 包括三個(gè)主要部分:(1)封裝 MXNet 機(jī)器學(xué)習(xí)庫的代碼包;(2)用 AWS SDK boto3 構(gòu)建本地客戶端,調(diào)用并管理 AWS Lambda 中的無狀態(tài)函數(shù);(3)用 TensorFlow 實(shí)現(xiàn) DRL agent,進(jìn)行動(dòng)態(tài)資源配置決策。此外,還對(duì) AWS Lambda 進(jìn)行了一系列約束,以保證無狀態(tài)函數(shù)的輕量級(jí)和可移植性。

由于 AWS Lambda 的編程 runtime 不支持原生的 ML 訓(xùn)練算法,作者在代碼包中引入了一部分 MXNet ML 庫。在 AWS Lambda 上,代碼包大小限制為 250 MB,這使得直接將任何現(xiàn)成的 ML 庫(如 MXNet、TensorFlow)加載到 AWS Lambda 上都是不可行的。為了縮小 MXNet 代碼包的大小,作者用不同的編譯選項(xiàng)組合重新編譯了 MXNet 源代碼,并排除了無服務(wù)器云中不必要的編譯選項(xiàng)。例如,禁用了 USE_CUDA、USE_CUDNN 和 USE_OPENMP 等選項(xiàng)。

在 AWS Lambda 上,單個(gè)函數(shù)的計(jì)算能力也受到限制:要求每個(gè) Lambda 函數(shù)最多在 300 秒內(nèi)執(zhí)行完畢,最大內(nèi)存大小為 3GB。但是,由于 AWS Lambda 支持每個(gè) AWS 賬戶中多達(dá) 3000 個(gè)函數(shù)并發(fā)執(zhí)行,因此 SIREN 通過使用大量 Lambda 函數(shù)并行化 ML 訓(xùn)練工作負(fù)載實(shí)現(xiàn)了高度的并行性。

作者提出了一種深度強(qiáng)化學(xué)習(xí)(Deep reinforcement learning,DRL)技術(shù),用于完成 SIREN 中的動(dòng)態(tài)資源部署。強(qiáng)化學(xué)習(xí) (RL) 是一種經(jīng)驗(yàn)驅(qū)動(dòng)的方法,agent 通過與動(dòng)態(tài)環(huán)境的交互以及執(zhí)行行動(dòng)獲得獎(jiǎng)勵(lì)來學(xué)習(xí)如何在動(dòng)態(tài)環(huán)境中表現(xiàn)。DRL 利用深度神經(jīng)網(wǎng)絡(luò) (Deep neural network,DNN) 來解決 RL 問題。agent 觀察來自動(dòng)態(tài)環(huán)境的各種噪聲信號(hào),這些信號(hào)被稱為狀態(tài)(state),并將這些狀態(tài)反饋給 DNN 由其產(chǎn)生動(dòng)作。agent 在環(huán)境中采取動(dòng)作并獲得獎(jiǎng)勵(lì),而獎(jiǎng)勵(lì)又被用來更新 DNN 中的參數(shù),以做出更好的決策。DRL 在一個(gè)閉環(huán)中工作以改善決策,其最終目標(biāo)是使總獎(jiǎng)勵(lì)最大化。

作者考慮在一個(gè)有 M 個(gè)樣本的數(shù)據(jù)集上訓(xùn)練 ML 工作負(fù)載,總獎(jiǎng)勵(lì)預(yù)算為 B。如果達(dá)到一定的損失值 L 或者總獎(jiǎng)勵(lì)預(yù)算 B 用完,則訓(xùn)練終止。在任何一個(gè) epoch t,調(diào)度器將對(duì)并行調(diào)用的函數(shù)數(shù)量(用 n_t 表示)以及每個(gè)函數(shù)的內(nèi)存大小 m_t 做出判斷。令 f_t,i 表示在第 t 個(gè) epoch 加載第 i 個(gè)活躍函數(shù),如圖 11 所示。需要注意的是,如果函數(shù) i 已經(jīng)到了它的運(yùn)行壽命,則會(huì)調(diào)用一個(gè)新的函數(shù)來代替它,且仍然用 f_t,i 來表示,所以在 epoch t 中總會(huì)有 n_t 個(gè)函數(shù)在并發(fā)執(zhí)行。在每一個(gè)函數(shù) f_t,i 中,重復(fù)計(jì)算一個(gè)新的 mini-batch 數(shù)據(jù)的聚合梯度,并根據(jù) HSP 模式下的 SGD 更新模型參數(shù)。

在 epoch t 中,假設(shè)函數(shù) f_t,i 花費(fèi)一個(gè)完整周期(P^F)_t,i 來獲取 mini-batch 數(shù)據(jù),(P^C)_t,i 計(jì)算梯度,(P^U)_t,i 更新模型參數(shù)。函數(shù) i 在 epoch t 的完整執(zhí)行時(shí)間為:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

epoch t 在 HSP 的全部持續(xù)時(shí)間為 P_t=max_i(P_t,i)。在 epoch t 結(jié)束時(shí),ML 任務(wù)的損失值更新為 l_t。

無服務(wù)器云根據(jù)函數(shù)執(zhí)行時(shí)間和函數(shù)內(nèi)存大小向用戶收費(fèi)。令 c 表示使用 1GB 內(nèi)存執(zhí)行一個(gè)函數(shù)一秒鐘的單價(jià)。一個(gè) epoch t 的總花費(fèi)為:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?
無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

而 ML 任務(wù)的總的獎(jiǎng)勵(lì)成本為:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

其中,T 表示 epoch 的總數(shù)。本文所述任務(wù)的目標(biāo)是最小化作業(yè)完成時(shí)間,即在一定獎(jiǎng)勵(lì)預(yù)算 B 約束下解決以下優(yōu)化問題:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

在每個(gè) epoch t 開始時(shí),DRL agent 決定資源配置計(jì)劃 (n_t, m_t),即 DRL 任務(wù)中的動(dòng)作 action,具體如圖 12。衡量動(dòng)作(n_t, m_t) 有效性的方法是在每個(gè) epoch t 的結(jié)束進(jìn)行數(shù)字 reward 量化計(jì)算。計(jì)算的依據(jù)是這個(gè) epoch 持續(xù)的時(shí)間 P_t 和任務(wù)結(jié)束時(shí)預(yù)算是否透支。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 12.DNN 策略表示的 DRL。

狀態(tài)(State):在本文所描述的問題中,epoch t 的狀態(tài)表示為:

其中,l_t 表示 epoch t 的損失值,(P^F)_t、(P^C)_t、(P^U)_t 分別表示獲取、平均計(jì)算和平均模型參數(shù)更新時(shí)間,P_t 為 epoch 的執(zhí)行時(shí)間。u_t 和ω_t 分別表示平均內(nèi)存和 CPU 的利用情況,b_t 為剩余預(yù)算。

動(dòng)作(Action):在本文所描述的問題中,動(dòng)作表示為 a_t=(n_t, m_t)。n_t 表示激活的函數(shù)數(shù)量,m_t 表示每個(gè)函數(shù)的內(nèi)存大小。DRL agent 根據(jù)策略選擇操作,策略定義為給定當(dāng)前狀態(tài)下整個(gè)操作空間的概率分布π(a | s)。作者使用策略梯度方法,通過參數(shù)θ的函數(shù)來近似策略π(a | s)。因此,策略π可以寫成π(a | s, θ),其中θ是要學(xué)習(xí)的參數(shù)。將策略π定義為實(shí)值空間的高斯概率密度:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

基于條件概率π(a_t | s_t-1, θ)確定動(dòng)作 a_t。然后,在一個(gè)大的離散作用空間上學(xué)習(xí)概率質(zhì)量函數(shù)的問題就轉(zhuǎn)化為在一個(gè)二維連續(xù)空間中尋找參數(shù) (μ(s,θ),σ(s,θ)) 的問題。

獎(jiǎng)勵(lì)(Reward):在本文所描述的問題中,每個(gè) epoch 結(jié)束時(shí)獎(jiǎng)勵(lì)定義為:r_t=-β P_t,其中β為正則化系數(shù)。epoch t 的時(shí)間越長(zhǎng),agent 得到的獎(jiǎng)勵(lì)就越少。最后一個(gè) epoch T 的獎(jiǎng)勵(lì)為:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

換句話說,如果作業(yè)成功停止,即在不超出預(yù)算 B 的情況下滿足收斂閾值 L,則向 agent 分配正 C 的獎(jiǎng)勵(lì)。否則,如果作業(yè)失敗,即在用完預(yù)算 B 之前還沒有收斂,則給獎(jiǎng)勵(lì)賦值為負(fù) C。在 DRL 中,agent 學(xué)習(xí)的是累計(jì)折扣獎(jiǎng)勵(lì):

其中,γ ∈ (0, 1]為未來折扣獎(jiǎng)勵(lì)因子。在整個(gè) DRL 訓(xùn)練過程中,上式中的目標(biāo)函數(shù)引導(dǎo)著 agent 找到最優(yōu)的估計(jì)值。

作者模擬了一個(gè)無服務(wù)器的云環(huán)境,運(yùn)行由 DRL agent 控制的 mini-batch SGD 算法。作者使用 OpenAI Gym 實(shí)現(xiàn)模擬環(huán)境(https://gym.openai.com (https://gym.openai.com/)),OpenAI Gym 是一個(gè)用于評(píng)估強(qiáng)化學(xué)習(xí)算法的開源接口。實(shí)驗(yàn)?zāi)康氖球?yàn)證與傳統(tǒng)的網(wǎng)格搜索(Grid Search)基線方法所找到的最優(yōu)(靜態(tài))策略相比使用 SIREN 進(jìn)行調(diào)度的優(yōu)勢(shì)。作者比較了在 AWS Lambda 上使用 SIREN 和在 EC2 集群上使用 MXNet 訓(xùn)練 ML 作業(yè)的完成時(shí)間和成本。具體實(shí)驗(yàn)中選擇了三種類型的 EC2 實(shí)例來構(gòu)建測(cè)試集群:m4.large(2 vCPU,8GB 內(nèi)存)、m4.xlarge(4 vCPU,16GB 內(nèi)存)和 m4.2xlarge(8 vCPU,32GB 內(nèi)存),每小時(shí)分別收費(fèi) 0.1 美元、0.2 美元和 0.4 美元。

圖 13 給出了 SIREN 與網(wǎng)格搜索最佳函數(shù)數(shù)量的比較實(shí)驗(yàn)。圖 13(a)比較了通過網(wǎng)格搜索和 SIREN 實(shí)現(xiàn)的訓(xùn)練時(shí)間。與網(wǎng)格搜索相比,SIREN 在預(yù)算為 300 美元的情況下最多可減少 36% 的訓(xùn)練時(shí)間。如圖 13(b)所示,網(wǎng)格搜索列舉了不同預(yù)算下不同數(shù)量的函數(shù)的總獎(jiǎng)勵(lì)情況。SIREN 能夠根據(jù)經(jīng)驗(yàn)動(dòng)態(tài)調(diào)整函數(shù)數(shù)量。圖 13(c)給出了分配給每個(gè) epoch 的函數(shù)數(shù)量。在前幾個(gè) epoch 中,SIREN 啟動(dòng)了大量的函數(shù)以快速降低損失值;在后幾個(gè) epoch,agent 減少了函數(shù)數(shù)量以節(jié)省成本。SIREN 的 DRL agent 通過與模擬的無服務(wù)器云的迭代交互進(jìn)行在線訓(xùn)練。圖 13(d)中的學(xué)習(xí)曲線表明,agent 通過探索不同數(shù)量的函數(shù)來學(xué)習(xí)最大化總獎(jiǎng)勵(lì)。agent 的訓(xùn)練在大約 200 次迭代之后完成。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 13. SIREN 與網(wǎng)格搜索最佳函數(shù)數(shù)量比較。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 14. 通過 SIREN 和 EC2 上的 MXNet 對(duì) MNIST 數(shù)據(jù)集訓(xùn)練 LeNet。

圖 14 的實(shí)驗(yàn)對(duì)比 SIREN 和 EC2 上的 MXNet。圖 14(a)顯示了使用 12 個(gè) EC2 集群和使用 SIREN 訓(xùn)練 LeNet 的完成時(shí)間和相應(yīng)的成本。由于 EC2 集群的異質(zhì)性,EC2 上的成本與訓(xùn)練完成時(shí)間呈非線性關(guān)系。例如,m4.xlarge×6 集群和 m4.2xlarge×6 集群幾乎在同一時(shí)間完成訓(xùn)練,但后者產(chǎn)生的成本是前者的兩倍。相比之下,SIREN 通過更多的投資縮短了完成時(shí)間。圖 14(b)顯示,SIREN 動(dòng)態(tài)調(diào)整每個(gè)訓(xùn)練 epoch 的函數(shù)及其內(nèi)存。當(dāng)函數(shù)數(shù)量減少時(shí),每個(gè)函數(shù)收到的訓(xùn)練數(shù)據(jù)分區(qū)更大,需要更大的內(nèi)存來處理數(shù)據(jù)分區(qū)。SIREN 中的 DRL agent 是通過與 AWS Lambda 在線交互進(jìn)行訓(xùn)練的。從圖 14(c)中的學(xué)習(xí)曲線可以看出,經(jīng)過 150 次左右的迭代,DRL agent 的訓(xùn)練已經(jīng)完成。

進(jìn)一步的,作者在 m4.2xlarge instances 的集群上訓(xùn)練 LeNet、CNN 模型和線性分類模型并確定相應(yīng)的成本。然后,在成本相同的情況下在 m4.2xlarge×8 集群上用 SIREN 訓(xùn)練同樣的模型。圖 15 中的實(shí)驗(yàn)數(shù)據(jù)顯示,與相同成本的 EC2 集群相比,SIREN 使用這些模型分別減少了 40%、39.4% 和 44.3% 的訓(xùn)練時(shí)間。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 15. 不同模型相同成本預(yù)算下 SIREN 與 EC2 的比較。

2.4、Serverless Linear Algebra [10]

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

本文作者構(gòu)建了 NumPyWren:一個(gè)基于無服務(wù)器編程模型的線性代數(shù)系統(tǒng),以及 LAmbdaPACK:一個(gè)為高度并行線性代數(shù)算法的無服務(wù)器執(zhí)行而設(shè)計(jì)的領(lǐng)域特定語言。相關(guān)工作發(fā)表在 SoCC’20 中。

無服務(wù)器計(jì)算(例如,AWS Lambda、Google Cloud Functions、Azure Functions)是一種編程模型,云提供商在其中管理服務(wù)器同時(shí)動(dòng)態(tài)管理資源分配。通常,無服務(wù)器平臺(tái)計(jì)算會(huì)公開一個(gè)有時(shí)間限制的、無狀態(tài)的 FaaS API,以及一個(gè)管理程序狀態(tài)的對(duì)象存儲(chǔ)系統(tǒng)。對(duì)于能夠清晰地分離程序狀態(tài)和邏輯的應(yīng)用程序設(shè)計(jì)人員來說,無服務(wù)器平臺(tái)提供了對(duì)大型計(jì)算能力的即時(shí)訪問,而無需應(yīng)對(duì)復(fù)雜集群部署的開銷。

本文所研究的內(nèi)容:密集線性代數(shù)(Dense linear algebra)極大地受益于現(xiàn)有的以服務(wù)器為中心的數(shù)據(jù)中心。現(xiàn)有的分布式線性代數(shù)框架可以通過利用局部性、網(wǎng)絡(luò)拓?fù)浜蛦蝹€(gè)服務(wù)器內(nèi)的資源緊密集成來完成高性能計(jì)算。在這樣的背景下作者提出這樣一個(gè)問題:這些線性代數(shù)算法能否成功地移植到一個(gè)分散數(shù)據(jù)中心中?也就是說,我們能否在無服務(wù)器編程模型中實(shí)現(xiàn)與基于 MPI 的分布式線性代數(shù)框架相當(dāng)?shù)男阅埽?/p>

本文作者構(gòu)建了 NumPyWren,一個(gè)在無服務(wù)器架構(gòu)上完成線性代數(shù)任務(wù)的系統(tǒng)。NumPyWren 執(zhí)行使用 LAmbdaPACK 編寫的程序,LAmbdaPACK 是作者構(gòu)建的一個(gè)高級(jí) DSL,可以簡(jiǎn)潔地表示任意基于分片的線性代數(shù)算法。NumPyWren 通過無狀態(tài)函數(shù)執(zhí)行來執(zhí)行大規(guī)模密集線性代數(shù)程序。通過對(duì)中間語言 LAmbdaPACK 的分析,作者最終證明了分散式無服務(wù)器計(jì)算模型(Disaggregated serverless computing model)可以用于具有復(fù)雜通信程序的計(jì)算密集型程序。

NumPyWren 解決的是類似 Cholesky 分解的線性代數(shù)問題??紤]求解線性方程 Ax=b 的問題,其中 a 是對(duì)稱正定矩陣。我們可以先把 a 分解成兩個(gè)三角形矩陣 a=LL^T,然后解兩個(gè)相對(duì)簡(jiǎn)單的 Ly=b 和 L^T x=y 得到解 x。從這個(gè)過程中可以看出,分解是該求解問題中計(jì)算代價(jià)最高的步驟。Communication-Avoiding Cholesky 是一個(gè)很好的計(jì)算 Cholesky 分解的算法。該算法將矩陣分成若干塊,并得出一個(gè)計(jì)算順序使總數(shù)據(jù)傳輸量最小。具體算法如下:

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

如圖 16,在 outer loop(j)的每一步中,算法首先計(jì)算單個(gè)塊 Ajj 的 Cholesky 分解(圖 16(a))。這個(gè)結(jié)果用來更新由 Aij 下面的列塊組成的 "面板(panel)"(圖 16(b))。最后,第 j 列右邊的所有區(qū)塊都會(huì)根據(jù)各自的位置,通過索引更新面板(圖 16(c))。通過向下移動(dòng)對(duì)角線重復(fù)這一過程(圖 16(d))。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 16. 并行 Cholesky 分解的前 4 個(gè)時(shí)間步驟:0)對(duì)角塊 Cholesky 分解,1)并行列更新,2)并行子矩陣更新,3)(后續(xù))對(duì)角塊 Cholesky 分解。

作者針對(duì) Algorithm 1 提出了兩點(diǎn)問題。首先,作者認(rèn)為 Algorithm 1 在執(zhí)行過程中展現(xiàn)出了動(dòng)態(tài)并行性。外循環(huán)(Outer loop)由三個(gè)不同的步驟組成,具有不同的并行度,從 O(1)、O(K)到 O(K2),其中 K 是每個(gè)步驟的封閉子矩陣大小。其次,該算法在這三個(gè)步驟之間存在細(xì)粒度的依賴關(guān)系,無論是在一個(gè)迭代內(nèi)還是在多個(gè)迭代之間。由此,作者提出了本文所考慮的工作,即:實(shí)現(xiàn)適應(yīng)可用的并行化,作者通過將程序分解為可并行運(yùn)行的細(xì)粒度執(zhí)行單元來實(shí)現(xiàn)這一點(diǎn)。為了在無狀態(tài)環(huán)境中實(shí)現(xiàn)這一點(diǎn),作者建議以分散的方式執(zhí)行依賴性分析。將描述程序控制流的全局依賴圖分發(fā)給每個(gè) worker。然后,每個(gè) worker 根據(jù)其在全局任務(wù)圖中的當(dāng)前位置,對(duì)其下游依賴關(guān)系進(jìn)行本地推理。

首先,我們介紹本文提出的 LAmbdaPACK:一種用于實(shí)現(xiàn)并行線性代數(shù)算法的特定語言。LAmbdaPACK 是生成和使用矩陣塊(Tiled matrices)的命令式程序。這些程序可以對(duì)標(biāo)量值執(zhí)行基本的算術(shù)和邏輯運(yùn)算。它們不能直接讀取或?qū)懭刖仃囍?;相反,所有?shí)質(zhì)性的計(jì)算都是通過調(diào)用矩陣塊上的本機(jī)內(nèi)核來執(zhí)行的。矩陣塊由索引引用,LAmbdaPACK 程序的主要作用是對(duì)內(nèi)核調(diào)用排序,并計(jì)算每個(gè)調(diào)用的分塊索引。LAmbdaPACK 包括簡(jiǎn)單的 for 循環(huán)和 if 語句,但是沒有遞歸,只有從 LAmbdaPACK 到內(nèi)核的一級(jí)函數(shù)調(diào)用。每個(gè)矩陣塊索引只能寫入一次,這是許多函數(shù)式語言的共同設(shè)計(jì)原則。LAmbdaPACK 中的原語功能強(qiáng)大,包括 Tall Skinny QR(TSQR)、LU、Cholesky 和奇異值分解等等。LAmbdaPACK 的示例性描述如圖 17 所示。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 17. LAmbdaPACK 語言的示例性描述。

關(guān)于 LAmbdaPACK 的算法分析主要包括兩個(gè)階段。由于原始未壓縮的 DAG 非常大,其節(jié)點(diǎn)數(shù)可能會(huì)隨著 Cholesky 或 QR 等算法的輸入大小呈立方級(jí)增長(zhǎng),因此,第一階段的任務(wù)是分析程序并提取任務(wù)的壓縮 DAG。DAG 中的每個(gè)任務(wù)對(duì)應(yīng)一個(gè)數(shù)組寫入,我們還需提取執(zhí)行此任務(wù)所需的內(nèi)核計(jì)算和數(shù)組讀取。由于每個(gè)數(shù)組讀取都有一個(gè)唯一的上游寫入任務(wù),因此此過程是可跟蹤處理的。第二個(gè)階段發(fā)生在 runtime,在執(zhí)行任務(wù)之后,能夠動(dòng)態(tài)發(fā)現(xiàn)下游任務(wù)。使用當(dāng)前循環(huán)變量綁定的信息來查詢下游任務(wù)的壓縮 DAG。圖 18 和圖 19 分別給出了 LAmbdaPACK 的 DAG 和程序示例。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 18.LAmbdaPACK DAG 示例。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 19. LAmbdaPACK 程序示例。

LAmbdaPACK 中沒有并行原語,而是 LAmbdaPACK runtime 通過靜態(tài)分析程序來推斷底層依賴關(guān)系圖。為了并行執(zhí)行程序,作者從程序產(chǎn)生的依賴結(jié)構(gòu)構(gòu)造了一個(gè)內(nèi)核調(diào)用的 DAG。作者借用并擴(kuò)展了循環(huán)優(yōu)化技術(shù)(loop optimization),將 LAmbdaPACK 程序轉(zhuǎn)換為隱式有向無環(huán)圖(Implicit DAG)。將程序 DAG 中的每個(gè)節(jié)點(diǎn) N 表示為一個(gè)元組(line_number, loop_indices)。利用這個(gè)信息,可以執(zhí)行程序迭代空間中的任何語句。

接下來,作者解決推導(dǎo) DAG 中特定節(jié)點(diǎn)的下游依賴關(guān)系問題。作者提出在 runtime 處理依賴性分析:每當(dāng)一個(gè)存儲(chǔ)位置被寫入時(shí),確定從同一存儲(chǔ)位置讀取的 N(所有行,所有循環(huán)索引)中的表達(dá)式。每當(dāng)一個(gè)存儲(chǔ)位置被寫入時(shí),我們確定從同一存儲(chǔ)位置讀取 N(所有行,所有循環(huán)索引)中的表達(dá)式。作者將約束建模為一個(gè)方程組。假設(shè)單個(gè)線性代數(shù)算法中的行數(shù)必然很小,而程序迭代空間通常非常大。當(dāng)數(shù)組僅由循環(huán)變量的仿射函數(shù)索引時(shí),即形式為 ai+b 的函數(shù),其中 i 是循環(huán)變量,a 和 b 是編譯時(shí)已知的常數(shù),則可以使用循環(huán)優(yōu)化來有效地查找特定節(jié)點(diǎn)的依賴關(guān)系。

如圖 19 中的程序示例,如果在 runtime 一個(gè) worker 正在執(zhí)行程序的第 7 行,i=0、j=1 和 k=1,以查找下游依賴項(xiàng),則分析器將掃描這 7 行中的每一行,并計(jì)算是否存在一組有效的循環(huán)索引,以便在程序中的該點(diǎn)讀取 S[1,1,1]。如果是這樣,那么元組(line_number, loop_indices)定義了該任務(wù)的下游依賴項(xiàng),并確定為當(dāng)前任務(wù)的子任務(wù)。為了便于訪問和開發(fā),作者將 LAmbdaPACK 嵌入 Python 中。由于大多數(shù) LAmbdaPACK 調(diào)用優(yōu)化的 BLAS 和 LAPACK 內(nèi)核,因此使用高級(jí)解釋語言的性能損失很小。LAmbdaPACK 詳細(xì)流程見 Algorithm2。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

然后,我們介紹本文提出的 NumPyWren 框架。NumPyWren 框架包括五個(gè)獨(dú)立可擴(kuò)展的主要組件:runtime 狀態(tài)存儲(chǔ)、任務(wù)隊(duì)列、輕量級(jí)全局任務(wù)調(diào)度器、無服務(wù)器計(jì)算 runtime 和分布式對(duì)象存儲(chǔ)。圖 20 展示了 NumPyWren 框架組件。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

圖 20. NumPyWren 執(zhí)行框架的體系結(jié)構(gòu),具體為 6x6cholesky 分解期間的 runtime 狀態(tài)。

任務(wù)排隊(duì)(Task Queue):客戶端進(jìn)程將需要執(zhí)行的第一個(gè)任務(wù)排隊(duì)到任務(wù)隊(duì)列中。任務(wù)隊(duì)列是一個(gè)發(fā)布 - 訂閱樣式的隊(duì)列,它包含 DAG 中的所有節(jié)點(diǎn),這些節(jié)點(diǎn)的輸入依賴關(guān)系都已滿足并準(zhǔn)備好執(zhí)行。

執(zhí)行器配置(Executor Provisioning):任務(wù)隊(duì)列的長(zhǎng)度由配置者(Provisioner)監(jiān)控,provisioner 管理計(jì)算資源以匹配執(zhí)行期間的動(dòng)態(tài)并行性。在第一個(gè)任務(wù)排隊(duì)后,provisioner 啟動(dòng)一個(gè)執(zhí)行器(executor),并根據(jù)任務(wù)隊(duì)列大小維護(hù)活動(dòng) executor 的數(shù)量。由于 provisioner 的角色只是輕量級(jí)的,所以它也可以作為 “無服務(wù)器” 云函數(shù)定期執(zhí)行。

任務(wù)執(zhí)行(Task Execution):執(zhí)行器管理 NumPyWren 任務(wù)的執(zhí)行和調(diào)度。一旦執(zhí)行器準(zhǔn)備就緒,它就輪詢?nèi)蝿?wù)隊(duì)列以獲取可用的任務(wù),并執(zhí)行任務(wù)中的編碼指令。大多數(shù)任務(wù)涉及從對(duì)象存儲(chǔ)讀取輸入和將輸出寫入對(duì)象存儲(chǔ),以及執(zhí)行 BLAS/LAPACK 函數(shù)等。假定對(duì)象存儲(chǔ)是一個(gè)分布式持久存儲(chǔ)系統(tǒng),它支持單個(gè)密鑰的先讀后寫一致性。使用一個(gè)帶有單一靜態(tài)賦值語言的持久對(duì)象存儲(chǔ),有助于設(shè)計(jì)容錯(cuò)協(xié)議。當(dāng)執(zhí)行器接近無服務(wù)器系統(tǒng)的 runtime 限制時(shí)(AWS Lambda 為 900),執(zhí)行器自動(dòng)終止。如果有必要的話,provisioner 將負(fù)責(zé)雇傭新 worker。容錯(cuò)協(xié)議能夠?qū)崿F(xiàn)即使工作進(jìn)程超過 runtime 限制或是在執(zhí)行過程中被云提供商殺死,程序仍能在有效狀態(tài)下運(yùn)行。

Runtime 狀態(tài)更新(Runtime state update):一旦任務(wù)執(zhí)行完成并且輸出被持久化,執(zhí)行器就會(huì)更新 runtime 狀態(tài)存儲(chǔ)中的任務(wù)狀態(tài)。runtime 狀態(tài)存儲(chǔ)跟蹤整個(gè)執(zhí)行的控制狀態(tài),并且需要支持每個(gè)任務(wù)的快速更新。如果已完成的任務(wù)具有 “ready” 子任務(wù),則執(zhí)行器會(huì)將該子任務(wù)添加到任務(wù)隊(duì)列中。狀態(tài)存儲(chǔ)的原子性保證了每個(gè)子任務(wù)都能夠被調(diào)度。這個(gè)使用執(zhí)行器執(zhí)行調(diào)度的過程實(shí)現(xiàn)了高效、分散、細(xì)粒度的任務(wù)調(diào)度。由于計(jì)算和存儲(chǔ)的分離,NumPyWren 中的容錯(cuò)非常容易實(shí)現(xiàn)。因?yàn)閷?duì)對(duì)象存儲(chǔ)的所有寫入都是持久的,所以在任務(wù)完成后都不需要重新計(jì)算。

任務(wù)租用(Task Lease):在 NumPyWren 中,所有掛起的和可執(zhí)行的任務(wù)都存儲(chǔ)在一個(gè)任務(wù)隊(duì)列中。保持一個(gè)不變量,即任務(wù)只有在完成后才能從隊(duì)列中刪除(例如,runtime 狀態(tài)存儲(chǔ)已更新,輸出持久化到對(duì)象存儲(chǔ))。當(dāng)一個(gè) worker 獲取一條任務(wù),這個(gè) worker 就獲得了該任務(wù)的租約(lease)。在租用期間,該任務(wù)被標(biāo)記為不可見,以防止其他 workers 獲取這條任務(wù)。

故障檢測(cè)和恢復(fù)(Failure Detection and Recovery):在正常操作期間,worker 將使用后臺(tái)線程續(xù)訂任務(wù)租約,直到任務(wù)完成。如果任務(wù)完成,worker 將從隊(duì)列中刪除該任務(wù)。如果 worker 失敗,它將無法再續(xù)訂租約,并且該任務(wù)將對(duì)任何可用的 worker 可見。因此,故障檢測(cè)在租約到期時(shí)發(fā)生,恢復(fù)時(shí)間由租約長(zhǎng)度決定。

垃圾收集(Garbage collection):由于 NumPyWren 將所有中間狀態(tài)存儲(chǔ)到一個(gè)持久對(duì)象存儲(chǔ)區(qū),因此在不再需要時(shí)清除狀態(tài)是非常必要的。但是,由于在對(duì)象存儲(chǔ)中存儲(chǔ)字節(jié)的成本極低,與處理 TB 級(jí)中間狀態(tài)問題的計(jì)算成本相比,在程序結(jié)束時(shí)進(jìn)行垃圾收集就足夠了。使用與程序相關(guān)聯(lián)的唯一 id 標(biāo)記對(duì)象存儲(chǔ)中單個(gè)程序執(zhí)行的所有分配。在程序執(zhí)行終止后,NumPyWren 通過啟動(dòng)一組并行的無服務(wù)器任務(wù)來異步清理對(duì)象存儲(chǔ),以清理與給定程序 id 關(guān)聯(lián)的所有對(duì)象。

自動(dòng)縮放(Autoscaling):與傳統(tǒng)的無服務(wù)器計(jì)算模型(每個(gè)新任務(wù)分配一個(gè)新容器)不同,NumPyWren 中的任務(wù)調(diào)度和 worker 管理是解耦的。這種解耦允許自動(dòng)擴(kuò)展計(jì)算資源,以實(shí)現(xiàn)更好的性價(jià)比權(quán)衡。在 NumPyWren 中,作者采用了一個(gè)簡(jiǎn)單的自動(dòng)縮放啟發(fā)式算法,能夠在保持較低作業(yè)完成時(shí)間的同時(shí)獲得很好的利用率。

作者對(duì) 4 種線性代數(shù)算法:矩陣乘(Matrix Multiply,GEMM)、QR 分解(QR Decomposition,QR)、奇異值分解(SingularValue Decomposition,SVD)、Cholesky 分解(Cholesky Decomposition,Cholesky)進(jìn)行了實(shí)驗(yàn)評(píng)價(jià)。對(duì)于這四種算法,作者將它們與最先進(jìn)的 MPI 實(shí)現(xiàn)進(jìn)行比較。其中 Cholesky,GEMM 和 SVDwe 使用 ScaLAPACK 實(shí)現(xiàn),ScaLAPACK 是一個(gè)工業(yè)級(jí) Fortran 庫,專為高性能、分布式密集線性代數(shù)而設(shè)計(jì)。對(duì)于 QR 分解,則使用了 communication-avoiding QR 分解算法的優(yōu)化實(shí)現(xiàn)。NumPyWren 實(shí)現(xiàn)大約有 6000 行 Python 代碼,作者將其構(gòu)建在 Amazon web 服務(wù)(AWS)平臺(tái)上。對(duì)于 runtime 狀態(tài)存儲(chǔ),使用的是 Redis--- 一個(gè)由 ElasticCache 提供的鍵值存儲(chǔ)。盡管 ElasticCache 是一種配置的(而不是“無服務(wù)器”)服務(wù),但作者發(fā)現(xiàn)使用一個(gè)實(shí)例就足以滿足所有工作負(fù)載。此外,作者還發(fā)現(xiàn),可以用托管供應(yīng)商提供的鍵值存儲(chǔ)(如 DynamoDB)來替換 Redis,但性能略有下降。作者將 Amazon 的簡(jiǎn)單隊(duì)列服務(wù)(Simple queue Service,SQS)用于任務(wù)隊(duì)列,Lambda 或 EC2,使用 Amazon S3 作為遠(yuǎn)程對(duì)象存儲(chǔ)。

作者對(duì)實(shí)驗(yàn)進(jìn)行了一些特殊的設(shè)備選擇、環(huán)境選擇或參數(shù)選擇。首先,由于不能很容易地控制并發(fā) Lambda 執(zhí)行的數(shù)量或 AWS 提供的硬件類型,出于實(shí)驗(yàn)控制的原因,作者通過模仿 EC2 上的無服務(wù)器 runtime 來進(jìn)行大部分評(píng)估以便與其他系統(tǒng)進(jìn)行比較。其次,本文的 Lambda 模擬基于 PyWren 框架中的“獨(dú)立模式”。PyWren 使用一個(gè)單獨(dú)的 SQS 隊(duì)列來模擬 Lambda 作業(yè)隊(duì)列,并使用有時(shí)間限制的進(jìn)程來模擬短函數(shù)調(diào)用。在控制底層硬件(AVX、NIC 等)時(shí),使用 SQS 會(huì)導(dǎo)致不確定性。然后,目前 Lambda 的定價(jià)是 EC2 現(xiàn)貨價(jià)格的 10 倍,這使得本文的大規(guī)模實(shí)驗(yàn)無法在 Lambda 上進(jìn)行。作者通過實(shí)驗(yàn)對(duì)比發(fā)現(xiàn),在 EC2 上運(yùn)行模擬的無服務(wù)器環(huán)境與在 AWS Lambda 上運(yùn)行的性能差別最小。最后,模擬環(huán)境中的實(shí)驗(yàn)還允許修改某些在真實(shí)無服務(wù)器環(huán)境中用戶無法控制的系統(tǒng)參數(shù),如函數(shù)超時(shí)等。

表 3 中給出針對(duì)四種密集線性代數(shù)方法 NumPyWren 與 MPI 的端到端性能比較。作者對(duì)比了在完全相同的硬件條件下(8 個(gè) r4.16xlarge 實(shí)例中的 256 個(gè)物理核),處理大小為 256k(262144)的方陣時(shí) MPI 和 NumPyWren 的性能。我們可以看到無服務(wù)器環(huán)境施加的限制導(dǎo)致的性能損失在 1.4x 到 1.6x 之間(按 wall-clock time 計(jì)算)。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

表 3. 在具有 512 個(gè)虛擬核的集群上,在 N=256K 的方陣上運(yùn)行時(shí),不同算法的 MPI 與 NumPyWren 執(zhí)行時(shí)間的比較。

在表 4 中,作者比較了 NumPyWren 和 MPI 使用的總核秒數(shù)(core-seconds)。對(duì)于 MPI,core seconds 是指核的總數(shù)乘以 wall-clock runtime。對(duì)于 NumPyWren,作者只計(jì)算“活動(dòng)核(Active cores)”,因?yàn)榭臻e核是可以被其他任務(wù)利用的。作者通過在無服務(wù)器核啟動(dòng)和冷卻計(jì)算過程中每個(gè)核的總計(jì)算時(shí)間中添加一個(gè)啟動(dòng)延時(shí)γ來計(jì)算總核秒數(shù)。具體的,作者選擇γ=20s 以對(duì)系統(tǒng)進(jìn)行保守的評(píng)估。對(duì)于 QR 和 Cholesky 這些具有可變并行性的算法,雖然 wall-clock time 相當(dāng),但作者發(fā)現(xiàn) NumPyWren 使用的核秒數(shù)減少了 1.15 倍。對(duì)于 SVD,實(shí)驗(yàn)中顯示出超過 3 倍的資源節(jié)省效果,不過,產(chǎn)生這種差異一部分是由于使用的 SVD 算法不同。然而對(duì)于具有固定數(shù)量的并行性的算法(如 GEMM),NumPyWren 中過多的通信會(huì)導(dǎo)致更高的資源消耗。

無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí),出路在哪里?

表 4. 在一個(gè) 256K 大小的方陣上運(yùn)行算法的 MPI 與 NumPyWren 總 CPU 時(shí)間(以核秒為單位)比較。

三、文章小結(jié)

本文重點(diǎn)關(guān)注了基于無服務(wù)器計(jì)算的機(jī)器學(xué)習(xí)的最新研究進(jìn)展。隨著云計(jì)算的不斷發(fā)展,開發(fā)人員對(duì)于按需執(zhí)行或擴(kuò)展的需求越來越強(qiáng)烈,越來越希望不去應(yīng)對(duì)服務(wù)器或其它底層基礎(chǔ)設(shè)施,而是集中精力關(guān)注于自身應(yīng)用的開發(fā)和調(diào)優(yōu)。無服務(wù)器計(jì)算的 FaaS 和 BaaS 服務(wù)必將迎來更多的關(guān)注。但是,正如我們開篇提到的,機(jī)器學(xué)習(xí)的算法或模型中包含大量的參數(shù)、復(fù)雜的處理流程,是典型的“性能關(guān)鍵型應(yīng)用”。針對(duì)機(jī)器學(xué)習(xí)這種要求復(fù)雜通信模式和工作負(fù)載的應(yīng)用如何基于無服務(wù)器計(jì)算去工作仍然是一個(gè)有待研究的問題。

本文關(guān)注了三個(gè)研究小組的四篇研究論文。其中前兩篇文章提出了一種無服務(wù)器基礎(chǔ)設(shè)施和 ML 工作流的無服務(wù)器 ML 框架原型,并將其封裝為一個(gè)實(shí)現(xiàn)端到端管理的分布式 ML 訓(xùn)練框架 Cirrus,可以直接調(diào)用使用。第三篇文章提出了一個(gè)基于無服務(wù)器架構(gòu)的分布式機(jī)器學(xué)習(xí)新框架,以及一種深度強(qiáng)化學(xué)習(xí)技術(shù),用于實(shí)現(xiàn) SIREN 中的動(dòng)態(tài)資源供應(yīng)。作者還提出了一種能夠在無服務(wù)器架構(gòu)中高效工作的 HSP 計(jì)算模式。最后一篇文章重點(diǎn)關(guān)注的是無服務(wù)器計(jì)算的模密集線性代數(shù)程序應(yīng)用,作者提出了一個(gè)在無服務(wù)器架構(gòu)上完成線性代數(shù)任務(wù)的系統(tǒng) NumPyWren,通過對(duì)中間語言 LAmbdaPACK 的分析,作者最終證明了該分散式無服務(wù)器計(jì)算模型 NumPyWren 可以用于具有復(fù)雜通信程序的計(jì)算密集型程序。

在幾篇文章中,作者都通過實(shí)驗(yàn)證明了幾種框架在執(zhí)行機(jī)器學(xué)習(xí)任務(wù)時(shí)性能遠(yuǎn)優(yōu)于經(jīng)典的基于粗粒度的 VM 集群的 ML 框架。盡管無服務(wù)器的機(jī)器學(xué)習(xí)具有敏捷、快速、可伸縮性等優(yōu)點(diǎn),但是它對(duì)機(jī)器學(xué)習(xí)的集成還處于初級(jí)階段,它自身也面臨著工具不全面、不成熟或者配置方式不統(tǒng)一等問題。隨著越來越多的研究人員關(guān)注,越來越多的應(yīng)用開發(fā)提出成本節(jié)約和效率提高的需要,無服務(wù)器計(jì)算將迎來更快更好的發(fā)展。

 

責(zé)任編輯:張燕妮 來源: 機(jī)器之心Pro
相關(guān)推薦

2018-11-26 15:04:49

SDN網(wǎng)絡(luò)數(shù)據(jù)中心

2022-03-18 20:54:24

無服務(wù)器計(jì)算無服務(wù)器服務(wù)器

2022-01-05 09:28:31

無服務(wù)器計(jì)算服務(wù)器應(yīng)用程序

2019-04-30 10:27:46

無服務(wù)器云計(jì)算安全

2019-04-01 13:47:57

無服務(wù)器計(jì)算云服務(wù)

2018-07-17 15:41:37

服務(wù)器虛擬化未來

2019-03-08 10:26:29

無服務(wù)器云計(jì)算德勤

2017-11-27 10:45:48

無服務(wù)器計(jì)算容器

2018-03-01 10:26:25

無服務(wù)器計(jì)算架構(gòu)

2023-08-27 15:20:58

Serverless架構(gòu)開發(fā)

2020-12-04 15:17:26

物聯(lián)網(wǎng)智慧城市技術(shù)

2023-07-05 08:00:45

架構(gòu)

2018-02-28 11:19:41

服務(wù)器云計(jì)算公共云

2021-11-26 08:00:00

機(jī)器學(xué)習(xí)數(shù)據(jù)庫AWS

2013-08-01 00:00:00

開發(fā)企業(yè)級(jí)App出路

2017-07-10 15:17:11

無服務(wù)器計(jì)算云計(jì)算IT

2023-10-26 19:15:40

2022-07-01 13:41:32

無服務(wù)器容器企業(yè)

2020-10-10 07:00:00

無服務(wù)器計(jì)算容器

2017-08-08 14:33:36

無服務(wù)計(jì)算服務(wù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)