不加班的祕訣:如何經過AOE快速集成NCNN?

做爲我司頭髮儲量前三的程序員html

始終仗着頭髮多奮鬥在加班的第一線java

時時靈魂拷問本身git

年輕人,你憑什麼不加班?程序員

雖然我沒有女友
可是,我有代碼呀github

但我不明白的是,隔壁工位那個,到崗比我遲,下班比我早,每天準點兒下班接女友,工做還完成的不錯的樣子,固然,頭髮也還不錯。除了長得比我顯老,難道他有什麼制勝法寶嗎?趁着午休,以一禮拜咖啡爲代價,我偷師了他的制勝法寶。GET了祕訣,或許我也能夠事業愛情雙豐收了。web

 

直接集成NCNN的缺點api

直接集成NCNN熬老小男顏哇,想當年我一邊淚流滿面地集成,一邊想用女朋友的SK2給本身的臉補補(不,你沒有,both SK2和女朋友)咋回事兒呢,爲SqueezeNet接入NCNN,把相關的模型文件,NCNN的頭文件和庫,JNI調用,前處理和後處理相關業務邏輯等。把這些內容都放在SqueezeNet Sample工程裏。這樣簡單直接的集成方法,問題也很明顯,和業務耦合比較多,不具備通用性,前處理後處理都和SqueezeNcnn這個Sample有關,不能很方便地提供給其餘業務組件使用。深刻思考一下,若是咱們把AI業務,做爲一個一個單獨的AI組件提供給業務的同窗使用,會發生這樣的狀況:數組

每一個組件都要依賴和包含NCNN的庫,並且每一個組件的開發同窗,都要去熟悉NCNN的接口,寫C的調用代碼,寫JNI。因此咱們很天然地會想到要提取一個NCNN的組件出來,提取之後呢長得順眼了不少,大概是這個樣子。緩存

 

AOE SDK裏的NCNN組件

有了AOE SDK,我也能夠一頓操做猛如虎了!在AOE開源SDK裏,咱們提供了NCNN組件,下面咱們從4個方面來說一講NCNN組件:app

      ●NCNN組件的設計

      ●對SqueezeNet Sample的改造

      ●應用如何接入NCNN組件

      ●對NCNN組件的一些思考

 

★ NCNN組件的設計

不懂NCNN的組件設計,即便一頓操做猛如虎,你可能最後也只有兩塊五。那它的組件是什麼嘞?NCNN組件的設計理念是組件裏不包含具體的業務邏輯,只包含對NCNN接口的封裝和調用。具體的業務邏輯,由業務方在外部實現。在接口定義和設計上,咱們參考了TF Lite的源碼和接口設計。目前提供的對外調用接口,長這個樣子:

// 加載模型和param
void loadModelAndParam(...)
// 初始化是否成功
boolean isLoadModelSuccess()
// 輸入rgba數據
void inputRgba(...)
// 進行推理
void run(...)
// 多輸入多輸出推理
void runForMultipleInputsOutputs(...)
// 獲得推理結果
Tensor getOutputTensor(...)
// 關閉和清理內存
void close()

而機智騷年本人,用的是這個:

├── AndroidManifest.xml
├── cpp
│   └── ncnn
│       ├── c_api_internal.h
│       ├── include
│       ├── interpreter.cpp
│       ├── Interpreter.h
│       ├── jni_util.cpp
│       ├── jni_utils.h
│       ├── nativeinterpreterwrapper_jni.cpp
│       ├── nativeinterpreterwrapper_jni.h
│       ├── tensor_jni.cpp
│       └── tensor_jni.h
├── java
│   └── com
│       └── didi
│           └── aoe
│               └── runtime
│                   └── ncnn
│                       ├── Interpreter.java
│                       ├── NativeInterpreterWrapper.java
│                       └── Tensor.java
└── jniLibs
    ├── arm64-v8a
    │   └── libncnn.a
    └── armeabi-v7a
        └── libncnn.a

 

    ●Interpreter,提供給外部調用,提供模型加載,推理這些方法。

    ●NativeInterpreterWrapper是具體的實現類,裏面對native進行調用。

    ●Tensor,主要是一些數據和native層的交互。

 

AOE NCNN用的好,任務完成早,奧祕在此。

     ●支持多輸入多輸出。

     ●使用ByteBuffer來提高效率。

     ●使用Object做爲輸入和輸出(實際支持了ByteBuffer和多維數組)。

 

光說不練假把式,AOE NCNN的實現過程,且聽我細細道來。

 

 如何支持多輸入多輸出

爲了支持多輸入和多輸出,咱們在Native層建立了一個Tensor對象的列表,每一個Tensor對象裏保存了相關的輸入和輸出數據。Native層的Tensor對象,經過tensor_jni提供給java層調用,java層維護這個指向native層tensor的「指針」地址。這樣在有多輸入和多輸出的時候,只要拿到這個列表裏的對應的Tensor,就能夠就行數據的操做了。

 

 ByteBuffer的使用

ByteBuffer,字節緩存區處理子節的,比傳統的數組的效率要高。
DirectByteBuffer,使用的是堆外內存,省去了數據到內核的拷貝,所以效率比用ByteBuffer要高。

 

固然ByteBuffer的使用方法不是咱們要說的重點,咱們說說使用了ByteBuffer之後,給咱們帶來的好處:
1.接口裏的字節操做更加便捷,例如裏面的putInt,getInt,putFloat,getFloat,flip等一系列接口,能夠很方便的對數據進行操做。
2.和native層作交互,使用DirectByteBuffer,提高了效率。咱們能夠簡單理解爲java層和native層能夠直接對一塊「共享」內存進行操做,減小了中間的字節的拷貝過程。

 

 如何使用Object做爲輸入和輸出
目前咱們只支持了ByteBuffer和MultiDimensionalArray。在實際的操做過程當中,若是是ByteBuffer,咱們會判斷是不是direct buffer,來進行不一樣的讀寫操做。若是是MultiDimensionalArray,咱們會根據不一樣的數據類型(例如int, float等),維度等,來對數據進行讀寫操做。

 

 對SqueezeNet Sample的改造

集成AOE NCNN組件之後,讓SqueezeNet依賴NCNN Module,SqueezeNet Sample裏面只包含了模型文件,前處理和後處理相關的業務邏輯,前處理和後處理能夠用java,也能夠用c來實現,由具體的業務實現來決定。新的代碼結構變得很是簡潔,目錄以下:

├── AndroidManifest.xml
├── assets
│   └── squeeze
│       ├── model.config
│       ├── squeezenet_v1.1.bin
│       ├── squeezenet_v1.1.id.h
│       ├── squeezenet_v1.1.param.bin
│       └── synset_words.txt
└── java
    └── com
        └── didi
            └── aoe
                └── features
                │       ├── squeezenet_v1.1.id.h
│       ├── squeezenet_v1.1.param.bin
│       └── synset_words.txt
└── java
    └── com
        └── didi  
         └── aoe
                └── features
                    └── squeeze
                        └── SqueezeInterpreter.java

↑ 本Sample也適用於其餘的AI業務組件對NCNN組件的調用。

(牛逼就完事兒)

 應用如何接入NCNN組件

對NCNN組件的接入,有兩種方式

     ●直接接入

     

 ●經過AOE SDK接入

▲兩種接入方式比較:

不BATTLE了,我單方面宣佈,AOESDK完勝!

 

 對NCNN組件的總結和思考

經過對NCNN組件的封裝,如今業務集成NCNN更加快捷方便了。以前咱們一個新的業務集成NCNN,可能須要半天到一天的時間。使用AOE NCNN組件之後,可能只須要1-2小時的時間。固然NCNN組件目前還存在不少不完善的地方,咱們對NCNN還須要去加深學習和理解。後面會經過不斷的學習,持續的對NCNN組件進行改造和優化。

 - - - - - - - - - - - - - - - - - - - - - - - - - - - A o E - - - - - - -  - - - - - - - - - - - - - - - - - - - -

 

原創不易,歡迎打賞

                  https://github.com/didi/AoE←聽說點了這裏的程序員們都準點下班了/

相關文章
相關標籤/搜索