
1. 为什么要把大模型塞进浏览器里跑1.1 一个真实的需求场景先说清楚这件事的来龙去脉。我手头有一批Excel文件大概三百多个每个文件里是不同区域的销售流水字段结构基本一致但列名有细微差异有的叫“客户名称”有的叫“客户名”有的还带空格。每个月末要做的事情就是把这些表合并、清洗、按客户维度汇总然后生成一份分析报告。以前的做法是写Python脚本用pandas批量读规则写死遇到列名不一致就手动改脚本。后来试过调云端大模型API来做字段映射和异常检测效果确实好但有两个问题一直绕不过去第一数据要传到别人的服务器上财务那边合规过不了第二网络一断或者API限流整个流程就卡住了。于是我开始琢磨一件事能不能把模型直接放在本地跑而且不装Python环境、不配CUDA、不折腾命令行打开浏览器就能用这就是“把15亿参数大模型塞进浏览器”这个项目的起点。核心思路是利用WebGPU在浏览器里做本地推理把模型权重下载到本地缓存通过一个浏览器插件在Excel页面侧边栏里直接调用数据从头到尾不出电脑断网也能用。这件事适合什么人参考如果你经常用Excel做批量数据处理对数据隐私有要求又不想学一整套深度学习部署流程那这套方案值得一看。如果你本身是前端或者全栈开发者想了解WebGPU在实际业务里怎么落地里面的工程细节也有参考价值。哪怕你只是好奇“浏览器里跑大模型”到底靠不靠谱我也会把实测数据和踩过的坑都摆出来。1.2 为什么是15亿参数这个量级模型参数量的选择不是拍脑袋定的。我试过三个量级3B、1.5B和0.5B。3B的模型在WebGPU上跑显存占用大概在2.2GB左右推理一条500字的输入需要8到12秒对于批量处理三百个文件来说太慢了。0.5B的模型速度快单条推理1到2秒但在字段映射这种需要理解语义的任务上准确率明显不够经常把“客户名称”和“联系人”搞混。1.5B这个量级是一个比较舒服的平衡点。量化到INT4之后模型文件大概在900MB到1.1GB之间浏览器缓存完全放得下。推理时显存占用在1.3GB左右主流核显和独显都能扛住。单条推理时间在3到5秒三百个文件如果每个文件抽10条样本做字段推断总共3000次推理大概两个半小时能跑完。这个速度对于月末批量处理来说完全可以接受而且是后台跑不耽误你干别的。注意这里说的“显存”在WebGPU里其实是GPU内存集显会共享系统内存。如果你的电脑只有8GB内存同时开着Excel和浏览器可能会有点吃紧建议16GB起步。1.3 WebGPU到底解决了什么问题以前在浏览器里跑模型只能用WebAssembly加CPU推理速度慢得让人想砸键盘。WebGPU的出现改变了这个局面它让JavaScript能直接调用GPU做并行计算推理速度比纯CPU快了大概8到15倍。更关键的是WebGPU是浏览器原生支持的不需要装任何驱动或者运行时Chrome 113之后默认开启Edge和Firefox也在陆续跟进。我用下来最直观的感受是以前在浏览器里跑1.5B模型一条推理要等半分钟现在3到5秒就出结果。这个速度差距决定了它能不能用在真实业务里。另一个好处是WebGPU的API设计比WebGL更贴近现代GPU编程模型写compute shader的时候心智负担小很多调试也方便。2. 整体架构与核心组件拆解2.1 三层结构插件层、推理层、数据层整个方案我拆成了三层。最上面是浏览器插件层负责和Excel页面交互读取单元格数据、展示推理结果、管理任务队列。中间是推理层基于WebGPU加载量化后的模型提供文本生成和语义理解能力。最下面是数据层负责Excel文件的解析、字段提取、结果写回以及本地缓存管理。这三层之间通过消息传递通信。插件的内容脚本注入到Excel页面里通过chrome.runtime.sendMessage和后台Service Worker通信后台再调用Offscreen Document里的WebGPU推理引擎。为什么要绕这么一圈因为Service Worker里不能直接访问DOM也不能稳定持有WebGPU上下文而Offscreen Document可以。这个架构是试了好几种方案之后定下来的后面会详细说。2.2 模型选型为什么选1.5B的指令微调模型模型选型上我对比了几个方向。首先是基座模型和指令微调模型的选择做字段映射和异常检测需要模型能理解自然语言指令所以必须用指令微调过的版本。其次是中文能力Excel里的字段名和备注基本都是中文英文模型直接排除。我最终选的是一个1.5B参数的中文指令微调模型具体名字就不说了市面上有好几个可选项选哪个主要看你的任务类型。选它的理由有三个第一参数量适中量化后体积可控第二中文语义理解在同类模型里属于第一梯队第三社区有现成的ONNX导出脚本省去了自己转换的麻烦。量化方案用的是INT4具体是GPTQ还是AWQ取决于模型本身支持哪种。INT4量化后模型精度损失大概在2%到5%之间对于字段映射这种任务来说完全够用。如果你要做更复杂的推理比如从流水描述里判断交易类型可能需要INT8或者FP16但那样模型体积和推理时间都会翻倍。2.3 浏览器插件开发的关键技术点插件开发这块有几个坑值得单独说。首先是Manifest V3的限制Service Worker是事件驱动的随时可能被浏览器回收所以不能把模型加载这种耗时操作放在Service Worker里。我的做法是创建一个Offscreen Document在里面初始化WebGPU设备和模型Service Worker只负责转发消息。其次是内容脚本和页面脚本的隔离。Excel Online的页面结构比较复杂直接操作DOM容易出问题。我的做法是通过chrome.scripting.executeScript注入一个函数在页面上下文里读取选区数据然后通过postMessage传回内容脚本。这样既能拿到数据又不会污染页面环境。还有一个细节是跨域问题。模型文件如果放在远程服务器上需要配置CORS头。我的做法是把模型文件打包进插件资源里通过chrome.runtime.getURL访问这样完全避免了跨域问题而且断网也能用。代价是插件包体积会大一些1.5B INT4模型大概1GB左右但现在的网络条件下载一次也不算什么事。3. 核心细节解析与实操要点3.1 WebGPU初始化与模型加载流程WebGPU的初始化流程比WebGL要严谨一些需要按顺序请求适配器和设备。下面是我实际用的代码骨架你可以直接参考async function initWebGPU() { if (!navigator.gpu) { throw new Error(当前浏览器不支持WebGPU请升级到Chrome 113); } const adapter await navigator.gpu.requestAdapter({ powerPreference: high-performance }); if (!adapter) { throw new Error(无法获取GPU适配器请检查显卡驱动); } const device await adapter.requestDevice({ requiredLimits: { maxStorageBufferBindingSize: 1024 * 1024 * 1024, maxBufferSize: 1024 * 1024 * 1024 } }); return { adapter, device }; }这里有几个参数需要根据你的模型调整。maxStorageBufferBindingSize和maxBufferSize默认值比较小加载大模型的时候会报错需要显式请求更大的值。但也不能随便设成无限大要先通过adapter.limits查询设备实际支持的上限取一个不超过上限的值。模型加载用的是ONNX Runtime Web的WebGPU后端。加载流程分两步先下载模型文件到浏览器缓存然后用ort.InferenceSession.create创建推理会话。第一次加载会比较慢1GB的模型大概需要20到30秒之后从缓存读取就快很多5秒左右能完成初始化。实操心得模型加载过程中浏览器可能会提示“页面无响应”这是正常的因为主线程被占用了。我的做法是把加载逻辑放在Web Worker里通过postMessage汇报进度这样页面不会卡死用户能看到加载百分比。3.2 Excel数据读取与字段提取Excel数据的读取分两种情况。如果是Excel Online可以通过Office.js的API直接读取选区和工作表数据。如果是本地Excel文件我的做法是让用户把文件拖到插件面板里用SheetJS解析成JSON。两种方式最终都归一化成同样的数据结构方便后续处理。字段提取的核心逻辑是先读取表头行把每个列名和该列的前若干条样本数据一起打包成一个提示词让模型判断这个列的实际语义。提示词模板大概长这样你是一个数据字段分析助手。请根据以下列名和样本数据判断该列的实际含义并从候选类别中选择最匹配的一个。 列名客户名称 样本数据张三、李四、王五贸易有限公司、赵六 候选类别客户姓名、公司名称、联系人、产品名称、金额、日期、备注 请只输出类别名称不要解释。这个提示词我调了好几版。最早的时候让模型直接输出字段含义结果它经常自由发挥输出一长串解释。后来改成从候选类别里选准确率明显提升。候选类别是根据我实际业务场景预定义的大概二十多个覆盖了常见的销售流水字段。3.3 批量任务队列与并发控制三百个文件如果一个个串行处理用户体验很差。我的做法是建一个任务队列同时跑2到3个推理任务。为什么不是越多越好因为WebGPU的显存有限同时跑太多任务会导致显存溢出浏览器直接崩溃。实测下来1.5B INT4模型同时跑3个任务是上限再多就不稳定了。队列的实现用了一个简单的信号量模式class TaskQueue { constructor(concurrency 2) { this.concurrency concurrency; this.running 0; this.queue []; } async add(task) { return new Promise((resolve, reject) { this.queue.push({ task, resolve, reject }); this.next(); }); } async next() { if (this.running this.concurrency || this.queue.length 0) return; this.running; const { task, resolve, reject } this.queue.shift(); try { const result await task(); resolve(result); } catch (err) { reject(err); } finally { this.running--; this.next(); } } }这个队列看起来简单但实际用的时候要注意错误处理。如果某个任务抛异常了不能让整个队列卡死所以finally里一定要调next()。另外任务结果要实时写回Excel不能等全部跑完再写否则用户看不到进度会以为程序卡了。3.4 结果写回与格式保持结果写回Excel的时候有个坑直接改单元格值会丢失原有格式。比如原来单元格是日期格式你写个字符串进去格式就乱了。我的做法是只改值不改格式用Office.js的range.values赋值而不是重建整个工作表。如果是本地文件用SheetJS写回的时候要注意保留原有的样式信息。SheetJS的社区版对样式支持有限我的做法是只更新数据区域其他部分原样保留。具体操作是先读取整个工作簿修改目标单元格的值然后整体写回。这样虽然会丢失一些高级样式但至少不会把表格搞乱。4. 实操过程与核心环节实现4.1 环境准备与插件骨架搭建先说一下开发环境。你需要Node.js 18以上Chrome 113以上以及一个支持WebGPU的显卡。我用的是一台带RTX 3060的笔记本后来在MacBook M1上也测过都能跑。核显的话Intel Iris Xe实测也能跑但速度慢一些单条推理大概6到8秒。插件骨架用Vite加CRXJS来搭这样开发的时候有热更新调试方便。目录结构大概是这样src/ background/ # Service Worker content/ # 内容脚本 offscreen/ # WebGPU推理引擎 popup/ # 插件弹窗 shared/ # 公共工具函数 public/ models/ # 模型文件 manifest.jsonManifest V3的配置里要特别注意offscreen权限和webgpu相关的设置。offscreen文档的创建需要在Service Worker里调用chrome.offscreen.createDocument传入reasons: [WORKERS]和justification。4.2 模型转换与量化实操模型转换是整个流程里最耗时的环节。我用的方案是先把原始模型导出成ONNX格式然后用ONNX Runtime的量化工具做INT4量化。具体命令大概是这样python -m onnxruntime.transformers.optimizer \ --input model.onnx \ --output model_optimized.onnx \ --model_type bert python -m onnxruntime.quantization.preprocess \ --input model_optimized.onnx \ --output model_preprocessed.onnx python -m onnxruntime.quantization.quantize \ --input model_preprocessed.onnx \ --output model_int4.onnx \ --weight_type int4量化过程中要注意校准数据的选择。校准数据应该从你的实际业务数据里采样而不是用通用语料。我用了一百条真实的Excel字段名和样本数据做校准量化后的模型在字段映射任务上的准确率比用通用校准数据高了大概7个百分点。注意INT4量化对模型结构有要求不是所有模型都能直接量化。如果遇到不支持的算子可以尝试混合量化把部分层保持FP16其余层用INT4。ONNX Runtime的文档里有详细说明。4.3 推理性能实测数据我在三台设备上做了性能测试测试任务是字段映射输入长度平均80个token输出长度平均5个token。结果如下设备GPU模型加载时间单条推理时间显存占用笔记本RTX 306022秒3.2秒1.3GBMacBookM1 8核GPU28秒4.1秒1.5GB轻薄本Intel Iris Xe35秒7.8秒1.8GB从数据可以看出独显和苹果芯片的表现最好核显也能用但速度慢一倍左右。显存占用都在2GB以内主流设备都能承受。模型加载时间第一次比较长之后从缓存读取会快很多大概5到8秒。批量处理三百个文件每个文件抽10条样本总共3000次推理。在RTX 3060上加上队列调度和数据读写开销总耗时大概2小时40分钟。这个时间是在后台跑的你可以正常用电脑干别的只是别同时跑大型游戏或者视频渲染。4.4 断网环境下的完整验证断网测试是我最看重的环节。具体做法是先把模型加载好然后断开网络再执行批量处理任务。实测下来只要模型已经加载到内存里断网完全不影响推理。Excel文件的读取和写回也都是本地操作不依赖网络。但有一个细节要注意如果浏览器缓存被清了模型文件就没了下次打开需要重新下载。我的做法是在插件里加了一个“模型管理”页面显示模型缓存状态并提供手动清理和重新下载的按钮。另外如果用户用的是Excel Online断网后页面本身就无法访问了所以这个方案更适合本地Excel文件。5. 常见问题与排查技巧实录5.1 WebGPU初始化失败怎么办这是最常见的问题表现是navigator.gpu返回undefined或者requestAdapter返回null。排查思路按顺序来第一确认浏览器版本Chrome 113以上才默认开启WebGPU低版本需要在chrome://flags里手动开启。第二确认显卡驱动是最新的老驱动可能不支持WebGPU。第三检查是否在chrome://gpu里看到WebGPU被禁用如果是看看禁用原因是什么。还有一个隐蔽的问题某些企业的组策略会禁用WebGPU。如果你在公司电脑上跑不起来先问问IT部门有没有相关限制。我遇到过一台电脑所有配置都正常就是requestAdapter返回null最后发现是组策略里禁用了硬件加速。5.2 模型加载到一半卡住模型加载卡住通常有两个原因。一是显存不足加载到一半显存溢出浏览器直接崩溃或者卡死。解决办法是降低量化精度或者换更小的模型。二是模型文件损坏下载过程中断了。解决办法是清理浏览器缓存重新下载或者在插件里加一个文件完整性校验。我遇到过一次比较诡异的情况模型加载到90%卡住等了十分钟也没动静。后来发现是ONNX Runtime在编译shader这个过程在有些显卡上特别慢。解决办法是提前预热在插件启动的时候先跑一次空推理把shader编译好后续加载就快了。5.3 推理结果不稳定怎么调推理结果不稳定表现为同样的输入有时候输出正确有时候输出乱七八糟的东西。这个问题通常和提示词有关。我的经验是第一提示词要尽可能明确给出候选类别比让模型自由发挥要稳定得多。第二温度参数调到0.1以下减少随机性。第三如果还是不稳定可以在提示词里加几个示例做少样本学习。还有一个容易被忽略的点输入文本的格式。如果样本数据里有特殊字符或者换行符可能会干扰模型。我的做法是在拼接提示词之前先把样本数据做一次清洗去掉多余的空格和换行。5.4 Excel数据读取的兼容性问题Excel的版本和格式差异很大xlsx、xls、csv各有各的坑。我的经验是第一优先用Office.js读取Excel Online的数据兼容性最好。第二本地文件用SheetJS解析但要注意xls格式的支持有限建议用户另存为xlsx。第三CSV文件的编码问题很常见UTF-8和GBK要自动识别否则中文会乱码。还有一个坑是合并单元格。如果表头有合并单元格读取出来的列名可能是空的。我的做法是检测合并区域把合并单元格的值填充到所有子单元格。这个逻辑用Office.js实现比较方便SheetJS的话需要手动处理merge属性。5.5 常见问题速查表问题现象可能原因排查方法解决方案WebGPU不可用浏览器版本低检查Chrome版本升级到113适配器获取失败驱动过旧查看chrome://gpu更新显卡驱动模型加载卡住显存不足查看任务管理器降低量化精度推理结果乱码提示词不明确检查提示词模板增加候选类别Excel读取失败文件格式不支持检查文件扩展名另存为xlsx批量处理中断队列异常查看控制台日志加错误重试机制6. 这套方案还能怎么扩展6.1 从字段映射扩展到数据清洗字段映射只是第一步同样的架构可以扩展到数据清洗。比如检测异常值、填充缺失值、标准化日期格式这些任务都可以用本地模型来做。我最近在试的一个场景是让模型判断某条流水记录是否可疑比如金额异常大或者客户名称和备注不匹配。初步测试下来1.5B模型在二分类任务上的准确率能到85%左右虽然不如云端大模型但胜在数据不出本地。6.2 多模型协同的可能性单个1.5B模型的能力有限但可以多个模型协同。比如用一个模型做字段映射另一个模型做数据校验还有一个模型生成汇总报告。WebGPU支持同时加载多个模型只要显存够用。我试过同时加载两个1.5B模型显存占用2.6GBRTX 3060完全扛得住。这种多模型协同的思路可以在不增加单模型参数量的前提下提升整体处理能力。6.3 插件分发的注意事项如果你想把插件分享给同事用有几个事情要提前考虑。第一模型文件太大不适合放在Chrome Web Store上我的做法是插件本体很小模型文件放在内部服务器上首次使用时下载。第二企业环境可能需要配置代理这个要提前和IT沟通。第三插件的权限要最小化只申请必要的权限否则审核和安装都会遇到阻力。我个人在实际操作中的体会是这套方案最大的价值不是技术本身而是它改变了数据处理的边界。以前必须把数据传到云端才能用大模型现在在本地就能完成这对于有数据合规要求的场景来说意义很大。当然它也有局限1.5B模型的能力上限就在那里复杂的推理任务还是得靠更大的模型。但对于字段映射、数据清洗这类结构化任务来说它已经足够好用了。