視覺感知未來,高德資料採集模型部署實踐!

amap_tech發表於2021-06-04

1. 導讀

作為DAU過億的國民出行服務平臺,高德地圖每天為使用者提供海量的檢索、定位和導航服務,實現這些服務需要有精準的道路資訊,比如電子眼位置、路況資訊、交通標識位置資訊等。讀者是否會好奇,高德是如何感知到現實世界的道路資訊,並提供這些資料給使用者呢?

事實上,我們有很多的方法將現實世界的道路要素採集回收,並更新到高德地圖App上。其中一種非常重要的方法是利用計算機視覺的手段,將視覺演算法部署到客戶端,透過對圖片的檢測識別,快速將道路的資訊回收。

為了低成本,高實時性地實現道路要素回收,我們藉助 MNN引擎(一個輕量級的深度神經網路推理引擎),將卷積神經網路模型部署到客戶端,在客戶端進行端側的模型推理,從而完成在 計算能力低,記憶體小的客戶端進行道路要素採集的任務。

傳統的CNN(卷積神經網路)計算量非常大,且業務場景需要部署多個模型。 如何在低效能的裝置上部署多個模型,並在不影響實時性的情況下保證應用的"小而優"是一個非常大的挑戰。本文將分享利用MNN引擎在低效能裝置上部署深度學習應用的實戰經驗。

2. 部署

2.1 背景介紹

如Figure2.1.1所示,業務背景是將道路要素識別相關的CNN模型部署到客戶端,在端側進行模型推理,並提取道路要素的位置和向量等資訊。

由於該業務場景的需要,目前端上需同時部署10+甚至更多的模型,以滿足更多的不同道路要素的資訊提取需要,對於低效能裝置來說是非常大的挑戰。

Figure 2.1.1 高德資料採集

為了達到應用的"小而優",MNN引擎部署模型的過程中遇到了很多問題和挑戰。下面就這些問題和挑戰分享一些經驗和解決辦法。

2.2 MNN部署

2.2.1 記憶體佔用

應用執行記憶體對於開發者來說是始終繞不開的話題,而模型推理產生的記憶體在應用執行記憶體中佔有很大的比例。因此,為了使模型推理記憶體儘可能小,在模型部署的過程中,作為開發者必須清楚模型執行產生記憶體的主要來源。根據我們的部署經驗,部署單模型的過程中,記憶體主要來源於以下四個方面:

Figure 2.2.1 單模型部署記憶體佔用

ModelBuffer: 模型反序列化的buffer,主要儲存模型檔案中的引數和模型資訊,其大小和模型檔案大小接近。

**FeatureMaps: **Featuremaps的記憶體,主要儲存模型推理過程中,每一層的輸入和輸出。

**ModelParams: **模型引數的記憶體,主要儲存模型推理所需的Weights, Bias, Op等記憶體。其中Weights佔用了該部分的大部分記憶體。

**Heap/Stack: **應用執行中產生的堆疊記憶體。

2.2.2 記憶體最佳化

知曉模型執行記憶體佔用後,就能方便理解模型執行時的記憶體變化。經過多個模型部署實踐, 為了降低部署模型的記憶體峰值,我們採取的措施如下:

  • 模型反序列化(createFromFile)並建立記憶體(createSession)後,將模型Buffer釋放(releaseModel), 避免記憶體累加。
  • 處理模型輸入,影像記憶體和inputTensor可記憶體複用。
  • 模型後處理,模型輸出Tensor和輸出資料的記憶體複用。

Figure 2.2.2.1 MNN模型部署記憶體複用方案

經過記憶體複用,以部署1個2.4M的視覺模型為例,模型執行時從載入到釋放,中間各階段所佔用記憶體變化可以用以下曲線表示:

Figure 2.2.2.2 單模型應用記憶體曲線(Android memoryinfo統計)

  • 模型執行前,模型佔用記憶體為 0M
  • 在模型載入(createFromFile)和建立記憶體(createSession)後,記憶體升到 5.24M, 來源於模型反序列化和Featuremaps記憶體建立。
  • 呼叫releaseModel記憶體降低至 3.09M,原因是釋放了模型反序列化後的buffer。
  • InputTensor和影像記憶體複用,應用記憶體增加到 4.25M, 原因是建立了儲存模型輸入的Tensor記憶體。
  • RunSession(),應用記憶體增加到 5.76M,原因是增加了RunSession過程中的堆疊記憶體。
  • 在模型釋放後,應用恢復到了模型載入前的記憶體值。

經過多次模型部署的實踐,下面總結了部署單模型到端的記憶體峰值預估公式:

MemoryPeak:單模型執行時記憶體峰值。

StaticMemory:靜態記憶體,包括模型Weights, Bias, Op所佔記憶體。

DynamicMemory:動態記憶體,包括Feature-maps所佔記憶體。

ModelSize:模型檔案大小。模型反序列化所佔記憶體。

MemoryHS:執行時堆疊記憶體(經驗取值0.5M-2M之間)。

2.2.3 模型推理原理

本章節分享模型推理原理,以便於開發者遇到相關問題時,快速定位和解決問題。

模型推理前模型的排程: MNN引擎推理保持了高度的靈活度。即可以指定模型不同的執行路徑,也可以對不同的執行路徑指定不同的後端,以提高異構系統的並行性。此過程主要是排程或者任務分發的過程。

對於分支網路,可以指定當前執行分支,也可以排程分支執行不同後端,提高模型部署的效能。圖Figure2.2.3.1所示為一個多分支模型, 兩個分支分別輸出檢測結果和分割結果。

Figure 2.2.3.1 多分支網路

部署時可做如下最佳化 :

  • 指定模型執行的Path。當僅需檢測結果時,只跑檢測分支,無需跑完兩個分支, 減小模型推理時間。
  • 檢測和分割指定用不同的後端。比如檢測指定CPU, 分割指定OpenGL,提高模型並行性。

模型推理前的預處理: 本階段會根據上一步的模型排程資訊進行預處理,本質是利用模型資訊和使用者輸入配置資訊,進行Session(持有模型推理資料)的建立。

Figure 2.2.3.2 根據Schedule建立Session

本階段根據模型反序列化的模型資訊和使用者排程配置資訊來進行運算排程。用於建立執行的Piplines和對應的計算後端。如Figure2.2.3.3所示。

Figure 2.2.3.3 Session建立

模型的推理: 模型推理本質是根據上一步建立的Session,依次執行運算元的過程。運算會根據預處理指定的模型路徑和指定後端進行模型每層的運算。值得一提的是,運算元在指定的後端不支援時,會預設恢復到備用後端執行計算。

Figure 2.2.3.4 模型推理計算圖

2.2.4 模型部署時間

本部分統計了單模型部署過程各階段耗時,方便開發者瞭解各階段的耗時,以便更好的設計程式碼架構。(不同裝置有效能差異,耗時資料僅供參考)

Figure 2.2.4.1 模型推理計算圖

模型反序列化和Session建立相對耗時較長,進行多張圖的推理時,儘量執行一次。

2.2.5 模型誤差分析

模型部署時,開發者難免會遇到部署端和X86端(Pytorch, Caffe, Tensorflow)訓練模型輸出結果有偏差的情況。下面分享誤差原因, 定位思路以及解決辦法。

模型Inference示意圖如Figure 2.2.5.1所示:

Figure 2.2.5.1 模型Inference示意圖

模型誤差的確定: 檢視是否有模型誤差最直觀的方法是,固定部署端模型和X86端模型的輸入值,分別推理,對比部署端模型和X86端模型輸出值,可確認是否有誤差。

模型誤差的定位: 當確定有模型誤差時,先排除因模型輸入誤差導致的模型輸出誤差。因為X86端和部分Arm裝置浮點的表示精度不一致,輸入誤差在某些模型中會被累積,最終造成較大的輸出誤差。用什麼方法來排除是輸入誤差導致的問題呢?我們提供一種方法是將模型輸入設定為0.46875(原因是該值在X86裝置和部分Arm裝置表示一致,本質是1經過移位獲得的浮點數在兩種端上表示均一致)。然後觀察輸出是否一致即可。

模型誤差的定位思路: 在排除模型輸入誤差導致模型輸出誤差(即模型輸入一致時,模型輸出不一致)的情況下,很可能是模型某些運算元導致的誤差了。如何定位模型哪個OP導致的誤差呢?透過下述的步驟可以定位模型內部引起誤差的原因:

1)透過runSessionWithCallBack來回撥模型每個OP的中間計算結果。目的是定位模型從哪個Op開始出現誤差。

2)定位到該層之後,即可定位到產生誤差的運算元。

3)定位到運算元後,透過指定的後端資訊即可定位到對應的運算元執行程式碼。

4)定位到對應的執行程式碼後,除錯定位產生誤差的程式碼行,從而定位到產生模型誤差的根本原因。

3. 總結

MNN引擎是一個非常好的端側推理引擎,作為開發者來說,模型的端上部署和效能最佳化在關注業務邏輯最佳化的同時,也需關注對引擎計算過程,框架設計和模型加速的思想,反過來可以更好的最佳化業務程式碼,做出真正"小而優"的應用。

4.未來規劃

隨著裝置效能的普遍提升,後續的業務會搭載到效能更高的裝置,我們會利用更豐富的計算後端做模型的加速,比如OpenCL, OpenGL等, 從而加速模型的推理。

未來裝置會搭載更多的模型到客戶端,用於實現更多品類道路要素資訊的回收,我們也會利用MNN引擎,探究更高效,更高實時性的程式碼部署框架,以更好的服務於地圖採集業務。

我們是 高德地圖資料研發團隊,團隊中有大量HC,歡迎對Java後端、平臺架構、演算法端上工程化(C++)、前端開發感興趣的小夥伴加入,請傳送您的簡歷到   ,郵件標題格式: 姓名-技術方向-來自高德技術。我們求賢若渴,期待您的加入。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69941357/viewspace-2775429/,如需轉載,請註明出處,否則將追究法律責任。

相關文章