一、引言
上篇文章《GPT简介及应用》介绍了GPT的应用场景,里面提到GPT bot的基本使用:基于GPT训练好的数据,回答用户的问题。
但在使用过程中,如果用户的问题里面出现最新的术语,就会出现这种提示:
截至我最后更新的时间(2023年4月),"llama_index"这个术语并不是广泛认知或者在特定领域内公认的一个概念,因此我无法直接提供关于"llama_index"的具体信息。这个术语可能是指某个特定项目、工具、指标或者是某个领域内的专有名词。
这时候我们自然会想到,有没有办法将最新的/私有的数据提供给GPT,让GPT基于这些数据来回答问题呢?答案当然是有的,那就是:GPT知识库。
二、简介
GPT 知识库,就像是一个包含了各种武功秘籍的宝库。GPT Bot 像是一位可以通过阅读和理解这些秘籍,来不断提高自己的武功水平的修炼者。
武功大师会将自身的武术经验沉淀升华,编撰成绝世的武功秘籍。
以往武功大师想要把这些武功秘籍传承下去,需要经过层层选拔,挑选出最合适的徒弟,辅以精心指导,日夜打磨,才可能培养出下一代的武功大师。
但现在只需要将武功秘籍给GPT Bot,它就可以快速理解,并且吸收为自身内力,为不同级别的人员提供指导。
这就是GPT知识库+GPT Bot的威力:
GPT Bot 利用 GPT 知识库中的信息,来回答用户的问题,提供帮助和建议,从而更好地满足用户的需求。
三、知识库构建
GPT的核心原理,就是基于大量的数据进行学习,然后根据用户提出的问题,将关联性最高的内容,组装成自然语言作为答案(当然实际的实现要复杂得多)。
GPT知识库的核心逻辑也是差不多:学习用户提供的文档,然后经过算法识别,得到文档内容的关联性。
当用户提供问题时,就可以根据关联性,获取对应的文档内容。然后组装成自然语言,返回给用户。
市面上比较出名的工具有 LangChain
、LlamaIndex
等,工具间各有优点,它们的核心功能都是:对大量语言相关的数据进行分析和处理,以提供最佳的搜索结果和答案。
下文均以LlamaIndex
为例。
3.1 demo
使用这些工具来构建知识库也相对简单,只需几行代码即可构建成功(前提是有OpenAI的账号)。
from llama_index import VectorStoreIndex
index = VectorStoreIndex.from_documents(
documents=documents
)
VectorStoreIndex
是LlamaIndex
提供的API,只需要将文档documents
(如何生成documents
在下文中介绍)传入,即可自动解析,根据默认的embedding算法,构建成一个有关联性的索引数据。
然后,将这些索引数据,转换为内置的搜索引擎,即可用自然语言进行问答。
query_engine = index.as_query_engine()
response = query_engine.query("武林第一是谁?")
print(response)
四、文档读取
在构建知识库时,需要将用户文档,转换为LlamaIndex
的参数documents
,LlamaIndex
提供了各式各样的文档读取器 Reader:Llama Hub
4.1 内置文档读取器
LlamaIndex
内置了许多文档读取器,可以读取不同格式的文件,如Markdown、PDF、Word、PPT、图片视频等。
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data").load_data()
4.2 Hive读取器
很多业务数据都存放在大数据仓库Hive中,LlamaIndex
也提供了HiveReader
快速读取数据:Hive Loader (llamahub.ai)。
但这个读取器,只能读取非安全的Hive,若Hive启用了Kerberos认证则会连接失败。
查看源码,很容易发现这个Reader只是对pyhive
的简单封装,没有适配Kerberos认证:
"""Initialize with parameters."""
try:
from pyhive import hive
except ImportError:
raise ImportError(
"`hive` package not found, please run `pip install pyhive`"
)
self.con = hive.Connection(
host=host,
port=port,
username=username,
database=database,
auth=auth,
password=password,
)
因此若Hive启用了Kerberos,则需要自定义实现:
from TCLIService.ttypes import TOperationState
from llama_index import (
Document,
)
from pyhive import hive
# 注意此处的配置可能根据你的 Hive 配置或集群细节而有所不同
conn = hive.Connection(
host=hive_server2_host,
port=10000,
auth='KERBEROS',
kerberos_service_name='hive',
database=hive_database
)
cursor = None
try:
# 创建游标
cursor = conn.cursor()
# 执行查询
cursor.execute(hive_query_sql)
# 以防查询是异步的,等待它完成
status = cursor.poll().operationState
while status in (TOperationState.INITIALIZED_STATE,
TOperationState.RUNNING_STATE):
status = cursor.poll().operationState
# 获取结果
rows = cursor.fetchall()
# 处理结果
documents = []
for row in rows:
document = Document(text=row.__str__())
documents.append(document)
logger.info(document)
finally:
# 无论是否遇到异常,始终关闭游标和连接
if cursor:
cursor.close()
conn.close()
这样将用户文档转换为LlamaIndex
的文档格式document
,即可快速构建成GPT知识库。
五、文档存储
通过以上示例可以看到,GPT知识库只保存在程序的内存中,退出程序就会被丢弃掉,下次再使用就需要重新构建。为了避免重复构建,需要将构建好的索引数据保存下来。
为了存储这些索引数据,业界一般会使用向量数据库
。
5.1 向量数据库
向量数据库与常规数据库的不同点,主要在于向量数据库是一种基于向量空间模型的数据库系统,它将数据存储为向量,并利用向量之间的相似度来进行查询和分类。在大模型模型训练中,可以提供更高效的数据存储及查询能力。
各大厂商都提供了自身的向量数据库,如阿里、腾讯、华为等。
以下以腾讯云VectorDB
为例。
5.2 上传数据
LlamaIndex
集成了腾讯云VectorDB
的SDK,二次封装功能接口,简化使用。
Tencent Cloud VectorDB - LlamaIndex
初始化连接:
import tcvectordb
vector_store = TencentVectorDB(
url="http://10.0.X.X",
key="eC4bLRy2va******************************",
collection_params=CollectionParams(dimension=1536, drop_exists=True),
)
注意:
drop_exists
默认为True
,即如果向量集合已存在,会先删除再重建。dimension
固定为1536
,因为LlamaIndex构建索引数据时,固定维度为1536。若不相同,在上传数据时会出现数据不兼容报错。
上传数据:
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context
)
这样,即可将构建好的索引数据,同步保存到腾讯云VectorDB。
5.3 复用数据
GPT查询腾讯云VectorDB,初始化连接时需要将drop_exists
参数设置为False
,并且去掉documents
即可。
import tcvectordb
vector_store = TencentVectorDB(
url="http://10.0.X.X",
key="eC4bLRy2va******************************",
collection_params=CollectionParams(dimension=1536, drop_exists=False),
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
storage_context=storage_context
)
到这里,GPT知识库基本构建成功。
接下来就是让GPT去查询索引数据,组装成自然语言,返回给用户。
待续。