大模型入门到精通——使用Embedding API及搭建本地知识库(一)

news2024/11/12 8:23:36

使用Embedding API及搭建本地知识库

1. 基于智谱AI调用Embedding API实现词向量编码

首先,生成.env 文件,填写好智谱AI的API-key

参考:大模型入门到实战——基于智谱API key 调用大模型文本生成

在这里插入图片描述

读取本地/项目的环境变量。

find_dotenv() 寻找并定位 .env 文件的路径

load_dotenv() 读取该 .env 文件,并将其中的环境变量加载到当前的运行环境中

如果你设置的是全局的环境变量,这行代码则没有任何作用。

from zhipuai import ZhipuAI
import os 
from dotenv import load_dotenv, find_dotenv
from zhipuai import ZhipuAI


# 读取本地/项目的环境变量。

# find_dotenv() 寻找并定位 .env 文件的路径
# load_dotenv() 读取该 .env 文件,并将其中的环境变量加载到当前的运行环境中  
# 如果你设置的是全局的环境变量,这行代码则没有任何作用。
_ = load_dotenv(find_dotenv())
def zhipu_embedding(text: str):

    api_key = os.environ["API_key"]
    client = ZhipuAI(api_key=api_key)
    response = client.embeddings.create(
        model="embedding-2",
        input=text,
    )
    return response

text = '要生成 embedding 的输入文本,字符串形式。'
response = zhipu_embedding(text=text)
print(response)

在这里插入图片描述

同样的我们也可以从response中获取embedding的类型和embedding。response为zhipuai.types.embeddings.EmbeddingsResponded类型,我们可以调用object、data、model、usage来查看response的embedding类型、embedding、embedding model及使用情况。

print(f'response类型为:{type(response)}')
print(f'embedding类型为:{response.object}')
print(f'生成embedding的model为:{response.model}')
print(f'生成的embedding长度为:{len(response.data[0].embedding)}')
print(f'embedding(前10)为: {response.data[0].embedding[:10]}')
  
response类型为:<class 'zhipuai.types.embeddings.EmbeddingsResponded'>
embedding类型为:list
生成embedding的model为:embedding-2
生成的embedding长度为:1024
embedding(前10)为: [0.017892399802803993, 0.0644201710820198, -0.009342825971543789, 0.02707476168870926, 0.004067837726324797, -0.05597858875989914, -0.04223804175853729, -0.03003198653459549, -0.016357755288481712, 0.06777040660381317]

2. 数据读取

2.1 使用 LangChain 的 PyMuPDFLoader 读取 PDF 文档

在构建知识库时,处理 PDF 文档是一项常见的任务。LangChain 提供了一个高效的工具——PyMuPDFLoader,用于读取和解析 PDF 文件。PyMuPDFLoader 是目前 PDF 解析器中速度最快的一种,能够快速处理大规模的 PDF 文件,并提取其中的内容和元数据。使用 LangChain 的 PyMuPDFLoader,可以快速、高效地解析 PDF 文档,并提取出详细的文本内容和元数据。这使得在知识库建设中,处理 PDF 文件变得更加简单和高效。

1. PyMuPDFLoader 的特点
  • 高效性:PyMuPDFLoader 能够快速解析 PDF 文件,并从中提取文本和元数据。
  • 详细的元数据:它不仅提取文本内容,还能够获取 PDF 文档和每一页的详细元数据,例如作者、标题、页数等。
  • 逐页返回文档:在解析过程中,PyMuPDFLoader 将每一页的内容作为单独的文档返回,便于进一步处理和分析。

安装

pip install langchain
pip install -U langchain-community
pip install pymupdf
pip install unstructured
2. PyMuPDFLoader 的用法

下面是使用 PyMuPDFLoader 读取 PDF 文件的基本步骤:

from langchain.document_loaders import PyMuPDFLoader

# 初始化加载器,传入 PDF 文件的路径
loader = PyMuPDFLoader("your_pdf_file.pdf")

# 加载文档,返回一个文档列表,每个文档对应 PDF 文件中的一页
documents = loader.load()

# 查看加载的文档
for doc in documents:
    print(doc.page_content)  # 打印每一页的内容
    print(doc.metadata)      # 打印每一页的元数据
  1. 导入模块:首先,从 langchain.document_loaders 导入 PyMuPDFLoader 类。
  2. 初始化加载器:创建一个 PyMuPDFLoader 实例,并传入要解析的 PDF 文件的路径。
  3. 加载文档:使用 load() 方法加载 PDF 文档。此方法将返回一个文档列表,每个文档对应 PDF 文件中的一页。
  4. 查看文档内容:通过遍历文档列表,可以访问每一页的内容和元数据。
  5. 注意事项
    1. 确保 PDF 文件路径正确且文件存在。
    2. 列表索引从 0 开始,因此 pdf_pages[1] 代表第二页。

实际例子:

from langchain.document_loaders.pdf import PyMuPDFLoader

# 创建一个 PyMuPDFLoader Class 实例,输入为待加载的 pdf 文档路径
loader = PyMuPDFLoader("传统CV算法-机器学习.pdf")

# 调用 PyMuPDFLoader Class 的函数 load 对 pdf 文件进行加载
pdf_pages = loader.load()

print(f"载入后的变量类型为:{type(pdf_pages)},",  f"该 PDF 一共包含 {len(pdf_pages)} 页")

pdf_page = pdf_pages[1]
print(f"每一个元素的类型:{type(pdf_page)}.", 
    f"该文档的描述性数据:{pdf_page.metadata}", 
    f"查看该文档的内容:\n{pdf_page.page_content}", 
    sep="\n------\n")

在这里插入图片描述

3. 应用场景

PyMuPDFLoader 特别适用于需要从大型 PDF 文档中提取特定内容或处理包含复杂结构的 PDF 文件的场景。它能够帮助用户有效地构建和管理基于 PDF 文档的知识库。

2.2 读取markdown文档

以几乎完全一致的方式读入 markdown 文档:

from langchain.document_loaders.markdown import UnstructuredMarkdownLoader

loader = UnstructuredMarkdownLoader("../../data_base/knowledge_db/prompt_engineering/1. 简介 Introduction.md")
md_pages = loader.load()
print(f"载入后的变量类型为:{type(md_pages)},",  f"该 Markdown 一共包含 {len(md_pages)} 页")
md_page = md_pages[0]
print(f"每一个元素的类型:{type(md_page)}.", 
    f"该文档的描述性数据:{md_page.metadata}", 
    f"查看该文档的内容:\n{md_page.page_content[0:][:200]}", 
    sep="\n------\n")

读取的对象和 PDF 文档读取出来是完全一致的:

在这里插入图片描述

3. 数据清洗

在构建知识库时,数据清洗是一个非常重要的步骤,其目的是为了确保知识库中的数据是有序的、优质的和精简的。以下是为什么在知识库搭建过程中需要清洗数据的一些原因:

3.1 特点

1. 提高数据的可读性

原始数据可能包含许多格式化问题,比如在读取 PDF 文件时常见的换行符(\n)问题。这些换行符在文档中可能是由于排版原因而存在,但在知识库中可能会破坏内容的连贯性,影响可读性。通过清洗数据,可以去除这些不必要的换行符,使文本更加流畅和易读。

2. 减少噪音数据

噪音数据是指那些对信息的理解没有帮助,甚至可能产生误导的无用数据。例如,文档中多余的空行、格式化字符、无意义的符号等,都会影响文本的质量和理解。清洗数据的过程可以帮助去除这些噪音,保留有用的关键信息。

3. 保证数据的一致性

知识库中的数据应该具有一致的格式和结构,以便于后续的查询和分析。如果数据格式不一致,例如同一类型的信息在不同文档中以不同的方式呈现,会导致查询复杂化,甚至产生错误的结果。清洗数据有助于确保格式的一致性。

4. 优化存储和处理效率

冗余和无用的数据不仅占用存储空间,还会增加处理复杂度,导致资源浪费。通过数据清洗,可以删除多余的信息,精简数据结构,从而提高存储和处理的效率。

5. 提升模型的精度

如果知识库数据是用于训练机器学习或自然语言处理模型的,那么数据的质量直接影响模型的性能。清洗数据可以确保模型的训练集更准确,从而提升模型的精度和有效性。

6. 保持数据的相关性

在一些情况下,原始文档中可能包含过时或不相关的信息,这些信息可能对当前的知识库没有价值。清洗数据的过程可以帮助筛选出最新的、最相关的信息,确保知识库内容的高质量。

3.2 代码示例:使用正则表达式清洗数据

以下是一个简单的 Python 代码示例,展示如何使用正则表达式来删除文本中的多余换行符:

import re

# 原始文本数据(包含多余的换行符)
raw_text = "这是一个示例文本。\n\n它被分成了\n多行,\n但实际上是\n一个连续的句子。"

# 使用正则表达式删除多余的换行符
cleaned_text = re.sub(r'\n+', ' ', raw_text)  # 替换多个连续的换行符为一个空格
cleaned_text = re.sub(r'(?<!\n)\n(?!\n)', ' ', cleaned_text)  # 删除单个换行符,但保留段落之间的换行

print("清洗后的文本:")
print(cleaned_text)

消除掉空格,•等字符

pdf_page.page_content = pdf_page.page_content.replace('•', '')
pdf_page.page_content = pdf_page.page_content.replace(' ', '')
print(pdf_page.page_content)

4. 文档分割

、在构建向量知识库时,由于文档长度可能超过模型支持的上下文长度,因此需要将文档分割成较小的片段(chunk),以便模型能够有效处理和检索。这是通过 chunk_sizechunk_overlap 两个参数来控制分割过程的。通过设置合理的 chunk_sizechunk_overlap,可以有效地分割文档,使得模型能够在处理长文档时,依然保持对上下文的理解能力,并且在检索时返回高质量的结果。这种方法在构建高效的向量知识库中非常重要。在检索时,我们会以 chunk 作为检索的元单位,也就是每一次检索到 k 个 chunk 作为模型可以参考来回答用户问题的知识。

在这里插入图片描述

4.1 chunk_size(块大小)

chunk_size 指每个块包含的字符或 Token (如单词、句子等)的数量

chunk_size 是指每个文档片段的最大长度(通常以字符或标记数来计量)。这个参数决定了每个 chunk 的大小。较大的 chunk_size 可以包含更多的上下文信息,但也有可能超出模型的处理能力;而较小的 chunk_size 则更容易被模型处理,但可能会丢失一些上下文。

4.2 chunk_overlap(块重叠大小)

  • chunk_overlap 指两个块之间共享的字符数量,用于保持上下文的连贯性,避免分割丢失上下文信息

chunk_overlap 定义了相邻 chunk 之间的重叠部分的大小。这是为了确保每个 chunk 在分割后,依然保留部分上下文信息,从而在模型处理时,不会因为分割而导致语义的断裂。例如,如果一个句子被分割成两个 chunk,通过 chunk_overlap 保持部分重叠,可以确保两个 chunk 都包含完整的句子信息。

4.3 分割方式的选择

  • 按长度分割:可以简单地按 chunk_size 指定的长度进行分割,然后按 chunk_overlap 进行重叠处理。这种方法适用于内容比较平铺直叙的文档。
  • 按固定规则分割:有时,我们可以根据自然段落、句子或其他语义单位来分割,这种方法需要更复杂的分割逻辑,但能够更好地保持文本的语义完整性。

4.4 实际使用示例

在实际操作中,我们可以通过 LangChain 提供的文本分割器来实现这些功能。

  • RecursiveCharacterTextSplitter(): 按字符串分割文本,递归地尝试按不同的分隔符进行分割文本。
  • CharacterTextSplitter(): 按字符来分割文本。
  • MarkdownHeaderTextSplitter(): 基于指定的标题来分割markdown 文件。
  • TokenTextSplitter(): 按token来分割文本。
  • SentenceTransformersTokenTextSplitter(): 按token来分割文本
  • Language(): 用于 CPP、Python、Ruby、Markdown 等。
  • NLTKTextSplitter(): 使用 NLTK(自然语言工具包)按句子分割文本。
  • SpacyTextSplitter(): 使用 Spacy按句子的切割文本。

以下是一个基本的代码示例:

from langchain.text_splitter import CharacterTextSplitter

# 设置块大小和重叠大小
chunk_size = 500
chunk_overlap = 50

# 初始化文本分割器
text_splitter = CharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)

# 原始文档内容
text = "这是一个非常长的文档内容,需要进行分割处理。..."

# 执行分割
chunks = text_splitter.split_text(text)

# 打印分割后的 chunks 数量和部分内容
print(f"总共分割为 {len(chunks)} 个 chunk")
print(chunks[:2])  # 打印前两个 chunk 作为示例
# 使用递归字符文本分割器
'''
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)
text_splitter.split_text(pdf_page.page_content[0:1000])
'''

4.5 检索时的应用

在检索时,模型会以 chunk 作为基本的检索单位,返回与查询最相关的 k 个 chunk。这些 chunk 作为模型回答问题的参考知识,k 的值可以根据具体需求和模型的容量进行调整,以平衡性能和答案的准确性。

参考

https://datawhalechina.github.io/llm-universe/#/C3/3.数据处理

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

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

相关文章

基于SSM的在线家教管理系统的设计与实现 (含源码+sql+视频导入教程+论文+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的在线家教管理系统拥有三个角色 管理员&#xff1a;用户管理、教师管理、简历管理、申请管理、课程管理、招聘教师管理、应聘管理、评价管理等 教师&#xff1a;课程管理、应聘…

Prometheus Operator部署管理

Prometheus Operator部署管理 Prometheus Operator & Kube-Prometheus & Helm chart 部署区别 Prometheus Operator 是 Kubernetes 原生的工具&#xff0c;它通过将 Prometheus 资源定义为 Kubernetes 对象&#xff08;CRD&#xff09;来简化 Prometheus 集群的管理。…

如何使用ssm实现公司项目管理系统设计与实现

TOC ssm136公司项目管理系统设计与实现jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规…

Avg函数求比率的应用(SQL)

题目 在 SQL 中&#xff0c;AVG 函数用于计算一组数值的平均值。这个功能也可以用来计算比率或比例。 平均值 可以用来计算比率的原因&#xff1a; 二元值&#xff1a;在许多情况下&#xff0c;我们用 1 和 0 表示发生或未发生的事件。例如&#xff0c;在你的查询中&#xff0…

基于Java的C语言课程教学实践小程序的设计与实现(论文+源码)_kaic

基于Java的C语言课程教学实践小程序的设计与实现 摘 要 在当前信息技术迅猛发展的大背景下&#xff0c;为了学生更好地利用信息技术学习C语言&#xff0c;急需开发一款C语言课程教学实践小程序。‎这个小程序可以让学生不再局限于课堂学习‎的教学模式&#xff0c;而是能够随…

freeCAD与stl文件如何互切?

大家好&#xff0c;我是山羊君Goat。 作为硬件工程师&#xff0c;如果需要给自己的硬件主板做一个DIY的造型&#xff0c;比如说B站稚晖君DIY的小电视等等。 对于这个&#xff0c;那3D打印技术就必不可少了&#xff08;怪不得说硬件学的东西都很杂 &#xff09;。 FreeCAD是一款…

BeautifulSoup4通过lxml使用Xpath定位实例

有以下html。<a>中含有图片链接&#xff08;可能有多个<a>&#xff0c;每一个都含有一张图片链接&#xff09;。最后一个<div>中含有文字。 上代码&#xff1a; import requests from bs4 import BeautifulSoup from lxml import etreeurlhttps://www.aaabb…

动态规划类型题目汇总及解析(持续更新)

目录 数字三角形模型 摘花生 最低通行费 方格取数&#xff08;洛谷&#xff09; 传纸条&#xff08;洛谷&#xff09; 最长上升子序列模型 最长上升子序列&#xff08;洛谷&#xff09;&最长递增子序列&#xff08;leetcode&#xff09; leetcode674. 最长连续递…

Image-to-Image Translation 图像翻译任务中的输入成对图像拼接成一张图技术详解

引 言 在图像翻译任务中&#xff0c;近几年比较火热的Generative Adversarial Nets (GAN)模型以及各种变体深受视觉研究团体的青睐&#xff0c;在具体任务中取得不错的实验表现。图像翻译包含两部分内容&#xff1a;一个是图像内容(image content)显示内部存在的实体,用于区分不…

【C++ Primer Plus习题】4.5

问题: 解答: #include <iostream> using namespace std;typedef struct _CandyBar {string brand;float weight;int calorie; }CandyBar;int main() {CandyBar snack { "德芙",2.1,20};cout << "品牌:" << snack.brand << endl;…

计算机毕业设计 养老院管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

IO进程day01(函数接口fopen、fclose、fgetc、fputc、fgets、fputs)

目录 函数接口 1》打开文件fopen 2》关闭文件fclose 3》文件读写操作 1> 每次读写一个字符&#xff1a;fgetc(),fputc() 针对文件读写 针对终端读写 练习&#xff1a;实现 cat 命令功能 格式&#xff1a;cat 文件名 2> 每次一个字符串的读写 fgets() 和 fputs() …

数据集笔记: FourSquare - NYC and Tokyo Check-ins

FourSquare - NYC and Tokyo Check-ins (kaggle.com) 这个数据集包含了从2012年4月12日到2013年2月16日&#xff0c;约10个月时间内在纽约市和东京收集的签到数据。数据集中包含纽约市的227,428次签到和东京的573,703次签到。每个文件包括以下8个字段&#xff1a; 用户ID&…

Shell脚本学习_运算符

目录 一、算数运算符 1、expr命令&#xff1a; 2、算数运算符介绍&#xff1a; 3、使用 ( ( ) ) 进行运算&#xff1a; 4、bc命令&#xff1a; 1.bc中互动式的数学运算&#xff1a; 2.非互动式的管道运算&#xff1a; 3.非互动式的输入重定向运算&#xff1a; 二、比较运…

Kafka的基本概念

目录 1.Kafka的介绍 1.1介绍 1.2Kafka的概念 1.3.Kafka实现的日志聚合 1.4简单的收发消息 1.5其他消费模式 1.5.1指定消费进度 1.5.2分组消费 1.5.3查看消费者组的偏移量 1.6基于Zookeeper的Kafka集群 1.6.1使用集群的原因 1.6.2Kafka集群架构 1.6.3Topic下的Part…

2024年8月25日 十二生肖 今日运势

小运播报&#xff1a;2024年8月25日&#xff0c;星期日&#xff0c;农历七月廿二 &#xff08;甲辰年壬申月辛酉日&#xff09;&#xff0c;法定节假日。 红榜生肖&#xff1a;龙、牛、蛇 需要注意&#xff1a;鸡、狗、兔 喜神方位&#xff1a;西南方 财神方位&#xff1a;…

UVM中的TLM(事务级建模)通信(2)

上一篇介绍了UVM中利用TLM进行的一对一通信&#xff1a;UVM中的TLM(事务级建模)通信(1)-CSDN博客&#xff0c;除此之外&#xff0c;UVM还有两种特殊的端口&#xff1a;analysis_port和analysis_export&#xff0c;用于完成一对多的通信。 1.analysis端口 这两种端口同样也是用于…

域名泛解析是什么?如何设置?

在当今数字化的时代&#xff0c;网站建设和网络运营对于企业和个人来说都变得至关重要。而在这个过程中&#xff0c;域名的管理和配置起着关键作用。其中&#xff0c;域名泛解析是一个重要的概念&#xff0c;它可以为网站的运营和管理带来诸多便利。 一、域名泛解析是什么&…

尚品汇静态网页设计

目录 尚品汇静态网页设计 在线浏览 项目结果展示 准备 顶部导航条设计 头部设计 主导航区设计 主要内容区设计 左侧边栏区 一级菜单 二级菜单 中间内容区 右侧其他内容区 上部分快报区 下部分图标导航区 秒杀区设计 楼层区设计 顶部设计 详情区设计 页脚设…

ResNet网络学习

简介 Residual Network 简称 ResNet (残差网络) 下面是ResNet的网络结构&#xff1a; ResNet详细介绍 原理 传统方法的问题&#xff1a; 对于一个网络&#xff0c;如果简单地增加深度&#xff0c;就会导致 梯度消失 或 梯度爆炸&#xff0c;我们采取的解决方法是 正则化。…