LazyLLM 教程 | 第 12 讲:实践:用缓存、异步与向量引擎加速你的 RAG

环境准备及基础组件定义

如果您的电脑上安装了 Python,请通过下方命令安装 lazyllm 及必要的依赖包。关于 LazyLLM 的环境更详细的准备可以参考第二讲中对应的内容。

pip install lazyllm

成功安装 LazyLLM 后,我们进行如下组件的定义:大模型 llm、向量模型 embedding_model、重排模型 rerank_model,这些组件在下面的实践过程当中会经常用到,该部分预先定义后,后面将不再重复定义。

对于 GPU 资源较紧张的开发者,推荐您全程使用线上模型,以快速上手开发,降低使用门槛。线上模型的创建如下

(https://github.com/LazyAGI/Tutorial/blob/282ffb74e3fe7c5c28df4ad498ed972973dfbc62/rag/codes/chapter12/online_models.py#L31):

from lazyllm import OnlineChatModule, OnlineEmbeddingModule

DOUBAO_API_KEY = ""
DEEPSEEK_API_KEY = ""
QWEN_API_KEY = ""

#线上大模型,此处使用DeepSeek-V3
llm = OnlineChatModule(
    source="deepseek",
    api_key=DEEPSEEK_API_KEY,
)

#向量模型,此处选用豆包向量模型
embedding_model = OnlineEmbeddingModule(
    source="doubao",
    embed_model_name="doubao-embedding-large-text-240915",
    api_key=DOUBAO_API_KEY,
)

#重排模型,线上的重排模型仅支持千问和智谱,这里使用千问重排模型
rerank_model = OnlineEmbeddingModule(
    source="qwen",
    api_key=QWEN_API_KEY,
    type="rerank"
)

对于一些期望使用远程连接方式连接向量模型,但 LazyLLM 内部没有支持的开发者,可以采用先前介绍的继承方式,实现两个方法后创建自定义的 OnlineEmbeddingModule(https://github.com/LazyAGI/Tutorial/blob/282ffb74e3fe7c5c28df4ad498ed972973dfbc62/rag/codes/chapter12/online_models.py#L8):

from typing import Dict, List, Union
from lazyllm.module import OnlineEmbeddingModuleBase


class CustomOnlineEmbeddingModule(OnlineEmbeddingModuleBase):
    """CustomOnlineEmbeddingModule"""

    def __init__(
            self,
            embed_url,
            embed_model_name,
            api_key,
            model_series):
        super().__init__(
            embed_url=embed_url, embed_model_name=embed_model_name, api_key=api_key, model_series=model_series
        )
    
    #实现request data封装方法
    def _encapsulated_data(self, text: str, **kwargs) -> Dict[str, str]:
        json_data = {"inputs": text, "model": self._embed_model_name}
        if len(kwargs) > 0:
            json_data.update(kwargs)

        return json_data
    
    #实现response解析方法
    def _parse_response(self, response: Union[List[List[str]], Dict]) -> Union[List[List[str]], Dict]:
        return response


# 传入正确的url和模型信息即可,以下是使用远程的bge-m3模型
embedding_model = CustomOnlineEmbeddingModule(
    embed_url="",
    embed_model_name="BAAI/bge-m3",
    api_key="",
    model_series="bge"
)

针对 GPU 资源相对充足,或者对模型效率或并发要求较高的场景,推荐使用 LazyLLM 内置的 TrainableModule 实现模型的本地部署:

from lazyllm import TrainableModule, pipeline

llm = TrainableModule('internlm2-chat-20b', stream=True)
embedding_model = TrainableModule("bge-large-zh-v1.5")
rerank_model = TrainableModule("bge-reranker-large")

pipeline(llm, embedding_model, rerank_model).start()

使用向量数据库实现知识库持久化存储

向量数据库是一种专门用于存储、管理和检索高维向量数据的数据库系统,广泛应用于搜索引擎、推荐系统、计算机视觉和自然语言处理等领域。与传统的关系型数据库不同,向量数据库能够高效存储高维向量,并采用相似度检索和优化索引技术,大幅提升大规模向量搜索的效率,是目前 AI 应用重要的数据存储和检索工具。

LazyLLM 原生支持 ChromaDB 和 Milvus 两种开源向量数据库,提供了开箱即用的向量存储和检索支持。在实际的使用过程中,用户只需要在 Document 定义阶段配置 store_conf 参数,进行简单的存储和检索配置,即可利用这两种数据库将文档处理后的数据存储于本地,并在下次系统启动时直接从本地加载这些数据,避免文档的重复入库,实现知识库持久化存储。使用 store_conf 配置 Document 存储的实现方式如下:

document = lazyllm.Document(dataset_path='/path/to/your/document',
           embed=lazyllm.OnlineEmbeddingModule(),
           ...,
           store_conf=store_conf)

参数 store_conf 接收字典形式的存储配置,配置时需要传入 type 和 kwargs 参数,具体字段解释如下:

  • type:使用存储类型。如之前介绍,LazyLLM 目前支持的存储类型有 map(基于内存)、chroma(基于 ChromaDB 向量数据库)以及 milvus(基于 Milvus 向量数据库):

    ⚒️map:仅使用内存 key/value 存储暂存所有文档处理数据,系统重启后数据消失;

    ⚒️chroma:使用 ChromaDB 存储数据,ChromaDB 是一个更轻量的向量数据库,相比于 Milvus 能处理的数据量级有限,适合调试,更多 ChromoDB 相关信息可以参考 ChromaDB 官方文档;

    ⚒️milvus:使用 Milvus 存储数据,支持海量数据的检索和存储,支持分布式部署,更适合生产级应用,更多 Milvus 相关信息可以参考 Milvus 官方文档;

  • kwargs:具体存储所需的额外配置参数,同样以字典的形式输入。

 type 为 chroma 时,所需配置参数为:

  • dir(必填):存储数据的目录;

当 type 为 milvus 时,所需配置参数为:

  • uri(必填):存储数据地址,可以是一个文件路径或者远程连接的 url

  • index_kwargs(可选):Milvus 数据库的索引配置,可以是一个 dict 或者 list [dict],索引配置主要包含两个字段:索引类型 index_type 和度量类型 metric_type(即 Index 和 Similarity,和 LazyLLM 的定义很像)。参数如果是一个 dict 表示所有向量模型使用相同配置;如果需要指定不同的向量模型以不同索引配置,则可以以列表的方式传入,由 embed_key 指定所使用配置即可。当前只支持 floating point embedding 和 sparse embedding 两种 embedding 类型,分别支持的参数如下,感兴趣的开发者可以前往官网查看:

    ⚒️floating point embedding

    (https://milvus.io/docs/zh/index-vector-fields.md?tab=floating)

    ⚒️sparse embedding

    (https://milvus.io/docs/zh/index-vector-fields.md?tab=sparse)

实践一. 使用向量数据库实现持久化存储

1. 系统启动性能对比

本部分在其余模块不变的情况下,分别使用内存、ChromaDB 和 Milvus 作为数据存储。分别测试三者首次启动和二次启动耗时,以展示持久化存储对于系统二次启动效率的提升。文件目录中包含 pdf、docx、txt 格式的文件,按照句子分块后共计 1614 个节点。

内存存储

由于 LazyLLM 默认使用内存作为存储类型,故开发者无需进行额外配置即可定义一个使用内存存储的 Document:

document = lazyllm.Document(
    dataset_path='/path/to/your/document',
    embed=embedding_model
)

ChromaDB

ChromaDB 以易用性、高性能和紧密集成 AI 应用为主要特点,适用于需要快速部署和轻量级管理的应用场景,如聊天机器人、个性化推荐、搜索引擎等。由于 ChromaDB 基于 sqlite3 实现了持久化存储,因此不支持分布式部署,适用于小型本地应用。在中使用 LazyLLM 的 ChromaDB 需要在 store_conf 中配置如下字段:

chroma_store_conf = {
  'type': 'chroma', 
  'kwargs': {
    'dir': 'dbs/test_chroma', # chromadb传入的 dir 是一个文件夹,不存在会自动创建
   }
}

document = lazyllm.Document(
    dataset_path='/path/to/your/document',
    embed=embedding_model,
    store_conf=chroma_store_conf
)

Milvus

Milvus 作为专为高性能向量检索设计的开源向量数据库,能够高效处理万亿级别的向量索引。与 ChromaDB 相比,Milvus 除了可以提供向量存储,还提供了高速检索接口,可以基于多种索引方式实现向量的高效检索。使用 Milvus 作为存储后端,需要传入如下配置:

milvus_store_conf = {
  'type': 'milvus',  # 指定存储后端类型
  'kwargs': {
    'uri': 'test.db',  # 存储后端地址,本例子使用的是本地文件 test.db,文件不存则创建新文件
    'index_kwargs': {  # 存储后端的索引配置
      'index_type': 'FLAT',  # 索引类型
      'metric_type': 'COSINE',  # 相似度计算方式
    }
  },
}

document = lazyllm.Document(
    dataset_path='/path/to/your/document',
    embed=embedding_model,
    store_conf=milvus_store_conf 
)

🚨注意:目前 LazyLLM 支持 Milvus 2.4.x,请注意您的 pymilvus >= 2.4.11 , milvus-lite == 2.4.10。使用 Milvus 时,检索会根据输入配置中的索引配置进行对应算法检索,Retriever 中无需指定 similarity 参数。

为了进行快速对比,编写以下测试脚本,以实现三种存储的性能测试

(https://github.com/LazyAGI/Tutorial/blob/282ffb74e3fe7c5c28df4ad498ed972973dfbc62/rag/codes/chapter12/use_diffierent_vector_store.py#L1):

import os
import time

import lazyllm
from lazyllm import LOG

from online_models import embedding_model    # 使用线上模型

DOC_PATH = os.path.abspath("docs")    # 实践文档总目录

def test_store(store_conf: dict=None):
    """接收存储配置,测试不同配置下系统启动性能"""
    st1 = time.time()
    dataset_path = os.path.join(DOC_PATH, "test")   # 文档所在路径

    docs = lazyllm.Document(
        dataset_path=dataset_path,
        embed=embedding_model,  # 设置嵌入模型
        store_conf=store_conf   # 设置存储配置
    )
    docs.create_node_group(name='sentence', parent="MediumChunk", transform=lambda x: x.split('。'))    # 创建节点组
    
    if store_conf and store_conf.get('type') == "milvus":
        # 存储类型为milvus时,无需similarity参数
        retriever1 = lazyllm.Retriever(docs, group_name="sentence", topk=3)
    else:
        # similariy=cosine,以使用向量检索
        retriever1 = lazyllm.Retriever(docs, group_name="sentence", similarity='cosine', topk=3)
    
    retriever1.start()  # 启动检索器
    et1 = time.time()

    # 测试单次检索耗时
    st2 = time.time()
    res = retriever1("牛车水")
    et2 = time.time()
    nodes = "\n======\n".join([node.text for node in res])  # 输出检索结果
    msg = f"Init time: {et1 - st1}, retrieval time: {et2 - st2}s\n" # 输出系统耗时
    LOG.info(msg)
    LOG.info(nodes)
    return msg

def test_stable_store():
    """一次测试多个存储配置"""
    chroma_store_conf = {
        'type': 'chroma', 
        'kwargs': {
            'dir': 'dbs/chroma1',
        }
    }

    milvus_store_conf = {
        'type': 'milvus',
        'kwargs': {
            'uri': 'dbs/milvus1.db',
            'index_kwargs': {
            'index_type': 'HNSW',
            'metric_type': 'COSINE',
            }
        },
    }

    test_conf = {
        "map": None,
        "chroma": chroma_store_conf,
        "milvus": milvus_store_conf
    }
    start_times = ""
    for store_type, store_conf in test_conf.items():
        LOG.info(f"Store type: {store_type}")
        res = test_store(store_conf=store_conf)
        start_times += res
    print(start_times)

test_stable_store()

运行结果如下:

根据耗时数据我们可以看到,由于系统多次运行程序时存在性能误差,使用两种向量数据库实现数据持久化存储对于系统启动性能均有不同程度的性能提升。在第一次启动时,三种存储类型的系统初始化时间相差不大,均在 16~17s,而在系统二次启动时,初始化时间便拉开了差距。其中,使用 ChromaDB 对于系统启动效率的提升幅度较小,节省时间约 21%,使用 Milvus 则对系统二次启动性能有较大的提升,启动时间节省约 87.36%。由此可见,使用存储后端可以在系统二次启动时节省时间,且使用持久化存储后,系统便无需重新执行文档分块和文档嵌入,从而节约一定的算力资源。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值