LLM RAG 多种方式装载LLM的实践

news2024/12/22 12:57:38

一、大模型系统中检索增强生成(RAG)的意义

当前大模型在处理特定领域或者高度专业化的查询时表现出知识缺失,当所需信息超出模型训练数据范围或需要最新数据时,大模型可能无法提供准确答案。基于行业SOP、行业标准、互联网实时信息等领域外部知识构建私域知识向量模型,设计RAG系统用于多文档、多源数据、多维数据的检索器,设计优化双编码、联合编码等方法的信息生成器,使得生成组件能够更深入地理解问题背后的上下文,并产生更加信息丰富的回答。

二、LLM-RAG的框架设计

整体框架包括 大部分:私域知识的嵌入;文档知识的分割;私域知识的向量化;大模型的装载;问答链的组装;
在这里插入图片描述
1、私域知识的嵌入
借助langchain及llama-index开发框架可满足目前大部分知识形式的嵌入,包括数据库、PDF、word、excel、csv、txt、markdown、知识图谱(neo4j)、图片等。
在这里插入图片描述
Llama-index提供的知识嵌入工具
在这里插入图片描述
Langchain 知识嵌入工具
2、文档知识的分割
我们知道目前的大模型对处理信息的多少有限制,输入到大模型系统内的信息量及其组合将直接影响大模型给出答案的相关性、准确性和及时性。因此对文档知识的合理分割是提升大模型检索增强及生成问答的关键。
文本分割主要考虑两个因素:1)embedding模型的Tokens限制情况;2)语义完整性对整体的检索效果的影响。一些常见的文本分割方式如下:
句分割:以”句”的粒度进行切分,保留一个句子的完整语义。常见切分符包括:句号、感叹号、问号、换行符等。
固定长度分割:根据embedding模型的token长度限制,将文本分割为固定长度(例如256/512个tokens),这种切分方式会损失很多语义信息,一般通过在头尾增加一定冗余量来缓解。

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

3、私域知识的向量化
向量化是一个将文本数据转化为向量矩阵的过程,该过程会直接影响到后续检索的效果。目前常见的embedding模型如表中所示,这些embedding模型基本能满足大部分需求,但对于特殊场景(例如涉及一些罕见专有词或字等)或者想进一步优化效果,则可以选择开源Embedding模型微调或直接训练适合自己场景的Embedding模型。
在这里插入图片描述
知识向量化的几种方式:

#modelscope下载:国内推荐
from langchain.embeddings import ModelScopeEmbeddings
model_id = "damo/nlp_corom_sentence-embedding_chinese-base"
#damo/nlp_corom_sentence-embedding_chinese-base
#damo/nlp_corom_sentence-embedding_english-base
embeddings = ModelScopeEmbeddings(model_id=model_id)
#hunggingface下载:国外推荐
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
#from langchain.embeddings import SentenceTransformerEmbeddings
#embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
# 构建向量数据库
# 加载数据库
vectordb = Chroma.from_documents(
    documents=split_docs,
    embedding=embeddings,
    )

4、大模型的装载
目前基于大模型的应用开发有多种框架,如何根据硬件、场景需求等高效、便捷装载大模型是开发LLM-RAG系统的关键。以下汇总了多种装载方式:
1)基于llama.cpp的cpu低成本装载:主要模型文件来自于hunggingface;
2)基于chatglm.cpp的CPU低成本装载:包括langchian[api]、openai[api]等形式。
3)基于langchain及Hugging Face Local Pipelines装载:支持的模型参考langchian文档中心。
5、问答链的组装
同样的,langchain为我们准备了一些构造好的问答链(langchain chains),包括sql数据库查询链、CSV查询链、html查询链、问答链等。

三、LLM-RAG的实践

1、多种方式低成本装载LLM
① langchain local_model形式

from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM,pipeline
import torch
from langchain.llms.huggingface_pipeline import HuggingFacePipeline
model_path = "Qwen/Qwen-1_8B-Chat"
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True).to(torch.bfloat16).cuda(0)
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=200000)
llm = HuggingFacePipeline(pipeline=pipe)

② langchain chatglm.cpp形式
参考chatglm.cpp GitHub网站:https://github.com/li-plus/chatglm.cpp

#安装chatglm.cpp库
!pip install --upgrade pip
!pip install chatglm.cpp[api]
#下载chatglm3-6b cpu量化文件
!git clone https://www.modelscope.cn/tiansz/chatglm3-6b-ggml.git
#启动 chatglm3-6b langchain-api服务
MODEL=./chatglm3-6b-ggml/chatglm3-ggml.bin uvicorn chatglm_cpp.langchain_api:app --host 127.0.0.1 --port 8000

获得chatglm3-6b langchain-api服务地址:http://127.0.0.1:8000
将chatglm3-6b接入langchain框架

endpoint_url = "http://127.0.0.1:8000"
llm = ChatGLM(
    endpoint_url=endpoint_url,
    max_token=1024,
    history=[
        ["我是数据分析师,可以向我查询任何关于数据分析的问题。"]
    ],
    top_p=0.9,
    model_kwargs={"sample_model_args": False},
)

③ langchian llama.cpp形式
llama.cpp是使用原始C ++的项目来重写LLaMa(长格式语言模型)等开源大模型推理代码。这使得可以在各种硬件上本地运行大模型。

#安装llama-cpp
!pip install llama-cpp-python
#从modelscope或者hunggingface下载量化模型:gguf
from modelscope.hub.file_download import model_file_download
model_dir = model_file_download(model_id='mikeee/TheBloke-openbuddy-zephyr-7B-v14.1-GGUF',file_path='openbuddy-zephyr-7b-v14.1.Q4_K_S.gguf',cache_dir='./Qwen')
#载入大模型
from langchain.llms import LlamaCpp
from langchain.prompts import PromptTemplate
from langchain.callbacks.manager import CallbackManager
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])

n_gpu_layers =0  # Change this value based on your model and your GPU VRAM pool.
n_batch = 5120  # Should be between 1 and n_ctx, consider the amount of VRAM in your GPU.
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
# Make sure the model path is correct for your system!
llm = LlamaCpp(
    model_path="./Qwen/mikeee/TheBloke-openbuddy-zephyr-7B-v14.1-GGUF/openbuddy-zephyr-7b-v14.1.Q4_K_S.gguf",
    n_gpu_layers=n_gpu_layers,
    n_batch=n_batch,
    max_tokens=200000,
    n_ctx=8912,
    callback_manager=callback_manager,
    verbose=True,  # Verbose is required to pass to the callback manager
)

2、私有知识的装载及向量化
① 多文档处理

#装载文件
def get_doc(dir_path):
    file_lst = os.listdir(dir_path)
    docs = []
    i = 1
    for file in file_lst:
        file_type = file.split('.')[-1]
       
        #print(file_type)
        if  file_type == 'docx':
            loader = UnstructuredWordDocumentLoader(dir_path+'/'+file)
        elif file_type == 'csv':
            loader = UnstructuredCSVLoader(dir_path+'/'+file)
        elif file_type == 'pdf':
            loader = UnstructuredPDFLoader(dir_path+'/'+file)
        else:
            # 如果是不符合条件的文件,直接跳过
            continue
        docs.extend(loader.load())
        print(str(i)+'-----'+file+'------完成装载')
        i = +1
    return docs

文档分割及向量化

#载入开源向量化模型
from langchain.embeddings import ModelScopeEmbeddings
model_id = "damo/nlp_corom_sentence-embedding_chinese-base"
#damo/nlp_corom_sentence-embedding_chinese-base
#damo/nlp_corom_sentence-embedding_english-base
embeddings = ModelScopeEmbeddings(model_id=model_id)
#文档分割
docs = get_doc('./Qwen')
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500, chunk_overlap=150)
#文档向量化
split_docs = text_splitter.split_documents(docs)
vectordb = Chroma.from_documents(
    documents=split_docs,
    embedding=embeddings
    )

② 单文档处理

#pdf
loader = UnstructuredPDFLoader('./Qwen/2304.08485.pdf')
docs=loader.load()
#docx
loader = UnstructuredWordDocumentLoader('./Qwen/《主数据质量检查报告》LL.docx')
docs=loader.load()
#csv
from langchain.document_loaders.csv_loader import CSVLoader
loader = CSVLoader(file_path="./Qwen/正则式.csv")
docs = loader.load()
#web文件
from langchain.document_loaders import AsyncHtmlLoader
urls = ["https://price.21food.cn/yurou/", "https://price.21food.cn/fushipin/"]
loader = AsyncHtmlLoader(urls)
docs = loader.load()

3、文档:RAG Q&A
使用 RetrievalQA 作为问答链

from langchain.prompts import PromptTemplate

# 我们所构造的 Prompt 模板
template = """你是一个数据治理工程师同时也是一个知识搜索查询工程师,请根据可参考的上下文回答用户的问题,如果用户的问题不清晰且不是给定的上下文覆盖的,请不要乱回答,请回答 抱歉!我尚未学习该知识。
问题: {question}
可参考的上下文:
···
{context}
···
基于用户给定的信息,重新汇总上下文生成精准的回答。
如果给定的上下文无法让你做出回答,请回答你不知道。
有用的回答:"""
# 调用 LangChain 的方法来实例化一个 Template 对象,该对象包含了 context 和 question 两个变量,在实际调用时,这两个变量会被检索到的文档片段和用户提问填充
QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)

from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectordb.as_retriever(),return_source_documents=True,chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})
#Q&A
question = "千信金属产业园主要业务数据以及业务术语有哪些?"
result = qa_chain({"query": question})
print("检索问答链回答 question 的结果:")
print(result["result"])

使用 ConversationalRetrievalChain 问答链检索增强生成

from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
bot = ConversationalRetrievalChain.from_llm(llm, retriever=vectordb.as_retriever(),memory=memory,verbose=True,return_source_documents=False)

query = "根基提供的上下文,千信产业园主要业务术语及主数据,并给出数据治理的建议"
result = bot.invoke({"question": query})
result["answer"]

4、问答结果探讨
将某企业的数据治理方向的一些文档做成私有知识库,基于私有知识库回答数据治理方面的问题。
在这里插入图片描述
私有知识库文档
问题一:

query = "根基提供的上下文,千信产业园主数据质量分析情况"
result = bot.invoke({"question": query})
result["answer"]

结果分析:对于私有知识库内确定的知识,整个RAG系统能比较精准的定位检索到用户问题所需的文档及文档块,并给出精准的答案。
在这里插入图片描述
问题二:

query = "根基提供的上下文,千信产业园仓储管理系统主数据质量评分都是多少"
result = bot.invoke({"question": query})
result["answer"]

结果分析:对于文档内存在的表格,目前简单的检索链和问答链无法给出精准的回答,分析原因应该是表格数据的检索还是需要使用CSV文件的嵌入以及CSV-chain才能获取精准的答案。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中间件-缓存、索引、日志

文章目录 缓存中间件本地缓存中间件分布式缓存中间件全文索引中间件分布式日志中间件小结 缓存中间件 缓存是性能优化的一大利器 我们先一起来看一个用户中心查询用户信息的基本流程 这时候,如果查找用户信息这个 API 的调用频率增加,并且在整个业务流…

强化学习(四)动态规划——1

动态规划算法(DP):在马尔可夫决策过程(MDP)的完美环境模型下计算最优策略。但其在强化学习中实用性有限,其一是它是基于环境模型已知;其二是它的计算成本很大。但它在理论伤仍然很重要&#xff…

Vscode 顶部Menu(菜单)栏消失如何恢复

Vscode 顶部Menu(菜单)栏消失如何恢复? 首先按一下 Alt按键,看一下是否恢复了菜单栏如果恢复了想了解更进一步的设置,或是没能恢复菜单栏,可以看后续。 1.首先点击左下角 齿轮,打开settings; 或者 直接 ctrl 逗号 …

如何本地搭建Splunk Enterprise数据平台并实现任意浏览器公网访问

文章目录 前言1. 搭建Splunk Enterprise2. windows 安装 cpolar3. 创建Splunk Enterprise公网访问地址4. 远程访问Splunk Enterprise服务5. 固定远程地址 前言 本文主要介绍如何简单几步,结合cpolar内网穿透工具实现随时随地在任意浏览器,远程访问在本地…

java SSM项目预算生成管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM项目预算生成管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的 源代码和数据库,系统主…

《WebKit 技术内幕》学习之十(1): 插件与JavaScript扩展

虽然目前的浏览器的功能很强 ,但仍然有其局限性。早期的浏览器能力十分有限,Web前端开发者希望能够通过一定的机制来扩展浏览器的能力。早期的方法就是插件机制,现在流行次啊用混合编程(Hybird Programming)模式。插件…

小微企业科技创新之策略:人才、投入、模式、技术、支持四管齐下

对于小微企业来说,搞科技创新需要从多个方面入手。以下是一些可供参考的方法: 明确创新方向:首先,企业需要明确自己的创新方向和目标,这有助于聚焦资源,避免盲目投入。同时,企业需要对市场进行…

charles使用指南

一、什么是charles Charles 是一个http代理、管理以及反向代理工具,它允许开发者查看本地机器和互联网之间的关于http、https的所有通信,包含请求、响应以及他们的请求头、响应头。 它的主要功能包含: 1、SSL代理 2、带宽限制 3、ajax断…

如何查看Linux CPU占有率

目录 1、top 2、htop 3、vmstat 4、mpstat 5、iostat 查看嵌入式设备CPU占有率是评估系统资源使用情况的重要方式。 在Linux系统中,有多种方法可以查看CPU占有率,这里介绍几种常用的命令行工具。 1、top 这是最常用的命令之一,它提供了…

go语言(十三)-----interface

一、Interface 通用万能类型 空接口int,string,float,struct都实现了interface都可以用interface{}类型,引用任意的数据类型 package mainimport "fmt"//interface()是万能数据类型 func myFunc(arg interface{}) {fmt.Println(&…

[娱乐]索尼电视安装Kodi

索尼电视不能直接apk安装kodi应用 android studio安装后附带 abd, 路径 C:\Users\[yourname]\AppuoData\Local\Android\Sdk\platform-tools\adb.exe安卓电视点击内部版本号,启用开发者模式 adb 连接索尼安卓电视,记得电视上运行调试 abi选…

函数传参数组时,使用数组形参的本质

c语言中函数的调用分为两种方式:传址调用、传值调用。 传值调用我们都知道就是将实参的值传送给被调函数,让被调函数的形参接收这个值,从而形参内存中的数据就变成了实参的一份拷贝。 而传址调用则是将实参的地址传送过去,然后令…

IaC基础设施即代码:Terraform 创建 docker 网络与容器资源

目录 一、实验 1.环境 2.Terraform查看版本 3.Linux主机安装Docker 4.Terraform使用本地编译(In-house)的Providers 5.Docker-CE 开启远程API 6. Linux主机拉取镜像 7.Terraform 创建docker 网络资源 8.Terraform 创建docker 容器资源 一、实验 …

8.3 Springboot整合Redis 之Jedis方式

文章目录 前言一、Maven依赖二、新增子Module:tg-book-redis三、Jedis配置类3.1 Jedis连接池核心配置说明四、Jedis 工具类五、新增controller测试前言 Jedis是Redis官方推荐的Java客户端连接工具,用法非常简单,Jedis的API与Redis的API可以说是一模一样,所以非常有利于熟悉…

【K8S 云原生】K8S的包包管理器-helm

目录 一、helm概念 1、什么是helm 2、helm的概念: 二、实验部署: 1、安装helm: 2、对chart仓库的基本使用: 2.1、查看和更新chart仓库 2.2、安装chart 2.3、卸载chart: 3、helm自定义模版: 3.1、…

未来趋势:视频美颜SDK与增强现实(AR)的融合

当下,视频美颜SDK不断演化,成为用户记录和分享生活时不可或缺的一部分。同时,增强现实技术也以其独特的沉浸感和交互性受到青睐,被广泛应用于游戏、教育、医疗等领域。 一、视频美颜与AR的结合 1.实时美颜的AR增值体验 借助AR的…

【Springboot】日志

1.日志的使用 日志主要用于记录程序运行的情况。我们从学习javase的时候就使用System.out.println();打印日志了,通过打印的日志来发现和定位问题,或根据日志来分析程序运行的过程。在Spring的学习中,也经常根据控制台的⽇志来分析和定位问题 。 日志除…

《WebKit 技术内幕》学习之七(1): 渲染基础

《WebKit 技术内幕》之七(1): 渲染基础 WebKit的布局计算使用 RenderObject 树并保存计算结果到 RenderObject 树。 RenderObject 树同其他树(如 RenderLayer 树等),构成了 WebKit 渲染的为要基础设施。 1…

w23靶场安装

一、实验环境 服务器:phpstudyv8.1.13 靶场:Bees二、实验目的 提供一个靶场环境 三、实验步骤 bees靶场安装 1.启动小皮的apache和mysql 2.在小皮V8.1.1.3版本上创建bees网站,选择的php版本最好在5.x,不然会有php解析错误。…

Windows系统如何修改Nginx配置实现远程访问多个本地站点

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…