7.10. CMSIS-NN¶
TFLM がたどる演算子リストは、ほとんどが少数の重い演算子で構成されています。畳み込み(convolution) は、学習済みの重みからなる小さなグリッドを入力テンソル上でスライドさせ、各位置で重み付き和を書き込みます。深さ方向畳み込み(depthwise convolution) は同じ処理をチャネルごとに行います。全結合(fully-connected) は入力ベクトルと重み行列の間の行列積です。プーリング(pooling) は、小さな近傍領域の最大値または平均値を取ることでテンソルを縮小します。ReLU やシグモイドなどの 活性化関数(activation functions) は、すべての値に対して要素ごとに実行されます。ビジョン推論はそのサイクルの大半をこれら少数の演算子の内部で費やします。
素朴に実装すると、これらはマイクロコントローラ上では低速になります。CMSIS-NN は Arm による高速版のライブラリで、アセンブリで手作業によりチューニングされ、テンソル I/O で説明した int8 および uint8 の値に整数量子化され、CPU の SIMD 命令に対して書かれています。SIMD(Single Instruction, Multiple Data)は、CPU が同じサイクル内で複数の値に対して 1 つの算術演算を実行できるようにするものです。通常のスカラ乗算加算はサイクルあたり 1 つの結果を生成しますが、SIMD 乗算加算は複数の値を幅広いレジスタに詰め込み、それらすべてを一度に生成します。
H7 と RT1062 に搭載された Cortex-M7 は Arm の DSP 拡張(DSP extension) を備えており、32 ビットレジスタに 4 つの int8 値を保持し、それら 4 つすべてに対する乗算加算を 1 サイクルで実行します。AE3 に搭載された Cortex-M55 は Helium(正式には MVE、M プロファイルのベクトル拡張)を備えており、128 ビットレジスタに 16 個の int8 レーンを保持し、サイクルあたりのスループットは 4 倍になります。Helium はより幅広い CPU 命令セットであって、アクセラレータではありません。同じダイ上にある Ethos-U55 NPU がアクセラレータです。
出荷される TFLM ビルドは CMSIS-NN とリンクされており、TFLM は実行時に各重い演算子をそのカメラに適した SIMD バリアントへディスパッチします。AE3 ではディスパッチがもう少し複雑です。Vela コンパイラはオフラインですでにモデルをたどり、NPU 対応の演算子が連結したスライス、すなわち サブグラフ(subgraphs) を Ethos-U へのディスパッチ対象としてマークしています。推論時、それらのサブグラフはアクセラレータ上で 1 ブロックとして実行され、残りは M55 上の Helium CMSIS-NN にフォールバックします。
浮動小数点演算子は CMSIS-NN を完全にバイパスし、TFLM のポータブルなリファレンスカーネルを通して実行されます。int8 モデルと浮動小数点モデルの精度差は通常わずかですが、スループットの差は大きくなります。このため、カメラに出荷されるモデルは int8 に量子化されています。