背景
pytorch にも入りはじめ, pytorch master
のビルドが XNNPACK 関連でこけるようになって存在に気がつきました.
(https://github.com/pytorch/pytorch/pull/32509 一応 XNNPACK が libtorch mobile でマージされているので, pytorch v1.5.0 では XNNPACK 対応されそう)
NNPACK -> QNNPACK を経ての XNNPACK っぽい.
(Quantize 系を使いたい場合は, 引き続き QNNPACK を使うことになるのかしらん)
Bilinear resize 対応していたり, Android/iOS 対応を謳っているのがいいですね.
ビルド
現状(2020 年 3 月 11 日), master
は結構コケます.
成熟に期待しましょう...(プロジェクトキャンセルされなければ...ですが. 少なくとも 1 年くらいは続きそうですかね)
それぞれはファイルサイズ大きくないですが, pthreadpool, clog(pytorch(libtorch) にある謎のライブラリ), fp16, fxdiv(固定小数点割り算)など, 依存ライブラリは多いです(NNPACK とちがい PeachPy がなくなったのでビルドしやすくはなった... かも?)
ビルドにおいては特に特殊なことは必要ありません. assember の利用も on/off できます.
Windows(MSVC)
MSVC ビルドは, pthreadpoool が stdatomic.h を使っているためビルドができません.
この辺りで差し替えればいけるかも...?
=> 他にも Linux(posix)仮定しているところがあり無理そうでした.
とりあえずは clang 限定と考えたほうがよさそうです.
clang-cl, llvm-mingw など使うといいかもしれません
(gcc は gcc で bench のビルドがコケたりと問題がいくつかあるので)
NCHW, NHWC
PyTorch は NCHW ですが, XNNPACK は NHWC です.
一応, convolution_2d では NCHW に対応しているようですが, 全てのパターンを対応しているわけでないかもしれません.
一方, libtorch mobile では, ATen の contiguous + MemoryFormat 指定で NHWC(channel first)で変換していることがわかりました.
また, XNNPACK の out-of-bounds アクセスを防ぐため, 余裕を持ったメモリアロケーションをするなど涙ぐましい努力がされています.
ちなみに,
Chainer で学習し TensorFlow-lite で推論するための準備メモ
https://qiita.com/syoyo/items/e84d66b2a938843c1594
では, 無理やり各 Conv op などごとに NCHW -> NHWC -> NCHW 変換を入れて対応したことがありますが, 二倍くらい遅くなりました.
追記: PyTorch 1.5 https://github.com/pytorch/pytorch/releases/tag/v1.5.0 で NHWC フォーマットが experimental 対応されました. 今後, PyTorch はよりシームレスに XNNPACK と統合されるのが期待されます.
CI ビルド
fork して, GitHub Actions で作りました.
qemu aarch64 環境で, ビルド, test も走るようにしています.
実装アルゴリズム関連
The Two-Pass Softmax Algorithm
https://arxiv.org/abs/2001.04438
通常 3 pass になる softmax 計算を, 2 pass で行う. キャッシュに載っている状態だと, 18% ~ 28% 程度の性能向上
pass = データのアクセス回数
通常の 3 pass:
u = X の最大 : 1 pass 目
sigma = sum exp(Xi - u) : 2 pass 目
Yi = exp(Xi - u) / sigma : 3 pass 目
2 pass の計算は, IEEE754 と exp(x) の計算関連性をうまく使う.
TODO
- 自前 CPU NN 推論ライブラリに組み込む
- bilinear resize の動作が正しいか検証する https://qiita.com/syoyo/items/52462a0348eeeae94146