在機器學習社區,越來越多的人開始討論研究的可復現性,但這些討論大部分局限于學術環境。如何確保生產環境的ML可復現?近日,機器學習開發服務提供商 maiot.io 的 CTO Benedikt Koller 發布一篇博客文章,介紹了他基于自身經驗總結的開發可復現生產級機器學習所要注意的 12 個要素。
過去二十年來,我們對軟件開發的理解有了大幅提升。其中一大部分原因是 DevOps 概念的出現及其在軟件開發行業的廣泛應用。
領先的軟件公司都遵循著同樣的模式:首先是在軟件開發過程中快速迭代,然后進行持續集成、持續交付、持續部署。每個特性都要經過測試,看其提供價值的能力如何,而且軟件始終要處于就緒的狀態,并且通過自動化方法進行部署。
機器學習這個領域雖不同于傳統的軟件開發,但我們也能從軟件開發行業汲取很多實用的經驗教訓。過去幾年里,我們一直在開發生產型機器學習項目。我們的目標并不只是概念驗證,而是與軟件開發一樣的可復現能力(reproducibility)。因此,我們構建了一套流程協調器、強大的自動化能力并建立了一套用于實現該目標的工作流程。
為什么不直接使用 Jupyter Notebook?從頭開始構建一組包含所有處理步驟的筆記需要多長時間?為團隊納入新成員的難易程度如何?你現在可以復現兩個月前的結果嗎?能以多快的速度復現?你能將今天的結果和歷史結果進行對比嗎?你能在訓練過程中關注到數據的出處嗎?如果你的模型過時了又會發生什么?
我們遇到過所有這些問題。現在,我們將這些經驗進行了歸納總結,得到了成功構建生產型機器學習的 12 個要素(類似于軟件開發中的十二要素應用/12 factor app)。
1. 版本控制
對軟件工程師來說,版本控制基本上是理所當然需要做的,但是這一方法論還尚未被數據科學家廣泛接受。讓我引述一下 Gitlab 上一些人的說法:
版本控制可促進整個軟件開發團隊之間的協調、共享和協作。版本控制軟件讓團隊可以在分布式和異步環境中工作、管理代碼和文件的修改和版本以及解決合并沖突和相關異常。
簡單來說,版本控制能讓你安全地管理軟件開發中會變化的部分。
機器學習其實是一種特殊的軟件開發,有著自己特定的要求。首先,機器學習中會變化的部分不止一種,而是兩種:代碼和數據。其次,模型訓練的方式是(快速)迭代,并且代碼中的差異會很大(比如拆分、預處理、模型)。
只要數據發生更改,就需要保存一個版本,這樣才能保證能復現結果以及重復執行實驗和訓練模型。簡單粗暴的版本控制(硬拷貝)具有很大的改進空間,不過尤其是在團隊共享的情況下,能夠保持不變的版本控制是至關重要的。
代碼的版本控制還要更加重要。除了上面引述的內容,預處理代碼不僅在訓練階段很重要,而且在服務階段也很重要,需要與模型有保持不變的相關性。為了在數據科學家的工作流程和投入生產的要求之間建立一種中臺,一種方便的方法是提供無服務器的功能。
總結:你需要對代碼進行版本控制,也需要對數據進行版本控制。 2. 明確的特征依賴關系
在理想世界中,產生你的輸入數據的東西應該總是會產生同樣的數據,至少結構上是這樣。但這個世界并不是完美的,你從上游服務獲取的數據也是由人類構建的,因此可能會發生變化。最終,特征也可能發生改變。最好的情況是你的模型會直接故障報錯,但還有最壞的情況:你的模型悄悄繼續工作,但得到的結果都是垃圾。
明確定義的特征依賴關系能夠盡快揭示出失敗案例。如果系統設計得好,還能在服務時進行持續訓練,然后調整依賴關系并加以適應。
總結:明確代碼中的特征依賴關系。
3. 描述性的訓練和預處理
優良的軟件都有優良的描述和注釋——讓人無需閱讀每一行代碼就能輕松閱讀和理解代碼功能。
盡管機器學習是一類特殊的軟件開發,但它并不鼓勵實踐者背離已有的代碼書寫準則。在代碼書寫標準中,最基本的一條是能讓人在短時間內不費力地閱讀。
預處理和模型的代碼都應該遵循 PEP8 規范。代碼中應當使用有意義的對象名并包含有助于理解的注釋。遵循 PEP8 規范可提升代碼的可讀性,降低復雜度并加快調試速度。SOLID 之類的編程范式提供了經過深思熟慮的框架,可讓代碼在未來用例中的可維護性、可理解性和靈活性都得到改善。
配置應該與代碼分離。不要將數據分配比例硬編碼到代碼之中,而是通過配置方式提供,以便在運行時修改。人們在超參數調節方面已經熟知這一點了:使用分離的配置文件可以顯著加快迭代速度,并且讓代碼庫可以重復使用。
總結:提升代碼可讀性并且將代碼和配置分開。 4. 訓練結果的可復現性
如果你不能復現訓練結果,那么這個結果就是不可信的。盡管這是本文的主題,但在可復現性方面有一些細節需要說明。不僅是你自己需要能復現訓練結果,你的整個團隊都要能做到這一點。不管是在 PC 還是在 AWS 虛擬機上,模糊處理 Jupyter Notebook 中的訓練結果都與可復現性背道而馳。
通過設定訓練的工作流程,整個團隊都可以透明地訪問已執行的實驗和已運行的訓練。通過綁定可復用的代碼庫以及分離的配置文件,每個人都可在任何時間成功重新訓練。
總結:使用管道式工作流程和自動化。
5. 測試
測試的形式有很多。舉兩個例子:
1)單元測試是原子層面上的測試——基于各自的標準單獨測試每個函數和功能。
2)集成測試則相反,是將代碼庫的所有元素都放到一起進行測試,同時還會測試上下游服務的克隆版本或模擬版本。
這兩種范式都適應于機器學習。預處理代碼是預先確定的,直到測試階段——這樣的轉換能在不同的輸入下都得到正確結果嗎?模型是集成測試的一個絕佳案例——在生產環境中提供服務時,你的模型的表現是否與評估時相當?
總結:測試你的代碼,測試你的模型。
6. 偏移與持續訓練
在生產場景中,任務發生偏移是合理存在的問題。只要數據存在變化的可能性,你就需要考慮偏移的可能性。對于此問題的風險,有兩種可以采取的措施:
1)監控生產系統中的數據。建立自動化報告機制,在數據發生變化時通知團隊,這種變化甚至可能超過明確定義的特征依賴關系。
2)基于新輸入的數據持續訓練。良好自動化的管道化流程可以基于新數據重復運行,然后與歷史訓練結果進行比較,展示性能變化情況以及將訓練得到的模型快速投放到生產中,從而讓模型表現更好。
總結:如果你的數據會發生變化,那就采用一種持續訓練的管道化流程。
7. 跟蹤結果
Excel 并非一種跟蹤實驗結果的好方法。而且還不只是 Excel,任何分散的人工跟蹤方法得到的信息都是不夠權威的,也因此是不可信的。
正確的做法是以一種中心化的數據存儲方式自動記錄訓練結果。自動化能夠保證可靠地跟蹤每次訓練,從而方便之后比較每次訓練的結果。對結果進行中心化存儲,能為團隊提供透明,實現持續性分析。
總結:通過自動化方法跟蹤結果。
8. 實驗模型與生產模型
我們需要努力才能理解數據集。通常來說,我們會通過實驗來實現理解,尤其是當我們關注的領域具備大量隱含領域知識時。創建一個 Jupyter Notebook,將部分/全部數據導入 Pandas Dataframe,進行幾個小時無序研究,訓練第一個模型,評估結果——任務完成。但幸運的是,現實并不如此。
在機器學習的生命周期中,實驗有自己的目的。這些目的并不是模型,而是理解。基于探索性 Jupyter Notebook 的模型是為了理解,而不是為生產開發的成品。理解之后,還需要進一步開發和適應,才能開始打造用于生產的訓練流程。
不過,所有與領域特定的知識無關的理解都可以自動化。你可以基于你使用的每個數據版本生成統計信息,從而可以跳過那些你在 Jupyter Notebook 中做過的一次性的臨時探索工作,然后直達第一個管道式流程。你在流程中實驗進行得越早,你就能越早地在中間結果上進行協作,也就能更早地實現可投入生產的模型。
總結:筆記不能投入生產,因此要在流程中盡早實驗。
9. 訓練和服務之間的方法差異
訓練和實際服務之間往往存在方法差異,為了正確地將所有數據預處理過程都納入到模型服務環境中,需要減少這些差異。這當然是正確的,你也需要堅持這一原則。但是,這只是對這一問題的部分解讀。
先來簡單看一段古老的 DevOps 歷史:2006 年,亞馬遜的 CTO Werner Vogels 創造了一個說法「You build it, you run it(你構建的東西你要運行)」。這是一個描述性的短語,意思是開發者的責任不只是寫程序,還需要運行它們。
機器學習項目也需要類似的機制——理解上游的數據生成以及下游的模型使用都在數據科學家的職責范圍內。你訓練用的數據是通過什么體系生成的?它會出問題嗎?該體系的服務級目標(SLO)是什么?這與實際服務的目標一致嗎?你的模型的服務方式是怎樣的?運行時環境是怎樣的?怎樣在服務時對函數進行預處理?這些都是數據科學家需要理解和解答的問題。
總結:正確地將預處理嵌入到服務之中,確保你理解數據的上下游。
10. 可比較性
從為項目引入第二個訓練腳本開始,可比較性就成了未來工作的重要組成部分。如果第二個模型的結果無法與第一個模型的結果進行比較,則整個過程就浪費了,其中至少有一個是多余的,甚至可能兩個都多余。
根據定義,所有試圖解決同一問題的模型訓練都需要可以比較,否則它們就不是在解決同一問題。盡管迭代過程可能導致所要比較的東西發生變化,但是在技術上實現模型訓練的可比較性需要一開始就作為首要功能內置于訓練架構之中。
總結:構建你自己的管道式流程,以便輕松比較各個流程的訓練結果。
11. 監控
粗略地說,機器學習的目標應該是通過學習數據來解決問題。為了解決這個問題,需要分配計算資源。首先是分配給模型的訓練,然后是分配給模型的服務。負責在訓練期間提供資源的不管是人還是部門,都需要負責將這些資源轉移給服務。模型在使用過程中可能出現很多性能下降問題。數據可以偏移,模型可能成為整體性能的瓶頸,偏差也是一個真實存在的問題。
效果:數據科學家和團隊負責監控他們創建的模型。他們并不一定要負責實施監控,尤其是當組織結構很大時,但他們肯定需要負責監控數據的理解和解釋。最低限度上,需要監控的內容包括輸入數據、推理次數、資源使用情況(CPU、RAM)和輸出數據。
總結:同樣,「You build it, you run it(你構建的東西你要運行)」。監控生產過程中的模型是數據科學的部分工作。
12. 模型的可部署性
從技術層面講,每個模型訓練流程都需要得到可部署到生產環境中的成品。毫無疑問,這些模型結果可能很糟糕,但它需要做成可以部署到生產環境的形態。
這是軟件開發中的常見模式,也叫做持續交付(Continuous Delivery)。團隊需要能夠隨時部署他們的軟件,為了滿足這個目標,迭代周期需要足夠快。
機器學習也需要采用類似的方法。這樣才能迫使團隊首先考慮現實與期望之間的平衡。所有利益相關者都應當清楚,在模型結果方面,哪些結果是理論上可能的。所有利益相關者都應當在模型的部署方式以及如何與更大的軟件架構整合上達成一致。但是,這也可能需要自動化,也需要前文提到的一些要素。
總結:每個訓練流程都需要得到可部署的成品,而不「只是」模型。
原文標題:機器學習工業復現的 12 個要素
文章出處:【微信公眾號:Imagination Tech】歡迎添加關注!文章轉載請注明出處。
責任編輯:haq
-
代碼
+關注
關注
30文章
4802瀏覽量
68736 -
機器學習
+關注
關注
66文章
8425瀏覽量
132766
原文標題:機器學習工業復現的 12 個要素
文章出處:【微信號:Imgtec,微信公眾號:Imagination Tech】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論