Leveraging the power of Tensorflow.js within web workers

I am trying to import 2 scripts into a webWorker using importScripts() like so, but I am encountering issues with the imports. Can someone provide guidance on how to resolve this?

self.importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs');
self.importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter');

view error screenshot

Answer №1

Presently, utilizing the webgl implementation on web-workers is not feasible due to the experimental nature of offlineCanvas. However, using the CPU backend is an option.

Here's a demonstration that delegates computation to a web-worker:

<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a6d2c0ccd5e6968897928894">[email protected]</a>/dist/tf.min.js"></script>
    <script>
        const worker_function = () => {

            onmessage =  () => {
                console.log('from web worker')
                    this.window = this
                    importScripts('https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="740711001d191911101d15001134455a445a41">[email protected]</a>/setImmediate.min.js')
                    importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="196d7f736a5929372829372a">[email protected]</a>')
                    tf.setBackend('cpu')
                    
                    const res = tf.zeros([1, 2]).add(tf.ones([1, 2]))
                    res.print()
                    
                    postMessage({res: res.dataSync(), shape: res.shape})
            };
        }
        if (window != self)
            worker_function();
    </script>
    <script>
        const worker = new Worker(URL.createObjectURL(new Blob(["(" + worker_function.toString() + ")()"], { type: 'text/javascript' })));
        worker.postMessage({});
        worker.onmessage = (message) => {
        console.log('from main thread')
        const {data} = message
        tf.tensor(data.res, data.shape).print()
        }
    </script>
</head>

When dealing with tensors, the size of data shared between the main thread and the web-worker can be significant. This data can either be cloned or transferred.

The distinction lies in whether the data is cloned, keeping a copy for further processing by the web-worker, or if ownership and data are transferred together when transferring. Transfer has the advantage of speed, analogous to passing a reference.

Lets evaluate the performance difference between these two snippets:

<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4e3a28243d0e7e607f7a607c">[email protected]</a>/dist/tf.min.js"></script>
    <script>
        const worker_function = () => {

            onmessage =  () => {
                console.log('from web worker')
                    this.window = this
                    importScripts('https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fd8e98899490909899949c8998bdccd3cdd3c8">[email protected]</a>/setImmediate.min.js')
                    importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a4d0c2ced7e4948a95948a97">[email protected]</a>')
                    tf.setBackend('cpu')
                    
                    const res = tf.randomNormal([2000, 2000, 3])
                    const t0 = performance.now()
                    postMessage({res: res.dataSync().buffer, shape: res.shape}, [res.dataSync().buffer])
                    console.log(`Prediction took ${(performance.now() - t0).toFixed(1)} ms`)
            };
        }
        if (window != self)
            worker_function();
    </script>
    <script>
        const worker = new Worker(URL.createObjectURL(new Blob(["(" + worker_function.toString() + ")()"], { type: 'text/javascript' })));
        worker.postMessage({});
        worker.onmessage = (message) => {
        console.log('from main thread')
        const {data} = message
        tf.tensor(new Float32Array(message.data.res), message.data.shape)
        }
    </script>
</head>

<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3a4e5c50497a0a140b0e1408">[email protected]</a>/dist/tf.min.js"></script>
    <script>
        const worker_function = () => {

            onmessage =  () => {
                console.log('from web worker')
                    this.window = this
                    importScripts('https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="156670617c787870717c74617055243b253b20">[email protected]</a>/setImmediate.min.js')
                    importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f5b49455c6f1f011e1f011c">[email protected]</a>')
                    tf.setBackend('cpu')
                    
                    const res = tf.randomNormal([2000, 2000, 3])
                    const t0 = performance.now()
                    postMessage({res: res.dataSync(), shape: res.shape})
                    console.log(`Prediction took ${(performance.now() - t0).toFixed(1)} ms`)
            };
        }
        if (window != self)
            worker_function();
    </script>
    <script>
        const worker = new Worker(URL.createObjectURL(new Blob(["(" + worker_function.toString() + ")()"], { type: 'text/javascript' })));
        worker.postMessage({});
        worker.onmessage = (message) => {
        console.log('from main thread')
        const {data} = message
        tf.tensor(message.data.res, message.data.shape)
        }
    </script>
</head>

There's approximately a 10ms disparity between the two code snippets. When performance is crucial, consideration must be given to how the data is handled – whether it should be cloned or transferred.

Answer №2

TensorflowJS relies on the canvas for its GPU computations, and unfortunately, a worker does not have access to a canvas at this time.

The development of OffscreenCanvas is in progress, but TFJS may require broader browser support before implementing it.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Detecting race conditions in React functional components promises

There's an INPUT NUMBER box that triggers a promise. The result of the promise is displayed in a nearby DIV. Users can rapidly click to increase or decrease the number, potentially causing race conditions with promises resolving at different times. T ...

What is the best way to create a sign-up box that appears on the same page when you click on the sign-up button

I am interested in implementing a 'sign up' box overlay at the center of my index page for new users who do not have an account. I would like them to be able to easily sign up by clicking on the 'sign up' button. Once they complete the ...

Removing Latex form of different English letters using Javascript

Is there a way to replace Latex characters following the {\'<1 alpha>} pattern with their corresponding English letter? For instance: L{\'o}pez Would become: Lopez This replacement should only target characters within the ...

What steps can be taken to stop the page from refreshing and losing its state when cancelling navigation using the back and forward browser buttons in React-router v4.3?

I'm currently facing an issue with a page in which user inputs are saved using a react context object. The problem arises when a user navigates away from the page without saving their entries. I want to prompt the user to either continue or cancel, wh ...

Troubleshooting Problems with Ruby Arrays, JavaScript, and JSON

I am facing a challenge with rendering a highcharts plugin in my rails application. I suspect it could be related to the sql queries fetching data from the database and converting them into a ruby array that the javascript code fails to interpret correctly ...

Retrieve HTML content from a JSON object and render it on a web page

I am facing a challenge with decoding html that is in json format. I'm struggling to figure out how to retrieve my html and display it on a page. It seems like json_decode isn't the solution. Can anyone help me with this issue? Appreciate any as ...

Utilizing Bresenham's line drawing algorithm for showcasing box contours

I am seeking a similar behavior to what is demonstrated on , but with some modifications to the boxes: div { display: inline-block; width: 100px; height: 100px; border: 1px solid black; cursor: pointer; } div.selected, div:hover { backgroun ...

Learn how to trigger various servlets by clicking different buttons within an HTML form

I have an HTML form and I need to call two different servlets when two different buttons are clicked. How can I change the form action at runtime? <form> <input type="submit" value="Question Paper" style="height:25px; width:120px; background-colo ...

(Solving the Issue of Size in Three.JS Transform Controls for Translation)

I have been working on customizing the transform controls in three.js for my current project. I successfully modified the rotation part and am now focusing on the translation aspect. In the translation Gizmo, there is an XYZ octahedron at the center. I hav ...

Is it possible to optimize the Dojo build system to only compile Dojo when necessary?

Greetings. I've been assigned the challenging task of enhancing the efficiency of the Javascript build process in our application. The current setup involves using Dojo libraries and build system, which takes approximately 6 minutes for a complete bui ...

Arrangement of bootstrap and CSS library in header has an impact on the styling of h3 Tag

After rearranging the order of the online Bootstrap and offline CSS library, I noticed an impact on the h3 element in my HTML document. To further clarify this conflict, let me provide more details. <link rel="stylesheet" href="https://maxcdn.boot ...

What are the best practices for avoiding the need to restart my node server every time an error occurs?

Network.js const mysql = require("mysql"); var connectionDetails = mysql.createConnection({ host: "xxx.amazonaws.com", user: "admin", password: "xxx", database: "xxx", multipleStatements: true, } ...

Are you in need of an IDE for Javascript, CSS, HTML, or Java

Alright, time to make a decision. I'm torn between Aptana, Eclipse, and Netbeans. Ideally, I want a versatile program that can handle all the different languages I plan on experimenting with - HTML, CSS, Javascript, and Java. I already have Visual Stu ...

Error: The property 'classList' cannot be read as it is null in Flask, jinja2, JavaScript, HTML, and Bootstrap

I am currently utilizing a bootstrap button class, and upon clicking the button, I pass this.id to the caretToggle() JavaScript function. Since I have multiple bootstrap buttons that I want to toggle the caret on, I attempted the method below, only to enco ...

Using the drag and drop feature with the v-textarea component in Vuetify

Struggling to incorporate a Drag and Drop feature on vuetify v-textarea. Encountering an issue where clicking on the v-textarea results in the value from a dropped component being removed. Unsure if it's a flaw in my code or a limitation in vuetify v- ...

Ways to receive notification during the user's selection of an option by hovering over it

Is there a way to receive an event when a user hovers over a select option? I thought that using the onMouseOver or onDragOver props on the option component would work, but it seems like they only trigger for the parent select component. Below is a simpli ...

The issue of an unexpected token '<' was encountered in both boostrap.js and chart.js

While trying to add boostrap.min.js to my hosting server, I encountered the error message Unexpected token <. However, when I used the bootstrap CDN, it worked perfectly. I thought I wouldn't have any further issues until integrating Angular-Chart. ...

Retrieving information from MongoDB queries using Node.js

I am facing an issue while trying to retrieve data from the find() method and use it outside the method. My goal is to incorporate this data into a JSON response. Unfortunately, my current code is not working as expected and the data is not accessible outs ...

React form submissions result in FormData returning blank data

I am having trouble retrieving the key-value pair object of form data when the form is submitted, using the new FormData() constructor. Unfortunately, it always returns empty data. Despite trying event.persist() to prevent react event pooling, I have not ...

Looking to update the key name in a script that produces a list sorted in ascending order

I have been working on code that iterates through a flat json document and organizes the items into a hierarchical structure based on their level and position. Everything is functioning correctly, but I now need to change the name of the child elements to ...