當前位置:
首頁 > 新聞 > 一串模型代碼,支持所有神經網路框架

一串模型代碼,支持所有神經網路框架

選自oracle,機器之心編譯,參與:機器之心編輯部。


甲骨文公司(Oracle)在人工智慧領域非常低調,但最近其開源的通用深度學習框架 GraphPipe 著實讓人眼前一亮,它可以讓你的模型在各種框架之間輕鬆轉換。Oracle 稱,這一新工具可提供跨深度學習框架的模型通用 API、開箱即用的部署方案以及強大的性能。目前 GraphPine 已支持 TensorFlow、PyTorch、MXNet、CNTK 和 Caffe2 等框架。

一串模型代碼,支持所有神經網路框架

項目地址:https://github.com/oracle/graphpipe

ML 的開發者經常會發現已有的模型服務方案存在非一致性和低效的問題。在缺乏一致、能用於不同模型伺服器的通信協議下,開發者經常需要為每一個工作負載構建定製客戶端。GraphPipe 通過標準化一種高效的通信協議解決了這些問題,並為主流的機器學習框架提供了簡單的模型伺服器。

GraphPipe 是一個用於簡化機器學習模型部署,並將其從特定框架的模型實現中解放出來的協議和軟體集合。GraphPipe 為在網路上傳遞張量數據提供了一個標準、高性能的協議,以及提供了客戶端和伺服器的簡單實現,因而使得從任何框架部署和查詢機器學習模型變得輕而易舉。GraphPipe 的高性能伺服器能支持 TensorFlow、PyTorch、MXNet、CNTK 和 Caffe2。

Oracle 希望開源 GraphPipe 可以使模型服務變得更加友好,因此通過調查當前的機器學習模型服務現狀,我們發現:

  • 模型服務網路協議嘗試隱藏模型的實現。例如,假設你擁有一個 TensorFlow 模型,你需要使用 TensorFlow 的協議緩存伺服器(TensorFlow-serving)來執行遠程推理。
  • 另一方面,PyTorch 和 Caffe2 並沒有在他們的代碼庫中提供高效的模型伺服器,但依賴於像 mxnet-model-server 這樣的工具來執行遠程推理。mxnet-model-server 是用 Python 編寫的,並提供了一個 json API,沒有批量支持。儘管這對於簡單的案例來說很好,但並不適用於後端基礎設施。
  • 雖然 Facebook 推出了 ONNX,但它是通過標準化模型格式而不是協議格式解決供應商耦合(vendor-coupling)的問題。這很有用但也存在挑戰,因為不是所有的後端模型格式都有完全等價的運算。這意味著簡單的轉換並不總是可行,並且有時候有必要重寫模型。
  • 對於希望穩健地維護基礎設施的運營者而言,擁有一種標準的方法實現前端客戶端和後端機器學習模型的通信,而不用管模型實現的框架,是很重要的。

換句話說,沒有 GraphPipe 的服務模型是很痛苦的。

一串模型代碼,支持所有神經網路框架

在我們發布的代碼中提供了:

  • 基於 flatbuffer 的極簡機器學習傳輸規範
  • 為 Tensorflow、Caffe2 和 ONNX 構建簡單高效的參照模型伺服器
  • Go、Python 和 Java 中高效的客戶端實現

有了這些工具,交流變得暢通無阻,服務也更加簡單:

一串模型代碼,支持所有神經網路框架

性能

實驗首先對比了對 Python 浮點張量數據的序列化和反序列化運算的速度,分別使用定製 ujson API,TensorFlow-serving 預測請求的協議緩存,以及 GraphPipe 遠程請求。該請求由大約 1900 萬個浮點值(包含 128 張 224x224x3 的圖像)組成,並且響應由大約 320 萬個浮點值(包含 128 張 7x7x512 的卷積輸出)組成。縱軸的單位是秒。

一串模型代碼,支持所有神經網路框架

GraphPipe 在並行化方面表現得特別好,因為 flatbuffers 無需複製內存即可提供對基礎數據的訪問。

其次,實驗比較了 Python-JSON TensorFlow 模型伺服器、TensorFlow-serving 和 GraphPipe-go TensorFlow 模型伺服器的端到端吞吐量。每種類型中,後端模型都是相同的。分別採用一路和五路並行向伺服器發出大量請求。縱軸單位是模型每秒計算的行數。

一串模型代碼,支持所有神經網路框架

請注意,以上所述的測試僅使用一般推薦的參數來構建 TensorFlow-serving。儘管推薦的構建參數不能讓 TensorFlow-serving 效果達到最優,但 Oracle 最終發現編譯參數能允許獲得與 GraphPipe 實現相同的性能。換而言之,最優的 TensorFlow-serving 與 GraphPipe 的性能相近,儘管構建最優性能的 TensorFlow-serving 並得不到記錄。

使用 GraphPipe 為模型提供服務

除了有效協議外,GraphPipe 還提供了用 Go 語言編寫的參考模型伺服器,以簡化部署機器學習模型的過程。根據 Oracle 的經驗,將現有的模型轉換成通用的格式可能會存在很多缺陷。因此,GraphPipe 提供了能夠本地運行最常見的 ML 模型格式的模型伺服器。

這些伺服器可以在 graphpipe-go repo 的 cmd 子目錄中找到:

  • graphpipe-tf 使用 libtensorflow 為 TensorFlow 模型提供支持
  • graphpipe-onnx 使用 libcaffe2 為 Caffe2 和 ONNX 模型提供支持

目標

在設計模型伺服器時,GraphPipe 的目標如下:

  • 優越的性能
  • 簡易文檔化的構建過程
  • 易於使用的靈活代碼
  • 支持最常見的 ML 框架
  • 更優化的 CPU 和 GPU 支持

伺服器功能概述

GraphPipe 的參考伺服器應用的基本機制非常直觀。

一串模型代碼,支持所有神經網路框架

為了最小化開銷,Oracle 嘗試儘可能提高以上步驟的效率。例如,因為使用 flatbuffers 作為網路傳輸格式,反序列化實際上就是一個指針轉換。

語言選擇

雖然 Go 語言並不是機器學習領域裡最常見的語言,但它是構建高效伺服器的理想選擇。它也是一種明確而友好的語言,不會給你帶來太多的驚喜。這些特性使得 Go 語言成為了一種優秀的協作語言,這也是 GraphPipe 模型伺服器選擇它的原因。

Go 語言存在一個缺點:現有的機器學習框架都是由 C/C++語言編寫的,當從 Go 代碼轉換為框架後端時會存在一些消耗。當然,在實踐中我們發現這對於性能的影響其實非常小。在性能測試期間,GraphPipe 的 Go 代碼實現了與純 C++編寫的 TensorFlow-serving 優化構建幾乎相同的性能。

CUDA GPU 加速

對於每個參考伺服器,項目中都提供了 docker 鏡像和源代碼,用於構建使用 CUDA 加速運行的二進位文件。

MKL CPU 加速

為了最大限度提高各種伺服器構建之間的兼容性,並且同時最大化性能,伺服器的 CPU 構建塊需要通過 MKL 編譯。當使用 TensorFlow 時,MKL 為支持 channels_first 維度順序的卷積運算提供了額外的優化,這通常是使用 GPU 的首選排序。因此在使用 GraphPipe 伺服器的默認配置時,CPU 和 GPU 可以使用相同的模型並接受相同的輸入。

當然,也有可能應用需要使用不同的最優化或通道順序。因此對於這種情況,應該直接調整源代碼以構建滿足我們需求的自定義版本。

緩存

Go 這類語言的優點之一就是易於訪問簡單而強大的庫。因此,我們能為兩個模型伺服器添加一些共享代碼以創建行級緩存。這個可選的行級緩存是基於 boltdb 的,對於接受相同數據的多項請求的模型非常有用。緩存通常可以在幾微秒內返回數據,而大型模型處理一個請求可能需要幾百毫秒。

使用 GraphPipe 用戶端

為了更便捷地將 GraphPipe 整合到我們的應用軟體,GraphPipe 為主要的編程語言提供了高效的用戶端實現。

一般而言,機器學慣用戶端的工作流程如下所示:

一串模型代碼,支持所有神經網路框架

虛線框中的每一個步驟都應該儘可能更高效地實現,這是非常重要的。GraphPipe 就以這些步驟的高效實現為目標。目前,GraphPipe 的用戶端支持 Python、Go 和 Java 語言。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

不思考體系結構的深度學習研究者不是好工程師
2018谷歌學術期刊&出版物排名公布:CVPR擠進前20

TAG:機器之心 |