tensorflow / tfjs

A WebGL accelerated JavaScript library for training and deploying ML models.
https://js.tensorflow.org
Apache License 2.0
18.52k stars 1.94k forks source link

Node.js binding does not load on Heroku #517

Closed nkreeger closed 5 years ago

nkreeger commented 6 years ago

From the mailing list:

"My team and I are working on deploying a web app that uses a TFJS model powered by Node, rather than WebGL. We've successfully run the app on our local machines, but have encountered an issue running tfjs-node through Heroku (Ubuntu 16.04) and Docker (with an Alpine image). The same error shows up in both setups.

When requiring tfjs-node, the backend registration fails looking for libtensorflow.so. I've double-checked that the file libtensorflow.so is present in the directory that tfjs-node/scripts/download-libtensorflow.sh is looking for it in. This is the setup that we've been running on our local machines without a problem.

Here's the error from Heroku bash:

~ $ node

const tf = require('@tensorflow/tfjs') undefined require('@tensorflow/tfjs-node') Registration of backend tensorflow failed Error: libtensorflow.so: cannot open shared object file: No such file or directory at Object.Module._extensions..node (module.js:681:18) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at bindings (/app/node_modules/bindings/bindings.js:81:44) at /app/node_modules/@tensorflow/tfjs-node/dist/index.js:8:60 at Environment.registerBackend (/app/node_modules/@tensorflow/tfjs-core/dist/environment.js:296:27) at Object. (/app/node_modules/@tensorflow/tfjs-node/dist/index.js:7:9) { version: '0.1.8' } "

Even with the fix shipped in 0.1.9 this is still happening. Some investigation is needed to figure out why the Node process can't find the library on Heroku.

kangyizhang commented 6 years ago

After some investigation, the problem is that @tensorflow/tfjs-node is not installed in the base Heroku system. With some hint from this post, I did the following and have a tfjs-node example up and running: 1) run heroku run /bin/bash to enter a one-off dyno bash prompt 2) run npm install @tensorflow/tfjs-node 3) start the process (I tried with this example and ran node index.js)

But it does not work after quit the bash prompt and start the process again without install tfjs-node later. More investigation required to make @tensorflow/tfjs-node stay in heroku forever.

kangyizhang commented 6 years ago

Quick updates:

Tried with clean node_modules cache and run yarn update --pattern @tensorflow/tfjs-node post install, still doesn't work. Working with heroku support to locate root cause (heroku ticket: https://help.heroku.com/tickets/609604).

pkamath2 commented 5 years ago

Hi @kangyizhang, In your comment (https://github.com/tensorflow/tfjs/issues/517#issuecomment-407232197) you mention that you were able to deploy tfjs-node app to GCP, was there anything specific you had to do in order to deploy?

I get the same error while deploying to GCP. Error: libtensorflow.so: cannot open shared object file: No such file or directory.

Did you have to bundle the node_modules/@tensorflow from your local while deploying?

tambien commented 5 years ago

I'm having the same issue on GCP using Cloud Functions: Error: libtensorflow.so: cannot open shared object file.

Looking through the documentation, i found that Cloud Functions have a read-only file-system. Is it possible that this blocks the install process from downloading or installing what needs to make this work?

Is it possible to specify the download/install directory of libtensorflow.so? or download the correct version for the platform manually and somehow link it to tfjs-node?

thanks!

vpanichkin commented 5 years ago

Hello, everyone! Solved this issue by using docker container Steps to reach the solution:

  1. Add heroku.yml

    build:
    docker:
    web: Dockerfile
    run:
    web: node app.js
  2. Add DockerFile

    FROM node:10
    WORKDIR /
    COPY package.json /
    RUN npm install
    COPY . /
    CMD node app.js
  3. Set heroku stack:set container in CLI to use DockerFile instead of ProcFile

  4. Commit changes and push with git push heroku master

After that, Docker image will be created on Heroku-side and you application will launch.

P.S. Some useful links: https://buddy.works/guides/how-dockerize-node-application https://devcenter.heroku.com/articles/build-docker-images-heroku-yml https://devcenter.heroku.com/articles/container-registry-and-runtime#unsupported-dockerfile-commands Keep in mind, that you do not need EXPOSE command to open PORT as Heroku will give a port dynamically, just use process.env.PORT in your node application. Heroku will do everything on its own!

dsmilkov commented 5 years ago

Thanks for the research everyone! @kangyizhang if you can add instructions in the README of our repo with the steps required to run tfjs-node on GCP and Heroku, that would be fantastic. Thanks!

kangyizhang commented 5 years ago

@dsmilkov that makes sense. I'll add GUIDE about how to deploy tfjs-node job on GCP and Heroku.

kangyizhang commented 5 years ago

The GUIDE has been added: https://github.com/tensorflow/tfjs-website/blob/master/docs/guide/node_in_cloud.md