【tensorflow.js】tfjs-nodeでIllegal instruction (core dumped)が出るときに見直すこと


2022/05/07

TensorflowのJavascript版である
tensorflow.jsにはネイティブnodeバックエンドで動かすことのできるtfjs-nodeが存在します。

素のtfjs(tensorflow.js)はブラウザ駆動のライブラリですので、tfjs-nodeで置き換えてNodeネイティブのアプリとして呼び出すと演算処理の高速化が期待できます。

しかしながら、どのようなパソコン環境でもtfjs-nodeが正常に動くかどうかの保証はありません。

例えばCPU環境によっては、node.jsのコンパイルこそ通るものの、tfjs-nodeを内部で呼び出す関数でいざ実行すると、

            
            $ mocha --require ts-node/register test/*.spec.ts
Illegal instruction (core dumped)
        
というエラーで実行途中でクラッシュします。

これはtfjs-node側のバグではなく、node.jsのネイティブアプリからのエラーです。

今回は簡単にこのエラーの対処法を考えてみます。


「Illegal instruction」エラーの対処法

この「Illegal instruction」エラーの対処法は、
「CPUのスペックを見直そう」、これに尽きます。

要はtfjs-nodeで使用しているCPUのニーモニック指令が古すぎて演算処理を高速化・最適化できない、と怒っているようです。

逆に、tfjs-nodeが正常に動作する比較的新しいCPUで同じソースコードを使ってみると、

            
            $ mocha --require ts-node/register test/*.spec.ts
2022-05-06 04:38:53.912393: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
#...以下略
        
という感じで、きちんとtfjs-nodeのプログラムが通常実行されています。

つまりは、
Illegal instruction (core dumped)が出た時点で、tfjs-nodeを利用できるほどのCPUスペックが無いという可能性が高いです。

最新のCPUを買ってマシーンの演算スペックを増強するか、tfjs-nodeは利用せずブラウザ版のtfjsの利用に絞るか、といった対処法が必要になります。


CPUのニーモニック一覧を確認する

tfjs-nodeが利用しているCPUニーモニックはAVX2以上の演算命令で、かなり古いCPUだと実行できないことになります。

CPUが対応しているかどうかは
/proc/cpuinfoを覗いてみると分かります。

手元のtfjs-nodeが正常動作していたCPU(さほど新しいCPUではありませんが...)で試すと、

            
            $ cat /proc/cpuinfo
processor    : 0
vendor_id    : GenuineIntel
cpu family   : 6
model        : 60
model name    : Intel(R) Core(TM) i7-4770S CPU @ 3.10GHz
stepping    : 3
microcode    : 0x7
cpu MHz        : 868.213
cache size    : 8192 KB
physical id    : 0
siblings    : 8
core id        : 0
cpu cores    : 4
apicid        : 0
initial apicid    : 0
fpu        : yes
fpu_exception    : yes
cpuid level    : 13
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb invpcid_single pti tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm xsaveopt dtherm ida arat pln pts
bugs        : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds
bogomips    : 6197.54
clflush size    : 64
cache_alignment    : 64
address sizes    : 39 bits physical, 48 bits virtual
power management:
#...他のコアは省略
        
avx2などのtfjs-nodeが指定できるニーモニックが見て取れます。

他方、tfjs-nodeが動かなかったマシーンのCPUではどうかというと、

            
            $ cat /proc/cpuinfo
processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 23
model name    : Intel(R) Core(TM)2 Quad CPU    Q9650  @ 3.00GHz
stepping    : 10
microcode    : 0xa0b
cpu MHz        : 2000.163
cache size    : 6144 KB
physical id    : 0
siblings    : 4
core id        : 0
cpu cores    : 4
apicid        : 0
initial apicid    : 0
fpu        : yes
fpu_exception    : yes
cpuid level    : 13
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl cpuid aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm pti tpr_shadow vnmi flexpriority vpid dtherm
vmx flags    : vnmi flexpriority tsc_offset vtpr vapic
bugs        : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit
bogomips    : 6000.08
clflush size    : 64
cache_alignment    : 64
address sizes    : 36 bits physical, 48 bits virtual
power management:
#...他のコアは省略
        
と、非対応のニーモニックしかなくて、このCPUでtfjs-nodeを使うのは不可能ということになります。

思えば、この古いCPUは4コア出始めた頃に買った製品ですので、かれこれ15年程度が経過しています...そりゃ動かなくても文句はいえません。

ということで、
「機械学習したいならCPUに限らずハードウェアは最新のものにせよ」、というお話でした。

記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。