Chroma向量数据库使用案例

​​​​​基于ChromaDB与BGEToward-VectorModel的本地私有化向量检索之路

安装基础环境

包括Python安装、pip安装及镜像设置等网上提供很多资料,这里就不介绍了。

  • 安装chromaDB环境安装
pip install chromadb
  • 安装pdf解析库
pip install pdfminer.six
  • 安装模型库
pip install sentence_transformers
  • 下载bge-large-zh-v1.5向量模型

如果能访问huggingface执行程序时自动下载,如果不能访问huggingface,请点击以下网盘链接进行下载:

链接:百度网盘 请输入提取码 提取码: fpej

手动下载模型需解压到项目工程目录,即与MyVectorDb.py在同一目录。

实践

在最后的环节,我们即将把理论化为实践。我们将用Python编写出一套基于chromadb向量数据库和bge-large-zh-v1.5向量模型实现本地向量检索的代码。

  • chromadb向量数据部分代码示例

引用

import chromadb
from chromadb.config import Settings

创建数据库对象

chroma_client = chromadb.Client(Settings(allow_reset=True))

创建一个 collection,即创建一个名为“demo”的数据库

collection = chroma_client.get_or_create_collection(name="demo")

向 collection 中添加文档与向量

collection.add(
    embeddings= embedding_fn(documents),  # 每个文档的向量,这里调用了向量模型,将文档转化成向量
    documents=documents,  # 文档的原文
    ids=[f"id{i}" for i in range(len(documents))]  # 每个文档的 id
)

检索向量数据库

collection.query(
     query_embeddings=embedding_fn([query]), # 检索内容的向量,这里调用了向量模型,将文档转化成向量
     n_results=top_n
 )
  • beg模型代码示例

引入

from sentence_transformers import SentenceTransformer

创建模型

model = SentenceTransformer('BAAI/bge-large-zh-v1.5')

内容向量化embedding_fn

doc_vecs = [
    model.encode(doc, normalize_embeddings=True).tolist()
    for doc in documents
]

完整源码:

import chromadb
from chromadb.config import Settings
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer
from sentence_transformers import SentenceTransformer
 
class MyVectorDB:
    '''
    私有化向量数据库
    \n作者:George
    \n时间:2024年3月7日
    '''
 
 
    def __init__(self, collection_name):
        chroma_client = chromadb.Client(Settings(allow_reset=True))
        model = SentenceTransformer('BAAI/bge-large-zh-v1.5')
 
        # 为了演示,实际不需要每次 reset()
        chroma_client.reset()
 
        # 创建一个 collection
        self.collection = chroma_client.get_or_create_collection(name=collection_name)
        self.bge_model = model
    
 
    def add_documents(self, filename, page_numbers=None, min_line_length=1, metadata={}):
        paragraphs = self.extract_text_from_pdf(filename, page_numbers, min_line_length)
        '''向 collection 中添加文档与向量'''
        self.collection.add(
            embeddings=self.embedding_fn(paragraphs),  # 每个文档的向量
            documents=paragraphs,  # 文档的原文
            ids=[f"id{i}" for i in range(len(paragraphs))]  # 每个文档的 id
        )
 
    def search(self, query, top_n):
        '''检索向量数据库'''
        results = self.collection.query(
            query_embeddings=self.embedding_fn([query]),
            n_results=top_n
        )
        return results
     
    def embedding_fn(self, paragraphs):
        '''文本向量化'''
        doc_vecs = [
            self.bge_model.encode(doc, normalize_embeddings=True).tolist()
            for doc in paragraphs
        ]
        return doc_vecs
     
    def extract_text_from_pdf(self, filename, page_numbers=None, min_line_length=1):
        '''从 PDF 文件中(按指定页码)提取文字'''
        paragraphs = []
        buffer = ''
        full_text = ''
        # 提取全部文本
        for i, page_layout in enumerate(extract_pages(filename)):
            # 如果指定了页码范围,跳过范围外的页
            if page_numbers is not None and i not in page_numbers:
                continue
            for element in page_layout:
                if isinstance(element, LTTextContainer):
                    full_text += element.get_text() + '\n'
        # 按空行分隔,将文本重新组织成段落
        lines = full_text.split('\n')
        for text in lines:
            if len(text) >= min_line_length:
                buffer += (' '+text) if not text.endswith('-') else text.strip('-')
            elif buffer:
                paragraphs.append(buffer)
                buffer = ''
        if buffer:
            paragraphs.append(buffer)
        return paragraphs
     
 
if "__main__" == __name__:
    # 创建一个向量数据库对象
    vector_db = MyVectorDB("demo")
    # 向向量数据库中添加文档
    vector_db.add_documents("llama2.pdf", page_numbers=[
                                    2, 3], min_line_length=10)
 
    user_query = "Llama 2有多少参数"
    results = vector_db.search(user_query, 2)
 
    for para in results['documents'][0]:
        print(para+"\n") 

 总结:

这只是一个简单的演示样例,方便大家进一步理解和操作Chroma数据库,也希望大家一起进步,有问题也可以评论相互学习!

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值