scikit-learn 機器學習模型跨平台部署的思路

(歡迎分享源網頁,禁止未經本人書面許可轉載至他處,或進行其他不當使用行為)

你是一名數據科學家/演算法工程師,在 Python/R/Spark/MATLAB(業界有幾個用?)等環境下用最愛的機器學習框架訓練好了模型,準確度不錯。想就這樣交差?公司當初招聘你難道就為了看一個 98% 的數字,或者期待你建立新演算法好發表論文?當然是要促進業務。於是問題來了,你並不能保證業務平台上能原封不動部署原本運行在個人電腦上的代碼,簡單的例子:

  • 非 x86 平台對 Python 的 NumPy 庫支持較為有限——移動平台最好不要指望直接運行或調用 Python。
  • iOS 應用商店禁止模擬器類 app,包括 Python 解釋器。
  • 嵌入式市場有 MicroPython,但比起原生 C 資源消耗還是太大,且也有兼容性問題。

另一方面,我們一般不想讓之前訓練的模型直接報廢,而在新平台上分別用其原生工具重新訓練(況且還不是所有平台都能這樣做——要是一塊 Cortex-M 微處理器呢?)。所以,一次訓練、跨平台部署是不少演算法工程師必須要跨過的坎。

本文將試圖簡介在移動平台等處部署機器學習模型的方法,並闡述個人體驗後所覺之利弊。目前只涉及線下學習線上預測的簡單情況,暫不考慮線上學習。雖然討論 scikit-learn 所生成模型的部署問題,但希望對其他庫和其他環境也能有舉一反三之效。

如果是 PC 或伺服器等以 x86 架構為主的非移動平台,考慮到其本身對 NumPy 支持較好,可以採取直接調用 Python 代碼的思路,典型的工具包括 Jython(jython.org/ )和 Jep(github.com/mrj0/jep )等。

對於移動平台,由前所述直接調用 Python 代碼不可行,只能考慮轉制,有兩種思路可供選擇:

1. 轉換成跨平台通用格式,典型如 PMML(dmg.org/pmml/v4-3/Gener )。例如在 Java 平台上,Java PMML API(github.com/jpmml )提供了各類介面;在 Android 上由於平台對 XML 解析的限制有人提供了 jpmml-android(github.com/jpmml/jpmml- )示例項目,其中包含一個 Maven 插件,將 PMML 文件序列化後編譯為一個靜態庫。簡單來說,將任何 scikit-learn 模型用 sklearn2pmml(github.com/jpmml/sklear )導出為 PMML 文件後,放進 jpmml-android 項目的對應位置,編譯後的 .pmml.ser 文件即可在任意 Android 項目中調用,方法可參照模板代碼。至於 iOS 則未受支持。目前以上所提及的 PMML 相關項目均已支持該語言最新標準(4.3),如條件限制只能使用舊標準,則需要到 GitHub 相應倉庫下載支持舊標準的最後版本。

2. 轉換成原生代碼,可以通過 sklearn-porter(github.com/nok/sklearn- )等實現,儘管支持模型種類有限。將模型用 joblib dump 成 pkl 後(假設其名為 model.pkl,注意模型若為 Pipeline,則所有步驟均需得到 sklearn-porter 支持),命令行中運行

python -m sklearn_porter -i model.pkl -l <目標語言>n

取決於模型大小,等候一段時間後即可見到原生語言的模型實現,文件名可能為 brain.c 或與之類似。自動生成的代碼可能需要手動修改後才能編譯運行。

以上兩種思路各有利弊。通用格式只需處理一次模型(如包括 Android 則為兩次),之後在各平台上分別編寫代碼以調用,支持演算法較多,但並非所有平台都受到支持,且解析 PMML 格式效率不算高。原生代碼則需要每種語言編譯一次,自動化框架所支持演算法較少(剩下的則需要設法導出參數後手動編寫),但在各自業務平台上基本不存在兼容性問題,效率也較高。為數不多的例外,一是自動生成的代碼對嵌入式系統仍不夠最優,可能需要較多人工編輯或直接手動編寫,當然這種情況下應該在建模時即優先考慮複雜度;二是 Java 單個方法位元組碼不能超過 64 KB,但機器學習模型稍大就會達到此限制,故 Java 上仍以 jpmml 為佳。

希望能對讀者有所幫助。歡迎評論切磋。

推薦閱讀:

記boost協程切換bug發現和分析
Qt和wxWidgets哪個好?
Google Chrome 的開發團隊是怎麼開發不同平台版本的?
既然.NET平台如此優秀,為什麼微軟不推廣到Linux、Mac等平台上?

TAG:sklearn | 跨平台 | 机器学习 |