【搭建个人知识库-3】

搭建个人知识库-3

  • 1 大模型开发范式
    • 1.1 RAG原理
    • 1.2 LangChain框架
    • 1.3 构建向量数据库
    • 1.4 构建知识库助手
    • 1.5 Web Demo部署
  • 2 动手实践
    • 2.1 环境配置
    • 2.2 知识库搭建
      • 2.2.1 数据收集
      • 2.2.2 加载数据
      • 2.2.3 构建向量数据库
    • 2.3 InternLM接入LangChain
    • 2.4 构建检索问答链
      • 1 加载向量数据库
      • 2 实例化自定义LLM与Prompt Template
      • 3 构建检索问答链
    • 2.5 Web Demo
  • 3 作业

基于InternLM和LangChain搭建专属个人的大模型知识库;

  • 大模型开发范式
  • LangChain简介
  • 构建

1 大模型开发范式

大模型具有简单的广度回答,但是在垂直领域的知识受限;

  • 如何让LLM及时获得最新的知识
  • 如何打造垂直领域大模型
  • 如何打造个人专属的LLM应用

两种常用开发范式:RAG VS Finetune
即:检索增强生成 VS 算法微调;
RAG:

  • 成本低
  • 可实时更新
  • 受基座影响大
  • 单次回答知识有限

Finetune:

  • 可个性化微调
  • 知识覆盖面广
  • 成本高昂
  • 无法实时更新

1.1 RAG原理

在这里插入图片描述

1.2 LangChain框架

LangChain框架:是一个开源工具,为各种LLM提供通用接口来简化应用程序的开发流程,帮助开发者自由构建LLM应用;
LangChain的核心组成模块:

  • 链:将组件实现端到端应用,通过一个对象封装实现一系列LLM操作;
  • Eg:检索问答链,覆盖实现了RAG的全部流程;

1.3 构建向量数据库

加载源文件–>文档分块–>文档向量化;
在这里插入图片描述

1.4 构建知识库助手

  • LangChain支持自定义LLM,可以直接接入到框架中;
  • 只需将InternLM部署到本地,并封装一个自定义LLM类,调用本地的InternLM即可。
    在这里插入图片描述
    RAG方案优化建议:
    RAG优化策略

1.5 Web Demo部署

支持简易Web 部署的框架:Gradio、Streamlit等;

2 动手实践

2.1 环境配置

1.安装环境,激活环境,并安装依赖
2.模型下载

  • 直接从服务器copy;–不可取;
  • modelscope 中的 snapshot_download 函数下载模型,第一个参数为模型名称,参数 cache_dir 为模型的下载路径。
import torch
from modelscope import snapshot_download, AutoModel, AutoTokenizer
import os
model_dir = snapshot_download('Shanghai_AI_Laboratory/internlm-chat-7b', cache_dir='/root/data/model', revision='v1.0.3')

3.LangChain相关环境部署

4.下载NLTK相关资源
在使用开源词向量模型构建开源词向量的时候,需要用到第三方库 nltk 的一些资源。

2.2 知识库搭建

2.2.1 数据收集

  • OpenCompass:面向大模型评测的一站式平台
  • IMDeploy:涵盖了 LLM 任务的全套轻量化、部署和服务解决方案的高效推理工具箱)
  • XTuner:轻量级微调大语言模型的工具库
  • InternLM-XComposer:浦语·灵笔,基于书生·浦语大语言模型研发的视觉-语言大模型
  • Lagent:一个轻量级、开源的基于大语言模型的智能体(agent)框架
  • InternLM:一个开源的轻量级训练框架,旨在支持大模型训练而无需大量的依赖

开源使用方式

# clone 上述开源仓库
git clone https://gitee.com/open-compass/opencompass.git
git clone https://gitee.com/InternLM/lmdeploy.git
git clone https://gitee.com/InternLM/xtuner.git
git clone https://gitee.com/InternLM/InternLM-XComposer.git
git clone https://gitee.com/InternLM/lagent.git
git clone https://gitee.com/InternLM/InternLM.git

为语料处理方案,在这里只选用仓库中的MD、TXT文件作为示例语料库。
当然也可以选用其中的代码文件放入到知识库中,但是需要针对代码文件格式进行专门的额外处理。(代码文件对逻辑联系要求较高,且规范性较强,在分割时最好基于代码模块进行分割再加入向量数据库)。

创建函数:将仓库里所以满足条件的.md或.txt文件 的路径找出来,定义一个函数:将该函数递归指定文件路径,返回其中所有满足条件的文件路径;

import os 
def get_files(dir_path):
    # args:dir_path,目标文件夹路径
    file_list = []
    for filepath, dirnames, filenames in os.walk(dir_path):
        # os.walk 函数将递归遍历指定文件夹
        for filename in filenames:
            # 通过后缀名判断文件类型是否满足要求
            if filename.endswith(".md"):
                # 如果满足要求,将其绝对路径加入到结果列表
                file_list.append(os.path.join(filepath, filename))
            elif filename.endswith(".txt"):
                file_list.append(os.path.join(filepath, filename))
    return file_list

2.2.2 加载数据

在上一步将所有目标文件的路径找出来之后,使用LangChain提供的FileLoader对象来加载目标文件,得到由目标文件解析出的纯文本内容。
不同类型文件对应不同的FileLoader:首先判断目标文件类型,并针对性调用对应类型的FileLoader,即调用FileLoader对象的load方法来得到加载之后的纯文本对象。
Python 真是好东西,实现简洁且可读性超级强

from tqdm import tqdm
from langchain.document_loaders import UnstructuredFileLoader
from langchain.document_loaders import UnstructuredMarkdownLoader

def get_text(dir_path):
    # args:dir_path,目标文件夹路径
    # 首先调用上文定义的函数得到目标文件路径列表
    file_lst = get_files(dir_path)
    # docs 存放加载之后的纯文本对象
    docs = []    # 得到一个纯文本对象对应的列表
    # 遍历所有目标文件
    for one_file in tqdm(file_lst):
        file_type = one_file.split('.')[-1]
        if file_type == 'md':
            loader = UnstructuredMarkdownLoader(one_file)
        elif file_type == 'txt':
            loader = UnstructuredFileLoader(one_file)
        else:
            # 如果是不符合条件的文件,直接跳过
            continue
        docs.extend(loader.load())
    return docs

2.2.3 构建向量数据库

在上一步得到纯文本对象的列表之后,将它引入到LangChain框架中构建向量数据库。由纯文本对象构建向量数据库,先对文本进行分块,接着对文本进行向量化。

1.#LangChain有多种文本分块工具,在这里使用字符串递归分割器
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500, chunk_overlap=150)
split_docs = text_splitter.split_documents(docs)

2.选用开源词向量模型进行文本向量化
from langchain.embeddings.huggingface import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")
3.将Chroma作为向量数据库,基于上文分块后的文档以及加载的开源向量化模型,将语料加载到指定路径下的向量数据库:
from langchain.vectorstores import Chroma
# 定义持久化路径
persist_directory = 'data_base/vector_db/chroma'
# 加载数据库
vectordb = Chroma.from_documents(
    documents=split_docs,
    embedding=embeddings,
    persist_directory=persist_directory  # 允许我们将persist_directory目录保存到磁盘上
)
# 将加载的向量数据库持久化到磁盘上
vectordb.persist()

2.3 InternLM接入LangChain

为方便构建LLM应用,基于本地进行部署InternLM,继承LangChain的LLM类自定义一个InternLM LLM子类,从而实现将InternLM接入到LangChain框架中。
完成 LangChain 的自定义 LLM 子类之后,可以以完全一致的方式调用 LangChain 的接口,而无需考虑底层模型调用的不一致。

from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

class InternLM_LLM(LLM):
    # 基于本地 InternLM 自定义 LLM 类
    tokenizer : AutoTokenizer = None
    model: AutoModelForCausalLM = None

    def __init__(self, model_path :str):
        # model_path: InternLM 模型路径
        # 从本地初始化模型
        super().__init__()
        print("正在从本地加载模型...")
        self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
        self.model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True).to(torch.bfloat16).cuda()
        self.model = self.model.eval()
        print("完成本地模型的加载")

    def _call(self, prompt : str, stop: Optional[List[str]] = None,
                run_manager: Optional[CallbackManagerForLLMRun] = None,
                **kwargs: Any):
        # 重写调用函数
        system_prompt = """You are an AI assistant whose name is InternLM (书生·浦语).
        - InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.
        - InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文.
        """
        
        messages = [(system_prompt, '')]
        response, history = self.model.chat(self.tokenizer, prompt , history=messages)
        return response
        
    @property
    def _llm_type(self) -> str:
        return "InternLM"

在上述类定义中,我们分别重写了构造函数和 _call 函数:对于构造函数,我们在对象实例化的一开始加载本地部署的 InternLM 模型,从而避免每一次调用都需要重新加载模型带来的时间过长;_call 函数是 LLM 类的核心函数,LangChain 会调用该函数来调用 LLM,在该函数中,我们调用已实例化模型的 chat 方法,从而实现对模型的调用并返回调用结果。
在Python中看到了类似C++中的用法

2.4 构建检索问答链

LangChain 通过提供检索问答链对象来实现对于 RAG 全流程的封装。所谓检索问答链,即通过一个对象完成检索增强问答(即RAG)的全流程。
原理:调用一个 LangChain 提供的 RetrievalQA 对象,通过初始化时填入已构建的数据库和自定义 LLM 作为参数,来简便地完成检索增强问答的全流程,LangChain 会自动完成基于用户提问进行检索、获取相关文档、拼接为合适的 Prompt 并交给 LLM 问答的全部流程。

1 加载向量数据库

将上文构建的向量数据库导入进来,直接通过Chroma以及上文定义的词向量模型来加载已构建的数据库:

vedtordb对象即为已经构建好的向量数据库对象,它可以针对用户的query进行语义向量检索,得到与用户提问相关的知识;

2 实例化自定义LLM与Prompt Template

实例化一个基于InternLM自定义的LLM对象:

3 构建检索问答链

调用 LangChain 提供的检索问答链构造函数,基于我们的自定义 LLM、Prompt Template 和向量知识库来构建一个基于 InternLM 的检索问答链:

2.5 Web Demo

上面两个小节分别完成之后,搭建基于Gradio框架部署到网页,搭建一个小型的Demo,这样便于测试和调试;

  • 将上面的代码封装成一个函数:用于返回 构建的检索问答链对象的函数。在启动Gradio的initial时调用函数得到检索问答链对象,后续直接使用该对象进行问答对话,避免重复加载模型;

  • 定义一个类:负责加载并存储检索问答链,响应Web界面里调用该检索问答链进行回答的动作;

  • 按照Gradio框架使用方法,实例化一个Web界面并将点击动作绑定到上述类的回答方法即可。

  • 启动上面封装的脚本,默认会在7860端口运行,因此做好服务器端口与本地端口映射。
    ssh -L 7860:127.0.0.1:7860 root@ssh.intern-ai.org.cn -p 34825

3 作业

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/322067.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Maven环境搭建及Maven部分目录分析

一、安装Maven Maven 本身就是⼀套由 Java 开发的软件,所以 Maven 的运⾏需要依赖 JDK 环境。在安装 Maven 之前请 确认JDK 是否配置正确(主要依赖 JAVA_HOME 环境变量)。如果没有正确安装和配置 JDK ,则运⾏ Maven 时 会出现以下…

实战 | 某电商平台类目SKU数获取与可视化展示

一、项目背景 最近又及年底,各类分析与规划报告纷至沓来,于是接到了公司平台类目商品增长方向的分析需求,其中需要结合外部电商平台做对比。我选择了国内某电商平台作为比较对象,通过获取最细层级前台类目下的SKU数以及结构占比&…

大数据深度学习ResNet深度残差网络详解:网络结构解读与PyTorch实现教程

文章目录 大数据深度学习ResNet深度残差网络详解:网络结构解读与PyTorch实现教程一、深度残差网络(Deep Residual Networks)简介深度学习与网络深度的挑战残差学习的提出为什么ResNet有效? 二、深度学习与梯度消失问题梯度消失问题…

D20XB60-ASEMI开关电源桥堆D20XB60

编辑:ll D20XB60-ASEMI开关电源桥堆D20XB60 型号:D20XB60 品牌:ASEMI 封装:GBJ-5(带康铜丝) 平均正向整流电流(Id):20A 最大反向击穿电压(VRM&#xff…

机器学习学习笔记(吴恩达)(第三课第一周)(无监督算法,K-means、异常检测)

欢迎 聚类算法: 无监督学习:聚类、异常检测 推荐算法: 强化学习: 聚类(Clustering) 聚类算法:查看大量数据点并自动找到彼此相关或相似的数据点。是一种无监督学习算法 聚类与二院监督…

常见的限流算法

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。 天下武学出同源 正所谓天下武学殊途同归&#xff…

用二维码介绍产品详情,扫码查看图文并茂的宣传册

传统的产品宣传方式,往往以产品手册、宣传单等纸质物料为主,更新成本高昂,一旦修改内容,就必须重新印刷,而且不易携带和保存,影响宣传效果和客户体验。 为了避免上述问题,可以在草料上搭建产品…

Python之循环判断语句

一、if判断语句 1. if...else if 条件: 满足条件时要做的事情1 满足条件时要做的事情2 ...... else: 不满足条件时要做的事情1 不满足条件时要做的事情2 ...... # -*- coding:utf-8 -*- age input("请输入年龄:") age int(age) if age > 18:print("已经成…

云贝教育 |【技术文章】存储对象的LIBRARY CACHE LOCK/PIN实验(一)

注: 本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。 实验环境 操作系统:Red Hat Enterprise Linux release 8.8 (Ootpa) 数据库:oracle Version 19.3.0.0.0 …

Openstack云计算(六)Openstack环境对接ceph

一、实施步骤: (1)客户端也要有cent用户: useradd cent && echo "123" | passwd --stdin cent echo -e Defaults:cent !requiretty\ncent ALL (root) NOPASSWD:ALL | tee /etc/sudoers.d/ceph chmod 440 /et…

Endothelin-1(内皮素-1) ELISA kit

灵敏、快速的内皮素-1 ELISA试剂盒,适用于心血管和应激相关研究 内皮素(Endothelin, ET)是由血管内皮细胞产生的异肽,具有强大的血管收缩活性。这种肽由三个独立的基因编码,经过加工产生39个残基的 大ET 分子&#xff…

Linux的SSH远程管理和服务器之间的免密连接

目录 一、远程管理基础 1.ssh协议 2.ssh原理 3、使用ssh协议传输的命令 4.登录方法 二、免密连接 1.免密连接的原理 2.实战 一、远程管理基础 1.ssh协议 ssh协议是基于C/S机构的安全通道协议,通信数据进行加密处理,用于远程管理。 ssh的服务名…

Linux多网卡绑定实现负载均衡详解

将多块网卡绑定同一IP地址对外提供服务,可以实现高可用或者负载均衡。直接给两块网卡设置同一IP地址是不可以的。通过 bonding,虚拟一块网卡对外提供连接,物理网卡的被修改为相同的MAC地址。 目录 1、bond的作用 2、Bonding聚合链路工作模…

低代码开发,企业的金钥匙,工业4.0转型的催化剂

近年,国内工业产值开始逐渐放缓,人口红利也开始逐渐消退,工业领域现在面临着高能耗、高投入、高风险以及低效益的困境。我国将“先进制造”作为十四五规划重要目标,推动工业领域实体经济、智能化转型、实现数字化、加快工业互联网…

PattPatel-“Introduction to Computing Systems“(3)期末样卷题目解析:C语言与汇编语言转化

上接(1)basic ideas和与解析(1) 核心思路还是借具体题目来理解书中的两条basic ideas——abstraction of layers与think both softwarely and hardwarely。 C语言与汇编语言的转化 题目的要求是将下面的这段代码用LC-3改写。 这…

SQL备忘--集合运算

前言 本文讨论的是两个子查询结果的合并问题, 是行维度下的合并处理 例如子查询A查出5条记录、子查询B查出3条记录,那么将两个结果合并,则共返回8条记录 行维度上要能进行合并,前置要求是:子查询的列字段是相同的&…

erlang/OTP 平台(学习笔记)(一)

OTP 我们在OPT概述里曾简单的了解过,现在让我们来进行进一步了解 理解并发和erlang的进程 1.理解并发 并发就是并行吗?不完全是,至少在讨论计算机和编程时二者并不等同。 有个常用的半正式定义是这么说的:“并发,用于形容那些无须以特定…

数据库——DAY1(Linux上安装MySQL8.0.35(网络仓库安装))

一、环境部署 1、Red Hat Enterprise Linux 9.3 64 位 2、删除之前安装过本地镜像版本的MySQL软件(以前未安装过,请跳过此步骤) [rootlocalhost ~]# dnf remove mysql-server -y [rootlocalhost ~]# rm -rf /var/lib/mysql [rootlocalhost …

十一、three场景实现太阳光晕

今天讲的太阳光不是three自带的DirectionalLight这个灯光,而是在场景里面能真实看到的光线特效,也可以叫做光晕。 先看实现效果图 现在讲讲实现步骤 安装maath,这是一个由数学助手、随机生成器、bits和bobs的集合。引入这个的目的是LensFlare.js文件要用这个来做太阳的旋转…

odoo 一日一技 odoo去除业务模块的基础框架

基础介绍​​​ 为了单纯使用odoo基础框架,我将源码整理成四个版本,分为社区版、企业版、社区基础版(去除非必要的业务模块)、企业基础版(去除非必要的业务模块)。如图还可以这样创建四个对应配置文件。 这边以社区基础版为例 下面简单介绍一下这些模…