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

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 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处于实验性阶段,生成用时比较久,除非是离线环境,以及对隐私要求比较高的情况下,目前的响应速度还是比较慢的

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

目录
相关文章
|
24天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
4天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
1天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
212 11
|
19天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
21天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2578 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
3天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
165 2
|
1天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
101 65
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1578 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
241 2