文章      动态     相关文章     最新文章     手机版动态     相关动态     |   首页|会员中心|保存桌面|手机浏览

nllvp

http://ww.kub2b.com/comnllvp/

相关列表
文章列表
  • 暂无文章
推荐文章
RAG(检索增强的生成式模型)项目的搭建
发布时间:2024-12-24        浏览次数:20        返回列表

1)LLM的知识不是实时的

2)LLM可能不知道你的私有领域/业务知识。

RAG(Retrieval Augmented Generation,通过检索的方式增强生成模型的能力。

类似于开卷考试,让LLM先翻书,再回答问题。同时可以减少LLM胡编乱造的情况。

3.1 项目需要达到的效果

上传本地知识,加载业务数据。

图中左侧是对话的结果,右侧是检索的结果。

3.2 文本关键字搜索的搭建过程

3.2.1 文档加载,并按一定条件切割成片段

安装pdf解析库

pip install pdfminer.six -i https://mirrors.aliyun.com/pypi/simple 

from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer


def extract_text_from_pdf(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()+'
'
    # 按空行分隔,将文本重新组织成段落
    lines = full_text.split('
')
    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 __name__ == "__main__":
    file = f"2404.16130v1.pdf"
    paragraphs = extract_text_from_pdf(file, [1, 2], min_line_length=20)
    for para in paragraphs[:3]:
        print(para)
3.2.2 将切割的文本片段灌入检索引擎

安装搜索引擎ES客户端

pip3 install elasticsearch7 -i https://mirrors.aliyun.com/pypi/simple 

安装NLTK 文本方法处理库

pip install nltk -i https://mirrors.aliyun.com/pypi/simple 

 

中文实现

 

将文本灌入搜索引擎

 
3.2.3 封装检索接口
 

其中,前三部是离线操作的,需要再系统上线前做好。

3.2.4 构建调用流程

query--> 检索-->prompt-->LLM-->回复

rag pipeline

 

3.2.5 关键字检索的局限性

同一个语义,用词不同,可以导致检索不到有效的信息。

 

3.3 向量检索

3.3.1 文本向量的表示
 

且OpenAI的向量模型是支持跨语言的。 

3.3.2 向量数据库

专门为向量检索做的中间件。

安装向量数据库中间件。

 
3.3.2.1 下面是将向量数据库建在内存中
from rag_test import paragraphs
from embedding import get_embeddings
import chromadb
from chromadb.config import Settings

# 此方法将向量数据库建在内存中
class MyVectorDBConector:
    def __init__(self, collection_name, embeddig_fn):
        chroma_client = chromadb.Client(Settings(allow_reset=True))
        # 为了演示,实际不需要每次reset
        chroma_client.reset()
        # 创建一个collection
        self.collection = chroma_client.get_or_create_collection(name=collection_name)
        self.embedding_fn = embeddig_fn   # 传入向量模型

    def add_document(self, documents, metadata={}):
        " 向collection中添加文档与向量 "
        self.collection.add(
            embeddings=self.embedding_fn(documents), # 每个文档的向量
            documents=documents, # 文档的原文
            ids=[f"id{i}" for i in range(len(documents))]
        )

    def search(self, query, top_n):
        ''' 检索向量数据库 '''
        results = self.collection.query(
            query_embeddings=self.embedding_fn([query]),
            n_results=top_n
        )
        return results


if __name__ == "__main__":
    # 创建一个向量数据库
    vector_db = MyVectorDBConector("demo", get_embeddings)
    # 向向量数据库总添加文档
    vector_db.add_document(paragraphs)
    user_query = "llama2有多少个参数"
    results = vector_db.search(user_query, 2)

    for para in results['documents'][0]:
        print(para + "
")
3.3.2.2 搭建向量数据库服务

在server端

chroma run --path /db_path

在client端

 
3.3.3 主流向量数据库对比
3.3.4 基于向量检索的RAG

搭建一个rag机器人

 

3.4 RAG系统性能提升

3.4.1 文本粒度

文本粒度太大->检索精度不准确,文本粒度太小->信息不全面,问题的答案可能跨越两个片段。

改进思路

1)按一定粒度,部分重叠式地切割文本,使上下文更加完整。

3.4.2 检索后排序

有时候最合适的答案不一定排在最前面

改进思路

1)检索时,过召回一部分文本

2)通过一个排序模型对query和document重新打分排序。

安装cross-encoder模块