oneAPI 1.3 暫定仕様書 Rev. 1 の解説 (18)

その他

この記事は、https://www.oneapi.io/spec/ で 2023年9月14日に公開された『oneAPI 1.3 Provisional Specification Rev. 1』 (HTMLPDF) をベースにしています。原文は2000 ページ近くあり、翻訳の時間とリソースも限られるため、全文翻訳ではなく、記事形式で区切った仕様とその解説を提供することにしました。


この回では、『oneAPI 1.3 Provisional Specification Rev. 1』の「oneDNN」の「Concat」と「Convolution and Deconvolution」の節を取り上げています。

結合 (Concat)

データを任意の次元で結合するプリミティブです。

結合プリミティブは、concat_dimension (ここでは C として示されます) 上で N テンソルを結合します。次にように定義されます。

説明:

  • c = C1 + … + Ci−1 + c′
  • は最外のインデックス (結合軸の左側) です。
  • は最内のインデックス (結合軸の右) です。

変数名は標準の規則 (英語) に従います。

順方向と逆方向

結合プリミティブには、順方向と逆方向の伝播の概念がありません。結合操作の逆伝播は、単純な単位元操作です。

実行引数

実行時に入力と出力は、次の表で示す実行引数インデックスにマップする必要があります。

プリミティブの入力/出力 実行引数インデックス
src DNNL_ARG_MULTIPLE_SRC
dst DNNL_ARG_DST

操作の詳細

  1. dst メモリー形式は、ユーザーが指定することも、プリミティブによって取得することもできます。推奨される方法は、プリミティブが最も適切な形式を選択できるようにすることです。

  2. 結合プリミティブでは、concat_dimension を除いて、すべてのソースとデスティネーション・テンソルが同一形状でなければなりません。concat_dimension のデスティネーションは、ソースの concat_dimension 次元の合計と等しくなければなりません (つまり C=∑iCi)。暗黙のブロードキャストはサポートされません。

サポートされるデータタイプ

結合プリミティブは、ソーステンソルとデスティネーション・テンソルの任意のデータタイプをサポートします。ただし、すべてのソーステンソルは同一のデータタイプである必要があります (デスティネーション・テンソルのデータタイプとは必ずしも一致する必要はありません)。

データ表現

結合プリミティブは、関連する論理次元に対し特別な意味は持ちません。

post-ops と属性

結合プリミティブは post-ops や属性をサポートしません。

API

API については、こちら (英語) をご覧ください。

畳み込みと逆畳み込み

畳み込みおよび逆畳み込みプリミティブは、バイアス付きの 1D、2D、または 3D 空間データに対するバッチ畳み込みまたは逆畳み込み操作の順方向、逆方向、もしくは重み更新を計算します。

操作は次の式で定義されます。高次元と低次元のケースでは、一般化が容易な 2D 空間データの式のみを示します。変数名は標準の規則 (英語) に従います。

順方向 (前方)

srcweights、および dst をそれぞれ N×IC×IH×IWOC×IC×KH×KWN×OC×OH×OW テンソルとし、biasOC 要素を持つ 1D テンソルとします。

さらに、残りの畳み込みパラメーターを次のようにします。

パラメーター 深さ 高さ コメント
パディング: front、top、left PDL PHL PWL API padding_l は、対応するパディングのベクトルを示します (_lleft を表します)
パディング: back、bottom、right PDR PHR PWR API padding_r は、対応するパディングのベクトルを示します (_rright を表します)
ストライド SD SH SW ストライドのない畳み込みは、ストライド・パラメーターを 1 に設定して定義できます。
膨張 DD DH DW 非膨張畳み込みは、膨張パラメーターを 0 に設定して定義できます。

次の式は、oneDNN における畳み込みの計算方法を示します。説明を簡単にするためいくつかのタイプに分類していますが、実際には畳み込みタイプを組み合わせます。

式をさらに単純化するため、ih<0ih≥IHiw<0、または iw≥IW の場合、src(n,ic,ih,iw)=0 と仮定します。

通常の畳み込み

ここでは以下が成り立ちます。

グループとの畳み込み

oneDNN は、重みテンソルを表すメモリー・オブジェクトに別のグループの次元を追加し、グループと 2D 畳み込みの場合、重みを G×OCG×ICG×KH×KW 5D テンソルとします。

ここでは以下が成り立ちます。

OCG = ICG = 1 の場合、深さ方向の畳み込みとも呼ばれます。

膨張を伴う畳み込み

ここでは以下が成り立ちます。

逆畳み込み (転置畳み込み)

逆畳み込み (フラクショナル・ストライド畳み込み、または転置畳み込みとも呼ばれます) は、畳み込みの前方パスと後方パスを入れ替えることで定義できます。言い変えると、重みが畳み込みを定義していることに注意してください。直接畳み込みであるか転置畳み込みであるかは、順方向と逆方向パスの計算方法によって決定されます。

順方向トレーニングと順方向推論の違い

forward_trainingforward_inference 伝播の種類に違いはありません。

逆方向 (後方)

逆方向伝播は、diff_dstweights に基づいて diff_src を計算します。

重みの更新では、diff_dstsrc に基づいて diff_weightsdiff_bias が計算されます。

注: 最適化されたメモリー形式の srcweights は、順方向伝播、逆方向伝播、および重みの更新で異なることがあります。

実行引数

実行時に入力と出力は、次の表で示す実行引数インデックスにマップする必要があります。

プリミティブの入力/出力 実行引数インデックス
src DNNL_ARG_SRC
weights DNNL_ARG_WEIGHTS
bias DNNL_ARG_BIAS
dst DNNL_ARG_DST
diff_src DNNL_ARG_DIFF_SRC
diff_weights DNNL_ARG_DIFF_WEIGHTS
diff_bias DNNL_ARG_DIFF_BIAS
diff_dst DNNL_ARG_DIFF_DST

操作の詳細

なし

サポートされるデータタイプ

畳み込みプリミティブは、ソース、デスティネーション、および重みメモリー・オブジェクトのデータタイプで次の組み合わせをサポートします。

注: この節では、可読性のためデータタイプの名称を省略しています。例えば、dnnl::memory::data_type::f32f32 に省略されます。

伝播 ソース 重み デスティネーション バイアス
順方向/逆方向 f32 f32 f32 f32
順方向 f16 f16 f16 f16
順方向 u8s8 s8 u8s8s32f32 u8s8s32f32
順方向 bf16 bf16 f32bf16 f32bf16
逆方向 f32bf16 bf16 bf16
重み更新 bf16 f32bf16 bf16 f32bf16

データ表現

ほかの CNN プリミティブと同様に、畳み込みプリミティブは次のテンソルを想定します。

空間 ソース/デスティネーション 重み
1D N×C×W [G×] OC×IC×KW
2D N×C×H×W [G×] OC×IC×KH×KW
3D N×C×D×H×W [G×] OC×IC×KD×KH×KW

データのメモリー形式とメモリー・オブジェクトの重みは、畳み込みプリミティブのパフォーマンスに重要です。oneDNN プログラミング・モデルは、畳み込みはプレースホルダー・メモリー形式タグ any をサポートするプリミティブの 1 つであり、プリミティブのパラメーターに基づいてデータとメモリー・オブジェクト形式を定義できます。any を使用する場合、最初に畳み込みプリミティブ記述子を作成してから、実際のデータと重みメモリー・オブジェクト形式を照会する必要があります。

畳み込みプリミティブは、明示的に指定されたメモリー形式によって作成できますが、パフォーマンスは最適ではない可能性があります。

次の表は、畳み込みプリミティブが最適化されるプレーンメモリー形式の組み合わせを示します。

空間 畳み込みタイプ データ/重み論理テンソル メモリー形式向けに最適化された実装
1D、2D、3D any 最適化済み
1D f32、bf16 NCW/OIW、GOIW ncw (abc)/oiw (abc)、goiw (abcd)
1D f32、bf16 NCW/OIW、GOIW nwc (acb)/wio (cba)、wigo (dcab)
1D int8 NCW/OIW nwc (acb)/wio (cba)
2D f32、bf16 NCHW/OIHW、GOIHW nchw (abcd)/oihw (abcd)、goihw (abcde)
2D f32、bf16 NCHW/OIHW、GOIHW nhwc (acdb)/hwio (cdba)、hwigo (decab)
2D int8 NCHW/OIHW、GOIHW nhwc (acdb)/hwio (cdba)、hwigo (decab)
3D f32、bf16 NCDHW/OIDHW、GOIDHW ncdhw (abcde)/oidhw (abcde)、goidhw (abcdef)
3D f32、bf16 NCDHW/OIDHW、GOIDHW ndhwc (acdeb)/dhwio (cdeba)、dhwigo (defcab)
3D int8 NCDHW/OIDHW ndhwc (acdeb)/dhwio (cdeba)

post-ops と属性

post-ops と属性を使用すると、プリミティブの結果に量子化パラメーターを適用し、プリミティブの後に特定の操作を結合することで畳み込みプリミティブの動作を変更できます。次の属性と post-op がサポートされます。

タイプ 操作 説明 制限事項
属性 scales 対応するテンソルのスケールを設定します。 Int8 計算のみ
属性 zero points 対応するテンソルのゼロポイントを設定します。 Int8 計算のみ
post-op eltwise 結果に要素ごとの操作を適用します。
post-op binary 結果にバイナリー操作を適用します。
post-op sum 演算結果を上書きせずに、デスティネーション・テンソルに加算します。

プリミティブは、実行時スケールを介した動的な量子化をサポートします。ユーザーは、プリミティブ記述子の作成時にスケールとゼロポイント属性を設定できます。ユーザーは、実行時に引数 DNNL_ARG_ATTR_SCALES および DNNL_ARG_ATTR_ZERO_POINTS を使用して、追加の入力メモリー・オブジェクトとしてスケールとゼロポイントを設定する必要があります (詳細は「量子化」 (英語) の節で説明します)。

注: ライブラリーは、トレーニングで post-ops の使用を妨げるものではありませんが、すべての post-ops がトレーニングに適しているわけではありません。例えば、非ゼロの負の勾配パラメーターで ReLU を post-op として使用しても、逆伝播を正しく計算するために必要な出力 workspace は作成されません。したがって、状況によってはトレーニングに個別の畳み込みプリミティブと要素ごとのプリミティブを使用する必要があります。

次の post-ops チェーンがライブラリーでサポートされる必要があります。

畳み込みタイプ サポートされる post-ops シーケンス
f32 と bf16 畳み込み eltwise、sum、sum -> eltwise
int8 畳み込み eltwise、sum、sum -> eltwise、eltwise -> sum

属性と post-ops 適用中の操作は、単精度浮動小数点データタイプで実行されます。実際のデスティネーション・データタイプへの変換は、保存の直前に行われます。

例 1

次の疑似コードについて考えてみます。

attribute attr;
attr.set_post_ops({
        { sum={scale=beta} },
        { eltwise={scale=gamma, type=tanh, alpha=ignore, beta=ignored }
    });

convolution_forward(src, weights, dst, attr)

以下が導き出されます。

例 2

次の疑似コードについて考えてみます

attribute attr;
attr.set_output_scale(alpha);
attr.set_post_ops({
        { eltwise={scale=gamma, type=relu, alpha=eta, beta=ignored }
        { sum={scale=beta} },
    });

convolution_forward(src, weights, dst, attr)

以下が導き出されます。

アルゴリズム

oneDNN の実装では、ユーザーが選択可能ないくつかの異なるアルゴリズムを使用して畳み込みプリミティブを実装できます。

  • Direct (dnnl::algorithm::convolution_direct)。畳み込み操作は、SIMD 命令によって直接計算されます。これには、ワークスペースを必要とする暗黙的な GEMM 公式も含まれます。

  • Winograd (dnnl::algorithm::convolution_winograd)。このアルゴリズムは、精度の低下とメモリー操作の増加と引き換えに、畳み込みの計算の複雑性を軽減します。実装は、A. Lavin および S. GrayFast 共著の「Algorithms for Convolutional Neural Networks」(英語) に基づいています。Winograd アルゴリズムは、高いパフォーマンスをもたらしますが、特定の形状でのみ利用できます。また、int8 と f32 データタイプのみをサポートします。

  • Auto (dnnl::algorithm::convolution_auto)。このアルゴリズムでは、ライブラリーはテンソルの形状と利用可能な論理プロセッサー数を考慮したヒューリスティックに基づいて、最適なアルゴリズムを自動的に選択します。

API

API については、こちら (英語) をご覧ください。


法務上の注意書き

The content of this oneAPI Specification is licensed under the Creative Commons Attribution 4.0 International License (英語). Unless stated otherwise, the sample code examples in this document are released to you under the MIT license (英語).

This specification is a continuation of Intel’s decades-long history of working with standards groups and industry/academia initiatives such as The Khronos Group*, to create and define specifications in an open and fair process to achieve interoperability and interchangeability. oneAPI is intended to be an open specification and we encourage you to help us make it better. Your feedback is optional, but to enable Intel to incorporate any feedback you may provide to this specification, and to further upstream your feedback to other standards bodies, including The Khronos Group SYCL* specification, please submit your feedback under the terms and conditions below. Any contribution of your feedback to the oneAPI Specification does not prohibit you from also contributing your feedback directly to other standard bodies, including The Khronos Group under their respective submission policies.

By opening an issue, providing feedback, or otherwise contributing to the specification, you agree that Intel will be free to use, disclose, reproduce, modify, license, or otherwise distribute your feedback at its sole discretion without any obligations or restrictions of any kind, including without limitation, intellectual property rights or licensing obligations.

This document contains information on products, services and/or processes in development. All information provided here is subject to change without notice.

© Intel Corporation. Intel、インテル、Intel ロゴ、その他のインテルの名称やロゴは、Intel Corporation またはその子会社の商標です。

* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。

« パート 17        目次        パート 19 »
タイトルとURLをコピーしました