我花了多得离谱的时间,试图让 WebGPU 在我的 Linux 机器上正常工作。
我最终搞明白了,写了一个脚本来带着所有必要的启动参数启动 Chrome,甚至还做了一个桌面启动器,这样每当我想运行基于浏览器的 AI 模型时,点一下图标就行。
问题解决了。
只不过最近,我开始回想自己经历过的所有这些麻烦,然后意识到了一件事。
我记不起来自己是怎么修好它的了。
实际上,我甚至不记得把脚本保存在哪里了。
于是我做了任何一位通情达理的开发者在 2026 年都会做的事。我派了一个 AI 智能体去我的电脑里搜索我自己写的代码。
它找到了什么?
我不仅保存了那个脚本,还写了说明文档解释它是怎么工作的,并且把所有东西备份在了两个不同的资源目录里。
显然,过去的我比现在的我所记得的要条理分明得多。
总之,既然我已经把所有苦活都干完了(然后又忘得一干二净),我想不如把我学到的东西分享出来。
我只是想在浏览器里运行 AI 模型
我花了相当多的时间试验本地 AI 模型,尤其是通过 Transformers.js 和 ONNX Runtime 运行的小型语言模型。
我很喜欢直接在浏览器里运行模型这个想法。没有服务器要维护,没有 API 调用要付费,推理就在你自己的硬件上进行。
WebGPU 让其中大部分成为可能,它允许 Web 应用使用 GPU 进行计算。
听起来很棒,对吧?
只不过我的环境配置并不怎么配合。
我在一台配备混合显卡的笔记本电脑上运行基于 Arch 的 Linux,使用 Wayland:
- Intel Raptor Lake UHD 集成显卡
- NVIDIA RTX 4090 Laptop GPU
而让 Chrome、Vulkan、NVIDIA 和 Wayland 和谐共处,简直痛苦至极。
这涉及好几个层面。你的 GPU 驱动得能正常工作,Vulkan 得找到正确的设备,Chrome 得使用正确的图形后端,WebGPU 得成功初始化。
而且,其中某一项能正常工作,并不意味着下一项也能。
我花了大量时间排查各种不同的配置,才终于得到足够可靠、可以日常使用的东西。
对我有效的解决方案
最终,我写出了一个 Bash 脚本,用来启动一个专门为 WebGPU 配置的独立 Chrome 实例。
以下是我恢复出来的脚本:
#!/usr/bin/env bash
# 在 X11 上启动 Google Chrome,启用 NVIDIA PRIME 卸载 + Vulkan + WebGPU。
# 使用独立的专用配置文件,以便与普通 Chrome 同时运行。
set -euo pipefail
CHROME_PROFILE_DIR="${HOME}/.config/chrome-webgpu-nvidia"
mkdir -p "$CHROME_PROFILE_DIR"
VK_LOADER_DRIVERS_SELECT='*nvidia*' \
__NV_PRIME_RENDER_OFFLOAD=1 \
__GLX_VENDOR_LIBRARY_NAME=nvidia \
__VK_LAYER_NV_optimus=NVIDIA_only \
google-chrome-stable \
--user-data-dir="$CHROME_PROFILE_DIR" \
--enable-unsafe-webgpu \
--enable-features=Vulkan \
--ozone-platform=x11 \
"$@"
看起来并不特别复杂。
但搞清楚该用哪些设置,就是另一回事了。
我还为它创建了一个.desktop启动器,所以现在当我想试验 WebGPU 时,只需打开那个版本的 Chrome,而不用记住这些内容。
正如我们已经确认的,这大概是件好事。
这些设置到底都做了什么
1. 让 Chrome 使用 NVIDIA GPU
我的笔记本电脑有两块 GPU。一块是集成的 Intel GPU,另一块是独立的 NVIDIA GPU。
在混合显卡环境下,应用程序不一定会使用你预期的那块 GPU。
当你想在 RTX 4090 上运行模型,而浏览器却认为集成 GPU 完全够用时,这就是个问题。
所以我的脚本设置了四个环境变量:
VK_LOADER_DRIVERS_SELECT='*nvidia*'
__NV_PRIME_RENDER_OFFLOAD=1
__GLX_VENDOR_LIBRARY_NAME=nvidia
__VK_LAYER_NV_optimus=NVIDIA_only
它们的作用如下:
-
VK_LOADER_DRIVERS_SELECT过滤 Vulkan 驱动清单,以便选中 NVIDIA 驱动。 -
__NV_PRIME_RENDER_OFFLOAD=1启用 NVIDIA PRIME 渲染卸载。 -
__GLX_VENDOR_LIBRARY_NAME=nvidia为 GLX 厂商分发选择 NVIDIA。 -
__VK_LAYER_NV_optimus=NVIDIA_only告诉 NVIDIA 的 Optimus Vulkan 层只暴露 NVIDIA GPU。
并非这四个变量对每个应用程序或图形路径都一定重要,但这个组合是我可用配置的一部分。
重要的是确保 Chrome 能够真正访问并使用我想要的那块 GPU。
2. 让 Wayland 配合的办法是……不使用原生 Wayland
这一点至今让我觉得好笑。
我运行的是 Wayland 桌面,但我可用的 Chrome 启动器包含:
--ozone-platform=x11
这会告诉 Chrome 使用它的 X11 后端,该后端在我的 Wayland 会话中通过 XWayland 运行。
当时,我在让 Vulkan 和 Chrome 的原生 Wayland 后端与 NVIDIA 协同工作时遇到了问题。
通过 XWayland 运行 Chrome 是最终在我的配置上奏效的变通方案。
所以,在费了那么多功夫让一切在 Wayland 下正常运行之后,我的解决方案的一部分本质上就是让 Chrome 假装自己运行在 X11 下。
有时候,实用的解决方案并不是优雅的那个。
而是那个真正能用的。
3. 给 Chrome 一个独立的配置文件
这是比较有用的发现之一。
--user-data-dir="$CHROME_PROFILE_DIR"
当你尝试用同一个配置文件再次启动 Chrome 时,它通常会复用已有的浏览器实例。
所以,如果 Chrome 已经打开,而你尝试用不同的 GPU 标志启动另一个窗口,你可能会发现新设置实际上并没有生效。
使用独立的配置文件目录可以让我的 WebGPU 启动器拥有自己的 Chrome 进程和 GPU 配置。
这也意味着我可以在保持常规浏览器打开的同时,运行一个单独的实例用于开发。
每次想测试东西时,都不必折腾我正常的浏览环境。
4. 启用 Vulkan 和 WebGPU
最后,这两个标志:
--enable-unsafe-webgpu
--enable-features=Vulkan
第一个启用实验性的 WebGPU 支持,并绕过某些 GPU 限制。
第二个启用 Chromium 的 Vulkan 图形特性。
这里有一个重要的区别:在 Chrome 中启用 Vulkan 并不一定保证 WebGPU 本身通过 Dawn(Chromium 的 WebGPU 实现)使用 Vulkan。
具体行为取决于你的 Chromium 版本、平台和图形配置。
另外,--enable-unsafe-webgpu是用于开发和测试的。我不建议在日常浏览器中随意启用它。
关于较新 Chrome 版本的说明:Linux 上的 WebGPU 支持一直在改进,所以你可能不再需要这套确切的配置。特别是,较新的版本扩大了对 Intel 和 NVIDIA 硬件的支持。在把每个标志都复制到你自己的配置之前,请先检查你当前的浏览器和驱动支持情况。
如何检查它是否真的在工作
用脚本启动 Chrome 后,打开:
chrome://gpu
查看 Graphics Feature Status(图形功能状态)部分。
理想情况下,你希望看到 WebGPU 和 Vulkan 启用了硬件加速,而不是回退到软件渲染。
同样值得检查 GPU 和驱动信息,确认 Chrome 使用的是 NVIDIA 设备,而不是 Intel 或 SwiftShader 之类的软件渲染器。
但别就此打住。
看到 WebGPU 被列为硬件加速,并不能保证你的实际应用能正常运行。
试着运行一个真实的 WebGPU 示例,或者你打算使用的模型。
我不止一次吃过这个亏。
例如,在开发我最近的 Mimu 笔记应用时,我 iPhone 上的 Safari 报告 WebGPU 可用。但尝试用 WebGPU 初始化 Whisper 模型时,标签页崩溃并重新加载了。
WASM 版本运行正常。
而且对于那个特定的小模型来说,WASM 已经足够快,用 WebGPU 根本不值得折腾。
这又是一个有用的提醒:理论上更快的选项并不总是最好的选择。
然后我忘了自己把东西都放在哪了
于是事情到这里就形成了一个完整的闭环。
最近,我开始为自己的项目保留详细的构建日志。
不只是记录我构建了什么,还有哪里出了问题、我尝试了什么、我为什么做出某些决定,以及如果再次面对同样的问题我会怎么做。
在 DEV 上多写东西实际上鼓励了这个习惯。想着自己最终可能会写些什么,让我在构建时更留意自己正在做的事。
我已经发现自己会回头翻看笔记,重新考虑一两天前做出的决定。
这让我想起了之前那些与 WebGPU 相关的经历。
我希望自己当时把它们记录得更详细些。
结果发现,我确实记录了。
我只是不记得自己做过这件事。
我的 AI 智能体在以下位置找到了最初的启动器:
~/.local/bin/chrome-webgpu-nvidia
桌面入口文件位于:
~/.local/share/applications/
而文档和其他副本则放在我的PINKPIXEL/RESOURCES目录里。
在两个不同的文件夹中。
我已经完成了所有我希望过去的自己完成的事。
我只是没把这件事做好——没能让这些信息容易被再次找到。
考虑到我目前正在开发一个旨在帮助人们捕捉、整理和记住事情的应用程序,这就更有趣了。
显然,我确实需要它。
我从这一切中学到了什么
这里的技术教训是,让 WebGPU 在 Linux 上运行可能不仅仅是启用一个浏览器标志,尤其是在混合显卡的情况下。
根据你的硬件和软件版本,你可能需要注意正在选择哪块 GPU、Chrome 正在使用哪个图形后端,以及你的应用程序是否真正获得了硬件加速。
但我认为对我来说更大的教训与 WebGPU 关系不大。
这些年来我构建了很多东西。我解决过问题,尝试过各种技术,也想出过一些变通方法,花费的精力远超我的预期。
然后我就转向了下一个有趣的事情。
我并不总是停下来思考自己学到了什么,或者那段经验以后可能有多大用处。
这是我一直试图改变的事情。
坚持写构建日志让我对自己所做的决定更加深思熟虑,而写下自己的经历也促使我更仔细地审视它们。
有时这意味着发现一种更好的解决问题的方法。
有时这意味着记住一项有用的技术。
而有时这意味着发现我早就解决过一个问题,记录了下来,备份了两次,然后完全把整件事忘得一干二净。
至少现在我知道我的 WebGPU 脚本在哪里了。
至少目前是这样。