把深度学习搬进浏览器:一行 JavaScript 就能跑的“零后端”目标检测实战
摘要:本文介绍了一种基于TensorFlow.js和WebGPU的浏览器端目标检测方案,通过YOLO-Nano轻量模型实现零后端、低延迟的AI推理。针对隐私保护、网络抖动和云端成本问题,该方案将1.7MB的量化模型部署为PWA,支持离线使用,在移动端实现24ms/帧的推理速度。关键技术包括模型蒸馏、WebGPU加速、ServiceWorker缓存及隐私保护设计(数据不出浏览器)。实测显示,千元机亦
标签:TensorFlow.js · WebGPU · YOLO-Nano · PWA · 零后端 · 隐私计算
----
1. 背景:为什么要在浏览器里做目标检测?
2024 年,公司做“AI 拍照识物”小程序,结果用户照片要先上传到云端,再返回结果。
• 隐私投诉:一天 200+ 工单,“我的照片会不会泄露?”
• 网络抖动:地铁里 3G 环境,上传 3 MB 图片失败率 30 %。
• 成本:GPU 推理 + CDN 流量,每月账单 6 万+。
于是老板一句话:“能不能让用户手机自己算?不准没关系,快就行!”
----
2. 技术选型:YOLO-Nano + WebGPU 的化学反应
方案 模型大小 首次加载 推理延迟 离线可用
YOLOv8-n 6.2 MB 2.1 s 38 ms ✅
YOLO-Nano-JS 1.7 MB 0.8 s 24 ms ✅
云端 YOLOv8-m 0 MB 0.1 s 120 ms ❌
结论:YOLO-Nano-JS 完胜,在骁龙 8 Gen2 实测 24 ms / 帧。
----
3. 三步把 PyTorch 模型搬进浏览器
3.1 训练 & 蒸馏(Python 侧)
# train.py
from ultralytics import YOLO
model = YOLO('yolov8n.yaml')
model.train(data='coco128.yaml', epochs=50)
# 蒸馏到更小通道
from torch import nn
class NanoHead(nn.Module):
def __init__(self, c1, c2):
super().__init__()
self.conv = nn.Conv2d(c1, c2//2, 1) # 通道减半
模型量化后 1.7 MB(FP16 → INT8)。
3.2 转换格式
tensorflowjs_converter \
--input_format=tf_saved_model \
--output_format=tfjs_graph_model \
--quantize_uint8=* \
./saved_model ./web_model
产出 model.json + group1-shard1of2.bin。
3.3 前端一行代码调用
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgpu"></script>
<video id="webcam" autoplay playsinline></video>
<canvas id="canvas"></canvas>
<script type="module">
import * as cocoSsd from './yolo-nano-js';
await cocoSsd.load(); // 加载模型
const stream = await navigator.mediaDevices.getUserMedia({video: true});
document.getElementById('webcam').srcObject = stream;
setInterval(async () => {
const predictions = await cocoSsd.detect(document.getElementById('webcam'));
drawBoxes(predictions); // 自己画框
}, 40); // 25 FPS
</script>
----
4. 性能实测:千元机也不卡
机型 芯片 首次加载 单帧延迟 功耗
iPhone 13 A15 0.7 s 22 ms 380 mW
Redmi Note12 Snapdragon 4 Gen1 1.1 s 35 ms 520 mW
桌面 Chrome RTX 3060 0.4 s 9 ms 28 W
----
5. 进阶技巧:让 PWA 像原生 App
5.1 Service Worker 缓存模型
// sw.js
const CACHE_NAME = 'ai-cache-v1';
const urlsToCache = [
'/model.json',
'/group1-shard1of2.bin',
'/index.html'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(c => c.addAll(urlsToCache))
);
});
5.2 Web Share Target API(接收外部图片)
// manifest.json
"share_target": {
"action": "/receive",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"files": [{ "name": "image", "accept": ["image/*"] }]
}
}
----
6. 隐私 & 安全:零数据出浏览器
• 零上传:所有推理在 WebGPU 计算管线完成。
• 零持久化:IndexedDB 仅缓存模型文件,用户一键清空。
• 零追踪:不调用任何第三方域名,通过 CSP 限制外链。
----
7. 踩坑记录
1. WebGPU 兼容性:
早期 Safari TP 不支持 writeBuffer,降级 WebGL 后延迟翻倍。
解决:动态检测 navigator.gpu,不支持就弹提示。
2. 模型加载阻塞 UI:
1.7 MB 文件在 3G 网络要 6 s。
解决:使用 fetch + ReadableStream 分段加载 + 进度条。
3. 安卓 WebView 崩溃:
部分厂商 WebView 89 版本有 bug。
解决:UA 检测 + 强制跳转系统浏览器。
----
8. 开源仓库 & 在线体验
GitHub:
https://github.com/frontai/yolo-nano-js
在线 Demo(需支持 WebGPU):
https://frontai.github.io/yolo-nano-js/
----
9. 结语:前端的尽头是“端智能”
当模型只有 1.7 MB,
当浏览器原生支持 GPU 计算,
你会发现 “前端工程师”也能写 AI,而且不用买服务器。
如果这篇文章帮到你,欢迎 Star ⭐;
也欢迎留言分享你在浏览器里跑 AI 的奇思妙想!
更多推荐
所有评论(0)