node.jslinuxdebiantensorflow.jstfjs-node

Nodejs throwing Illegal instruction - Debian GNU/Linux 10.9


I am trying to run the following nodejs application on a virtual machine running Debian GNU/Linux 10.9 with Node version v14.20.0.

require('@tensorflow/tfjs-node');
require('@tensorflow/tfjs-core'); 
require('@tensorflow/tfjs-backend-cpu');
const qna = require('@tensorflow-models/qna');

const passage=`Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season.
The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24–10 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California.
As this was the 50th Super Bowl, the league emphasized the "golden anniversary" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have  been known as "Super Bowl L"), so that the logo could prominently feature the Arabic   numerals 50.`

const qu= "Who won the Super Bowl?";


async function test(){
const model = await qna.load();
const answers = await model.findAnswers(qu, passage);
console.log('Answers: ');
console.log(answers);
}

test();

The app runs fine on MacBook Pro but on Debian GNU/Linux 10.9, Nodejs only throws a message saying Illegal instructions without further details.The problem has not been resolved by removing node_modules directory, reinstalling modules, and running npm rebuild.
Any help would be greatly appreciated. Below are more details about the Linux virtual machine I am using:

Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
Address sizes:       40 bits physical, 48 bits virtual
CPU(s):              1
On-line CPU(s) list: 0
Thread(s) per core:  1
Core(s) per socket:  1
Socket(s):           1
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
Model:               6
Model name:          QEMU Virtual CPU version 2.5+
Stepping:            3
CPU MHz:             2095.076
BogoMIPS:            4190.15
Hypervisor vendor:   KVM
Virtualization type: full
L1d cache:           32K
L1i cache:           32K
L2 cache:            4096K
L3 cache:            16384K
NUMA node0 CPU(s):   0
Flags:               fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti

I used curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash to install nvm.Then used nvm to install node

nvm --version
0.38.0


nvm list
  v12.22.12
-> v14.20.0
     system
default -> 12 (-> v12.22.12)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v14.20.0) (default)
stable -> 14.20 (-> v14.20.0) (default)
lts/* -> lts/gallium (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12
lts/fermium -> v14.20.0
lts/gallium -> v16.17.0 (-> N/A)

Solution

  • tfjs-node relies on pre-built tensorflow.so which is downloaded per detected platform. and that tensorflow is compiled using specific cpu optimizations, for example avx is enabled by default and mac's virtual machine does not provide those instructions to guest os.

    you could skip downloading pre-built tensorflow and build it yourself, but that is anything but painless.

    or try a different vm layer (you didn't say what you're using to start with).

    Edit#1: If VM is provided by your University, you cannot change how it works (and its not uncommon that its restricted). On how to build TF from scratch, its too much for here - and honestly, its a lot of work.

    As a workaround, you may try older version of tfjs-node that relies on version of tensorflow that doesn't require specific CPU instructions. But I don't remember exactly how far back version-wise you'd have to go (hint: its quite a lot, definitely nothing from v3.x release branch).

    Edit#2: Having sudo access gives you root on the guest OS, you cannot change CPU flags from there - it needs to be done from parent host. But if your maintainer is willing to change flags, take a look at https://ahelpme.com/howto/qemu-full-virtualization-cpu-emulations-enable-disable-cpu-flags-instruction-sets/

    Could you please tell me what CPU flags Tensorflow requires

    Most likely, its AVX that is missing as that is common problem with QEMU

    And alternatively, if you want to build tensorflow yourself, take a look at https://github.com/tensorflow/tfjs/tree/master/tfjs-node#optional-build-optimal-tensorflow-from-source