前端RAG:使用Transformers.js手搓纯网页版RAG(二)- 基于qwen1.5-0.5B

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 本文继续探讨了RAG的后半部分,通过在浏览器中运行qwen1.5-0.5B模型实现了增强搜索全流程。然而,由于浏览器与模型性能限制,该方案更适合研究、离线及高隐私场景。文章提供了完整的前端代码,让读者能够动手尝试。此外,详细介绍了代码框架、知识库准备、模型初始化及问答实现等步骤,并展示了实际运行效果。受限于当前技术,除非在离线或高隐私环境下,网页大模型的应用仍需进一步优化。

书接上文,本文完了RAG的后半部分,在浏览器运行qwen1.5-0.5B实现了增强搜索全流程。但受限于浏览器和模型性能,仅适合于研究、离线和高隐私场景,但对前端小伙伴来说大模型也不是那么遥不可及了,附带全部代码,动手试试吧! 纯前端,不适用第三方接口

1 准备工作

1.1 前置知识

1.2页面代码框架

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>网页端侧增强搜索</title>
</head>
<body>
  <div id="app">
    <div>
      <input type="text" id="question" />
      <button id="search">提问</button>
    </div>
    <div id="info"></div>
  </div>
  <script type="module">
    import {
      pipeline,
      env,
      cos_sim,
    } from "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2/dist/transformers.min.js";
    env.remoteHost = "https://hf-mirror.com";
    // 后续代码位置
  </script>
</body>
</html>

image.gif

1.3 chrom/edge浏览器

目前测试firefox模型缓存有问题,建议用这两个,首次加载模型需要点时间,后续就不需要了,记住刷新时按F5不要清空缓存了。

2 搜索代码实现

2.1 准备好知识库和初始化向量库

前一篇文章已经介绍了相关内容,本文知识库有些不一样,因为是需要给大模型去生成回答,而不是直接给出答案,所以合并在了一起。

const knowledges = [
      "问:洛基在征服地球的尝试中使用了什么神秘的物体?\n答:六角宝",
      "问:复仇者联盟的哪两名成员创造了奥创?\n答:托尼·斯塔克(钢铁侠)和布鲁斯·班纳(绿巨人浩克)。",
      "问:灭霸如何实现了他在宇宙中消灭一半生命的计划?\n答:通过使用六颗无限宝石",
      "问:复仇者联盟用什么方法扭转了灭霸的行动?\n通过时间旅行收集宝石。",
      "问:复仇者联盟的哪位成员牺牲了自己来打败灭霸?\n答:托尼·斯塔克(钢铁侠)",
    ];
    const verctorStore = [];

image.gif

2.2 定义打印输出和参数

topK控制送给大模型处理的最匹配的知识数量上下,越多的知识条数prompt越大会导致处理用时越长,一般三个最匹配的知识就差不多够用了,尤其是在网页中运行时

const infoEl = document.getElementById("info");
    const print = text => infoEl.innerHTML = text;
    const knowEl = document.getElementById("knowEl");
    const topK = 3;

image.gif

2.3 准备好嵌入和生成模型

嵌入使用 bge-base ,回答生成使用qwen1.5-0.5B

const embedPipe = pipeline("feature-extraction", "Xenova/bge-base-zh-v1.5", {
      progress_callback: (d) => {
        infoEl.innerHTML = `embed:${JSON.stringify(d)}`;
      },
    });
    const chatPipe = pipeline('text-generation', 'Xenova/Qwen1.5-0.5B-Chat', {
      progress_callback: (d) => {
        infoEl.innerHTML = `chat:${JSON.stringify(d)}`;
      },
    });

image.gif

2.4 定义向量库数据初始方法

这个不多赘述,和前一篇的类似

const buildVector = async () => {
      if (!verctorStore.size) {
        const embedding = await embedPipe;
        print(`构建向量库`)
        const output = await embedding(knowledges, {
          pooling: "mean",
          normalize: true,
        });
        knowledges.forEach((q, i) => {
          verctorStore[i] = output[i];
        });
      }
    };

image.gif

2.5 定义问答主方法

这里也不赘述过多,和上一篇不同之处在于:根据score从大到小排序,选出topK传入生成方法

const search = async () => {
      const start = Date.now()
      const embedding = await embedPipe;
      const question = document.getElementById("question").value;
      const [qVector] = await embedding([question], {
        pooling: "mean",
        normalize: true,
      });
      await buildVector();
      const scores = verctorStore.map((q, i) => {
        return {
          score: cos_sim(qVector.data, verctorStore[i].data),
          knowledge: knowledges[i],
          index: i,
        };
      });
      scores.sort((a, b) => b.score - a.score);
      const picks = scores.slice(0, topK)
      const docs = picks.map(e => e.knowledge)
      const answer = await generateAnswer(question, docs.join('\n'))
      print(answer + `(用时:${Date.now()- start}ms)`)
    };
    document.querySelector("#search").onclick = search;

image.gif

3 生成代码实现 - G

这一部分主要介绍generateAnser的实现

3.1 定义prompt

这部分自己测试时可多调整下,prompt定义的越好效果越好

const prompt =
        `请根据【上下文】回答【问题】,当得不到较为准确的答案时,必须回答我不知道。
  【上下文】
  ${context}
  【问题】
  ${question}
  请给出你的答案:
  `

image.gif

3.2 构建消息和输入

const messages = [
        { role: 'system', content: '你是一个分析助手,根据上下文回答问题。必须生成更人性化的答案。' },
        { role: 'user', content: prompt }
      ]
      console.log(messages)
      // 生成cha
      const text = generator.tokenizer.apply_chat_template(messages, {
        tokenize: false,
        add_generation_prompt: true,
      });
      console.log(text)

image.gif

3.3 等待回答返回首个答案

print(`思考中...`)
      const output = await generator(text, {
        max_new_tokens: 128,
        do_sample: false,
        return_full_text: false,
      });
      console.log(output)
      return output[0].generated_text;

image.gif

4 运行测试

4.1 等待模型加载就绪

嵌入和千问整体有接近1G的数据下载,需要稍微等待下,直到看到下图所示结果

image.gif 编辑

4.2 输入提问

我的问题是“他是怎么实现计划的”,点击提问

4.3 检查控制台输出的prompt

可以看到匹配到的三个答案和问题

<|im_start|>system
你是一个分析助手,根据上下文回答问题。必须生成更人性化的答案。<|im_end|>
<|im_start|>user
请根据【上下文】回答【问题】,当得不到较为准确的答案时,必须回答我不知道。
  【上下文】
  问:灭霸如何实现了他在宇宙中消灭一半生命的计划?
答:通过使用六颗无限宝石
问:复仇者联盟用什么方法扭转了灭霸的行动?
通过时间旅行收集宝石。
问:洛基在征服地球的尝试中使用了什么神秘的物体?
答:六角宝
  【问题】
  他是怎么实现计划的
  请给出你的答案:
  <|im_end|>
<|im_start|>assistant

image.gif

4.4 等待回复

耗时25s,有点长,但考虑到这是可以离线在端侧运行的非gpu版本,用于做一些后台任务还是可以的,结果如下 image.gif 编辑

5 总结

5.1 qwen1.5-0.5B比预期效果好

结果比续期要好一些,因为比较新的web版本大模型就找到qwen1.5-0.5B的,后续有时间我会出一期试试llama3.2-1B,但整个过程会比较长 - 因为还涉及到模型迁移

5.2 除非离线和高隐私环境网页大模型暂不适用

受限于网页性能和WebGPU的支持在transformer.js处于实验性阶段,生成用时比较久,除非是离线环境,以及对隐私要求比较高的情况下,目前的响应速度还是比较慢的

最近眼睛肿了,今天就一篇吧,剩下时间休息了,明天又得上班 ~ 啊啊啊

目录
相关文章
|
3天前
|
存储 JavaScript 前端开发
前端技术分享:使用Vue.js与Vuex管理状态
【10月更文挑战第1天】前端技术分享:使用Vue.js与Vuex管理状态
22 6
|
3天前
|
JavaScript 前端开发 开发者
前端技术分享:Vue.js 中的自定义指令
【10月更文挑战第1天】前端技术分享:Vue.js 中的自定义指令
24 5
|
3天前
|
JavaScript 前端开发 API
前端技术分享:Vue.js 动态路由与守卫
【10月更文挑战第1天】前端技术分享:Vue.js 动态路由与守卫
|
2天前
|
JavaScript 前端开发 开发者
使用 Vue.js 和 Vuex 构建响应式前端应用
【10月更文挑战第2天】使用 Vue.js 和 Vuex 构建响应式前端应用
9 0
|
2天前
|
存储 自然语言处理 文字识别
纯前端RAG:使用Transformers.js实现纯网页版RAG(一)
本文将分两部分教大家如何在网页中实现一个RAG系统,本文聚焦于深度搜索功能。通过浏览器端本地执行模型,可实现文本相似度计算和问答匹配,无需依赖服务器。RAG搜索基于高维向量空间,即使不完全匹配也能找到意义相近的结果。文中详细介绍了如何构建知识库、初始化配置、向量存储及相似度计算,并展示了实际应用效果。适用于列表搜索、功能导航、文档查询及表单填写等多种场景。
13 0
|
3天前
|
机器学习/深度学习 自然语言处理 前端开发
前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革
除了调用API接口使用Transformer技术,你是否想过在浏览器中运行大模型?Xenova团队推出的Transformer.js,基于JavaScript,让开发者能在浏览器中本地加载和执行预训练模型,无需依赖服务器。该库利用WebAssembly和WebGPU技术,大幅提升性能,尤其适合隐私保护、离线应用和低延迟交互场景。无论是NLP任务还是实时文本生成,Transformer.js都提供了强大支持,成为构建浏览器AI应用的核心工具。
41 0
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
79 2
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
70 4
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
61 4
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
82 4