文档

大模型RAG对话系统

更新时间:

EAS提供了场景化部署方式,通过简单配置几个参数,您便可以一键部署集成了大语言模型(LLM)和检索增强生成(RAG)技术的对话系统服务,显著缩短服务部署时间。在使用该服务进行推理验证时,它能够有效地从知识库中检索相关信息,并与大语言模型的回答相结合,以产生准确且信息丰富的答案,从而大幅提高问答的质量和整体性能。该服务适用于问答、摘要生成和依赖外部知识的自然语言处理任务。本文为您介绍如何部署RAG对话系统服务以及如何进行模型推理验证。

背景信息

大语言模型(LLM)在生成准确性和实时性回复方面存在局限,因此并不适合直接用于需要精确信息的客服或问答等场景。为了解决这一问题,当前业界广泛采用的方法是利用检索增强生成(Retrieval-Augmented Generation, RAG)技术来增强LLM的性能,这一技术可以显著提升问答、摘要生成以及其他需要引用外部知识的自然语言处理(NLP)任务的质量。

RAG通过将大语言模型(如通义千问)和信息检索组件结合在一起,增强了模型生成答案的准确性和信息量。在处理用户查询时,RAG通过信息检索组件在知识库中寻找与查询相关的文档或信息片段,将这些检索到的内容与原始查询一同输入大语言模型之后,模型能够利用现有的归纳生成能力产生基于最新信息的、符合事实的回复,而无需对模型进行重新训练。

EAS部署的对话系统服务,通过集成大语言模型(LLM)和检索增强生成(RAG)技术,克服了LLM在准确性和实时性方面的局限,为多种问答场景提供了准确且信息丰富的响应,从而提升了自然语言处理任务的整体效能和用户体验。

前提条件

  • 已创建一个专有网络(VPC)、交换机和安全组。详情请参见创建和管理专有网络创建安全组

    说明

    使用Faiss作为向量检索库时,不需要创建VPC、交换机和安全组。

  • 当使用微调模型部署服务时,您需要准备OSS存储空间(Bucket)或NAS文件系统,用来存放微调的模型文件。具体操作,请参见控制台快速入门创建文件系统

    说明

    使用Faiss作为向量检索库时,需要准备OSS存储空间(Bucket)。

使用限制

向量检索库和EAS必须在相同地域下。

注意事项

本实践受制于LLM服务的最大Token数量限制,旨在帮助您体验RAG对话系统的基本检索功能:

  • 该对话系统受制于LLM服务的服务器资源大小以及默认Token数量限制,能支持的对话长度有限。

  • 如果无需进行多轮对话,建议您关闭RAG服务的with chat history功能,这样能有效减少达到限制的可能性。详情请参见如何关闭RAG服务的with chat history功能

步骤一:准备向量检索库

RAG支持通过Faiss(Facebook AI Similarity Search)ElasticsearchMilvusHologres构建向量检索库。您需要获取相关配置参数,以便后续连接向量检索库。

Faiss

使用Faiss构建本地向量库,无需购买线上向量库产品,免去了线上开通向量库产品的复杂流程,更轻量易用。

ElasticSearch

  1. 创建阿里云Elasticsearch实例。具体操作,请参见创建阿里云Elasticsearch实例

    其中:

    • 实例类型选择通用商业版

    • 场景初始化配置选择通用场景

    • 您需要将配置的登录名登录密码保存到本地。

  2. 单击实例名称,进入实例基本信息页面。在该页面获取私网地址私网端口并保存到本地。

Milvus

  1. 创建Milvus实例,并配置公网访问。具体操作请参见快速创建Milvus实例网络访问与安全设置

    您需要将设置的root用户密码保存到本地。

  2. 在Milvus实例详情页面,查看内网地址和Proxy Port,并保存到本地。

    1. 单击实例名称,进入实例详情页面。

    2. 访问地址区域,分别单击内网地址Proxy Port后的复制按钮,将内网地址和端口号保存到本地。

Hologres

  1. 开通Hologres实例并创建数据库。具体操作,请参见购买Hologres创建数据库。您需要将已创建的数据库名称保存到本地。

  2. 在实例详情页面查看调用信息。

    1. 单击实例名称,进入实例详情页面。

    2. 网络信息区域,单击指定VPC后的复制,将域名:80前面的内容保存到本地。

  3. 切换到账号管理Tab页,创建自定义用户。并将账号和密码保存到本地,后续用于连接Hologres实例。具体操作,请参见创建自定义用户

    其中:选择成员角色选择实例超级管理员(SuperUser)

步骤二:部署RAG服务

  1. 进入模型在线服务页面。

    1. 登录PAI控制台

    2. 在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。

    3. 在工作空间页面的左侧导航栏选择模型部署>模型在线服务(EAS),进入模型在线服务(EAS)页面。image

  2. 模型在线服务页面,单击部署服务,在场景化模型部署区域,单击大模型RAG对话系统部署6eea7736f88e6ec8b3b900e4d028bb48

  3. 部署大模型RAG对话系统页面,配置以下关键参数。

    • 基本信息

      参数

      描述

      服务名称

      自定义服务名称。

      模型来源

      支持使用开源公共模型自持微调模型

      模型类别

      根据您的使用场景,选择模型类型。

      使用自持微调模型时,您需配置相应模型的参数量和精度。

      模型配置

      使用自持微调模型时,您需配置微调模型的文件路径。支持以下两种配置方法:

      说明

      确保使用的模型文件格式与HuggingFace Transformers兼容。

      • 按对象存储(OSS):请选择微调模型文件所在的OSS路径。

      • 按文件存储(NAS):请选择微调模型文件所在的NAS文件系统和NAS源路径。

    • 资源配置

      参数

      描述

      资源配置选择

      • 当使用开源公共模型时,系统会根据选定的模型类别自动推荐适合的实例规格,默认选中。

      • 当使用自持微调模型时,请选择与目标模型相匹配的实例规格,详情请参见如何切换其他的开源大模型

      推理加速

      目前,部署在A10或GU30系列机型上的Qwen、Llama2、ChatGLM或Baichuan2等系列模型服务,支持启用推理加速功能。支持以下两种加速类型:

      • PAI-BladeLLM自动推理加速:BladeLLM提供超高性价比的大模型推理加速能力,可帮助您一键享受高并发和低延时的技术优势。

      • 开源框架vllm推理加速

    • 向量检索库设置

      根据您的场景需要,任意选择一种版本类型,作为向量检索库。

      FAISS

      参数

      描述

      版本类型

      选择FAISS

      OSS地址

      选择当前地域下已创建的OSS存储路径。如果没有可选的存储路径,您可以参考控制台快速入门进行创建。

      ElasticSearch

      参数

      描述

      版本类型

      选择Elasticsearch

      私网地址/端口

      配置为步骤一中获取的私网地址和端口,格式为:http://私网地址:端口

      索引名称

      输入新的索引名称或已存在的索引名称。对于已存在的索引名称,索引结构应符合PAI-RAG要求,例如可以填写之前通过EAS部署RAG服务时自动创建的索引。

      账号

      配置为步骤一中创建Elasticsearch实例时配置的登录名。

      密码

      配置为步骤一中创建Elasticsearch实例时配置的登录密码。

      Milvus

      参数

      描述

      版本类型

      选择Milvus

      访问地址

      配置为步骤一中查询到的内网地址。

      代理端口

      配置为步骤一中查询到的Proxy Port。

      账号

      配置为root。

      密码

      配置为创建Milvus实例时,您自定义的root用户的密码。

      数据库名称

      配置为已创建的数据库名称,例如default。

      Collection名称

      输入新的Collection名称或已存在的Collection名称。对于已存在的Collection,Collection结构应符合PAI-RAG要求,例如可以填写之前通过EAS部署RAG服务时自动创建的Collection。

      Hologres

      参数

      描述

      版本类型

      选择Hologres

      调用信息

      配置为步骤一中查询到的Hologres调用信息。

      数据库名称

      配置为步骤一中创建的数据库名称。

      账号

      配置为步骤一中创建的自定义用户的账号。

      密码

      配置为步骤一中创建的自定义用户的密码。

      表名称

      输入新的表名称或已存在的表名称。对于已存在的表名称,表结构应符合PAI-RAG要求,例如可以填写之前通过EAS部署RAG服务自动创建的Hologres表。

    • 专有网络配置

      参数

      描述

      VPC

      • 当选择Hologres、ElasticSearch或Milvus作为向量检索库时,请确保所配置的专有网络与选定的向量检索库保持一致。

      • 当选择Faiss作为向量检索库时,无需配置专有网络。

      交换机

      安全组名称

  4. 单击部署

    服务状态变为运行中时,表示服务部署成功。

步骤三:通过WebUI页面进行模型推理验证

您可以先在WebUI页面,参考以下操作步骤对服务进行调试。当您在WebUI页面调试好问答效果后,可以基于PAI提供的API将其应用到您自己的业务系统中,详情请参见步骤四:通过API调用进行模型推理验证

1、配置RAG对话系统

  1. RAG服务部署成功后,单击服务方式列下的查看Web应用,启动WebUI页面。

  2. 配置机器学习模型。

    • Embedding Model Name:系统内置四种模型供您选择,将自动为您配置最合适的模型。

    • Embedding Dimension:选择Embedding Model Name后,系统会自动进行配置,无需手动操作。

  3. 测试向量检索库连接是否正常。

    系统已自动识别并应用了部署服务时配置的向量检索库设置,并且该设置不支持修改。以Hologres为例,您可以单击Connect Hologres,来验证Hologres连接是否正常。

2、上传指定的业务数据文件

Upload页签中,上传指定的业务数据文件,类型为.txt、.pdf、Excel(.xlsx或.xls)、.csv、Word(.docx或.doc)、Markdown或.html。

image

  1. 设置语义切块参数。

    通过配置以下参数来控制文档切块粒度的大小和进行QA信息提取:

    参数

    描述

    Chunk Size

    指定每个分块的大小,单位为字节,默认为500。

    Chunk Overlap

    表示相邻分块之间的重叠量,默认为10。

    Process with QA Extraction Model

    通过选中Yes复选框启动QA信息提取功能,系统将在您上传业务数据文件后自动抽取出QA对,以获得更好的检索和回答效果。

  2. FilesDirectory页签下上传业务数据文件(支持多文件上传)或对应目录。例如rag_chatbot_test_doc.txt

  3. 单击Upload,系统会先对上传的文件进行数据清洗(文本提取、超链接替换等)和语义切块,然后进行上传。image

3、配置模型推理参数

配置Retrieval问答策略

Chat页签中,配置Retrieval问答策略。

image

参数

说明

Streaming Output

选中Streaming Output后,系统将以流式方式输出结果。

Top K

向量检索库返回的相似结果数,即从向量数据库中召回Top K条相似结果。

Re-Rank Model

大多数向量数据库为了计算效率会牺牲一定程度的准确性,这使其检索结果存在一定随机性,原始返回的Top K不一定最相关。您可以选择开源模型BAAI/bge-reranker-baseBAAI/bge-reranker-largellm-reranker,对向量数据库第一次召回的Top K结果进行精度更高的Re-Rank操作,以得到相关度更高、更准确的知识文档。

说明

首次使用时,加载模型可能需要较长时间,请根据需要进行选择。

Keyword Model

支持以下三种检索方式:

  • Embedding Only:向量数据库检索召回。

  • Keyword Only:关键词检索召回。

  • Hybrid:向量数据库和关键词检索多路召回融合。

说明

在大多数复杂场景下,向量数据库检索召回都能有较好的表现。但在某些语料稀缺的垂直领域,或要求准确匹配的场景,向量数据库检索召回方法可能不如传统的稀疏检索召回方法。稀疏检索召回方法通过计算用户查询与知识文档的关键词重叠度来进行检索,因此更为简单和高效。

PAI提供了BM25等关键词检索召回算法来完成稀疏检索召回操作。向量数据库检索召回和关键词检索召回具有各自的优势和不足,因此综合二者的召回结果能够提高整体的检索准确性和效率。倒数排序融合(Reciprocal Rank Fusion, RRF)算法通过对每个文档在不同召回方法中的排名进行加权求和,以此计算融合后的总分数。当Retrieval选择Hybrid时,PAI将默认使用RRF算法对向量数据库召回结果和关键词检索召回结果进行多路召回融合。

配置RAG(Retrieval + LLM)问答策略

Chat页签中,配置RAG(Retrieval + LLM)问答策略。2f946624a50449a379a901b6a8bf716d

  • PAI提供多种不同的Prompt策略,您可以选择合适的预定义Prompt模板或输入自定义的Prompt模板以获得更好的推理效果。

  • 此外RAG(Retrieval + LLM)问答方式还支持配置Streaming Output、Re-Rank Model和Keyword Model,关于这些参数的配置说明,请参见配置Retrieval问答策略

4、模型推理验证

Retrieval

直接从向量数据库中检索并返回Top K条相似结果。

image

LLM

直接与EAS-LLM对话,返回大模型的回答。

image

RAG(Retrieval + LLM)

将检索返回的结果与用户的问题输入至已选择的Prompt模板中,送入EAS-LLM服务,从中获取问答结果。

image

步骤四:通过API调用进行模型推理验证

  1. 获取RAG服务的调用信息。

    1. 单击RAG服务名称,进入服务详情页面。

    2. 基本信息区域,单击查看调用信息

    3. 调用信息对话框的公网地址调用页签,获取服务访问地址和Token。

  2. 通过WebUI页面连接向量数据库,并上传业务数据文件。具体操作,请参见1、配置RAG对话系统2、上传指定的业务数据文件

  3. 通过API调用服务。

    PAI提供了三种调用API的对话方式:service/query/retrieval(Retrieval)service/query/llm(LLM)和service/query(RAG)。具体调用方法如下:

    curl 命令

    • 发送单轮对话请求

      • 方式一:service/query/retrieval(Retrieval)

        curl -X 'POST'  '<service_url>service/query/retrieval' -H 'Authorization: <service_token>' -H 'accept: application/json' -H 'Content-Type: application/json'  -d '{"question": "什么是人工智能平台PAI?"}'
        # <service_url>替换为步骤1获取的服务访问地址;<service_token>替换为步骤1获取的服务Token。
      • 方式二:/service/query/llm(LLM)

        curl -X 'POST'  '<service_url>service/query/llm' -H 'Authorization: <service_token>' -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{"question": "什么是人工智能平台PAI?"}'
        # <service_url>替换为步骤1获取的服务访问地址;<service_token>替换为步骤1获取的服务Token。

        支持添加其他可调推理参数,例如{"question":"什么是人工智能平台PAI?", "temperature": 0.9}

      • 方式三:service/query(RAG)

        curl -X 'POST'  '<service_url>service/query' -H 'Authorization: <service_token>' -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{"question": "什么是人工智能平台PAI?"}'
        # <service_url>替换为步骤1获取的服务访问地址;<service_token>替换为步骤1获取的服务Token。

        支持添加其他可调推理参数,例如{"question":"什么是人工智能平台PAI?", "temperature": 0.9}

    • 发送多轮对话请求

      其中对话方式RAG和LLM支持发送多轮对话请求,以RAG对话为例,具体配置方法如下:

      # 发送请求。 
      curl -X 'POST'  '<service_url>service/query' -H 'Authorization: <service_token>' -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{"question": "什么是人工智能平台PAI?"}'
      
      # 传入上述请求返回的session_id(对话历史会话唯一标识),传入session_id后,将对话历史进行记录,调用大模型将自动携带存储的对话历史。
      curl -X 'POST'  '<service_url>service/query' -H 'Authorization: <service_token>' -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{"question": "它有什么优势?","session_id": "ed7a80e2e20442eab****"}'
      
      # 传入chat_history(用户与模型的对话历史),list中的每个元素是形式为{"user":"用户输入","bot":"模型输出"}的一轮对话,多轮对话按时间顺序排列。
      curl -X 'POST'  '<service_url>service/query' -H 'Authorization: <service_token>' -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{"question":"它有哪些功能?", "chat_history": [{"user":"PAI是什么?", "bot":"PAI是阿里云的人工智能平台......"}]}'
      
      # 同时传入session_id和chat_history,会用chat_history对存储的session_id所对应的对话历史进行追加更新。 
      curl -X 'POST'  '<service_url>service/query' -H 'Authorization: <service_token>' -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{"question":"它有哪些功能?", "chat_history": [{"user":"PAI是什么?", "bot":"PAI是阿里云的人工智能平台......"}], "session_id": "1702ffxxad3xxx6fxxx97daf7c"}'

    Python脚本

    • 发送单轮对话请求,代码示例如下:

      import requests
      
      EAS_URL = 'http://xxxx.****.cn-beijing.pai-eas.aliyuncs.com'
      headers = {
          'accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': 'MDA5NmJkNzkyMGM1Zj****YzM4M2YwMDUzZTdiZmI5YzljYjZmNA==',
      }
      
      
      def test_post_api_query_llm():
          url = EAS_URL + '/service/query/llm'
          data = {
             "question":"什么是人工智能平台PAI?"
          }
          response = requests.post(url, headers=headers, json=data)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans = dict(response.json())
          print(f"======= Question =======\n {data['question']}")
          print(f"======= Answer =======\n {ans['answer']} \n\n")
      
      
      def test_post_api_query_retrieval():
          url = EAS_URL + '/service/query/retrieval'
          data = {
             "question":"什么是人工智能平台PAI?"
          }
          response = requests.post(url, headers=headers, json=data)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans = dict(response.json())
          print(f"======= Question =======\n {data['question']}")
          print(f"======= Answer =======\n {ans['docs']}\n\n")
      
      
      def test_post_api_query_rag():
          url = EAS_URL + '/service/query'
          data = {
             "question":"什么是人工智能平台PAI?"
          }
          response = requests.post(url, headers=headers, json=data)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans = dict(response.json())
          print(f"======= Question =======\n {data['question']}")
          print(f"======= Answer =======\n {ans['answer']}")
          print(f"======= Retrieved Docs =======\n {ans['docs']}\n\n")
      # LLM
      test_post_api_query_llm()
      # Retrieval
      test_post_api_query_retrieval()
      # RAG(Retrieval+LLM)
      test_post_api_query_rag()
      

      其中:EAS_URL配置为RAG服务的访问地址,您需要将访问地址末尾的/删除;Authorization配置为RAG服务的Token。

    • 发送多轮对话请求

      LLM和RAG(Retrieval+LLM)支持发送多轮对话请求,代码示例如下:

      import requests
      
      EAS_URL = 'http://xxxx.****.cn-beijing.pai-eas.aliyuncs.com'
      headers = {
          'accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': 'MDA5NmJkN****jNlMDgzYzM4M2YwMDUzZTdiZmI5YzljYjZmNA==',
      }
      
      
      def test_post_api_query_llm_with_chat_history():
          url = EAS_URL + '/service/query/llm'
          # Round 1 query
          data = {
             "question":"什么是人工智能平台PAI?"
          }
          response = requests.post(url, headers=headers, json=data)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans = dict(response.json())
          print(f"=======Round 1: Question =======\n {data['question']}")
          print(f"=======Round 1: Answer =======\n {ans['answer']} session_id: {ans['session_id']} \n")
         
          # Round 2 query
          data_2 = {
             "question": "它有什么优势?",
             "session_id": ans['session_id']
          }
          response_2 = requests.post(url, headers=headers, json=data_2)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans_2 = dict(response_2.json())
          print(f"=======Round 2: Question =======\n {data_2['question']}")
          print(f"=======Round 2: Answer =======\n {ans_2['answer']} session_id: {ans_2['session_id']} \n\n")
      
      
      def test_post_api_query_rag_with_chat_history():
          url = EAS_URL + '/service/query'
         
          # Round 1 query
          data = {
             "question":"什么是人工智能平台PAI?"
          }
          response = requests.post(url, headers=headers, json=data)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans = dict(response.json())
      
          print(f"=======Round 1: Question =======\n {data['question']}")
          print(f"=======Round 1: Answer =======\n {ans['answer']} session_id: {ans['session_id']}")
          print(f"=======Round 1: Retrieved Docs =======\n {ans['docs']}\n")
      
          # Round 2 query
          data = {
             "question":"它可以做什么?",
             "session_id": ans['session_id']
          }
          response = requests.post(url, headers=headers, json=data)
      
          if response.status_code != 200:
              raise ValueError(f'Error post to {url}, code: {response.status_code}')
          ans = dict(response.json())
      
          print(f"=======Round 2: Question =======\n {data['question']}")
          print(f"=======Round 2: Answer =======\n {ans['answer']} session_id: {ans['session_id']}")
          print(f"=======Round 2: Retrieved Docs =======\n {ans['docs']}")
      # LLM
      test_post_api_query_llm_with_chat_history()
      # RAG(Retrieval+LLM)
      test_post_api_query_rag_with_chat_history()
      

      其中:EAS_URL配置为RAG服务的访问地址,您需要将访问地址末尾的/删除;Authorization配置为RAG服务的Token。

相关文档

通过EAS,您还可以完成以下场景化部署:

  • 部署支持WebUI和API调用的LLM大语言模型,并在部署LLM应用后,利用LangChain框架集成企业知识库,实现智能问答和自动化功能。详情请参见5分钟使用EAS一键部署LLM大语言模型应用

  • 部署基于ComfyUI和Stable Video Diffusion模型的AI视频生成服务,帮助您完成社交平台短视频内容生成、动画制作等任务。详情请参见AI视频生成-ComfyUI镜像部署

常见问题

如何关闭RAG服务的with chat history功能

在RAG服务的WebUI页面中,去勾选Chat history复选框。image