WebGPU 特性检测不足以在手机上运行小型 LLM
作者尝试在手机浏览器中运行小型语言模型,发现仅靠 WebGPU 特性检测无法保证成功。四个测试环境中,即便 WebGPU 可用,模型运行仍出现页面重载、下载中断、速度差异大等问题。
作者本想通过 WebGPU 在手机浏览器中离线运行小型语言模型,无需服务器推理。特性检测很简单:请求 WebGPU 适配器,读取其限制,如果缓冲区大小足够大,就假定可以运行。所有测试的浏览器环境都暴露了 WebGPU,且报告的限制看起来足够容纳模型权重。然而,实际运行结果却并非如此。
设备报告的 GPU 能力和推理能否完成是两回事。以下是作者测量的四种情况。所有数据来自仓库中的原始测量文件。使用的模型包括 Llama-3.2-1B-Instruct、Qwen2.5-1.5B-Instruct 和 Qwen2.5-0.5B-Instruct,量化至约 4 位。引擎包括 WebLLM 0.2.84、transformers.js 4.2.0 和 wllama 3.4.1。每次运行均冷启动,短提示约 50 词元,长提示约 1200 词元。
第一种情况:iPhone 上的 Safari 在生成过程中重载页面。设备为 iPhone 11 Pro Max,iOS 18.7,Safari 26.5。报告 webgpu: true,Apple 适配器,支持 f16,maxBufferSize 为 715827880 字节。作为初步检查,该大小足以容纳模型权重。但所有运行均未完成。Qwen2.5-1.5B 通过 WebLLM 下载了全部 728 MB 后,在初始化时失败并报错“TypeError: Load failed”。Llama-3.2-1B 通过 WebLLM 走得更远,到达了 WebGPU 后端的生成阶段,然后页面在生成过程中重载,没有 JavaScript 可见的异常或可捕获的“内存不足”错误。较小的 Qwen2.5-0.5B 通过 wllama 在初始化时也出现了同样的问题:标签页在准备完毕前重载。该设备上所有引擎和模型均零运行完成。故障模式是无法处理的错误,而是标签页在背后重启。
第二种情况:LINE 的内置浏览器暴露了 WebGPU,但运行从未完成。设备为 Pixel 8a,8 GB 内存,在 Android 16 上的 LINE 内置浏览器中打开。报告 webgpu: true,Arm Valhall 适配器,支持 f16,maxBufferSize 为 4294967292 字节(4 GB 上限)。适配器限制与成功完成的 Chrome 运行无明显区别。Llama-3.2-1B 会话开始后,下载中途停滞,从未达到一次完整运行。该会话的结果文件运行列表为空。适配器报告没有透露内置浏览器是否能完成下载和初始化,实际上它不能。
第三种情况:同一硬件和模型,仅因引擎不同吞吐量相差约两倍。在搭载 AMD RDNA 4 GPU 的 Windows 桌面、Chrome 148 上,作者用短提示在三个引擎上分别运行了相同的 Llama-3.2-1B。WebGPU 均存在且被使用。解码率为三次运行的中位数。WebLLM 0.2.84 的解码速率为 196.17 词元/秒,transformers.js 4.2.0 为 125.41,wllama 3.4.1 为 97.61。最快引擎的解码速度是最慢的约两倍。三者的 WebGPU 支持标志相同,但测量到的吞吐量不同。
第四种情况:Pixel 8a 能完成运行,但长提示词的预填充耗时 76 秒。设备同样是 Pixel 8a,但这次使用普通 Chrome 149,而非内置浏览器。Arm Valhall 适配器报告同样的 4 GB 缓冲区上限。此环境下模型加载并运行至完成,因此作者有完整的时间记录。短提示(52 输入词元)时,首次输出词元时间约 3.8 秒;长提示(1213 输入词元)时,首次输出词元时间为 77153、76996 和 76449 毫秒,即 76 到 77 秒。之后解码速度接近 9 词元/秒。同一设备处理单行提示只需几秒,但读取一页上下文却要超过一分钟。
在这四个测试环境中,WebGPU 的暴露和较大适配器限制不足以预测小型 LLM 运行能否完成。特性检测回答了能否请求 WebGPU,而非推理能否完成。