概述
ONNX全稱Open Neural Network Exchange,是微軟設計的一個開放式深度學習神經網絡模型的格式。旨在通過一個統一的模型格式標準,建立一個強大的人工智能生態。
深度神經網絡的實現是通過數據流圖實現的,數據(張量等)從輸入,流過一個個集選節點,最終在輸出結點得到推理結果。不同的框架實現數據流圖的的方式不盡相同,有的使用靜態圖,有的在運行的過程中動態創建。但是不管哪種方式,最終都會得到一個神經網絡模型的結構圖以及權重。通常,神經網絡模型的結構、權重等信息不會一直在內存裏,通常需要將它們保存到文件中,用於部署、轉換等。而每一種框架都有他們自己的一套專有的模型表示方法,擁有自己的一套標準去操作、運行他們自己的模型。由於AI 研究正在迅猛發展當中,每種框架都有自己的側重點,比如有的框架特別適合於做研究,能夠快速的搭建驗證模型;而有的框架則最特定硬件做了大量性能優化,特別適合生產部署。
這時候,一個通用的模型格式標準應運而生,它就是ONNX。有了這樣一個統一的模型格式標準,你就可以使用能夠快速的框架去驗證你的模型,然後將模型導出到ONNX格式,再用有特殊優化的推理引擎進行推理或者轉換到可以在移動端進行推理的特殊格式。
ONNX還有另一個變種,ONNX-ML,它額外增加了一些傳統的標準機器學習操作。
組成
ONNX是一個開放的標準,這個標準主要有以下三部分組成:
- 一個可擴展的計算圖模型的定義,它主要確定了一套用於序列化模型的格式標準。這個序列化後的模型可以不遵循原有框架在內存中的表示,序列化或者使用ONNX模型的框架可以處於效率等的目的使用不同的內存佈局;
- 一個標準數據類型的定義,它主要定義了模型中的數據如權重、計算中間結果等的表示方法;
- ONNX自帶的操作,它定義了一套原子操作和函數。
版本號表示
版本號有兩種表示方法:簡單數字表示和語義表示,用8個字節存儲版本信息。
簡單數字表示全部字節用於表示一個數,表現形式爲XXX,如0x0000000000000001
表示數字1;語義表示則將這八個字節分開,最高位兩個字節表示主版本號,次高位兩個字節表示此版本好,剩下四個字節表示補丁、編譯等版本號,最終的表現形式爲MAJOR.MINOR.PATCH,例如0x0001000200000003
表示主版本號爲1,此版本號爲2,補丁版本號等爲3。兩種表示方法的區分方法是查看最高四個字節內容,如果最高四個字節爲0,則使用的是簡單數字表示;如果最高四個字節不爲零,則使用的是語義表示。例如0x0000000000000001
最高四個字節爲0,所以表示這個版本號是用簡單數字表示;而0x000000010000000
最高四個字節不爲0,則表示這是語義版本號。
值得注意的是,ONNX標準中規定,IR和OP的版本號必須用簡單數字來表示,版本數值單調遞增,而對於模型版本,並未作出規定,可以隨意二選一。
模型結構
Model
處於模型結構頂層的是一個被稱爲Model的結構,它的主要目的是將一個包含模型所有執行元素的圖和它的元數據關聯起來。元數據可以在模型被讀取的時候告訴讀取方一些重要信息,比如版本、執行該模型所需要的操作集(Operators Set)等信息,讀取方根據這些信息決定下一步是繼續執行該模型還是選擇報錯等操作。另外,有些工具,例如模型查看工具等可以根據元數據告訴人們模型的信息和模型的作用等。Model的組成結構如下:
Name | Type | Description |
---|---|---|
ir_version | int64 | The ONNX version assumed by the model. |
opset_import | OperatorSetId | A collection of operator set identifiers made available to the model. An implementation must support all operators in the set or reject the model. |
producer_name | string | The name of the tool used to generate the model. |
producer_version | string | A string representing the version of the generating tool. |
domain | string | A reverse-DNS name to indicate the model namespace or domain, for example, ‘org.onnx’ |
model_version | int64 | A version of the model itself, encoded in an integer. |
doc_string | string | A human-readable documentation for this model. Markdown is allowed. |
graph | Graph | The parameterized graph that is evaluated to execute the model. |
metadata_props | map<string,string> | Named metadata values; keys should be distinct. |
training_info | TrainingInfoProto[] | An optional extension that contains information for training. |
每個Model都必須指定它所屬機構的域名,使用類似Java包結構的反向域名錶示。此外,Model的metadata_props
字段可以用於定義其他額外的元數據信息,例如下表定義了一些額外的元數據屬性:
Name | Type | Format | Description |
---|---|---|---|
model_author | string | A comma-separated list of names. | The personal name of the author(s) of the model, and/or their organizations. |
model_license | string | Name or URL. | The well-known name or URL of the license under which the model is made available. |
Operator Sets
每個模型必須明確的指出它所以來的操作集,操作集定義了可用的操作以及他們的版本。模型通過他們的域定義了需要導入的操作集,如果沒有特別指定,模型將默認導入默認的ONNX操作集。
操作集的屬性如下:
Name | Type | Description |
---|---|---|
magic | string | The value ‘ONNXOPSET’ |
ir_version | int32 | The ONNX version corresponding to the operators. |
ir_version_prerelease | string | The prerelease component of the SemVer of the IR. |
ir_build_metadata | string | The build metadata of this version of the operator set. |
domain | string | The domain of the operator set. Must be unique among all sets. |
opset_version | int64 | The version of the set of operators. |
doc_string | string | A human-readable documentation for this set of operators. Markdown is allowed. |
operator | Operator[] | The operators of this operator set. |
Operators
圖(Graph)中的任何一個操作(Operator)都必須是在模型導入了的操作集中有明確聲明瞭的。
操作的屬性如下:
Name | Type | Description |
---|---|---|
op_type | string | The name of the operator, as used in graph nodes. MUST be unique within the operator set’s domain. |
since_version | int64 | The version of the operator set when this operator was introduced. |
status | OperatorStatus | One of ‘EXPERIMENTAL’ or ‘STABLE.’ |
doc_string | string | A human-readable documentation string for this operator. Markdown is allowed. |
Graphs
圖用於表示一個計算過程,它由元數據字段、模型參數以及計算結點三部分組成。計算結點按照一定拓撲結構組成了一個有向無環圖,每個結點表示一個操作。每個結點可以有0到多個輸入以及至少一個輸出。
圖的屬性如下:
Name | Type | Description |
---|---|---|
name | string | The name of the model graph. |
node | Node[] | A list of nodes, forming a partially ordered computation graph based on input/output data dependencies. |
initializer | Tensor[] | A list of named tensor values. When an initializer has the same name as a graph input, it specifies a default value for that input. When an initializer has a name different from all graph inputs, it specifies a constant value. |
doc_string | string | A human-readable documentation for this model. Markdown is allowed. |
input | ValueInfo[] | The input “parameters” of the graph, possibly initialized by a default value found in ‘initializer.’ |
output | ValueInfo[] | The output parameters of the graph. Once all output parameters have been written to by a graph execution, the execution is complete. |
value_info | ValueInfo[] | Used to store the type and shape information of values that are not inputs or outputs. |
Nodes
計算節點由結點名字、這個結點的操作的名字、輸入的名字、輸出的名字以及一系列屬性組成。結點的輸入輸出和操作的輸入輸出通過位置相關聯,例如第一個輸入是上一個結點的輸出,第二個輸入是權重,第三個輸入是偏置等,結點屬性名字和操作屬性通過名字相關聯。
結點屬性如下:
Name | Type | Description |
---|---|---|
name | string | An optional name of the node, used for diagnostic purposes only. |
input | string[] | Names of the values used by the node to propagate input values to the node operator. It must refer to either a graph input or a graph initializer or a node output. |
output | string[] | Names of the outputs used by the node to capture data from the operator invoked by the node. It either introduces a value in the graph or refers to a graph output. |
op_type | string | The symbolic identifier of the operator to invoke. |
domain | string | The domain of the operator set that contains the operator named by the op_type. |
attribute | Attribute[] | Named attributes, another form of operator parameterization, used for constant values rather than propagated values. |
doc_string | string | A human-readable documentation for this value. Markdown is allowed. |
數據類型
ONNX有兩個變種:ONNX和ONNX-ML。ONNX只識別張量,ONNX-ML除了張量還能識別序列以及字典。
總結
總的來說,ONNX就是定義了一套標準,這套標準使得不同機器學習框架的數據流圖有了一個統一的表示。
它定義瞭如何將一個內存的模型序列化到磁盤,也定義瞭如何去讀取這個序列化的模型進入內存。
References
[1] Open Neural Network Exchange - ONNX
本文首發於個人微信公衆號TensorBoy。如果你覺得內容還不錯,歡迎分享並關注我的微信公衆號TensorBoy,掃描下方二維碼獲取更多精彩原創內容!