DevOps二三事:用持續(xù)集成構(gòu)建自動(dòng)模型訓(xùn)練系統(tǒng)的理論和實(shí)踐指南
本文轉(zhuǎn)載自公眾號“讀芯術(shù)”(ID:AI_Discovery)。
近幾年來,機(jī)器學(xué)習(xí)飛速發(fā)展,開展機(jī)器學(xué)習(xí)試驗(yàn)變成小事一樁。有了scikit-learn和Keras這樣的資源庫,只需幾行代碼,就能創(chuàng)建模型。
然而,把數(shù)據(jù)科學(xué)項(xiàng)目轉(zhuǎn)變成有意義的應(yīng)用程序(比如公告團(tuán)隊(duì)決策或融入產(chǎn)品的模型)卻愈加困難。傳統(tǒng)的機(jī)器學(xué)習(xí)項(xiàng)目涉及許多不同的技能組合,想同時(shí)掌握全部技能,即便不是絕無可能也絕非易事——那些罕見的既能開發(fā)優(yōu)質(zhì)軟件,又能做工程師的數(shù)據(jù)科學(xué)家即為獨(dú)角獸!
機(jī)器學(xué)習(xí)領(lǐng)域愈加成熟,許多工作都將融合軟件、工程和數(shù)學(xué)知識,一些工作已然如此了。
引用傳奇數(shù)據(jù)科學(xué)家、工程師、批判觀察家Vicki Boykis博客《數(shù)據(jù)科學(xué)現(xiàn)已不同》中的話:“在熱潮后期,數(shù)據(jù)科學(xué)漸漸與工程學(xué)靠攏。顯而易見的是,數(shù)據(jù)科學(xué)家所需技能的可視性將減弱、數(shù)據(jù)依賴性將降低,且會愈加偏向傳統(tǒng)計(jì)算機(jī)科學(xué)課程。”
為什么數(shù)據(jù)科學(xué)家需要了解DevOps
有那么多工程和軟件技能,數(shù)據(jù)科學(xué)家應(yīng)該學(xué)習(xí)什么呢?我選DevOps。
DevOps是開發(fā)和運(yùn)營的合稱,它于2009年在比利時(shí)的一場會議中誕生。該會議旨在緩解技術(shù)組織中開發(fā)、運(yùn)營因長期的巨大分歧而產(chǎn)生的緊張態(tài)勢。軟件開發(fā)人員需要快速產(chǎn)出、頻繁試驗(yàn),而運(yùn)營團(tuán)隊(duì)則優(yōu)先考慮服務(wù)的穩(wěn)定性及可用性(這群人讓服務(wù)器全天候運(yùn)轉(zhuǎn))。其目標(biāo)對立,彼此之間更是競爭關(guān)系。
這不禁令人想到當(dāng)下的數(shù)據(jù)科學(xué)。通過實(shí)驗(yàn),數(shù)據(jù)科學(xué)家創(chuàng)造價(jià)值:用新方式建模、組合、轉(zhuǎn)換數(shù)據(jù)。同時(shí),聘用數(shù)據(jù)科學(xué)家的技術(shù)組織更看重穩(wěn)定性。
這種分歧波及范圍廣泛:最新的Anaconda數(shù)據(jù)科學(xué)狀況報(bào)告顯示,認(rèn)為自己能詮釋數(shù)據(jù)科學(xué)對其組織影響的受訪者不足一半(48%)。據(jù)估計(jì),數(shù)據(jù)科學(xué)家創(chuàng)建的模型大多被束之高閣。我們目前沒有十分可行的方式,能在建模團(tuán)隊(duì)及部署團(tuán)隊(duì)間傳遞模型。數(shù)據(jù)科學(xué)家、開發(fā)者及落實(shí)二者工作的工程師有著截然不同的工具、限制及技能。
DevOps的出現(xiàn)旨在解決開發(fā)者和運(yùn)營者之間的軟件僵局,并取得了極大成功:許多團(tuán)隊(duì)部署新代碼的頻率從數(shù)月一次變?yōu)橐惶鞌?shù)次。現(xiàn)在面對的是機(jī)器學(xué)習(xí)和運(yùn)營的對抗,MLOps這一為數(shù)據(jù)科學(xué)服務(wù)的DevOps原則閃亮登場。
圖源:unsplash
持續(xù)集成
DevOps既是理論,又是實(shí)踐,它包括:
- 自動(dòng)化一切事物
- 快速獲得新想法的反饋
- 減少工作流中的手動(dòng)交接
在典型的數(shù)據(jù)科學(xué)項(xiàng)目中,存在如下應(yīng)用:
- 自動(dòng)化一切事物。重復(fù)且可預(yù)測的部分?jǐn)?shù)據(jù)處理、模型訓(xùn)練及模型測試皆可自動(dòng)化。
- 快速獲得新想法的反饋。當(dāng)數(shù)據(jù)、代碼或軟件環(huán)境發(fā)生變化時(shí),在類生產(chǎn)環(huán)境下迅速對其進(jìn)行測試(即,生產(chǎn)中有依賴項(xiàng)和限制的機(jī)器)。
- 減少工作流中的手動(dòng)交接。盡可能為數(shù)據(jù)科學(xué)家找尋模型測試的機(jī)會,切勿等到開發(fā)人員在生產(chǎn)環(huán)境下檢測模型效果再行動(dòng)。
為實(shí)現(xiàn)以上目標(biāo),DevOps采用的標(biāo)準(zhǔn)是持續(xù)集成(continuous integration, CI)。關(guān)鍵在于,改變項(xiàng)目源代碼時(shí)(一般是通過git commits更改),軟件被自動(dòng)創(chuàng)建并測試,每個(gè)行為都會得到反饋。通常,CI與創(chuàng)建新功能Git分支的軟件開發(fā)活動(dòng)模型Git-flow配合使用。功能分支通過自動(dòng)測試便可候選并入主分支。
CI在軟件開發(fā)過程中的示意圖
由此即可實(shí)現(xiàn)自動(dòng)化——改變代碼觸發(fā)自動(dòng)構(gòu)建,測試緊隨其后。由于迅速得到測試結(jié)果,便可以得到快速反饋,因此,開發(fā)者能對代碼進(jìn)行反復(fù)迭代。并且,由于一切皆為自動(dòng),無需等待他人反饋,實(shí)現(xiàn)零切換。
所以,我們?yōu)槭裁床皇褂靡汛嬖谟跈C(jī)器學(xué)習(xí)中的CI呢?我將部分歸因于文化,比如數(shù)據(jù)科學(xué)與軟件工程群體的低交叉性。
另一部分就是技術(shù)原因。比如,了解模型性能,需查看準(zhǔn)確率、特異度和敏感度等指標(biāo)。要了解模型的性能,就需要查看準(zhǔn)確率、特異度和靈感度等指標(biāo)。數(shù)據(jù)可視化(如混淆矩陣或損失圖)或許會對此有所幫助。所以,測試通過/失敗并不會阻礙反饋。若要了解模型是否得到改進(jìn),我們需要了解當(dāng)前問題領(lǐng)域的知識,所以測試結(jié)果需要以高效且可人為詮釋的方式報(bào)道。
機(jī)器學(xué)習(xí)項(xiàng)目中的連續(xù)集成
持續(xù)集成系統(tǒng)如何運(yùn)作?
現(xiàn)在,看看典型的CI系統(tǒng)如何運(yùn)作。多虧了GitHub Actions和GitLab CI這類圖像界面清晰且為新手提供詳細(xì)操作文檔的工具,學(xué)習(xí)CI系統(tǒng)的門檻降至最低。由于GitHub Actions對開源項(xiàng)目完全免費(fèi),我們就用它舉例:
其運(yùn)作方式如下:
(1) 建立一個(gè)GitHub倉庫。創(chuàng)建名為.github/workflows的目錄,在目錄中放置一個(gè)特殊的.yaml文件,其中包含要運(yùn)行的腳本,如:
- $ python train.py
(2) 更改項(xiàng)目庫內(nèi)文件,git commit更新,然后提交到GitHub庫。
- # Create a new git branch for experimenting$ git checkout -b "experiment"
- $ edit train.py# git add, commit, and push your changes
- $ git add . && commit -m "Normalized features"
- $ git push origin experiment
(3) 檢測到推送,GitHub立刻在其中一臺計(jì)算機(jī)上運(yùn)行.yaml文件的函數(shù)。
(4) GitHub彈出通知,是否成功運(yùn)行函數(shù)。
在GitHub倉庫的操作選項(xiàng)卡中找到以上內(nèi)
就這么簡單!只需更新代碼,并把更新提交到數(shù)據(jù)庫,工作流就自動(dòng)執(zhí)行。
回到第一步提到的特殊的.yaml文件——快速看一個(gè)。隨意命名,文件后綴是.yaml即可,并將其儲存在.github/workflows中。如:
- # .github/workflows/ci.yamlname: train-my-model
- on: [push]jobs:
- run:
- runs-on: [ubuntu-latest]
- steps:
- - uses: actions/checkout@v2
- - name: training
- run: |
- pip install -r requirements.txt
- python train.py
指令多如云,但大多數(shù)都是從一個(gè)Action到另一個(gè)Action——大可照搬這份GitHubActions指南,記得在“運(yùn)行”段填寫工作流就好。
若文件在項(xiàng)目庫中,只要GitHub檢測到代碼更新(通過推送變更),GitHub Actions便會部署Ubuntu服務(wù)器,嘗試執(zhí)行安裝需求的命令并運(yùn)行Python腳本。請注意,項(xiàng)目倉庫中必須有工作流程所需文件——在這里為requirements.txt和train.py!
得到更好的反饋
自動(dòng)訓(xùn)練很酷,但對所有的結(jié)果來說,采用易于理解的格式也很重要?,F(xiàn)在,GitHub Actions允許訪問純文本格式的服務(wù)器日志。
GitHub Actions日志的打印輸出示例
但了解模型性能是個(gè)棘手的活兒。模型和數(shù)據(jù)都是高維且非線性的——若無圖片,了解這二者太難了。
我可以展示一種將數(shù)據(jù)可視化放入CI循環(huán)的方法。近幾個(gè)月,我在Iterative.ai的團(tuán)隊(duì)(做數(shù)據(jù)版本控制)一直在研究工具包,助力GitHub Actions和GitLab CI在機(jī)器學(xué)習(xí)項(xiàng)目中的使用,稱為持續(xù)機(jī)器學(xué)習(xí)(Continuous Machine Learning ,簡稱CML)。這是開源且免費(fèi)的。
團(tuán)隊(duì)的基本理念是:“用GitHub Actions訓(xùn)練機(jī)器學(xué)習(xí)模型”。我們已經(jīng)建立了一些函數(shù),可給出更詳細(xì)的報(bào)告而非一個(gè)成功/失敗的通知。CML有助于在報(bào)告中放置圖片和表格,如這個(gè)SciKit-learn生成的混淆矩陣:
在GitHub中點(diǎn)Pull Request即顯示此報(bào)告
為了制作報(bào)告,GitHub Actions執(zhí)行Python模型訓(xùn)練腳本,用CML函數(shù)把模型準(zhǔn)確率和混淆矩陣寫入markdown文件。然后CML把markdown文件傳到GitHub。
修改后的.yaml文件包含以下工作流(新添加的行以粗體突出顯示)。
- name: train-my-model
- on: [push]
- jobs:
- run:
- runs-on: [ubuntu-latest]
- container: docker://dvcorg/cml-py3:latest
- steps:
- - uses: actions/checkout@v2
- - name: training
- env:
- repo_token: ${{secrets.GITHUB_TOKEN }}
- run: |
- # train.py outputs metrics.txtand confusion_matrix.png
- pip3 install -rrequirements.txt
- python train.py
- # copy the contents ofmetrics.txt to our markdown report
- cat metrics.txt >>report.md # addour confusion matrix to report.md
- cml-publishconfusion_matrix.png --md >> report.md # send the report to GitHub fordisplay
- cml-send-comment report.md
記住,.yaml現(xiàn)在包含更多詳細(xì)配置信息,例如特殊的Docker容器和環(huán)境變量,以及一些要運(yùn)行的新代碼。每個(gè)CML項(xiàng)目中的容器及環(huán)境變量的詳細(xì)信息都是固定的,用戶無需操作,只關(guān)注代碼就行。
將這些CML函數(shù)添加到工作流中,我們便在CI系統(tǒng)中創(chuàng)建了更完整的反饋循環(huán):
- 建立一個(gè)Git分支,在分支上更新代碼。
- 自動(dòng)訓(xùn)練模型并生成度量(準(zhǔn)確率)和可視化(混淆矩陣)。
- 將這些結(jié)果嵌入到Pull Request中的可視報(bào)告。
當(dāng)你和隊(duì)友還在考慮更新是否有助于實(shí)現(xiàn)建模目標(biāo)時(shí),各種可參照的可視化表盤就已經(jīng)新鮮出爐了。另外,該報(bào)告通過Git連接到確切項(xiàng)目版本(數(shù)據(jù)和代碼)、訓(xùn)練所用服務(wù)器及服務(wù)器的日志。無比詳細(xì)!工作空間不再總是漂浮著與代碼無關(guān)的圖表了。
這就是CI在數(shù)據(jù)科學(xué)項(xiàng)目中的基本概念。明確一下,這只是使用CI的最簡單的實(shí)例。實(shí)際操作中很可能遇到各種更為復(fù)雜的情況。CML也有一些特性,可幫你使用儲存在GitHub庫之外的大數(shù)據(jù)集(使用DVC)并在云端進(jìn)行訓(xùn)練,而非在默認(rèn)的GitHub Actions服務(wù)器訓(xùn)練。這意味著能使用GPU和其它專業(yè)設(shè)置。
例如,我用GitHub Actions創(chuàng)建一個(gè)項(xiàng)目以部署EC2 GPU,然后訓(xùn)練神經(jīng)風(fēng)格轉(zhuǎn)換模型。這是我的CML報(bào)告:
還可使用自己的Docker容器,進(jìn)一步模擬
CI對機(jī)器學(xué)習(xí)的最后思考
總結(jié)一下,DevOps不是一種特定技術(shù)。它既是理論,又是一系列原則和實(shí)踐,用于徹底重建開發(fā)軟件過程,其高效性在于解決了團(tuán)隊(duì)工作及測試新代碼的系統(tǒng)性瓶頸。
未來,數(shù)據(jù)科學(xué)愈加成熟,掌握在機(jī)器學(xué)習(xí)項(xiàng)目中運(yùn)用DevOps原則的人就更加炙手可熱——薪資可觀,組織影響力大。持續(xù)集成是DevOps的基礎(chǔ),也是已知的建立具有可靠自動(dòng)化、快速測試和團(tuán)隊(duì)自治文化的最有效方法之一。
GitHub Actions或GitLab CI之類的系統(tǒng)可實(shí)現(xiàn)CI。可使用這些服務(wù)構(gòu)建自動(dòng)模型訓(xùn)練系統(tǒng)。其益處頗多:
- 代碼、數(shù)據(jù)、模型和訓(xùn)練基礎(chǔ)(硬軟件環(huán)境)都是git版本。
- 自動(dòng)化工作、進(jìn)行高頻測試并得到迅速反饋(使用CML即可拿到可視化報(bào)告)。從長期看,這無疑會加速項(xiàng)目發(fā)展。
- CI系統(tǒng)讓每個(gè)團(tuán)隊(duì)成員都能看到工作進(jìn)展。大家無需絞盡腦汁搜集最佳運(yùn)行的代碼、數(shù)據(jù)及模型。
圖源:unsplash
一旦入了坑,一鍵git commit就能自動(dòng)進(jìn)行模型訓(xùn)練、記錄并報(bào)告,絕對讓你樂翻天。行動(dòng)起來,感覺棒極了!