※ 当ページには【広告/PR】を含む場合があります。
2022/05/08
2022/08/18
【tensorflowjs入門】tfjs-nodeでIllegal instruction (core dumped)が出るときに見直すこと
【tensorflowjs入門】Nexeでシェルスクリプトからデータ解析できるツールを作成する
去年の話題になりますが、Google Chrome 89のx86版でもSSE3命令以前のCPUのサポートを廃止するという情報がありました。デフォルトでブラウザ動作するTensorflow.jsとブラウザに対応したCPU命令には密接な関係があります。これを理解して使わないと、Googlw Chromeでtensorflow.jsアプリを動かした際の演算パフォーマンスにも多大な影響を及ぼします。前回の記事で、Node.jsのネイティブアプリとして呼び出したtensorflow.js(node)は古いCPUだと動かない、という内容を説明していました。【tensorflowjs入門】tfjs-nodeでIllegal instruction (core dumped)が出るときに見直すことtfjs-nodeでIllegal instructionが発生してしまう場合にハードウェア周りの対処法を考えます。
今回は「ブラウザ駆動でも古いCPUほどSIMDとMultiThreadingの恩恵を受け取れなくなる」というそんなお話です。
【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集
Tensorflow.jsバックエンドとSIMD系ニーモニック
先に脇道に逸れて、少々SIMDの話をします。SIMD系のCPU命令
隔年でGoogle Chromeで古いCPUへの互換性が切り捨てられています。2020年9月に公開されたドラフトの内容においては、x86のGoogle Chrome 89以降でも、CPU命令でいうSSE3以上のニーモニックが必須となります。SSE3以降非対応の古いCPUを搭載したマシーンでも、Chromeブラウザでtensorflow.jsライブラリを呼び出した途端クラッシュします。SSE(Streaming SIMD Extensions;ストリーミングSIMD拡張命令)は、CPU命令を複数のデータへ同時に適用できるようか拡張指令です。同時に単一データ/単一命令(SISD)しか扱えない対して、単一データ/マルチ指令(SIMD)に対応させることで、1回の演算処理のパフォーマンスが大幅に向上することができます。このため、音声映像などリアルタイム性を求められるマルチメディア処理などに利用されています。ストリーミングSIMD拡張命令は年を経るごとに変遷しており、Intel製品の場合、最初のSIMD拡張命令のMMXから順にという流れで発展しています。Google Chromeでは、2014年以降からSSE2以上が必須となっていましたが、2021年よりSSE3以上が要求されます。このスペック要求の節目のバージョンがGooogle Chrome 87ということで、それより以前のバージョンを使っている場合、「SSE3が検出できない」といった趣旨の警告が表示されるようです。SIMDとは
折角なので、「SIMD」(Single Instruction, Multi Data)についても簡単に触れておきます。その名の通り、CPUに単一の命令を複数のデータに並列に処理させる手法の一つです。通常の処理では、SISD(Single Instruction, Single Data)で一回の演算で一回の処理を行うところを、SIMDで置き換えると、複数の演算を一回の処理でまとめて行うことが可能です。いわゆるSIMDはベクトル演算の一種であり、繰り返し制御等を行わない変わりに、同時にデータ処理するだけ高速化が期待できます。全てのプログラムが高速化できるとは限りませんが、多量のデータを一度に扱う必要のあるプログラムなどでは、SIMD系命令で飛躍的に動作速度がする可能性があり、画像処理プログラムなどはその一つです。通常ベクトル演算はCPUのハードウェア構造に因る機能ですので、当然古いCPUアーキテクチャを持つCPU製品ではここ最近のSIMD系ニーモニックは利用できないという点は知っておきたいところです。生のSIMDをレジスタから呼び出してバイナリ実装したい方は、こちらのサイトなどが詳しく説明されていますので参考にしてみてください。おらがクラシックCPUでtensorflow.jsの動作を検証
話を主題に戻します。8年前に割と高値で購入したCPUでIntel製の第4世代Corei7プロセッサー(Intel i7-4770S)でTensorflow.jsの演算を少々やっていた時に、nodeネイティブな「tfjs-node」で処理させるよりも、Chrome(ハードウエアアクセラレーションあり)上で素の「tfjs」のほうが明らかに処理が早い...ということに気づきました。どうもChromeブラウザではWebGLで実装したソフトウェアレベルの高速な演算処理を行わせており、これがSIMD系命令で高速化したネイティブアプリのCPU処理よりも高速だ、というなんだか感覚に逆転してしまいました。通常、node.jsネイティブのバックエンドであるtfjs-nodeの方が、ただのtfjsよりは速く処理できるというつもりだったので、ハードウェアアクセラレーション有りのブラウザ処理でこんなに速いのであれば、tfjs-nodeなんて不要なのでは...とも思いました。結果として、tfjs-nodeが遅いのではなく、「AVX-512以降を使えないCPUでないとtfjs-nodeの恩恵がない」という話のようです。現在、Chromeブラウザが搭載しているWebGLハードウェアアクセラレーションは非常に有能で、古いSIMD命令では太刀打ちできないレベルにあります。他方で、AVX-512以降を利用できるCPU製品では、WebGLをも凌ぐSIMD演算とマルチスレッド処理に対応しています。そんな既にアンティークと化してしまいそうなこのCPUの命令セットを表示させてみると見ての通りで、まぁ...sse4_2やavxまではSIMD対応しているようです。当然ながらAVX-512は使えないので、せめてここ5年以内に発売されたCPUでなければ、tfjs-nodeを使うより、通常のtfjsでブラウザのハードウェアアクセラレーションや、マルチスレッド処理できるWASM(webassembly)バックエンドを利用すべきです。
【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集
参照
Tensorflow.jsをNodejsで高速化しようとしたが、旧型CPUでは、WebGLの方が高速だった話Supercharging the TensorFlow.js WebAssembly backend with SIMD and multi-threadingTensorFlow.js の WebAssemblyバックエンド の紹介