• 基于检索增强的大语言模型


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 西门吹糖人 2024-05-21 20:10 采纳率: 42.1% 浏览 1 首页/ 人工智能 / 基于检索增强的大语言模型 人工智能自然语言处理 我想建立一个基于RAG的大型语言模型。我知道通常首先加载文档,然后将文档分块,向量化并存储在向量数据库中,最后检索向量数据库的内容。我现在不明白的是,文档在分块后存储在向量数据库中,所以检索的不是块的向量吗?怎么才能返回整个文档的向量呢? 我想要的最终的答案是基于检索到的块的原始文档信息来组合LLM,但不确定如何实现。另一件让我困惑的事情是,我想要做的事基于多个文档的,如果我检索这些块,我可能会得到多个来自于不同文档的分块。但其他组块不满足我提出的问题,请问如何处理这种情况? 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    4条回答 默认 最新

    • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-21 20:10
      关注

      引自免费微信小程序:皆我百晓生

      要构建一个基于检索增强的大型语言模型(例如RAG),你需要执行以下几个步骤:

      1. 文档预处理和分块:
        • 加载文档:将文本数据集加载到内存中。
        • 分块:将每个文档分割成较小的段落或句子。这可以按照固定长度(例如,每块256个单词)或按自然段落进行。
      import re
      
      def split_into_blocks(text, block_size):
          return [text[i:i+block_size] for i in range(0, len(text), block_size)]
      
      documents = [...]  # List of documents as strings
      block_size = 256
      blocks = []
      for doc in documents:
          blocks.extend(split_into_blocks(doc, block_size))
      
      1. 向量化:
        • 使用预训练的嵌入模型(如BERT、RoBERTa等)将文本块转换为向量表示。
        • 这里可以使用transformers库中的encode_plus方法。
      from transformers import BertTokenizerFast, BertModel
      
      tokenizer = BertTokenizerFast.from_pretrained('bert-base-uncased')
      model = BertModel.from_pretrained('bert-base-uncased')
      
      encoded_blocks = []
      for block in blocks:
          inputs = tokenizer.encode_plus(block, add_special_tokens=True)
          encoded_block = model(**inputs)[0].mean(dim=1)  # Mean pooling over tokens
          encoded_blocks.append(encoded_block)
      
      1. 存储向量数据库:
        • 将向量化后的块存储在一个可快速检索的数据结构中,如Faiss或Annoy。
      from annoy import AnnoyIndex
      
      index = AnnoyIndex(encoded_blocks[0].shape[0], 'euclidean')  # Choose an appropriate metric
      for i, vector in enumerate(encoded_blocks):
          index.add_item(i, vector.cpu().numpy())  # Assuming you're using PyTorch; use .numpy() for TensorFlow
      index.build(n_trees=10)  # Tune this parameter for better performance
      
      1. 检索与组合:
        • 当用户输入查询时,计算查询的向量表示,然后从向量数据库中找到最相关的文档块。
        • 对于每个匹配的文档块,提取其原始文本,并将其传递给大型语言模型(LLM,如GPT-3)进行解码和答案生成。
        • 可能会出现来自不同文档的块组合在一起的情况。为了处理这个问题,一种可能的方法是在组合时考虑块之间的语义连贯性,或者在生成答案时添加一些上下文提示。
      query = "Your question here"
      query_encoded = encode_query(query, tokenizer, model)
      
      # Perform retrieval from the index
      relevant_indices = index.get_nns_by_vector(query_encoded.cpu().numpy(), k=10)  # k is the number of top matches to retrieve
      
      # Retrieve original text and feed it into LLM
      retrieved_text = [blocks[i] for i in relevant_indices]
      llm_input = "Question: " + query + "\n" + "\n".join(retrieved_text)
      answer = generate_answer(llm_input, lmm_model)  # Replace with your LLM generation function
      

      注意:这里的代码片段仅作为示例,实际应用中可能需要根据具体需求进行调整。例如,编码和检索部分可能需要优化,以适应不同的模型和数据集规模。同时,generate_answer函数需要你自己实现,它应该调用一个预训练的语言模型(如Hugging Face Transformers中的GPT-3接口)来生成答案。如果你有多个文档来源,那么在检索阶段,确保你对每个来源都创建了一个独立的索引,以便正确地检索和组合结果。

      展开全部

      评论 编辑记录
    • 阿里嘎多学长 2024-05-21 20:10
      关注

      以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


      您想要解决的问题:您的目的在于构建一个基于检索增强(RAG)的大型语言模型(LLM),您希望理解如何从向量数据库中检索到文档的分块后,如何利用这些分块来组合并生成整个文档的向量表示,以及如何处理检索到的来自不同文档的分块,以确保它们能够满足您的问题需求。

      问题出现原因:这个问题出现的原因可能是您对RAG模型的工作原理理解不够深入,特别是关于如何从分块的文档中检索信息并整合这些信息以生成完整的文档向量表示。此外,您可能也对如何处理多个文档的分块以确保它们与问题相关性有疑问。

      问题解决方案:为了解决这个问题,您可以采取以下步骤:

      1. 文档分块与向量化:首先,将文档分块并为每个分块生成向量表示。这些向量随后存储在向量数据库中。

      2. 向量检索:当提出一个问题时,使用问题的向量表示在向量数据库中检索最相关的分块。

      3. 分块整合:检索到的分块需要被整合以生成整个文档的向量表示。这可以通过多种方式实现,例如通过取检索到的分块向量的加权平均,或者使用注意力机制来确定每个分块对整体文档表示的贡献。

      4. 处理多文档分块:如果检索到的分块来自不同的文档,您需要确定哪些分块对于回答当前问题最为相关。这可以通过进一步的相似度计算或使用机器学习方法来预测分块的相关性。

      5. 生成文档向量:一旦确定了最相关的分块,就可以使用上述方法之一来生成整个文档的向量表示。

      提供代码:由于这是一个相对高级的问题,涉及多个步骤和可能需要定制的解决方案,提供一个完整的代码示例可能不现实。然而,我可以提供一个简化的伪代码示例,以说明如何实现上述步骤:

      # 伪代码示例
      def retrieve_blocks(query_vector, vector_db):
          # 在向量数据库中检索与查询向量最相似的分块
          similar_blocks = vector_db.retrieve_similar_blocks(query_vector)
          return similar_blocks
      
      def integrate_blocks(retrieved_blocks):
          # 整合检索到的分块以生成文档向量
          document_vector = integrate_block_vectors(retrieved_blocks)
          return document_vector
      
      def answer_question(query, vector_db):
          query_vector = vectorize_query(query)
          relevant_blocks = retrieve_blocks(query_vector, vector_db)
          document_vector = integrate_blocks(relevant_blocks)
          # 使用文档向量来生成答案
          answer = generate_answer(document_vector)
          return answer
      
      # 运行环境和代码运行方式
      # 需要安装的库:numpy, faiss(或其他向量数据库库)
      # 运行方式:定义好向量数据库,输入问题,调用answer_question函数
      

      代码运行方式:您需要一个Python环境,安装了numpy和faiss(或其他向量数据库库)。您需要定义好向量数据库,输入问题,然后调用answer_question函数。

      代码预期运行结果:代码将返回一个基于检索到的文档分块生成的答案。

      推荐相关链接

      请注意,这些链接可能需要根据您的具体需求进行调整,并且需要进一步的学习和实验来实现一个完整的系统。

      展开全部

      评论 编辑记录
    • Kwan的解忧杂货铺 2024-05-21 20:10
      关注

      晚上好🌙🌙🌙
      本答案参考ChatGPT-3.5

      基于检索增强的大语言模型的实现可以采用Retrieve-and-Generate (RAG)模型。在建立大型语言模型之前需要进行以下步骤:

      1. 加载文档,分块并向量化,存储在向量数据库中。

      2. 采用向量检索技术从向量数据库中检索出和用户输入相关的块。

      3. 利用检索到的块的原始文档信息,组合起来形成一个整个文档的向量。

      针对上述问题,以下是具体的解决方案:

      1. 为了解决返回整个文档的向量的问题, 可以对分块的向量进行平均或加权平均等操作来得到整个文档的向量,如下所述:

        • 加权平均:根据块的重要性设置权重,对每个块的向量进行加权平均得到整个文档的向量;
        • 简单平均:对每个块的向量进行简单平均得到整个文档的向量。
      2. 为了解决检索到的块来自多个文档的问题,可以对每个块添加文档ID,并且在检索结果中根据文档ID对块进行分组,只选择来自同一文档的块。这个过程可以使用聚类算法或者分组算法来实现。

      3. 对于基于检索增强的大型语言模型,最终的解决方案是将检索到的块作为输入,生成RAG模型的输出序列,然后根据输出序列进行各种任务,比如文本摘要、答案生成等。

      下面是一个示例代码,演示如何对检索到的块进行加权平均,得到整个文档的向量:

      import numpy as np
      
      # 块向量和权重
      block_vectors = [np.array([0.1, 0.2, 0.3]), np.array([0.4, 0.5, 0.6])]
      weights = [0.7, 0.3]
      
      # 加权平均
      doc_vector = np.average(block_vectors, axis=0, weights=weights)
      
      评论
    • 专家-百锦再@新空间代码工作室 全栈领域优质创作者 2024-05-21 20:12
      关注

      # 代码示例# 这里提供一个简单的示例代码来说明如何使用自然语言处理来处理文档分块和向量化 
      # 加载文档document = "
      这是一个简单的文档示例,用于说明文档分块和向量化的过程。"

      # 分块文档chunks = [document[i:i+5] for i in range(0, len(document), 5)]
      # 向量化文档vector_db = {}for chunk in chunks:vector_db[chunk] = get_vector_representation(chunk)
      # 检索向量数据库query = "
      简单文档"
      query_vector = get_vector_representation(query)similar_chunks = []for chunk, vector in vector_db.items():similarity = calculate_similarity(query_vector, vector)if similarity >
      threshold:similar_chunks.append(chunk)
      # 组合LLMcombined_LLM = combine_LLM(similar_chunks)
      # 处理多文档情况# 如果检索到多个文档的分块,可以根据文档ID对分块进行分组# 然后根据分组的文档ID来组合LLM

      有问题你别着急,评论留言都可以,看到马上就回复,尽量及时补充齐
      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    ARP Cache Poisoning Attack Lab(SEED实验)
    go gin r.Any Query PostForm Param获取请求参数
    解决“error C267 ‘Beep_Led_yellow‘ requires ANSI-style prototype”错误方法
    如何画产品架构图?
    Linux下lsof命令使用
    pdf怎么转换成jpg图片?收藏这几种方法
    利用apache ftpserver搭建ftp服务器
    window安装ffmpeg播放本地摄像头视频
    识别户口本易语言代码
    剑指 Offer 53 - I. 在排序数组中查找数字 I
  • 原文地址:https://ask.csdn.net/questions/8107129