開放式神經網路交換-ONNX(上)

wujianming_110117發表於2020-12-05

開放式神經網路交換-ONNX(上)

目的

本文件包含ONNX語義的規範性規範。

“onnx”資料夾下的.proto和.proto3檔案構成了用協議緩衝區定義語言編寫的語法規範。.proto和.proto3檔案中的註釋目的是提高這些檔案的可讀性,但如果它們與本文件衝突,則不具有規範性。此類衝突應報告為文件錯誤。

模型驗證說明

有一個工具可以根據此規範執行模型的一般驗證。它在C++中用Python命令列package實現。

本檔案及所有相關檔案中的語言說明:

在本檔案中使用SHOULD、MUST、MAY等與RFC 2119一致。

“list”的使用應表示專案的有序集合,“set”應表示唯一元素的無序集合,“bag”表示可能非唯一元素的無序集合。

Components

ONNX is an open specification that consists of the
following components:

A definition of an extensible computation graph model. Definitions of standard data types.
Definitions of built-in operators.

其中#1和#2包含在本文中;內建操作器在本文件末尾列出的文件中單獨介紹。具體來說,內建運算元operator被劃分為一組原始運算元operator和函式。函式是一種運算元operator,其語義通過使用其他運算元operator(和函式)擴充套件到子圖(稱為函式體)中來正式表示。就功能而言,與ONNX相容的框架或執行時可以行內函數來執行它,如果它沒有相應的函式實現。

有兩個官方的ONNX變體;兩者之間的主要區別在於支援的型別和預設的運算元operator集。只有神經網路的ONNX變體只識別張量作為輸入和輸出型別,而經典的機器學習擴充套件ONNX-ML也識別序列和對映。ONNX-ML用非神經網路的ML演算法擴充套件了ONNX運算元集。

直到IR版本6,ONNX規範和模型格式只處理推理(也稱為評分)。從IR版本7開始,ONNX規範和模型格式已擴充套件到支援訓練。ONNX訓練模型本身是推理模型的一個擴充套件,允許只進行推理的runtime忽略與訓練相關的擴充套件並執行推理。然而,在典型的使用場景中,與訓練模型相比,僅推理模型可以實現更優化的模型表示(用於推理目的)。

runtime不可知

ONNX並不預先假設或暗示任何特定的執行時實現方法。

例如,一個實現可以由一個解釋模型的富執行時組成;

可以是一個程式碼生成器,它將整個模型轉換為某些目標程式語言的可執行程式碼;

可以是硬體實現;

可以是其中兩個或三個的組合。

本規範中的任何內容都不應被解釋為主張一種實現方法勝過任何其他方法;

對具體實現的內部工作原理的任何評論都應解釋為示例。

ONNX版本控制

ONNX中有幾個地方有版本控制功能——IR(中間表示)規範本身、模型版本和運算元operator集版本。此外,每一個單獨的運算元operator都指明它是在哪個版本的包含運算元operator集中引入或穩定的。

版本號可以用作簡單的數字,也可以用於對語義版本進行編碼。如果使用semver,慣例是使用兩個最高有效位元組作為主要編號,下兩個位元組用於次要編號,最低有效的四個位元組用於構建/錯誤修復build/bugfix編號。使用semver版本控制時,至少有一個主/輔編號必須為非零。

IR規範對其版本使用簡單的單調遞增數。有效的IR版本由列舉定義,該列舉當前具有以下值:

// Version 1, published on Oct 10, 2017.

IR_VERSION_2017_10_10 =0x0000000000000001;

// Version 2, published on Oct 30,2017

IR_VERSION_2017_10_30 =0x0000000000000002;

// Version 3 published on Nov 3, 2017

IR_VERSION = 0x0000000000000003;

運算元operator集使用簡單的版本號。每個運算元operator集版本表示運算元operator集及其在特定時間點的語義的快照。

本規範沒有提供關於模型生產者應該使用什麼版本控制方案的指導。

有關IR、運算元operator集和模型版本控制的約定和最佳實踐的更多詳細資訊,請參閱版本控制。
可擴充套件計算圖模型

ONNX指定計算圖的可移植、序列化格式。它不一定是框架選擇的在內部使用和操作計算的形式。例如,如果在優化過程中操作更有效,則實現可能在記憶體中以不同的方式表示模型。

一個實現可以通過新增表示語義的運算元operator來擴充套件ONNX,這些運算元operator超出了所有實現必須支援的標準運算元operator集。其機制是將運算元operator集新增到依賴於擴充套件運算元operator的模型中的opset_import屬性。

模型Models

頂層ONNX構造是一個“Model”,在協議緩衝區中表示為型別onnx.ModelProto

模型結構的主要目的是將後設資料與包含所有可執行元素的圖形相關聯。後設資料是在第一次讀取模型檔案時使用的,它為實現提供了所需的資訊,以確定它是否能夠執行模型、生成日誌訊息、錯誤報告等。此外,後設資料對工具(如IDE和模型庫)很有用,它需要它來告訴人類一個給定模型的目的和特性。

每個模型都有以下元件:

在這裡插入圖片描述

模型必須指定一個域,並根據負責組織的標識使用反向域名,這與傳統上用於命名Java包的約定相同。

注意:檢測ONNX檔案

可以使用協議緩衝區分發中的Protocol工具檢查ONNX檔案的內容,方法如下:

$ protoc
–decode=onnx.ModelProto onnx.proto < yourfile.onnx

Where onnx.proto is the file
that is part of this repository.

Alternatively, you can use a tool like Netron
to explore the ONNX file.

模型語義

推理模型的語義是一個無狀態函式(除了用於隨機數生成的狀態)。因此,每當一個推理模型(沒有隨機的生成器操作)被用於對同一輸入執行推理時,它都會產生相同的輸出。

訓練模型的語義是有狀態物件的語義,狀態由訓練權重的當前值組成(以及學習演算法所需的任何其他輔助狀態,例如動量)。具體地說,它的語義是通過三種方法獲取的:初始化方法(用於初始化或重置狀態變數的值)、訓練步驟方法(使用一批輸入輸出對進行訓練)和一種推理方法,該方法利用學習到的權重的當前值進行推理。前兩個方法更新物件的狀態,而第三個方法沒有副作用。

可選後設資料

模型中的“metadata_props”欄位可用於工具或模型開發人員選擇放置在其中的任何型別的可選後設資料。以下是定義的模型的“標準”可選後設資料屬性。

在這裡插入圖片描述

運算元operator

每個模型都必須顯式地命名其功能所依賴的運算元operator。運算元operator定義可用運算元operator及其版本。每個模型按其域定義匯入的運算元operator。所有模型都隱式匯入預設的ONNX運算元operator。

每個運算元operator應在單獨的文件中定義,並使用protobuf作為序列化格式。如何在執行時找到運算元operator文件取決於實現。

注:截至本文件的釋出,還沒有任何ONNX實現用於處理操作文件。

運算元operator的屬性包括:

在這裡插入圖片描述

運算元operator版本是一個簡單的整數值,隨著新版本的運算元operator的釋出,該值單調增加。

預設運算元operator以外的運算元operator必須指定其域,並應根據負責組織的標識使用反向域名,這與用於命名Java包的約定相同。

運算元operator

圖中使用的每個運算元operator必須由模型匯入的運算元operator之一顯式宣告。

運算元operator定義的屬性包括:

在這裡插入圖片描述

版本值必須與首次釋出運算元operator時的運算元operator版本值相同。運算元operator的後續版本一旦釋出為穩定版本,則不得更改運算元operator的簽名或語義。

“status”屬性指示運算元operator的語法、語義或存在是否處於實驗階段或穩定階段。一旦一個運算元operator被髮布為穩定的,它的語法和語義在運算元operator集的後續版本中就不能改變。

有兩種不同的方法將資訊傳遞給運算元operator–輸入和屬性。後者用於表示圖中常量的值,而前者表示圖形輸入或在圖中其他地方計算的值。這種區別可能與某些實現的良好效能密切相關,而與其他實現完全無關。 圖

圖用於描述無副作用的計算(函式)。序列化圖由一組後設資料欄位、一組模型引數和一組計算節點組成。

每一個計算資料流圖都被構造成一個拓撲排序的節點列表,這些節點必須沒有迴圈。每個節點表示對運算元operator的呼叫。每個節點有零個或多個輸入和一個或多個輸出。

圖形具有以下屬性:

在這裡插入圖片描述

ValueInfo has the following properties:

在這裡插入圖片描述

版本值必須與首次釋出運算元operator時的運算元operator版本值相同。

運算元operator的後續版本一旦釋出為穩定版本,則不得更改運算元operator的簽名或語義。

“status”屬性指示運算元operator的語法、語義或存在是否處於實驗階段或穩定階段。一旦一個運算元operator被髮布為穩定的,它的語法和語義在運算元operator的後續版本中就不能改變。

有兩種不同的方法將資訊傳遞給運算元operator–輸入和屬性。後者用於表示圖中常量的值,而前者表示圖形輸入或在圖中其他地方計算的值。這種區別可能與某些實現的良好效能密切相關,而與其他實現完全無關。

圖用於描述無副作用的計算(函式)。序列化圖由一組後設資料欄位、一組模型引數和一組計算節點組成。

每一個計算資料流圖都被構造成一個拓撲排序的節點列表,這些節點必須沒有迴圈。每個節點表示對運算元operator的呼叫。每個節點有零個或多個輸入和一個或多個輸出。

圖形具有以下屬性:

在這裡插入圖片描述

相關文章