切換語言為:簡體
只用瀏覽器,無後端支援,實現AI互動式聊天

只用瀏覽器,無後端支援,實現AI互動式聊天

  • 爱糖宝
  • 2024-10-31
  • 2063
  • 0
  • 0

想象一下,在你的瀏覽器中執行一個類似chatgpt的人工智慧——完全離線。不需要伺服器,不需要API呼叫,只是純粹的瀏覽器功能。聽起來不可能嗎?不了!現代瀏覽器已經發展成為令人難以置信的強大平臺,我很高興向您展示它們的功能。我們將共同構建一個React.js web應用程式,即使在離線時也可以與之聊天

在沒有後端的情況下在瀏覽器中執行自己的本地模型

這種方法的特別之處在於,我們直接在瀏覽器中執行LLM模型——不需要後端。這個概念很簡單:下載一個模型檔案,然後在本地執行推理,就在瀏覽器中。現代瀏覽器的功能確實非常出色。

多虧了WebAssembly,我們可以利用強大的C/C工具,比如llama.cpp。

請打鼓🥁…

Wllama——一個令人印象深刻的專案,它為llama.cpp提供WebAssembly繫結,支援瀏覽器內無縫的LLM推理。

從頭開始建造💪

1. 用Vite建立一個React應用

首先,讓我們建立我們的開發環境:

npm create vite@latest

然後初始化你的專案:

cd browser-llm-chat 
npm install

2. 設計基本UI

讓我們建立一個乾淨、實用的介面。將 App.jsx 的內容替換為:

import { useState } from "react";

function App() {
  const [prompt, setPrompt] = useState("");
  const [output, setOutput] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [progress, setProgress] = useState(0);

  const handlePromptInputChange = (e) => setPrompt(e.target.value);
  const shouldDisableSubmit = isLoading || prompt.trim().length === 0;


  const submitPrompt = () => {
    // We'll implement this next
  };

  return (
    <div>
      <pre>{output.map(({ role, content }) => `${role}: ${content}\n\n`)}</pre>
      {!output.length && (
        <div>
          {isLoading ? <span>Loading {Math.ceil(progress)}%</span> : <h1>Hi, How may I help you?</h1>}
        </div>
      )}
      <div>
        <input
          type="text"
          value={prompt}
          onChange={handlePromptInputChange}
          placeholder="Enter your prompt here"
        />
        <button type="button" onClick={submitPrompt} disabled={shouldDisableSubmit}>
          <div>→</div>
        </button>
      </div>
    </div>
  );
}

export default App;

 index.css 新增一些基本的樣式:

body {
 font-family: sans-serif;
 display: flex;
 justify-content: center;
}

pre {
 font-family: sans-serif;
 min-height: 30vh;
 white-space: pre-wrap;
 white-space: -moz-pre-wrap;
 white-space: -pre-wrap;
 white-space: -o-pre-wrap;
}

input {
 padding: 12px 20px;
 border: 1px solid #aaa;
 background-color: #f2f2f2;
}

input, pre {
 width: 60vw;
 min-width: 40vw;
 max-width: 640px;
}

button {
 padding: 12px 20px; 
 background-color: #000;
 color: white; 
}

只用瀏覽器,無後端支援,實現AI互動式聊天

3. 整合Wllama

現在是令人興奮的部分——讓我們在應用程式中新增AI功能:

npm install @wllama/wllama @huggingface/jinja

更新 App.jsx 以整合Wllama:

import { useState } from "react";
import { Wllama } from "@wllama/wllama/esm/wllama";
import wllamaSingleJS from "@wllama/wllama/src/single-thread/wllama.js?url";
import wllamaSingle from "@wllama/wllama/src/single-thread/wllama.wasm?url";
import { Template } from "@huggingface/jinja";

const wllama = new Wllama({
  "single-thread/wllama.js": wllamaSingleJS,
  "single-thread/wllama.wasm": wllamaSingle,
});

/* You can find more models at HuggingFace: https://huggingface.co/models?library=gguf
 * You can also download a model of your choice and place it in the /public folder, then update the modelUrl like this:
 * const modelUrl = "/<your-model-file-name>.gguf";
 */
const modelUrl = "https://huggingface.co/neopolita/smollm-135m-instruct-gguf/resolve/main/smollm-135m-instruct_q8_0.gguf";

/* See more about templating here:
* https://huggingface.co/docs/transformers/main/en/chat_templating
*/
const formatChat = async (messages) => {
  const template = new Template(wllama.getChatTemplate() ?? "");
  return template.render({
    messages,
    bos_token: await wllama.detokenize([wllama.getBOS()]),
    eos_token: await wllama.detokenize([wllama.getEOS()]),
    add_generation_prompt: true,
  });
};

function App() {
  // previous state declarations...

  const submitPrompt = async () => {
    setIsLoading(true);

    if (!wllama.isModelLoaded()) {
      await wllama.loadModelFromUrl(modelUrl, {
        n_threads: 1,
        useCache: true,
        allowOffline: true,
        progressCallback: (progress) => setProgress((progress.loaded / progress.total) * 100),
      });
    }
    const promptObject = { role: "user", content: prompt.trim() };
    setOutput([promptObject]);
    await wllama.createCompletion(await formatChat([promptObject]), {
      nPredict: 256,
      sampling: { temp: 0.4, penalty_repeat: 1.3 },
      onNewToken: (token, piece, text) => {
        setOutput([promptObject, { role: "assistant", content: text }]);
      },
    });
    setIsLoading(false);
  };
  // rest of existing code...
}
export default App;

恭喜你!👏至此,您已經擁有了一個完全在瀏覽器中執行的AI聊天介面!

只用瀏覽器,無後端支援,實現AI互動式聊天

您的web應用程式將:

  1. 在第一次使用時下載並快取模型,以便以後完全離線。

  2. 在瀏覽器中使用CPU本地處理提示

  3. 生成響應時進行流處理

使用 npm run dev 啟動它並訪問http://localhost:5173/。測試它 🎉👏

目前的限制😅

  • 目前僅支援cpu(尚未支援WebGPU)

  • 模型的檔案大小限制為2GB,但有一個解決方案可以拆分它們(請參閱Wllama文件)。

原文: Run Your Offline AI Chat: Pure Browser, No Backend - DEV Community

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.