Saturday, July 27, 2024
Google search engine
HomeUncategorizedWeb AI Model Testing: WebGPU, WebGL, and Headless Chrome

Web AI Model Testing: WebGPU, WebGL, and Headless Chrome

Jason Mayes

François Beaufort

Great news! You’ve built a cool Web AI application
that runs machine learning models directly on a user’s device. It runs entirely
on the client-side web browser, without relying on the cloud. This on-device
design enhances user privacy, boosts performance, and reduces costs
significantly.

However, there’s a hurdle. Your
TensorFlow.js model can operate on
both CPUs (WebAssembly) and more powerful GPUs (through
WebGL and
WebGPU). The question is:
how can you consistently automate browser testing with the selected hardware?

Maintaining consistency is crucial for comparing machine learning model
performance over time as you iterate and improve them, prior to deployment for
real-world users to use on their device.

Setting up a consistent testing environment with GPUs can be harder than
expected. In this blog post, we’ll share the problems we faced and how we solved
them, so you can improve your application’s performance.

This isn’t just for Web AI developers! If you’re working on web gaming or
graphics, this post is valuable for you, too.

What’s in our automation toolbox

Here is what we are using:

  • Environment: A Linux-based Google Colab
    notebook connected to an NVIDIA
    T4 or V100 GPU. You can use other cloud platforms, such as Google Cloud
    (GCP), if preferred.
  • Browser: Chrome supports WebGPU,
    a powerful successor to WebGL, that
    brings the advancements of modern GPU APIs to the web.
  • Automation: Puppeteer is a Node.js library that lets
    you control browsers programmatically with JavaScript. With Puppeteer, we can
    automate Chrome in headless mode, which means the browser runs without a
    visible interface, on a server. We are using the improved
    new headless mode, not the
    legacy form.

Verify the environment

The best way to check whether hardware acceleration is turned on in Chrome is to
type chrome://gpu into the address bar. You can
programmatically perform the equivalent with Puppeteer
with console.log or save the full report as PDF to check manually:

/* Incomplete example.js */
import puppeteer from 'puppeteer';

// Configure launch parameters: Expands later
const browser = await puppeteer.launch({
  headless: 'new',
  args:  ['--no-sandbox']
});

const page = await browser.newPage();
await page.goto('chrome://gpu');

// Verify: log the WebGPU status or save the GPU report as PDF
const txt = await page.waitForSelector('text/WebGPU');
const status = await txt.evaluate(g => g.parentElement.textContent);
console.log(status);
await page.pdf({ path: './gpu.pdf' });

await browser.close();

Open chrome://gpu and you should have the following results:

Graphics feature status
OpenGL: Disabled
Vulkan: Disabled
WebGL: Software only, hardware acceleration unavailable.
WebGL2: Software only, hardware acceleration unavailable.
WebGPU: Disabled

Problems detected.

WebGPU has been disabled via blocklist or the command line.

Not a great start. It’s fairly clear that hardware detection was failing.
WebGL, WebGL2, and WebGPU are essentially disabled or software only. We
aren’t alone in this problem – there are numerous discussions online of people
in a similar situation, including on the official Chrome support channels
(1),
(2).

Enable WebGPU and WebGL support

By default, Headless Chrome
disables GPU.
To enable it on Linux, apply all of the following flags when launching Headless
Chrome:

  • --no-sandbox flag disables Chrome’s security sandbox, which isolates the
    browser process from the rest of the system. Running Chrome as root without
    this sandbox is not supported.
  • --headless=new flag runs Chrome with the new and improved
    headless mode, without any visible UI.
  • --use-angle=vulkan flag tells Chrome to use the
    Vulkan backend
    for ANGLE, which
    translates OpenGL ES 2/3 calls to Vulkan API calls.
  • --enable-features=Vulkan flag enables Vulkan graphics backend for
    compositing and rasterization in Chrome.
  • --disable-vulkan-surface flag disables the VK_KHR_surface vulkan
    instance extension. Instead of using a swapchain,
    Bit blit is used for the
    present render result on screen.
  • --enable-unsafe-webgpu flag enables the experimental WebGPU API in
    Chrome on Linux and disables the adapters blocklist.

Now we combine all the changes we have made so far. Here is the complete script.

/* Complete example.js */
import puppeteer from 'puppeteer';

// Configure launch parameters
const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--no-sandbox',
    '--headless=new',
    '--use-angle=vulkan',
    '--enable-features=Vulkan',
    '--disable-vulkan-surface',
    '--enable-unsafe-webgpu',
  ]
});

const page = await browser.newPage();
await page.goto('chrome://gpu');

// Verify: log the WebGPU status or save the GPU report as PDF
const txt = await page.waitForSelector('text/WebGPU');
const status = await txt.evaluate(g => g.parentElement.textContent);
console.log(status);
await page.pdf({path: './gpu.pdf'});

await browser.close();

Run the script again. No WebGPU problems are detected and the value changes from
disabled to software only.

Graphics feature status
OpenGL: Disabled
Vulkan: Disabled
WebGL: Software only, hardware acceleration unavailable.
WebGL2: Software only, hardware acceleration unavailable.
WebGPU: Software only, hardware acceleration unavailable.

However, hardware acceleration is still unavailable, the NVIDIA T4 GPU isn’t
detected.

Install the correct GPU drivers

We investigated more closely the output of chrome://gpu, with some GPU experts
on the Chrome team. We found issues with the default drivers installed on the
Linux Colab

instance, causing issues with Vulkan, leading to Chrome unable to detect the
NVIDIA T4 GPU at the GL_RENDERER level as shown in the following output. This
causes problems with Headless Chrome.

The default output doesn’t detect NVIDIA T4 GPU.
Driver information
GL_RENDERER ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver-5.0.0)

Installing the correct drivers that were compatible therefore fixes the issue.

Updated output after drivers are installed.
Driver information
GL_RENDERER ANGLE (NVIDIA Corporation, Tesla T4/PCIe/SSE2, OpenGL ES 3.2 NVIDIA 525.105.17)

To install the correct drivers, run the following commands during setup. The
last two lines help you to log the outputs of what NVIDIA drivers detects along
with vulkaninfo.

apt-get install -y vulkan-tools libnvidia-gl-525

// Verify the NVIDIA drivers detects along with vulkaninfo
nvidia-smi
vulkaninfo --summary

Now run the script again and we get the following result. 🎉

Graphics feature status
OpenGL: Enabled
Vulkan: Enabled
WebGL: Hardware accelerated but at reduced performance.
WebGL2: Hardware accelerated but at reduced performance.
WebGPU: Hardware accelerated but at reduced performance.

By using the correct drivers and flags when running Chrome, we now have WebGPU
and WebGL support using the shiny, new headless mode.

Behind the scenes: Our team’s investigation

After much research, we didn’t find working methods for the environment we
needed to execute in Google Colab, although there were some
hopeful posts
that worked in other environments, which was promising. Ultimately, we weren’t
able to replicate their success in the Colab NVIDIA T4 environment, as we had 2
key issues:

  1. Some combinations of flags allow detection of the GPU, but don’t allow you to
    actually use the GPU.
  2. Examples of working solutions by third parties used the old Chrome headless
    version, which at some point will be deprecated in favor of the
    new version. We needed a solution
    that worked with the new Headless Chrome to be better future proofed.

We confirmed the under utilization of the GPU by running an
example TensorFlow.js web page for image recognition,
whereby we trained a model to recognize clothing samples (sort of like a “hello
world” of machine learning).

On a regular machine, 50 training cycles (known as epochs) should run in less
than 1 second each. Calling Headless Chrome in its default state, we could log
the JavaScript console output to the Node.js server-side command line to see how
fast these training cycles were actually taking.

As expected, each training epoch took much longer than expected (several
seconds), which suggests Chrome has fallen back to plain old JS CPU execution
instead of utilizing the GPU:

The training epochs move at a slower cadence.
Figure 1: Real-time capture showing how long each training epoch took to execute (seconds).

After fixing the drivers and using the right combination of flags for Headless
Chrome, rerunning the TensorFlow.js training example results in much faster
training epochs.

There's an increase in speed for epochs..
Figure 2: Real-time capture showing the speed up of epochs.

Summary

Web AI has grown exponentially
since its creation in 2017. With browser technologies such as WebGPU, WebGL, and
WebAssembly, a machine learning model’s
mathematical operations can be further accelerated on the client side.

As of 2023 TensorFlow.js and MediaPipe Web crossed over 1 billion downloads of
models and libraries—a historic milestone and a sign of how web
developers and engineers are shifting to embrace AI in their next generation
web apps to make some truly incredible solutions
.

With great success in usage comes great responsibility. At this level of usage
in production systems, the need arises for testing client-side, browser-based AI
models in a true browser environment, while also being scalable, automatable,
and within a known standardized hardware setup.

By harnessing the combined power of the new Headless Chrome and Puppeteer, you
can confidently test such workloads in a standardized and replicable
environment, ensuring consistent and reliable results.

Wrap up

A step-by-step guide is available in
our documentation, so you can try out the complete setup yourself.

If you found this useful, drop a shout out over on
LinkedIn,
X (formerly Twitter), or whatever
social network you use using hashtag #WebAI. It would be great to hear any
feedback you have so we know to write more stuff like this in the future.

Add a star on the Github repo
to receive any future updates.

Acknowledgements

A huge thank you to everyone on the Chrome team who helped debug the driver and
WebGPU issues we faced in this solution, with a special thanks to
Jecelyn Yeen and
Alexandra White for helping to wordsmith
this blog post. Thanks to Yuly Novikov, Andrey Kosyakov, and
Alex Rudenko who were instrumental
in creating the final, working solution.

Read More

RELATED ARTICLES

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments