当前位置:   article > 正文

llm构建知识库

llm构建知识库

构建词向量

在RAG应用中,我们需要大模型调用知识库中的专业内容对用户的提问进行更加完善的回答,因此如何为llm引入知识库便尤为关键,在本篇内容中,我会从基础的词向量开始介绍,最终到如何完成一个可供llm调用的向量知识库。

对于搭建知识库的疑惑

带着问题去学习往往能够对项目产生更深刻的理解,对于下一部分学习如何搭建向量知识库,我在一开始提出了如下的问题:

  • 为什么要建立知识库?

  • 知识库具体来说是什么?

  • 建立知识库对llm有什么帮助,能够解决什么方面的问题?

  • 使用何种方式将知识导入进知识库?

  • 知识库的数据质量该如何保证?

对于搭建知识库的具体细节提出了如下问题:

  • 怎样判断知识库数据的质量?

  • 对于初学者来说,选择什么样的向量数据库来保存文本向量?

  • 在保存前应该对数据进行什么处理?

  • 在数据保存到向量数据库后,我们可以怎么使用这些数据?

词向量介绍

在机器学习和自然语言处理(NLP)中,词向量(Embeddings)是一种将非结构化数据,如单词、句子或者整个文档,转化为实数向量的技术。这些实数向量可以被计算机更好地理解和处理。嵌入背后的主要想法是,相似或相关的对象在嵌入空间中的距离应该很近。让我们以“king”、“queen”和“man”为例来说明词向量的应用。

假设我们使用Word2Vec模型训练了一组词向量,我们可以通过简单地对这些向量进行数学运算来表达一些语义关系。例如,我们可以使用以下算术表达式:

v ( ′ q u e e n ′ ) − v ( ′ k i n g ′ ) + v ( ′ m a n ′ ) v('queen') - v('king') + v('man') v(queen)v(king)+v(man)

其中,( v(w) ) 表示单词 ( w ) 的词向量。

我们期望的结果是得到一个与 “queen” 相关的向量。因为我们在这个表达式中做的操作是:取 “queen” 的词向量,减去 “king” 的词向量(这是一种“男性到女性”的转变),然后加上 “man” 的词向量(这是一种“成为男人”的行为)。所以,我们希望得到的结果是一个与 “queen” 相关的向量。

通过计算这个表达式,我们可以得到一个向量,然后可以在向量空间中找到与这个向量最接近的单词。如果我们得到的结果是 “woman”,那么这个词向量模型就成功地捕捉到了 “king” 到 “queen” 的语义关系。

利用词向量来表达单词的好处在于,它能够将单词转换为连续的实值向量,这样做有几个优点:

  1. 语义信息保留: 词向量在向量空间中可以捕捉到单词之间的语义相似性,这使得我们能够在数学上表示和计算单词之间的语义关系。

  2. 降维: 将单词转换为词向量将其从高维的离散空间转换为低维的连续空间,这样做不仅减少了计算的复杂性,而且使得单词之间的关系更容易被理解和计算。

  3. 用于机器学习任务: 词向量可以作为机器学习模型的输入,这些模型可以更好地理解和处理自然语言文本。

词向量的语义相似

假设我们有两个词向量分别表示 “cat” 和 “dog”,我们可以通过以下几种方法来计算它们的相似度:

  1. 点积(Dot Product):计算两个向量之间的点积,值越大表示两个向量越相似。

  2. 余弦距离(Cosine Similarity):计算两个向量之间的余弦相似度,值越接近1表示两个向量越相似。

  3. 欧几里得距离(Euclidean Distance):计算两个向量之间的欧几里得距离,值越小表示两个向量越相似。

相似度计算的数学表达
  1. 点积(Dot Product)

    点积是两个向量对应位置元素的乘积之和。对于两个向量 a \mathbf{a} a b \mathbf{b} b,点积 a ⋅ b \mathbf{a} \cdot \mathbf{b} ab 的计算公式为:

    a ⋅ b = ∑ i = 1 n a i ⋅ b i \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i \cdot b_i ab=i=1naibi

    其中, a i a_i ai b i b_i bi 分别是向量 a \mathbf{a} a b \mathbf{b} b 在第 i i i 个维度上的元素, n n n 是向量的维度数。

  2. 余弦相似度(Cosine Similarity)

    余弦相似度是通过计算两个向量之间的夹角余弦值来衡量它们的相似度。对于两个向量 a \mathbf{a} a b \mathbf{b} b,余弦相似度 similarity ( a , b ) \text{similarity}(\mathbf{a}, \mathbf{b}) similarity(a,b) 的计算公式为:

    similarity ( a , b ) = a ⋅ b ∥ a ∥ ∥ b ∥ \text{similarity}(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\| \|\mathbf{b}\|} similarity(a,b)=a∥∥bab

    其中, ∥ a ∥ \|\mathbf{a}\| a ∥ b ∥ \|\mathbf{b}\| b 分别表示向量 a \mathbf{a} a b \mathbf{b} b 的范数(模)。

  3. 欧几里得距离(Euclidean Distance)

    欧几里得距离是指两个向量之间的直线距离。对于两个 n n n 维向量 a \mathbf{a} a b \mathbf{b} b,欧几里得距离 d ( a , b ) d(\mathbf{a}, \mathbf{b}) d(a,b) 的计算公式为:

    d ( a , b ) = ∑ i = 1 n ( a i − b i ) 2 d(\mathbf{a}, \mathbf{b}) = \sqrt{\sum_{i=1}^{n} (a_i - b_i)^2} d(a,b)=i=1n(aibi)2

    这表示了向量 a \mathbf{a} a b \mathbf{b} b 之间每个维度上差值的平方和的平方根。

这些公式提供了计算向量相似度的标准方法,它们在自然语言处理和机器学习等领域中被广泛应用。

词向量的优势:

  • 词向量比文字更适合检索。当我们在数据库检索时,如果数据库存储的是文字,主要通过检索关键词(词法搜索)等方法找到相对匹配的数据,匹配的程度是取决于关键词的数量或者是否完全匹配查询句的;但是词向量中包含了原文本的语义信息,可以通过计算问题与数据库中数据的点积、余弦距离、欧几里得距离等指标,直接获取问题与数据在语义层面上的相似度;

建立词向量知识库

什么是向量数据库

向量数据库是用于高效计算和管理大量向量数据的解决方案。向量数据库是一种专门用于存储和检索向量数据(embedding)的数据库系统。它与传统的基于关系模型的数据库不同,它主要关注的是向量数据的特性和相似性。

向量数据库的原理及核心优势

向量数据库中的数据以向量作为基本单位,对向量进行存储、处理及检索。向量数据库通过计算与目标向量的余弦距离、点积等获取与目标向量的相似度。当处理大量甚至海量的向量数据时,向量数据库索引和查询算法的效率明显高于传统数据库。

建立知识库流程

数据处理流程:使用langchain PyMuPDFLoader或其他处理器对文档进行解析>对pdf进行数据清洗>对原文进行分块处理==>储存进向量数据库

document对象介绍

我们会使用langchain的loader模块加载数据

载入后的变量类型为langchain_core.documents.base.Document, 文档变量类型同样包含两个属性

  • page_content 包含该文档的内容。

  • meta_data 为文档相关的描述性数据。

读入pdf的流程

from langchain.document_loaders.pdf import PyMuPDFLoader

# 创建一个 PyMuPDFLoader Class 实例,输入为待加载的 pdf 文档路径
loader = PyMuPDFLoader("../../data_base/knowledge_db/pumkin_book/pumpkin_book.pdf")

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

pdf_page = pdf_pages[1]
print(f"每一个元素的类型:{type(pdf_page)}.", 
    f"该文档的描述性数据:{pdf_page.metadata}", 
    f"查看该文档的内容:\n{pdf_page.page_content}", 
    sep="\n------\n")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

知识库数据的预处理

import re
pattern = re.compile(r'[^\u4e00-\u9fff](\n)[^\u4e00-\u9fff]', re.DOTALL)
pdf_page.page_content = re.sub(pattern, lambda match: match.group(0).replace('\n', ''), pdf_page.page_content)
pdf_page.page_content = pdf_page.page_content.replace('•', '')
pdf_page.page_content = pdf_page.page_content.replace(' ', '')
print(pdf_page.page_content)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用re筛选掉\n换行符以及其他干扰原始文本的数据。

文档分割

由于大模型输入的token有限制,不能够一次性读入大量的数据,因此我们需要将文档分割成一个一个的小文字块。

#导入文本分割器
from langchain.text_splitter import RecursiveCharacterTextSplitter  

# 使用递归字符文本分割器
text_splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n", "\n", " ", ""],
    chunk_size=CHUNK_SIZE,
    chunk_overlap=OVERLAP_SIZE
)  

split_docs = text_splitter.split_documents(pdf_pages)
print(f"切分后的文件数量:{len(split_docs)}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

将整理好的数据存入向量数据库

from langchain.embeddings.baidu_qianfan_endpoint import QianfanEmbeddingsEndpoint
embedding = QianfanEmbeddingsEndpoint()
# 定义持久化路径
persist_directory = '../../data_base/vector_db/chroma'  
  • 1
  • 2
  • 3
  • 4

存入chroma数据库

from langchain.vectorstores.chroma import Chroma

vectordb = Chroma.from_documents(
    documents=split_docs[:20], # 为了速度,只选择前 20 个切分的 doc 进行生成;使用千帆时因QPS限制,建议选择前 5 个doc
    embedding=embedding,
    persist_directory=persist_directory  # 允许我们将persist_directory目录保存到
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

补充知识 使用千帆api进行Eembedding操作

api调用的返回结果

API返回的数据为json格式,除object向量类型外还有存放数据的data、embedding model 型号model以及本次 token 使用情况usage等数据,具体如下所示:

{

  "object": "list",

  "data": [

    {

      "object": "embedding",

      "index": 0,

      "embedding": [

        -0.006929283495992422,

        ... (省略)

        -4.547132266452536e-05,

      ],

    }

  ],


  "usage": {

    "prompt_tokens": 5,

    "total_tokens": 5

  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

调用代码

import os
from dotenv import load_dotenv, find_dotenv
import requests
import json

def wenxin_embedding(text: str):
    # 获取环境变量 wenxin_api_key、wenxin_secret_key
    api_key = os.environ['QIANFAN_AK']
    secret_key = os.environ['QIANFAN_SK']

    # 使用API Key、Secret Key向https://aip.baidubce.com/oauth/2.0/token 获取Access token
    url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={0}&client_secret={1}".format(api_key, secret_key)
    payload = json.dumps("")
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload)
    
    # 通过获取的Access token 来embedding text
    url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/embedding-v1?access_token=" + str(response.json().get("access_token"))
    input = []
    input.append(text)
    payload = json.dumps({
        "input": input
    })
    headers = {
        'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, data=payload)

    return json.loads(response.text)
# text应为List(string)
_ = load_dotenv()
text = "苹果,梨子,例子。王弛,张弛,王朔坤。强者,悟者,觉者,屠夫,老师。"
response = wenxin_embedding(text=text)  


print('返回的embedding类型为:{}'.format(response['object']))
print('embedding长度为:{}'.format(len(response['data'][0]['embedding'])))
print('embedding(前10)为:{}'.format(response['data'][0]['embedding'][:10]))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

返回结果:

返回的embedding类型为:embedding_list
embedding长度为:384
embedding(前10)为:[-0.0137910395860672, 0.00669039785861969, 0.010889548808336258, 0.024803854525089264, -0.058536287397146225, -9.339831012766808e-05, -0.06190592795610428, 0.012383501045405865, -0.08669111132621765, 0.06586026400327682, 0.08852116763591766, -0.021553991362452507, -0.019318103790283203, 0.051555123180150986, 0.013934466056525707, -0.03671779856085777, -0.027411723509430885, 0.06774383783340454, 0.0713854506611824, -0.07149849832057953, 0.013166148215532303, -0.06947434693574905, 0.016240054741501808, 0.020508628338575363, -0.03692181780934334, -0.06365703046321869, 0.018085960298776627, 0.00555068626999855, 0.05624716728925705, 0.08585838973522186, -0.09124935418367386, -0.025409957394003868, 0.0323883518576622, -0.0395120307803154, -0.044960372149944305, 0.12625740468502045, -0.06943001598119736, 0.006840592250227928, -0.036086615175008774, 0.04910583421587944, -0.07057742029428482, -0.1229444071650505, -0.002475174143910408, -0.03346749395132065, 0.033686887472867966, -0.04297911003232002, -0.03653896600008011, -0.05093971639871597, -0.07366011291742325, -0.044543106108903885, -0.013850185088813305, 0.07790923863649368, 0.04364033043384552, -0.013255196623504162, 0.09316448122262955, -0.05067949369549751, -0.015010404400527477, -0.03314557671546936, 0.07524704188108444, 0.05248184874653816, -0.03229234367609024, -0.0022475142031908035, -0.05658654868602753, -0.0568392276763916, 0.07862589508295059, -0.05903521552681923, -0.017429033294320107, -0.007445120718330145, -0.07381026446819305, 0.0029583799187093973, -0.04045562073588371, 0.02001262828707695, -0.08423849940299988, 0.10041883587837219, 0.00814094115048647, 0.03789811581373215, -0.07324040681123734, 0.020854875445365906, -0.031439159065485, 0.050521478056907654, -0.0028353973757475615, -0.06105911731719971, -0.07613781094551086, 0.011927973479032516, -0.011217274703085423, 0.03328155353665352, -0.004470432177186012, -0.09518494457006454, 0.09251786768436432, 0.04979020729660988, -0.06189896538853645, -0.007699169684201479, 0.08785741031169891, -0.0014502285048365593, -0.003492671763524413, 0.017373954877257347, -0.050552431493997574, 0.03604050725698471, 0.10989511758089066, -0.06560186296701431, 0.04091433063149452, -0.027753248810768127, -0.018566548824310303, 0.034535687416791916, -0.014601895585656166, -0.04412383958697319, -0.04106394946575165, -0.03261107951402664, 0.02256716974079609, -0.02498782053589821, 0.03999119997024536, 0.08914127945899963, 0.02798462100327015, 0.04732557386159897, -0.11950581520795822, -0.022280465811491013, 0.05755891650915146, -0.09359212964773178, -0.005178273655474186, 0.03537743538618088, 0.030156932771205902, 0.09336911886930466, 0.03503556177020073, 0.042811062186956406, -0.06377719342708588, 0.03479842096567154, 0.060883235186338425, -0.05802207440137863, -0.036426857113838196, 0.06918418407440186, 0.001452093943953514, -0.04299251735210419, -0.006984018255025148, -0.010986932553350925, 0.02274271287024021, 0.059066932648420334, -0.026285285130143166, -0.0625336617231369, 0.04083579033613205, -0.004560801666229963, -0.005203348118811846, 0.030152590945363045, 0.009230109862983227, -0.01837928034365177, -0.014525971375405788, -0.016671858727931976, -0.04618184268474579, -0.0003189221606589854, 0.028988540172576904, 0.0024551283568143845, 0.08513922989368439, -0.004833311308175325, 0.005179562605917454, -0.08062075823545456, -0.0392337441444397, 0.029934542253613472, 0.024773884564638138, 0.027588119730353355, -0.044103145599365234, 0.020014595240354538, 0.0349888950586319, 0.0017083219718188047, 0.009083355776965618, -0.002302837325260043, 0.030515193939208984, -0.13030388951301575, 0.04282761365175247, 0.06131679564714432, 0.03047861158847809, -0.01327563263475895, -0.1040450930595398, 0.09224918484687805, 0.051528509706258774, -0.03188223019242287, 0.015648724511265755, 0.03566725552082062, 0.02148253656923771, -0.08265466243028641, -0.007617986295372248, -0.017934387549757957, 0.03628987446427345, 0.047213904559612274, -0.048268016427755356, -0.02815909869968891, 0.05609947070479393, 0.0031261586118489504, -0.05929427221417427, -0.027171725407242775, 0.1347961574792862, -0.08684950321912766, 0.007888241671025753, 0.05977453663945198, -0.04015236347913742, -0.02864030934870243, 0.009431385435163975, 0.051309626549482346, -0.04797493666410446, -0.1107059046626091, -0.024543827399611473, 0.1020059660077095, 0.06933923810720444, -0.002221355214715004, -0.010468573309481144, 0.04409249126911163, 0.11023233830928802, -0.02976001799106598, -0.04711640998721123, -0.01189271081238985, 0.08988781273365021, 0.011541414074599743, 0.05096153914928436, -0.04510663077235222, 0.025409871712327003, -0.057353269308805466, -0.021000508219003677, 0.06689801067113876, 0.020161395892500877, -0.10265550017356873, 0.055223286151885986, 0.04069473594427109, -0.005491399671882391, -0.031750988215208054, 0.007012813352048397, 0.08509360253810883, 0.061793625354766846, -0.0027206584345549345, -0.057915449142456055, 0.04146212711930275, 0.062674880027771, 0.06150578334927559, -0.05386114865541458, 0.039093200117349625, -0.01489906944334507, -0.0877571702003479, 0.012969030998647213, 0.09187497198581696, 0.06128633767366409, -0.030842328444123268, 0.0011320621706545353, 0.013872279785573483, -0.01465094555169344, -0.061543360352516174, -0.007441539783030748, 0.011468968354165554, -0.07299011945724487, -0.0687471479177475, 0.003538120537996292, 0.05061567202210426, -0.03105730190873146, -0.040395624935626984, -0.04366876929998398, 0.051849376410245895, -0.013580442406237125, 0.08037030696868896, -0.03588113188743591, -0.005321354139596224, 0, 0, 0, -0.1953086107969284, 0, 0, 0, 0, 0, 0, 0, -0.018724417313933372, 0.07478241622447968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.014981468208134174, 0, -0.09227314591407776, 0, 0, 0, 0, 0, 0, 0, -0.14850953221321106, 0, 0, 0, 0, 0, -0.19588588178157806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.03274175897240639, 0, -0.17042233049869537, 0, 0, 0, -0.03166965767741203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.05664284527301788, 0, 0, 0, 0.04790239781141281, 0, 0, 0, 0, 0, -0.14636999368667603, 0, 0, 0.17318415641784668, 0, 0, 0, 0, 0, 0.19202835857868195, 0, 0, 0, -0.2088545560836792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.18635402619838715, 0, 0]
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/467318
推荐阅读
相关标签
  

闽ICP备14008679号