隨著機(jī)器學(xué)習(xí)(ML)在過(guò)去幾年的快速發(fā)展,開(kāi)始ML實(shí)驗(yàn)變得非常容易。多虧了像scikit-learn和Keras這樣的庫(kù),用幾行代碼就可以創(chuàng)建模型。
但是,將數(shù)據(jù)科學(xué)項(xiàng)目轉(zhuǎn)化為有意義的應(yīng)用程序比以往任何時(shí)候都更加困難,比如將模型轉(zhuǎn)化為團(tuán)隊(duì)決策或成為產(chǎn)品的一部分。典型的ML項(xiàng)目涉及到許多不同的技能集,對(duì)于任何一個(gè)人來(lái)說(shuō),如果不是完全不可能的話,那也是一種挑戰(zhàn)——如此困難,少有的同時(shí)還能開(kāi)發(fā)高質(zhì)量軟件和游戲工程師的數(shù)據(jù)科學(xué)家被稱為獨(dú)角獸!
隨著這一領(lǐng)域的成熟,很多工作將需要軟件、工程和數(shù)學(xué)技能的結(jié)合,有些人說(shuō)他們已經(jīng)這么做了。
引用一位無(wú)與倫比的數(shù)據(jù)科學(xué)家/工程師/評(píng)論家Vicki Boykis在她的博客data science is different now里的話:
越來(lái)越清楚的是,在炒作周期的后期階段,數(shù)據(jù)科學(xué)正逐漸接近工程,數(shù)據(jù)科學(xué)家需要的技能不再是可視化和基于統(tǒng)計(jì)的,而是與傳統(tǒng)的計(jì)算機(jī)科學(xué)課程更加一致。
為什么數(shù)據(jù)科學(xué)家需要了解DevOps
那么,在眾多的工程和軟件技能中,數(shù)據(jù)科學(xué)家應(yīng)該學(xué)習(xí)哪一種呢?我的錢(qián)花在DevOps上了。
DevOps是development和operations的合成詞,于2009年在比利時(shí)的一次會(huì)議上正式誕生。這次會(huì)議的召開(kāi)是為了應(yīng)對(duì)科技公司在歷史上經(jīng)歷過(guò)深刻分歧的兩個(gè)方面之間的緊張關(guān)系。軟件開(kāi)發(fā)人員需要快速行動(dòng)并經(jīng)常進(jìn)行試驗(yàn),而運(yùn)維團(tuán)隊(duì)則優(yōu)先考慮服務(wù)的穩(wěn)定性和可用性(這些人讓服務(wù)器每天都在運(yùn)行)。他們的目標(biāo)不僅是對(duì)立,而且是競(jìng)爭(zhēng)。
這聽(tīng)起來(lái)很像今天的數(shù)據(jù)科學(xué)。數(shù)據(jù)科學(xué)家通過(guò)實(shí)驗(yàn)創(chuàng)造價(jià)值:數(shù)據(jù)建模、組合和轉(zhuǎn)換的新方法。與此同時(shí),雇傭數(shù)據(jù)科學(xué)家的組織受到穩(wěn)定的激勵(lì)。
這種劃分的后果是深遠(yuǎn)的:在最新的Anaconda數(shù)據(jù)科學(xué)狀態(tài)”報(bào)告中,“不到一半(48%)的受訪者認(rèn)為他們可以證明數(shù)據(jù)科學(xué)對(duì)他們的組織的影響”。據(jù)估計(jì),絕大多數(shù)由數(shù)據(jù)科學(xué)家創(chuàng)建的模型最終都被束之高閣。我們還沒(méi)有強(qiáng)大的實(shí)踐來(lái)在創(chuàng)建模型的團(tuán)隊(duì)和部署模型的團(tuán)隊(duì)之間傳遞模型。數(shù)據(jù)科學(xué)家和實(shí)現(xiàn)他們工作的開(kāi)發(fā)人員和工程師擁有完全不同的工具、約束條件和技能集。
DevOps的出現(xiàn)就是為了解決軟件中的這種僵局,就像開(kāi)發(fā)人員vs運(yùn)維一樣。它取得了巨大的成功:許多團(tuán)隊(duì)已經(jīng)從每幾個(gè)月部署一次新代碼發(fā)展到一天部署幾次。既然我們已經(jīng)有了機(jī)器學(xué)習(xí)和操作,那么現(xiàn)在就該考慮MLOps了——來(lái)自DevOps的用于數(shù)據(jù)科學(xué)的原則。
引入持續(xù)集成
DevOps既是一種哲學(xué),也是一套實(shí)踐,包括:
自動(dòng)化你所能做到的一切
快速獲得對(duì)新想法的反饋
減少工作流程中的手工交接
在一個(gè)典型的數(shù)據(jù)科學(xué)項(xiàng)目中,我們可以看到一些應(yīng)用:
自動(dòng)化你所能做到的一切。自動(dòng)化部分重復(fù)和可預(yù)測(cè)的數(shù)據(jù)處理、模型訓(xùn)練和模型測(cè)試。
快速獲得對(duì)新想法的反饋。當(dāng)你的數(shù)據(jù)、代碼或軟件環(huán)境發(fā)生變化時(shí),立即在類似生產(chǎn)的環(huán)境(即具有預(yù)期在生產(chǎn)中具有的依賴關(guān)系和約束的機(jī)器)中進(jìn)行測(cè)試。
減少工作流程中的手工交接。為數(shù)據(jù)科學(xué)家尋找機(jī)會(huì),盡可能多地測(cè)試他們自己的模型。不要等到有開(kāi)發(fā)人員時(shí)才查看模型在類似生產(chǎn)環(huán)境中的行為。
實(shí)現(xiàn)這些目標(biāo)的標(biāo)準(zhǔn)DevOps方法是一種稱為持續(xù)集成(CI)的方法。
要點(diǎn)是,當(dāng)你更改項(xiàng)目的源代碼時(shí)(通常通過(guò)Git提交注冊(cè)更改),你的軟件將被自動(dòng)構(gòu)建和測(cè)試。每個(gè)動(dòng)作都會(huì)引發(fā)反饋。CI通常與Git-flow一起使用,Git-flow是一種開(kāi)發(fā)架構(gòu),其中的新特性構(gòu)建在Git分支上。當(dāng)一個(gè)特性分支通過(guò)自動(dòng)化測(cè)試時(shí),它就成為了一個(gè)候選分支,可以合并到主分支中。
軟件開(kāi)發(fā)中的持續(xù)集成
通過(guò)這種設(shè)置,我們有了自動(dòng)化——代碼更改觸發(fā)一個(gè)自動(dòng)構(gòu)建,然后進(jìn)行測(cè)試。我們有快速的反饋,因?yàn)槲覀兛梢钥焖俚玫綔y(cè)試結(jié)果,所以開(kāi)發(fā)人員可以不斷迭代他們的代碼。而且因?yàn)樗羞@些都是自動(dòng)發(fā)生的,你不需要等待其他人得到反饋——少了一個(gè)切換!
那么我們?yōu)槭裁床辉贛L中使用持續(xù)集成呢?一些原因是文化上的,比如數(shù)據(jù)科學(xué)和軟件工程社區(qū)之間的低交叉。其他的則是技術(shù)性的——例如,為了理解模型的性能,你需要查看諸如準(zhǔn)確性、特異性和敏感性等指標(biāo)。數(shù)據(jù)可視化可能會(huì)幫助你,比如混淆矩陣或損失圖。所以通過(guò)/失敗的測(cè)試不會(huì)減少反饋。理解一個(gè)模型是否得到了改進(jìn)需要一些關(guān)于手頭問(wèn)題的領(lǐng)域知識(shí),因此測(cè)試結(jié)果需要以一種有效的和可理解的方式進(jìn)行報(bào)告。
機(jī)器學(xué)習(xí)項(xiàng)目中持續(xù)集成的樣子
CI系統(tǒng)是如何工作的?
現(xiàn)在我們要更實(shí)際一些,讓我們看看典型的CI系統(tǒng)是如何工作的。對(duì)于學(xué)習(xí)者來(lái)說(shuō),幸運(yùn)的是,由于GitHub Actions和GitLab CI等工具的出現(xiàn),障礙從來(lái)沒(méi)有降低過(guò)——它們有清晰的圖形界面和為首次用戶準(zhǔn)備的優(yōu)秀文檔。由于GitHub操作對(duì)于公共項(xiàng)目是完全免費(fèi)的,所以我們將在本例中使用它。
它是這樣工作的:
1、你創(chuàng)建了一個(gè)GitHub存儲(chǔ)庫(kù)。你創(chuàng)建了一個(gè)名為.github/workflows的目錄,并在其中放置了一個(gè)特殊的.yaml文件,其中包含你想要運(yùn)行的腳本。
2、你可以以某種方式更改項(xiàng)目存儲(chǔ)庫(kù)中的文件,然后Git提交更改。然后,推到GitHub存儲(chǔ)庫(kù)。
3、一旦GitHub檢測(cè)到push,GitHub就會(huì)部署他們的一臺(tái)計(jì)算機(jī)來(lái)運(yùn)行.yaml中的函數(shù)。
4、如果函數(shù)運(yùn)行成功或失敗,GitHub會(huì)返回一個(gè)通知。
在GitHub存儲(chǔ)庫(kù)的Actions選項(xiàng)卡中找到它
就是這樣!真正奇妙的是,你正在使用GitHub的計(jì)算機(jī)來(lái)運(yùn)行你的代碼。你所要做的就是更新代碼并將更改推送到存儲(chǔ)庫(kù)中,工作流就會(huì)自動(dòng)發(fā)生。
回到我在第1步中提到的特殊的.yaml文件——讓我們快速查看一個(gè)。它可以有任何你喜歡的名稱,只要文件擴(kuò)展名是.yaml,并且它存儲(chǔ)在.github/workflows目錄中。這里有一個(gè):
有很多操作在進(jìn)行,但大多數(shù)操作都是相同的——你可以復(fù)制粘貼這個(gè)標(biāo)準(zhǔn)的GitHub動(dòng)作模板,但在“運(yùn)行”字段中填寫(xiě)你的工作流。
如果這個(gè)文件在你的項(xiàng)目repo中,每當(dāng)GitHub檢測(cè)到對(duì)你的代碼的更改(通過(guò)push注冊(cè)),GitHub Actions就會(huì)部署一個(gè)Ubuntu運(yùn)行程序,并嘗試執(zhí)行你的命令來(lái)安裝需求并運(yùn)行Python腳本。請(qǐng)注意,你必須在項(xiàng)目repo中包含你的工作流所需的文件——這里是requirementes .txt和train.py。
得到更好的反饋
正如我們之前提到的,自動(dòng)訓(xùn)練是非??岬?,但重要的是要有一個(gè)容易理解的形式的結(jié)果。目前,GitHub操作允許你訪問(wèn)運(yùn)行的純文本日志。
從GitHub動(dòng)作日志中打印出來(lái)的示例
但是理解你的模型的性能是很棘手的。模型和數(shù)據(jù)是高維的,并且通常是非線性的——如果沒(méi)有圖片,這兩件事是特別難以理解的。
我可以向你展示一種將數(shù)據(jù)viz放入CI循環(huán)的方法。在過(guò)去的幾個(gè)月里,我的團(tuán)隊(duì)在Iterative.ai(我們做數(shù)據(jù)版本控制)正在開(kāi)發(fā)一個(gè)工具包,幫助在機(jī)器學(xué)習(xí)項(xiàng)目中使用GitHub動(dòng)作和GitLab CI。它被稱為持續(xù)機(jī)器學(xué)習(xí)(簡(jiǎn)稱CML),并且是開(kāi)源免費(fèi)的。
從“讓我們使用GitHub動(dòng)作來(lái)訓(xùn)練ML模型”的基本思想出發(fā),我們構(gòu)建了一些函數(shù)來(lái)提供比通過(guò)/失敗通知更詳細(xì)的報(bào)告。CML幫助你在報(bào)告中放入圖像和表格,就像這個(gè)由SciKit-learn生成的混淆矩陣:
當(dāng)你在GitHub中請(qǐng)求Pull時(shí),這個(gè)報(bào)告就會(huì)出現(xiàn)
為了制作這個(gè)報(bào)告,我們的GitHub操作執(zhí)行了一個(gè)Python模型訓(xùn)練腳本,然后使用CML函數(shù)將我們的模型準(zhǔn)確性和混淆矩陣寫(xiě)入一個(gè)markdown文檔。然后CML將減價(jià)文檔傳遞給GitHub。
我們修改后的.yaml文件包含以下工作流(新添加的行被加粗以示強(qiáng)調(diào)):
你可以在這里看到整個(gè)項(xiàng)目存儲(chǔ)庫(kù)。注意,我們的.yaml現(xiàn)在包含更多的配置細(xì)節(jié),比如一個(gè)特殊的Docker容器和一個(gè)環(huán)境變量,以及一些要運(yùn)行的新代碼。容器和環(huán)境變量細(xì)節(jié)在每個(gè)CML項(xiàng)目中都是標(biāo)準(zhǔn)的,而不是用戶需要操作的東西,所以請(qǐng)關(guān)注代碼。
在工作流中添加了這些CML功能后,我們?cè)贑I系統(tǒng)中創(chuàng)建了一個(gè)更完整的反饋循環(huán):
創(chuàng)建一個(gè)Git分支并更改該分支上的代碼。
自動(dòng)訓(xùn)練模型并產(chǎn)生度量(準(zhǔn)確性)和可視化(混淆矩陣)。
將這些結(jié)果嵌入到Pull請(qǐng)求的可視報(bào)告中。
現(xiàn)在,當(dāng)你和你的團(tuán)隊(duì)成員決定你的變更是否對(duì)你的建模目標(biāo)有積極的影響時(shí),你就有了一個(gè)可以檢查的儀表板。另外,Git還將此報(bào)告鏈接到你的確切項(xiàng)目版本(數(shù)據(jù)和代碼)、用于訓(xùn)練的跑步器以及那次運(yùn)行的日志。很徹底,不再有那些很久以前就失去了與代碼的任何連接的圖形在你的工作空間中浮動(dòng)。
這就是數(shù)據(jù)科學(xué)項(xiàng)目中CI的基本思想。明確地說(shuō),這個(gè)示例是使用CI的最簡(jiǎn)單方法之一。在現(xiàn)實(shí)生活中,你可能會(huì)遇到相當(dāng)復(fù)雜的場(chǎng)景。CML還有一些功能可以幫助你使用存儲(chǔ)在GitHub存儲(chǔ)庫(kù)之外的大型數(shù)據(jù)集(使用DVC),并在云實(shí)例上進(jìn)行訓(xùn)練,而不是使用默認(rèn)的GitHub動(dòng)作運(yùn)行器。這意味著你可以使用GPU和其他專門(mén)的設(shè)置。
例如,我做了一個(gè)使用GitHub Actions部署EC2 GPU的項(xiàng)目,然后訓(xùn)練一個(gè)神經(jīng)類型的傳輸模型。以下是我的CML報(bào)告:
你還可以使用自己的Docker容器,這樣就可以在生產(chǎn)中緊密地模擬模型的環(huán)境。以后我將更多地介紹這些高級(jí)用例。
關(guān)于ML的CI的最后思考
總結(jié)一下我們到目前為止所說(shuō)的:
DevOps不是一種特定的技術(shù),而是一種哲學(xué)、一套原則和實(shí)踐,用于從根本上重構(gòu)創(chuàng)建軟件的過(guò)程。它之所以有效,是因?yàn)樗鉀Q了團(tuán)隊(duì)如何工作和試驗(yàn)新代碼的系統(tǒng)瓶頸。
隨著數(shù)據(jù)科學(xué)在未來(lái)幾年的成熟,懂得如何將DevOps原則應(yīng)用到他們的機(jī)器學(xué)習(xí)項(xiàng)目中的人將成為一種有價(jià)值的商品——無(wú)論是從薪水還是從組織影響的角度。持續(xù)集成是DevOps的主要內(nèi)容,也是構(gòu)建具有可靠自動(dòng)化、快速測(cè)試和團(tuán)隊(duì)自治的文化的最有效的已知方法之一。
CI可以通過(guò)GitHub Actions或GitLab CI等系統(tǒng)實(shí)現(xiàn),你可以使用這些服務(wù)來(lái)構(gòu)建自動(dòng)模型培訓(xùn)系統(tǒng)。好處很多:
你的代碼、數(shù)據(jù)、模型和培訓(xùn)基礎(chǔ)設(shè)施(硬件和軟件環(huán)境)都是Git版本化的。
你正在自動(dòng)化工作,頻繁地進(jìn)行測(cè)試并獲得快速的反饋(如果使用CML,則使用可視化的報(bào)告)。從長(zhǎng)遠(yuǎn)來(lái)看,這幾乎肯定會(huì)加速項(xiàng)目的開(kāi)發(fā)。
CI系統(tǒng)使你的工作對(duì)團(tuán)隊(duì)中的每個(gè)人都可見(jiàn)。沒(méi)有人需要非常費(fèi)力地搜索你的最佳運(yùn)行的代碼、數(shù)據(jù)和模型。
我保證,一旦你進(jìn)入最佳狀態(tài),通過(guò)一個(gè)Git提交自動(dòng)啟動(dòng)你的模型訓(xùn)練、記錄和報(bào)告是非常有趣的。
你會(huì)覺(jué)得很酷。