FlatBuffers鳄虱,MNN模型存儲結(jié)構(gòu)基礎(chǔ) ---- 無法解讀MNN模型文件的秘密

寫在前面

我會盡可能地將一些關(guān)鍵概念進行描述和解釋弟塞,但基于 深度學(xué)習(xí)程序設(shè)計 的天坑,固然無法讓一個完全沒有相關(guān)概念基礎(chǔ)的人完全跟上文章的節(jié)奏拙已。對此請看不懂的各位多多見諒咯决记,畢竟這不是一片基礎(chǔ)教程(當(dāng)然,有問題可以在評論區(qū)提出倍踪,我會一一答復(fù))系宫。
參考閱讀適宜人群:
1 關(guān)注AI實現(xiàn)技術(shù)的人們
2 對數(shù)據(jù)結(jié)構(gòu)癡迷的人們
3 MNN的使用者

1 MNN

我們知道索昂,如今的AI主要 以深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)的方式 進行實踐。神經(jīng)網(wǎng)絡(luò)模型的基本操作有 訓(xùn)練(Train笙瑟,即創(chuàng)造模型)推理(Inference楼镐,即使用模型)。神經(jīng)網(wǎng)絡(luò)模型自有它的復(fù)雜性往枷,所以框产,出現(xiàn)了 神經(jīng)網(wǎng)絡(luò)框架 這樣讓我們可以 忽略模型細節(jié) 來 使用 訓(xùn)練、推理 功能的工具错洁。我們熟知的框架比如:Caffe秉宿,TensorFlow,Pytroch屯碴,Mxnet描睦,Ncnn,當(dāng)然导而,還有我們今天的主角之一忱叭, 阿里巴巴的深度神經(jīng)網(wǎng)絡(luò)推理引擎 MNN

我們會好奇 MNN模型文件(.mnn)的秘密今艺,想知道它組織結(jié)構(gòu)的秘密(這點對 進行模型轉(zhuǎn)換和模型調(diào)試 有至關(guān)重要的意義)韵丑,即:
它是像一個.json文件一樣使用字符串結(jié)構(gòu)化的存儲?
還是像ncnn的.bin文件一樣只是將二進制的數(shù)值直接無隙存儲虚缎?

調(diào)試MNN模型加載過程中我發(fā)現(xiàn)撵彻,.mnn文件的內(nèi)容竟似乎是 莫名其妙地 從一個“不可讀” 的狀態(tài)變?yōu)榱艘粋€“可使用”的狀態(tài),即:
調(diào)試過程中我找不到字符串解析代碼
調(diào)試過程中我也找不到二進制數(shù)據(jù)映射代碼

我看到的只有:

const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *tensorName() const {
  return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TENSORNAME);
}

--->
template<typename P> P GetPointer(voffset_t field) const {
   return const_cast<Table *>(this)->GetPointer<P>(field);
}

--->
template<typename P> P GetPointer(voffset_t field) {
  auto field_offset = GetOptionalFieldOffset(field);
  auto p = data_ + field_offset;
  return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p))
      : nullptr;
}

--->
voffset_t GetOptionalFieldOffset(voffset_t field) const {
  auto vtable = GetVTable();
  auto vtsize = ReadScalar<voffset_t>(vtable);
  return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
}

呃……試問一下大家看到這些代碼的感受实牡,應(yīng)該不會很興奮吧……

2 FlatBuffers

其實陌僵,無法解讀MNN模型文件的秘密在于:MNN模型文件采用的存儲結(jié)構(gòu)是 FlatBuffers,而FlatBuffer的特點之一即為“ Access to serialized data without parsing/unpacking”创坞,即 沒有解析過程碗短,沒有解包過程

我們(某一批特定的“我們”)知道题涨,數(shù)據(jù)結(jié)構(gòu)有 基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)結(jié)構(gòu)化數(shù)據(jù)結(jié)構(gòu)豪椿,那么,先在就優(yōu)先了解一下FlatBuffer中常用的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu):

flatbuffers::String

“OK”字符串的內(nèi)存結(jié)構(gòu).png

該圖即 字符串“OK”在 內(nèi)存中携栋,又或 文件中存儲字節(jié)排布(左邊低字節(jié),右邊高字節(jié))咳秉。

  1. 標(biāo)黃的部分說明 字符串的長度婉支,占用4個字節(jié)(圖示存儲模式為 小端模式)。
    圖中表示字符串長度為2澜建,即(2 = 0 * 256^3 + 0 * 256^2 + 0 * 256^1 + 2 * 256^0)向挖;
  2. 緊跟著字符串長度的存儲空間即為 字符串的內(nèi)容蝌以,圖中字符串長度為2,所以緊跟其后的2個字節(jié)為該字符串的有效值何之。

flatbuffers::Vector & flatbuffers::Offset

這兩個數(shù)據(jù)結(jié)構(gòu)結(jié)合在一起使用會比較常見:如:flatbuffers::Vector<flatbuffers::Offset<Op>>
通俗地說跟畅,理解其為:一個指向特定數(shù)據(jù)結(jié)構(gòu)的指針的數(shù)組

長度為6的指針數(shù)組.png

類似flatbuffers::String的理解溶推,4字節(jié)的Vector長度描述后徊件,緊跟6個4字節(jié)的指針描述。

flatbuffers::Table

這個結(jié)構(gòu)比較復(fù)雜蒜危,一片文章中的描述也比較清晰虱痕,我就不自己辛苦畫圖了。
文章:Improving Facebook’s performance on Android with FlatBuffers

image.png

簡單來說辐赞,一個Table結(jié)構(gòu) 被分為左右兩部分(如圖中黃色部分pivot point for John即為分界線)部翘,左邊表示數(shù)據(jù)信息的偏移,右邊表示數(shù)據(jù)信息响委。我們把圖中黃色位置計做0新思,則:

  1. 圖中最左側(cè)的 1 指向黃色位置右邊 第一個矩形
  2. 圖中左側(cè)的 6 指向黃色位置右邊 第6個矩形赘风;
  3. 每個矩形我們依然理解為 1字節(jié)(8位) 的數(shù)據(jù)存儲空間

3 MNN 中描述模型的數(shù)據(jù)結(jié)構(gòu)

有了上面的基礎(chǔ)夹囚,我們會好奇flatbuffers的存儲內(nèi)容與數(shù)據(jù)結(jié)構(gòu)的 具體舉例 或者 應(yīng)用場景。所以贝次,我們來初步了解一下MNN的底層模型數(shù)據(jù)結(jié)構(gòu)崔兴。

3.1 MNN 底層模型數(shù)據(jù)結(jié)構(gòu)全家福

MNN FlatBuffers based Data Structure.png

從MNN的源碼中把這些內(nèi)容扒出來然后繪圖貌似也沒有讓它能那么得容易閱讀。哈哈蛔翅,那就圈一些重點吧(當(dāng)然圖中的信息比重點多好多喲):
1 圖中中部靠下的Op部分衍生了近100個操作(或說神經(jīng)網(wǎng)絡(luò)層)的flatbuffers::Table結(jié)構(gòu)的定義敲茄,這邊我只象征性地列舉了常見的4個;
2 FlatBuffer數(shù)據(jù)結(jié)構(gòu)是和存儲對應(yīng)的山析,所以我們可以認(rèn)為MNN的設(shè)計者們期望過將整張圖的內(nèi)容放置到一個MNN模型文件中(至少他們預(yù)留了這樣的擴展性)堰燎;
3 當(dāng)然,現(xiàn)階段的大多MNN模型文件并沒有包含上述全部的信息笋轨,詳情見下圖秆剪。

3.2 MNN 底層模型數(shù)據(jù)結(jié)構(gòu)關(guān)鍵成員

MNN模型文件目前存在的信息內(nèi)容.png

這張圖就簡單了很多,這是我經(jīng)過對一些真實MNN模型的調(diào)試爵政,篩出來的模型關(guān)鍵信息相關(guān)的數(shù)據(jù)結(jié)構(gòu)仅讽。說白了:
1 網(wǎng)絡(luò)結(jié)構(gòu)信息:Op與Op的排布順序
2 網(wǎng)絡(luò)操作的參數(shù)信息(權(quán)重等):存儲在具體的Op衍生數(shù)據(jù)結(jié)構(gòu)中(最右邊的部分)

4 預(yù)告

這篇文章真的相當(dāng)干燥!是否很期待一些更實踐一些的內(nèi)容呢钾挟?
后續(xù)我會再擬草一片文章以舉例的方式來詳細地分析 MNN模型文件的存儲結(jié)構(gòu)的關(guān)系(這篇文章即作為一片技術(shù)基礎(chǔ)參照)洁灵,我會拿出證據(jù)告訴大家,MNN真的是遵照 “這種規(guī)則” 來設(shè)計和運作的掺出。所以我們知道了規(guī)則徽千,完全可以按照你的思想去 修改和調(diào)試 MNN源碼 和 MNN模型苫费。

想把這 有些復(fù)雜并夾雜著大量基礎(chǔ)知識知識實踐短篇幅 說清楚真的不是一件容易的事情啊。(還是講課做分享更輕松哈哈双抽,畢竟有即時的聽眾反饋提問)

先看預(yù)告張草圖吧百框,證明我的每篇文章都是很用心地希望創(chuàng)造一些幫助哦~:)


[預(yù)告]一個真實MNN模型的存儲結(jié)構(gòu)部分解讀圖示.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市牍汹,隨后出現(xiàn)的幾起案子铐维,更是在濱河造成了極大的恐慌,老刑警劉巖柑贞,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件方椎,死亡現(xiàn)場離奇詭異,居然都是意外死亡钧嘶,警方通過查閱死者的電腦和手機棠众,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來有决,“玉大人闸拿,你說我怎么就攤上這事∈槟唬” “怎么了新荤?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長台汇。 經(jīng)常有香客問我苛骨,道長,這世上最難降的妖魔是什么苟呐? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任痒芝,我火速辦了婚禮,結(jié)果婚禮上牵素,老公的妹妹穿的比我還像新娘严衬。我一直安慰自己,他們只是感情好笆呆,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布请琳。 她就那樣靜靜地躺著,像睡著了一般赠幕。 火紅的嫁衣襯著肌膚如雪俄精。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天榕堰,我揣著相機與錄音嘀倒,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛测蘑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播康二,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碳胳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了沫勿?” 一聲冷哼從身側(cè)響起挨约,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎产雹,沒想到半個月后诫惭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡蔓挖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年夕土,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘟判。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡怨绣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拷获,到底是詐尸還是另有隱情,我是刑警寧澤匆瓜,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布赢笨,位于F島的核電站,受9級特大地震影響驮吱,放射性物質(zhì)發(fā)生泄漏茧妒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一糠馆、第九天 我趴在偏房一處隱蔽的房頂上張望嘶伟。 院中可真熱鬧,春花似錦又碌、人聲如沸九昧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铸鹰。三九已至,卻和暖如春皂岔,著一層夾襖步出監(jiān)牢的瞬間蹋笼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剖毯,地道東北人圾笨。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像逊谋,于是被迫代替她去往敵國和親擂达。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容