深度學習網絡模型部署——知識儲備Docker(一)

歡迎關注公眾號:七只的Coding日志,[更多鏈接](https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=Mzk0ODA5NTc5MQ==&uin=&key=&devicetype=Windows+10+x64&version=6302019c&lang=zh_CN&a8scene=7&fontgear=2)

實現從項目調研、數據收集、數據預處理、深度卷積神經網絡訓練再到服務器部署的人臉表情識別小項目

一、需求

1、簡單的demo演示,只要看看效果的,像是學校里面的demo展示這種

caffe、tf、pytorch等框架隨便選一個,切到test模式,拿python跑一跑就好,順手寫個簡單的GUI展示結果

高級一點,可以用CPython包一層接口,然后用C++工程去調用

2、要放到服務器上去跑,但一不要求吞吐二不要求時延的那種,說白了還是有點玩玩的意思

caffe、tf、pytorch等框架隨便選一個,按照官方的部署教程,老老實實用C++部署,例如pytorch模型用工具導到libtorch下跑(官方有教程,很簡單)

這種還是沒有脫離框架,有很多為訓練方便保留的特性沒有去除,性能并不是最優的;

另外,這些框架要么CPU,要么NVIDIA GPU,對硬件平臺有要求,不靈活;

還有,框架是真心大,占內存(tf還占顯存),占磁盤

3、放到服務器上跑,要求吞吐和時延(重點是吞吐)

這種應用在互聯網企業居多,一般是互聯網產品的后端AI計算,例如人臉驗證、語音服務、應用了深度學習的智能推薦等。

由于一般是大規模部署,這時不僅僅要考慮吞吐和時延,還要考慮功耗和成本。所以除了軟件外,硬件也會下功夫,比如使用推理專用的NVIDIA P4、寒武紀MLU100等。這些推理卡比桌面級顯卡功耗低,單位能耗下計算效率更高,且硬件結構更適合高吞吐量的情況

軟件上,一般都不會直接上深度學習框架。對于NVIDIA的產品,一般都會使用TensorRT來加速(我記得NVIDIA好像還有TensorRT inference server什么的,名字記不清了,反正是不僅可以加速前傳,還順手幫忙調度了)。TensorRT用了CUDA、CUDNN,而且還有圖優化、fp16、int8量化等。反正用NVIDIA的一套硬軟件就對了

4、放在NVIDIA嵌入式平臺上跑,注重時延

比如PX2、TX2、Xavier等,參考上面(用全家桶就對了),也就是貴一點嘛

5、放在其他嵌入式平臺上跑,注重時延

硬件方面,要根據模型計算量和時延要求,結合成本和功耗要求,選合適的嵌入式平臺。

比如模型計算量大的,可能就要選擇帶GPU的SoC,用opencl/opengl/vulkan編程;也可以試試NPU,不過現在NPU支持的算子不多,一些自定義Op多的網絡可能部署不上去

對于小模型,或者幀率要求不高的,可能用CPU就夠了,不過一般需要做點優化(剪枝、量化、SIMD、匯編、Winograd等)

順帶一提,在手機上部署深度學習模型也可以歸在此列,只不過硬件沒得選,用戶用什么手機你就得部署在什么手機上23333。為老舊手機部署才是最為頭疼的

上述部署和優化的軟件工作,在一些移動端開源框架都有人做掉了,一般拿來改改就可以用了,性能都不錯。

6、上述部署方案不滿足我的需求

比如開源移動端框架速度不夠——自己寫一套。比如像商湯、曠世、Momenta都有自己的前傳框架,性能應該都比開源框架好。只不過自己寫一套比較費時費力,且如果沒有經驗的話,很有可能費半天勁寫不好。

就目前來說,我打算將需求定位到2,后期在2的基礎上考慮吞吐和延遲問題,從而能夠進一步達到需求3和5(位于手機端部署)

二、部署方面問題

模型部署就是在某一框架內訓練好的模型(權重文件),通過具體框架進行模型轉化或者直接使用對應語言所提供的API接口,load、get一系列操作,使得訓練好的“黑箱”能得到實際應用。這種方式可能是簡單的pyinstaller庫進行簡單的封裝、也可以是pyqt進行界面集成、接口調用,或者使用flask或者Django框架進行前端和后臺服務器的嵌入,這些總體來說,都算是模型部署。

1、首先,不得不提Docker部署模型

Docker的前生是LXC,全名Linux Container,是一種輕量級的虛擬化手段,以便隔離進程和資源。容器是指將單個系統管理的資源劃分到孤立的組中,有效地安排資源使用需求。總之,LXC是一種操作系統層次上的資源虛擬化,提供了一個自己的進程和網絡空間的虛擬環境。

什么是Docker呢?? Docker底層使用了LXC實現,在此基礎上,增添了更多強大的功能。Docker屬于一種開源應用容器引擎,是基于go語言開發并遵循apache2.0協議開源。

優點:?可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的linux服務器,也可以實現虛擬化。

Docker總體架構:

架構

由于本次輕量化網絡結構部署,因此采用Docker作為容器。

2、Docker基本概念

Docker包括三個基本概念:

? ??——鏡像(Image)

? ??——容器(Container)

? ??——倉庫(Repository)

整個生命周期

2.1?鏡像(Image)——一個特殊的文件系統

Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。?鏡像不包含任何動態數據,其內容在構建之后也不會被改變。

鏡像構建時,會一層層構建,前一層是后一層的基礎。每一層構建完就不會再發生改變,后一層上的任何改變只發生在自己這一層。比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當前層標記為該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,但是實際上該文件會一直跟隨鏡像。因此,在構建鏡像的時候,需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應該在該層構建結束前清理掉。

2.2 容器(Container)——鏡像運行時的實體

鏡像(Image)和容器(Container)的關系,就像是面向對象程序設計中的類和實例 一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等?。

容器的實質是進程,但與直接在宿主執行的進程不同,容器進程運行于自己的獨立的命名空間。前面講過鏡像使用的是分層存儲,容器也是如此。

容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存于容器存儲層的信息都會隨容器刪除而丟失。

按照 Docker 最佳實踐的要求,容器不應該向其存儲層內寫入任何數據?,容器存儲層要保持無狀態化。所有的文件寫入操作,都應該使用數據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。數據卷的生存周期獨立于容器,容器消亡,數據卷不會消亡。因此,?使用數據卷后,容器可以隨意刪除、重新 run ,數據卻不會丟失。

2.3 倉庫(Repository)——集中存放鏡像文件的地方

鏡像構建完成后,可以很容易的在當前宿主上運行,但是,?如果需要在其它服務器上使用這個鏡像,我們就需要一個集中的存儲、分發鏡像的服務,Docker Registry就是這樣的服務。

一個 Docker Registry中可以包含多個倉庫(Repository);每個倉庫可以包含多個標簽(Tag);每個標簽對應一個鏡像。所以說:鏡像倉庫是Docker用來集中存放鏡像文件的地方類似于我們之前常用的代碼倉庫。

3、“Docker - Build, Ship, and Run Any App, Anywhere”

操作

——Build(構建鏡像)?: 鏡像就像是集裝箱包括文件以及運行環境等等資源。

——Ship(運輸鏡像)?:主機和倉庫間運輸,這里的倉庫就像是超級碼頭一樣。

——Run (運行鏡像)?:運行的鏡像就是一個容器,容器就是運行程序的地方。

4、Docker安裝

Docker也是支持其他如CentOS, Mac OS X, Windows等平臺。Docker運行對內核要求比較高,一般建議直接在Ubuntu平臺運行。

CentOS中安裝docker教程Windows10中安裝docker教程Windows10中docker的安裝與使用Mac系統docker安裝

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容