尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

React + WebGPU + ONNX:构建浏览器本地运行的隐私优先LLM应用

React + WebGPU + ONNX:构建浏览器本地运行的隐私优先LLM应用 1. 项目概述为什么我们要把LLM“请”到本地最近几个月我身边不少做前端和全栈的朋友都在讨论同一个问题如何在不依赖云端API的情况下把大语言模型LLM的能力集成到自己的Web应用里。原因很简单大家受够了。受够了调用OpenAI、Claude这些接口时对网络延迟的焦虑对每月账单的心疼更关键的是对数据隐私和安全性的深深担忧。一个简单的聊天记录一次代码生成的请求都可能在不经意间离开你的设备去往一个你无法掌控的远方服务器。对于处理敏感信息的企业内部工具、教育软件或者仅仅是追求极致隐私的个人项目这都成了一个无法绕开的痛点。于是“本地部署LLM”从一个极客圈的小众话题迅速变成了一个具有普遍性的工程需求。但传统的本地部署方案比如用Python后端搭配PyTorch对前端开发者来说门槛不低环境配置复杂资源消耗也大。直到WebGPU的出现事情开始有了转机。WebGPU让我们可以直接在浏览器这个最普及的“客户端”里调用GPU进行高性能通用计算。那么一个大胆的想法自然浮现能不能用React构建用户界面用WebGPU在浏览器里直接运行一个精简版的LLM实现真正的“开箱即用、数据不出本地”这个项目就是对这个想法的一次完整实践和探索。它不只是一个技术Demo而是一套可供参考的、用于构建下一代隐私优先、离线可用的AI Web应用的方案。如果你是一名React开发者对AI应用感兴趣又希望完全掌控数据和计算过程那么接下来的内容就是为你准备的“从零到一”实操指南。2. 核心架构与工具选型为什么是React WebGPU ONNX当我们决定在浏览器里跑模型技术选型就变得非常关键。这不像在服务器端有成熟的CUDA生态和丰富的框架。浏览器的沙箱环境、有限的资源和对安全性的苛刻要求都意味着我们需要一套全新的工具链。2.1 前端框架为什么选择React选择React几乎是顺理成章的。它庞大的生态系统、声明式的UI构建方式以及高效的虚拟DOM更新非常适合构建复杂的交互式应用比如一个聊天界面或者一个带有实时推理状态显示的AI工具。更重要的是React社区有大量成熟的组件库如MUI, Ant Design和状态管理方案Zustand, Redux Toolkit能让我们快速搭建起美观且健壮的应用外壳而把主要精力集中在核心的模型推理逻辑上。一个典型的应用结构可能是用React组件管理聊天消息列表、输入框和设置面板用状态管理库来维护对话历史、模型加载状态和推理参数如temperature, top_p。React的响应式特性能让UI随着推理过程的进行如token的逐个生成而平滑更新。2.2 计算引擎为什么是WebGPU而不是WebGL或WASM这是整个架构的基石。我们有几个候选纯JavaScript太慢、WebAssemblyWASM有一定加速、WebGL为图形设计通用计算别扭、WebGPU新一代通用计算API。WebGL虽然可以通过图形API“伪装”成计算API用纹理存储数据用片元着色器进行计算但这种方式极其晦涩编程模型不直观且对很多计算任务优化不足。它就像用螺丝刀去敲钉子不是不行但很费劲。WASM通过将C/Rust编写的模型推理引擎如GGML库编译成WASM可以在浏览器中获得不错的性能。这是目前很多“本地LLM”方案的选择例如通过llama.cpp的WASM构建。但它仍然主要依赖CPU进行计算对于LLM这种计算密集型任务无法利用现代设备中强大的GPU性能天花板明显。WebGPU它是为现代GPU和通用计算而生的底层API。它提供了更接近Metal/Vulkan/DirectX 12的现代GPU编程模型能够更高效地调度计算着色器Compute Shader直接操作GPU的并行计算单元。对于矩阵乘法LLM推理的核心这类任务WebGPU能带来数量级级别的性能提升。简而言之WebGPU是让我们能在浏览器中榨干设备GPU潜力的唯一标准途径。注意WebGPU的浏览器支持仍在推进中。截至2024年中Chrome 113、Edge 113已默认开启Firefox和Safari也在积极跟进。在项目启动前务必检查你的目标用户群体的浏览器环境或做好功能降级回退到WASM的准备。2.3 模型格式为什么是ONNX选定了计算引擎接下来要决定用什么格式的模型。我们不可能直接把PyTorch的.pt或TensorFlow的.pb文件扔给浏览器。模型需要被转换成一个跨平台、高效且能被WebGPU轻松操作的格式。ONNXOpen Neural Network Exchange成为了我们的首选。它是一个开放的模型格式标准几乎所有主流训练框架PyTorch, TensorFlow等都能将模型导出为ONNX格式。更重要的是有一个非常关键的库onnxruntime-web。这个库是微软ONNX Runtime的Web版本它提供了一个统一的JavaScript API来加载和运行ONNX模型。而其最强大的特性在于它内置了WebGPU后端执行提供程序EP。这意味着当我们通过onnxruntime-web加载一个ONNX模型时它可以自动或在我们的配置下尝试使用WebGPU来执行模型中的算子如果失败则回退到WASM后端。这样一来我们就不需要自己用WGSLWebGPU的着色器语言去手写每一个神经网络层了。onnxruntime-web帮我们完成了最繁重的工作将ONNX模型图翻译成高效的WebGPU计算管线。我们的代码只需要关注如何准备输入数据、调用会话Session进行推理以及处理输出数据。工具链总结模型准备在Python环境中使用torch.onnx.export将训练好的模型如一个精简版的Llama 2 7B-Chat或Phi-2转换为ONNX格式。这一步可能涉及模型裁剪、量化如INT8量化以减小模型体积和提升推理速度。核心运行时在React应用中通过npm安装onnxruntime-web。应用构建使用React TypeScript Vite或Webpack构建项目通过onnxruntime-web的API加载并运行ONNX模型利用WebGPU加速。模型分发将转换好的ONNX模型文件可能是分片的放置在项目的public目录或通过CDN分发供前端应用异步加载。这个组合构成了我们“零数据上传、离线可用”的坚实技术底座。3. 从零开始环境搭建与项目初始化理论说完了我们动手搭建一个最小的可运行项目。这里假设你已具备基本的Node.js和React开发环境。3.1 创建React项目并安装核心依赖我们使用Vite来快速搭建因为它对现代前端工具链支持更好构建速度更快。npm create vitelatest local-llm-webgpu-app -- --template react-ts cd local-llm-webgpu-app npm install接下来安装最核心的依赖——onnxruntime-web。我们需要安装支持WebGPU的版本。npm install onnxruntime-web同时我们安装一些辅助库用于UI和状态管理这里以Zustand和MUI为例npm install mui/material emotion/react emotion/styled mui/icons-material npm install zustand3.2 配置Vite以处理WASM和资源文件onnxruntime-web会依赖一些WASM二进制文件。我们需要配置Vite确保这些文件能被正确打包和提供服务。在vite.config.ts中添加以下配置import { defineConfig } from vite import react from vitejs/plugin-react export default defineConfig({ plugins: [react()], assetsInclude: [**/*.onnx], // 告诉Vite.onnx文件是资源 optimizeDeps: { exclude: [onnxruntime-web], // 避免预构建onnxruntime-web防止出现问题 }, })3.3 准备一个精简的ONNX模型这是最具挑战性的一步。我们无法在浏览器中运行一个完整的700亿参数模型。我们需要一个小型、高效的模型。对于入门和演示可以从以下途径获取Hugging Face Model Hub搜索“onnx”和“small”标签例如microsoft/phi-2的ONNX量化版本或者一些专门为边缘设备优化的模型如Qwen/Qwen2.5-0.5B-Instruct-onnx。确保模型文件是.onnx格式。自行转换如果你有PyTorch模型可以使用以下脚本进行转换和动态量化以简化版模型为例import torch import torch.onnx from transformers import AutoModelForCausalLM, AutoTokenizer # 1. 加载模型和分词器 (这里以一个超小模型为例实际需替换) model_name microsoft/phi-2 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name, torch_dtypetorch.float32) # 为演示我们只取模型的前几层或者使用官方提供的精简版 # 这里假设我们有一个已经处理好的tiny_model例如只有解码器的前几层 tiny_model ... # 你的精简模型 # 2. 设置模型为评估模式 tiny_model.eval() # 3. 定义输入样例维度batch_size, sequence_length dummy_input torch.randint(0, tokenizer.vocab_size, (1, 16)) # 4. 导出为ONNX torch.onnx.export( tiny_model, dummy_input, tiny_llm.onnx, input_names[input_ids], output_names[logits], dynamic_axes{ input_ids: {1: sequence_length}, # 动态序列长度 }, opset_version15, # 使用较高的opset版本 ) print(模型已导出为 tiny_llm.onnx)重要提示自行转换和量化是一个专业且复杂的过程涉及模型结构修改、算子兼容性检查等。对于初学者强烈建议先从Hugging Face下载现成的、已验证可在浏览器中运行的ONNX模型开始。将下载好的model.onnx文件放入项目的public/models/目录下。4. 核心实现在React中集成ONNX Runtime与WebGPU现在我们进入最核心的编码环节创建一个自定义Hook来管理模型的加载和推理。4.1 创建模型推理Hook在src/hooks/useONNXModel.ts中我们创建这个逻辑中心。import { useState, useCallback, useRef } from react; import { InferenceSession, Tensor } from onnxruntime-web; interface UseONNXModelReturn { loading: boolean; error: string | null; loadModel: (modelPath: string) Promisevoid; runInference: (inputIds: number[]) Promisenumber[]; isReady: boolean; } export const useONNXModel (): UseONNXModelReturn { const [loading, setLoading] useState(false); const [error, setError] useStatestring | null(null); const sessionRef useRefInferenceSession | null(null); const [isReady, setIsReady] useState(false); const loadModel useCallback(async (modelPath: string) { setLoading(true); setError(null); try { // 关键配置指定执行提供程序为‘webgpu’并设置回退 const session await InferenceSession.create(modelPath, { executionProviders: [webgpu, wasm], // 优先尝试WebGPU失败则用WASM graphOptimizationLevel: all, // 启用所有图优化 }); sessionRef.current session; setIsReady(true); console.log(模型加载成功使用执行提供程序: ${session.providers.join(, )}); } catch (err) { const errMsg 模型加载失败: ${err}; setError(errMsg); console.error(errMsg, err); } finally { setLoading(false); } }, []); const runInference useCallback(async (inputIds: number[]): Promisenumber[] { if (!sessionRef.current) { throw new Error(模型未加载请先调用 loadModel); } // 1. 准备输入Tensor // ONNX模型通常期望输入是Int64或Int32类型形状为 [batch_size, sequence_length] const inputTensor new Tensor(int64, BigInt64Array.from(inputIds.map(id BigInt(id))), [1, inputIds.length]); // 2. 准备模型输入 feeds const feeds: Recordstring, Tensor {}; // 这里需要根据你的具体ONNX模型的输入节点名来设置可能是“input_ids” feeds[input_ids] inputTensor; // 3. 运行推理 const results await sessionRef.current.run(feeds); // 4. 处理输出 // 输出节点名也可能是“logits”需要根据模型定义调整 const outputTensor results[logits]; // 将输出Tensor转换为JavaScript数组这里简化处理取最后一个token的logits const logitsData outputTensor.data as Float32Array; // 假设输出形状是 [batch, seq, vocab_size]我们取最后一个序列位置的logits const vocabSize outputTensor.dims[2]; const startIdx (inputIds.length - 1) * vocabSize; const lastTokenLogits Array.from(logitsData.slice(startIdx, startIdx vocabSize)); return lastTokenLogits; // 返回词汇表大小的概率分布 }, []); return { loading, error, loadModel, runInference, isReady }; };这个Hook封装了模型的生命周期loadModel负责异步加载模型文件并创建推理会话runInference负责执行一次前向传播。关键在于executionProviders: [webgpu, wasm]这个配置它指示ONNX Runtime优先尝试使用WebGPU加速。4.2 构建简单的文本生成循环LLM的文本生成是一个自回归过程根据已有的tokens预测下一个token然后将这个token加入输入继续预测下一个。我们需要实现这个循环。在src/utils/textGenerator.ts中import { useONNXModel } from ../hooks/useONNXModel; // 假设我们有一个简单的分词器工具实际中需要集成一个JS分词器如bert-tokenizer或sentencepiece import { simpleTokenizer } from ./tokenizer; export const useTextGenerator (modelPath: string) { const { loadModel, runInference, isReady, loading, error } useONNXModel(); const [isGenerating, setIsGenerating] useState(false); const [context, setContext] useStatenumber[]([]); // 存储当前的token ID序列 // 初始化加载模型 useEffect(() { loadModel(modelPath); }, [modelPath, loadModel]); const generateNextToken async (): Promisenumber { if (!isReady || context.length 0) { throw new Error(模型未就绪或上下文为空); } const logits await runInference(context); // 简单的采样策略选择logits最大的token贪心搜索 let maxIdx 0; let maxVal logits[0]; for (let i 1; i logits.length; i) { if (logits[i] maxVal) { maxVal logits[i]; maxIdx i; } } return maxIdx; }; const generateText async (prompt: string, maxTokens: number 50): Promisestring { setIsGenerating(true); try { // 1. 将提示词编码为token IDs let tokenIds simpleTokenizer.encode(prompt); setContext(tokenIds); let generatedTokens: number[] []; for (let i 0; i maxTokens; i) { // 2. 预测下一个token const nextTokenId await generateNextToken(); generatedTokens.push(nextTokenId); // 3. 更新上下文在实际模型中可能需要管理KV Cache这里简化 tokenIds.push(nextTokenId); setContext([...tokenIds]); // 更新状态可能会触发UI更新显示部分结果 // 4. 简单解码并检查终止条件如遇到结束符 const token simpleTokenizer.decode([nextTokenId]); if (token |endoftext|) { // 假设的结束符 break; } } // 5. 解码全部生成的tokens const fullText simpleTokenizer.decode(generatedTokens); return fullText; } finally { setIsGenerating(false); } }; return { generateText, isGenerating, loading, error, isReady }; };这个实现是高度简化的。一个生产级的实现需要考虑高效的KV Cache避免每次推理都重新计算所有历史token的注意力这是LLM推理优化的关键。更复杂的采样如Top-p (nucleus)采样、温度采样。流式输出逐个token生成并实时更新UI。完整的分词器集成一个真正的子词分词器如Tiktoken的Web版本或SentencePiece。4.3 创建React UI组件最后我们创建一个简单的UI来连接这一切。在src/App.tsx中import { useState } from react; import { Button, TextField, CircularProgress, Alert, Box, Typography } from mui/material; import { useTextGenerator } from ./utils/textGenerator; function App() { const [prompt, setPrompt] useState(你好请介绍一下你自己。); const [generatedText, setGeneratedText] useState(); const modelPath /models/tiny_llm.onnx; // 模型在public目录下的路径 const { generateText, isGenerating, loading, error, isReady } useTextGenerator(modelPath); const handleGenerate async () { if (!prompt.trim()) return; const text await generateText(prompt, 100); setGeneratedText(text); }; return ( Box sx{{ maxWidth: 800, margin: 40px auto, padding: 3 }} Typography varianth4 gutterBottom 本地LLM演示 (React WebGPU) /Typography {error Alert severityerror sx{{ mb: 2 }}{error}/Alert} {loading Alert severityinfo正在加载模型.../Alert} TextField fullWidth multiline rows{4} label输入提示词 value{prompt} onChange{(e) setPrompt(e.target.value)} disabled{!isReady || isGenerating} sx{{ mb: 2 }} / Button variantcontained onClick{handleGenerate} disabled{!isReady || isGenerating || loading} startIcon{isGenerating ? CircularProgress size{20} / : null} {isGenerating ? 生成中... : 生成文本} /Button {generatedText ( Box sx{{ mt: 4, p: 2, border: 1px solid #ccc, borderRadius: 1 }} Typography varianth6生成结果/Typography Typography{generatedText}/Typography /Box )} Box sx{{ mt: 4, fontSize: 0.9em, color: gray }} Typography variantbody2 状态: {isReady ? 模型就绪 (使用 (window.navigator.gpu ? WebGPU : WASM) ) : 未就绪} /Typography Typography variantbody2 说明这是一个演示项目使用的模型能力有限。所有计算均在您的浏览器本地完成无数据上传。 /Typography /Box /Box ); } export default App;至此一个最基础的、能在浏览器中利用WebGPU或回退到WASM运行本地LLM的React应用就搭建起来了。运行npm run dev打开浏览器需支持WebGPU你应该能看到界面。输入提示词并点击生成就能体验到完全离线的AI文本生成。5. 性能优化与生产级考量上面的Demo跑通只是第一步。要让它真正可用我们需要解决性能、体验和稳定性问题。5.1 模型优化量化与裁剪浏览器环境对资源极其敏感。一个未经优化的7B参数模型仅权重文件就可能超过14GBFP16这是不可接受的。量化Quantization这是最重要的优化手段。将模型权重从FP32或FP16转换为INT8甚至INT4可以大幅减少模型体积和内存占用同时推理速度也能提升。ONNX Runtime支持多种量化格式。在模型转换时就应使用onnxruntime的量化工具进行处理。模型裁剪Pruning移除模型中不重要的权重在精度损失可控的情况下减小模型大小。可以寻找已经过裁剪和量化的模型如llama.cpp社区提供的GGUF格式模型并尝试将其转换为ONNX。选择小模型从微型模型开始如Phi-2 (2.7B)、Qwen2.5-0.5B、TinyLlama等。它们在有限的资源下能提供更有意义的输出。5.2 推理优化KV Cache与批处理实现KV Cache这是LLM推理的“标配”。在自回归生成中每次前向传播都会为之前的token计算Key和Value向量并缓存起来下次生成时直接复用避免重复计算。ONNX模型需要支持past_key_values的输入和输出。你需要找到一个已经导出为支持KV Cache格式的ONNX模型或者在导出时配置好。在推理循环中你需要维护并传递这个Cache。注意力优化WebGPU对于矩阵乘法和注意力计算有天然优势。确保你的ONNX模型使用了高效的注意力算子如FlashAttention的ONNX实现。onnxruntime-web的WebGPU后端会尝试优化这些算子的执行。5.3 用户体验优化流式输出Streaming不要等所有token生成完再一次性显示。利用React的状态更新每生成一个或几个token就更新一次UI让用户立即看到生成过程。这需要将generateText函数改造成一个异步生成器async generator。模型分片与懒加载大型模型可以分割成多个文件。在应用初始化时只加载必要的部分如分词器和第一层在用户首次触发推理时再按需加载其他分片。这可以显著缩短应用的首屏加载时间。降级与兼容性处理在InferenceSession.create时我们配置了[webgpu, wasm]。如果WebGPU不可用会自动降级到WASM。你应该在UI上明确告知用户当前使用的后端。WASM速度虽慢但保证了基本功能的可用性。5.4 安全与隐私强化这是我们方案的核心优势但仍需注意彻底的离线确保所有资源模型文件、分词器数据、wasm文件都能在无网络环境下通过Service Worker缓存或打包在应用中。使用localStorage或IndexedDB缓存模型文件避免重复下载。输入输出审查虽然数据不出本地但应用本身前端代码是暴露的。避免在客户端代码中硬编码敏感逻辑。如果涉及非常敏感的处理可以考虑与WebAssembly编写的、经过混淆的本地安全模块结合。6. 常见问题与排查技巧实录在实际开发和测试中我遇到了不少坑。这里记录下最常见的问题和解决方法。6.1 WebGPU初始化失败问题控制台报错Failed to create WebGPU device或navigator.gpu is undefined。排查浏览器不支持访问chrome://gpu或about:gpu查看“Graphics Feature Status”中“WebGPU”是否为“Enabled”。确保Chrome/Edge版本在113以上并在chrome://flags中确认“Unsafe WebGPU”未被启用正式版中不应需要。硬件或驱动问题某些旧显卡或集成显卡可能不支持WebGPU所需的特性集。可以尝试更新显卡驱动。安全上下文WebGPU要求页面在安全上下文中运行即通过https://或http://localhost访问。如果你在file://协议下打开WebGPU将不可用。开发时务必使用localhost。6.2 ONNX模型加载或推理错误问题InferenceSession.create失败或session.run抛出异常。排查模型路径错误确保modelPath是相对于服务器根目录或public目录的正确路径。使用浏览器开发者工具的“网络Network”标签页查看模型文件是否成功加载状态码200。模型格式或Opset不兼容ONNX模型有版本opset之分。确保onnxruntime-web支持的opset版本包含你的模型版本。尝试使用onnx库的version_converter工具将模型转换为较新的opset版本。输入/输出名称不匹配这是最常见的问题。session.run(feeds)中的feeds对象键名必须与模型输入节点名称完全一致。使用Netron一个可视化工具打开你的.onnx模型文件查看输入input和输出output节点的名称。我们的示例代码中用的input_ids和logits只是示例你必须替换成自己模型的实际名称。输入数据类型或形状错误同样使用Netron查看模型输入节点的数据类型如int64,float32和形状如[1, -1]其中-1表示动态维度。在创建Tensor时必须严格匹配。6.3 推理速度极慢或内存溢出问题生成一个token需要好几秒或者浏览器标签页崩溃。排查使用了WASM后端在控制台查看模型加载时的日志确认是否回退到了wasm后端。WASM后端在CPU上运行对于大模型会非常慢。优先解决WebGPU的可用性问题。模型太大即使是量化后的模型如果参数量过大如超过3B在消费级设备的GPU内存通常4-8GB中也可能放不下。尝试更小的模型或进行更激进的量化INT4。未启用KV Cache每次推理都传入全部历史token计算量随对话长度平方级增长。必须使用支持KV Cache的模型和推理逻辑。浏览器内存限制单个浏览器标签页的内存使用是有限制的。复杂的模型和长的上下文会消耗大量内存。监控浏览器的任务管理器观察内存使用情况。6.4 生成的文本质量差或无意义问题模型能跑通但生成的文字是乱码或重复的废话。排查分词器不匹配这是头号原因。ONNX模型只包含计算图不包含分词器。你必须使用与模型原始训练时完全一致的分词器。如果模型是bert-base-uncased你就必须使用对应的BertTokenizer。将正确的分词器通常是vocab.json和merges.txt等文件集成到前端项目中并使用相同的编码/解码逻辑。预处理/后处理错误检查输入模型的token IDs是否正确。有些模型需要在输入前后添加特殊的token如s,/s,[CLS],[SEP]等。同样解码时也要过滤掉这些特殊token。采样策略过于简单贪心搜索总是选概率最大的容易导致重复和枯燥的文本。实现温度采样Temperature Sampling和Top-p采样能极大改善生成文本的多样性和创造性。模型本身能力有限你使用的可能是一个过于精简或训练不足的模型。尝试换一个公认能力更强的微型模型进行测试。6.5 部署后资源加载问题问题本地开发一切正常但部署到服务器后模型或wasm文件加载失败404错误。排查路径问题最常见生产构建后资源文件的路径可能发生变化。在Vite中使用new URL(./model.onnx, import.meta.url).href来获取资源的绝对URL这在不同环境下都更可靠。服务器MIME类型确保你的服务器为.onnx和.wasm文件配置了正确的MIME类型分别是application/octet-stream和application/wasm。否则浏览器可能拒绝加载。跨域问题CORS如果模型文件存放在另一个域名下需要配置CORS头Access-Control-Allow-Origin: *。7. 进阶方向与生态展望走通整个流程后你可以在此基础上进行更多探索集成更成熟的推理引擎直接使用onnxruntime-web是相对底层的。可以关注像Transformers.js这样的项目它正在积极集成ONNX Runtime和WebGPU后端旨在提供类似Hugging Facetransformers库的易用API省去手动处理分词、模型流水线等繁琐工作。探索WebLLM等封装方案MLC社区推出的WebLLM项目是一个更高层次的解决方案。它基于Apache TVM将LLM编译为WebGPU可执行的格式并内置了聊天模板、流式输出等高级功能。你可以将其视为一个“开箱即用”的运行时你的React应用只需通过RPC与之通信。构建复杂AI应用将本地LLM作为智能内核结合浏览器的其他能力如文件系统访问API、IndexedDB、WebRTC可以构建出真正强大的离线AI应用。例如本地文档分析助手用户上传PDF/Word应用在本地提取文本由LLM进行总结、问答。私有化代码助手在VS Code的Web版或本地IDE插件中集成一个完全本地的代码补全和解释模型。离线语言学习伙伴一个完全离线的对话练习应用所有语音识别可用Web Speech API、对话生成、语音合成均在本地完成。模型管理与切换设计一个模型管理器允许用户动态加载、切换不同的本地模型例如一个用于聊天的小模型一个用于代码生成的专业模型。这条路目前仍然充满挑战尤其是模型性能与资源消耗的平衡。但它的潜力是巨大的将AI的能力真正 democratize交还给每一个终端用户在享受智能的同时牢牢守住数据的私密性。随着WebGPU的普及和模型压缩技术的进步我相信“浏览器即AI运行时”的未来并不遥远。
返回列表