老板看了竞品,眼睛发光:“我们也上AI!用户问啥都得秒回!” 我默默算了算OpenAI的账单——一个月2万,一年24万,够全组去三亚团建三次。于是我干了件疯狂的事:把AI模型塞进用户浏览器里。不用服务器,不花一分钱API,用户电脑自己跟自己聊天。老板看着账单上的“0”,问我是不是偷偷充了值。

前言

这事儿起因很简单:老板要AI客服。大模型API便宜吗?初看几分钱一次,用户一多,一个月一辆特斯拉没了。而且用户问的重复问题占80%,每问一次就烧一次钱,像开着水龙头浇花。

我寻思:能不能把模型直接扔到用户浏览器里?现在电脑、手机性能过剩,跑个小模型绰绰有余。说干就干,我找到了Transformers.js——一个能在浏览器里跑Hugging Face模型的库,完全本地推理,不花一分钱API,隐私还安全。

今天我就带你手把手在React里集成一个本地AI问答模型(用的还是微软的Phi-3 mini,效果媲美GPT-3.5,体积只有2GB左右,量化后更小)。用户打开网页,模型自动下载到IndexedDB,然后所有对话都在他电脑上完成。老板再也不用看账单了。

一、为什么敢在浏览器里跑AI?

  • 硬件进步:WebAssembly + WebGL,现代CPU/GPU能跑几十亿参数的小模型。
  • 模型变小:Phi-3、TinyLLaMA、Gemma 2B,量化后几十到几百MB。
  • 隐私:数据不上传,用户放心(尤其金融、医疗行业)。
  • 成本:固定成本(服务器带宽),没有按次收费。

缺点:首次加载慢(下载模型),低端设备可能卡。但你可以用闲时下载+缓存策略,用户第一次访问花一分钟,之后秒开。

二、技术选型:Transformers.js + Phi-3

Transformers.js 是Hugging Face官方库,支持在浏览器里运行Transformer模型。它自动利用WebGL加速,比纯CPU快5-10倍。

我们要用的模型:Phi-3-mini-4k-instruct(微软出品,38亿参数,量化后约2GB)。太大了?别急,有128k上下文版更小,或者用TinyLLaMA 1.1B(量产后几百MB)。我推荐先上onnx-community/Phi-3-mini-4k-instruct-onnx,经过ONNX优化,体积更友好。

三、实战:React + Transformers.js 实现本地问答

1. 安装依赖

npm install @xenova/transformers

2. 创建一个AI Hook

// hooks/useLocalLLM.js
import { pipeline, env } from '@xenova/transformers';

// 设置模型缓存路径(IndexedDB)
env.localModelPath = '/models/';
env.useBrowserCache = true;

export function useLocalLLM() {
  const [generator, setGenerator] = useState(null);
  const [loading, setLoading] = useState(true);
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const loadModel = async () => {
      // 加载文本生成模型(这里用Phi-3的ONNX版本)
      const pipe = await pipeline('text-generation', 'onnx-community/Phi-3-mini-4k-instruct-onnx', {
        progress_callback: (p) => {
          if (p.status === 'downloading') {
            setProgress(p.progress);
          }
        },
      });
      setGenerator(() => pipe);
      setLoading(false);
    };
    loadModel();
  }, []);

  const generate = async (prompt, options = {}) => {
    if (!generator) return;
    const result = await generator(prompt, {
      max_new_tokens: 256,
      temperature: 0.7,
      ...options,
    });
    return result[0].generated_text;
  };

  return { generate, loading, progress };
}

3. 在组件中使用

function AIChat() {
  const { generate, loading, progress } = useLocalLLM();
  const [question, setQuestion] = useState('');
  const [answer, setAnswer] = useState('');
  const [isGenerating, setIsGenerating] = useState(false);

  const ask = async () => {
    if (!question.trim() || isGenerating) return;
    setIsGenerating(true);
    // Phi-3 指令格式
    const prompt = `<|user|>\n${question}\n<|end|>\n<|assistant|>\n`;
    const response = await generate(prompt);
    setAnswer(response.replace(prompt, '').trim());
    setIsGenerating(false);
  };

  if (loading) {
    return <div>正在加载AI模型 {Math.round(progress * 100)}% ... (首次约需1分钟)</div>;
  }

  return (
    <div>
      <textarea value={question} onChange={e => setQuestion(e.target.value)} />
      <button onClick={ask} disabled={isGenerating}>问AI</button>
      {isGenerating && <div>AI在你电脑里拼命想...</div>}
      {answer && <div className="answer">{answer}</div>}
    </div>
  );
}

四、效果与优化

  • 首次访问:下载模型(约1.5GB,看网速),之后缓存在IndexedDB,第二次秒加载。
  • 推理速度:Intel i7 16GB 上,生成20个token约2秒。M1 Mac 更快。手机上可换更小模型。
  • 优化技巧
    • 用Web Worker运行模型,避免阻塞UI。
    • 提前预加载:用户鼠标悬停在聊天按钮时就开始下模型。
    • 量化:选择int8fp16版本,体积减半。

五、这和Vercel AI SDK有什么区别?

  • Vercel AI SDK:后端调API,前端拿流式响应。还是要花钱,但开发快。
  • Transformers.js:完全本地,零成本,但首次加载慢,设备性能要求高。

我的建议:混合模式。默认用本地模型,如果用户设备太老或模型下载失败,fallback到云端API。既省钱又不丢用户体验。

六、老板的反应

上线后,老板问:“这月AI账单怎么是0?” 我说:“我把AI搬到用户浏览器里了。” 他沉默了三秒:“那岂不是我们没数据了?” 我说:“要数据干嘛?又卖不掉。省下的钱给我们加鸡腿。” 老板居然同意了。

七、总结:本地AI不是梦,是未来

  • Transformers.js 让浏览器跑大模型成为可能。
  • 适合隐私敏感、成本敏感的场景(客服、笔记、翻译)。
  • 首次加载慢,但配合缓存和进度提示,用户能接受。
  • 技术选型:模型选Phi-3/TinyLLaMA,量化版几十到几百MB。

下次老板再让你接入AI,你可以淡定地说:“本地跑,不花钱,隐私好。” 然后默默打开这篇文章——代码都给他准备好了。

评论区聊聊:你的公司花多少钱在AI API上?想不想省下来换新电脑?

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐