Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use @tensorflow/tfjs-tflite with a bundler #5819

Open
Michael-F-Bryan opened this issue Nov 5, 2021 · 6 comments
Open

Unable to use @tensorflow/tfjs-tflite with a bundler #5819

Michael-F-Bryan opened this issue Nov 5, 2021 · 6 comments

Comments

@Michael-F-Bryan
Copy link

Michael-F-Bryan commented Nov 5, 2021

System information

  • OS Platform and Distribution: Arch Linux
  • TensorFlow.js installed from (npm or script link): @tensorflow/tfjs-tflite version 0.0.1-alpha.7

Describe the problem

The @tensorflow/tfjs-tflite package can't be imported by a project that uses a bundler unless the end user manually copies the dist/ folder out of node_modules/ and serves its contents themselves.

This causes usability issues where developers will get non-obvious errors (404 response, "Unexpected token <", etc.) when trying to do inference, and can be particularly difficult to troubleshoot when @tensorflow/tfjs-tflite is a transitive dependency and the end user may not know anything about tflite.

Provide the exact sequence of commands / steps that you executed before running into the problem

First, create a new project and add @tensorflow/tfjs-tflite as a dependency. For convenience, I used create-react-app because it comes with webpack already configured.

$ cd /tmp
$ yarn create react-app repro
$ cd $_
$ yarn add @tensorflow/tfjs-tflite @tensorflow/tfjs-core

Next, update a file to use something from @tensorflow/tfjs-tflite. It doesn't really matter what gets used as long as you make sure webpack bundles it.

diff --git a/src/index.js b/src/index.js
index ef2edf8..7730a34 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,6 +3,9 @@ import ReactDOM from 'react-dom';
 import './index.css';
 import App from './App';
 import reportWebVitals from './reportWebVitals';
+import { loadTFLiteModel } from '@tensorflow/tfjs-tflite';
+
+loadTFLiteModel("https://raw.githubusercontent.com/hotg-ai/test-runes/master/audio/multispeech/model.tflite");

 ReactDOM.render(
   <React.StrictMode>

Opening the dev tools will show you that a bunch of exceptions coming from tflite_web_api_client.js because it seems to load files at runtime instead of importing them.

tflite_web_api_cc_simd.js:1 Uncaught SyntaxError: Unexpected token '<'
tflite_web_api_client.js:1973 Uncaught (in promise) TypeError: A[(d.tfliteWebApiName + "_ModuleFactory")] is not a function
    at push../node_modules/@tensorflow/tfjs-tflite/dist/tflite_web_api_client.js.$jscomp.generator.Engine_.program_ (tflite_web_api_client.js:1973)
    at push../node_modules/@tensorflow/tfjs-tflite/dist/tflite_web_api_client.js.$jscomp.generator.Engine_.nextStep_ (tflite_web_api_client.js:31)
    at push../node_modules/@tensorflow/tfjs-tflite/dist/tflite_web_api_client.js.$jscomp.generator.Engine_.next_ (tflite_web_api_client.js:27)
    at push../node_modules/@tensorflow/tfjs-tflite/dist/tflite_web_api_client.js.$jscomp.generator.Generator_.next (tflite_web_api_client.js:32)
    at g (tflite_web_api_client.js:1567)

I've found the best workaround is to use the public/ directory to make sure webpack copies the contents of @tensorflow/tfjs-tflite/dist/ into the output directory when it builds your app.

$ mkdir -p public/static && cd $_
$ ln -s ../../node_modules/@tensorflow/tfjs-tflite/dist ./js
$ cd ../..
$ yarn build

Any other info / logs

This is similar to #5532 in that @tensorflow/tfjs-tflite is hard to use with normal JavaScript packages, but that issue is about the code using browser-only APIs while this is about the NPM package being unusable without copying files out of your node_modules/ folder.

@jinjingforever
Copy link
Collaborator

Please see my comments in #6026. Thanks!

@google-ml-butler
Copy link

Are you satisfied with the resolution of your issue?
Yes
No

@Michael-F-Bryan
Copy link
Author

@jinjingforever thanks for your comment.

I understand why things work the way they do, but tflite.setWasmPath() isn't a very satisfying solution because it means every downstream user (including when @tensorflow/tfjs-tflite is a dependency of a dependency of a dependency) will need to set up their build system to copy node_modules/@tensorflow/tfjs-tflite/dist/tflite_web* into their app's static/ folder.

That means the package isn't usable with a bundler out of the box and adds a lot of friction, which is the issue this ticket is getting at.

Most bundlers already support a mechanism for code splitting and dynamic imports (e.g. see Webpack, Parcel), which would solve this issue while also simplifying @tensorflow/tfjs-tflite's code for selecting backends.

Can we reopen this issue for now?

@jinjingforever
Copy link
Collaborator

Sure! I agree that a better solution is needed. The main thing is that it is tricky to make the wasm binaries (.wasm files) work well with bundlers (e.g. can bundlers bundle wasm files)? From our experience with the tfjs wasm backend (where we also use setWasmPath), some extra steps are needed if you use npm.

We will investigate more on this.

@jackson-sandland
Copy link

jackson-sandland commented Feb 22, 2023

Was this ever resolved? I've got a react app that I'd like to bundle tensorflowJS assets but webpack is unable to handle the tf file types.

@miguel-lorenzo
Copy link

any chance of solving this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants