在亚马逊云科技AWS上利用ElasticSearch和RAG搭建个性化推荐系统

简介:

小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案,帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践,并应用到自己的日常工作里。

本次介绍用当下热门的RAG和大语言模型,结合亚马逊云科技热门AI模型管理服务Amazon SageMaker,手把手开发一个用户的个性化推荐系统。本文将通过利用Bloom-7B向量化模型将用户数据文档生成向量,并保存到向量数据库ElasticSearch中,最后利用RAG和部署在SageMaker上的Falcon-7B大语言模型在ElasticSearch中进行语义搜索生成用户个性化建议。我将带领大家编写一步一步的细节代码和展示实际的生成式AI实操项目,0基础学会AI核心技能。本架构设计全部采用了云原生Serverless架构,提供可扩展和安全的AI应用解决方案。本方案架构图如下:

方案实操背景知识

Amazon SageMaker

Amazon SageMaker 是一款亚马逊云科技AWS上的机器学习模型托管服务,旨在帮助开发者和数据科学家快速构建、训练和部署机器学习模型。SageMaker 提供了丰富的工具和功能,如内置的 Jupyter Notebook、自动模型调优和托管训练环境,使整个机器学习工作流程更加简化和高效。

特别值得一提的是 SageMaker 的 JumpStart 功能。JumpStart 提供了一系列预训练模型和机器学习解决方案,用户可以通过简单的界面快速部署这些模型,大大缩短了从实验到生产的时间。这对于那些需要快速验证模型效果或不具备大量机器学习知识的开发者来说尤为有用。

Amazon OpenSearch Service

Amazon OpenSearch Service 是一个亚马逊云科技托管的搜索和分析引擎,基于开源的 Elasticsearch 和 Kibana 构建。OpenSearch Service 提供了强大的数据索引和搜索能力,适用于日志分析、实时应用监控和复杂数据分析等场景。

此外,OpenSearch Service 还支持向量化数据库功能。通过将嵌入的向量数据存储在 OpenSearch Service 中,开发者可以实现高效的相似性搜索和推荐系统。向量化数据库能够处理高维度的数据查询,特别适合需要处理自然语言处理(NLP)和图像识别等任务的应用。

本方案包括的内容:

使用 Amazon SageMaker JumpStart 快速部署向量化模型

在 SageMaker Studio 中使用 Jupyter notebook 处理原始数据

在 Amazon OpenSearch Service 中创建索引并存储向量化数据

使用 OpenSearch Service 探索数据

多场景测试利用检索增强生成(RAG)构建的个性化推荐应用

项目搭建具体步骤:

1. 首先我们进入亚马逊云科技控制台,点击OpenSearch服务

2. 创建一个OpenSeach实例,点击左侧的domain查看创建好的实例

3.  查看OpenSearch实例登录界面的URL

4. 接下来我们进入SageMaker服务,点击Studio ,并打开Studio

5. 接下来我们进入JumpStart功能,点击HuggingFace,在这里我们可以直接在服务器上部署HuggingFace上的开源大模型

 6. 我们点击模型“Bloom 7B1 Embedding FP16”向量模型

 7. 点击Deploy部署向量模型

8. 配置参数后部署

 9. 模型部署时间约为5分钟,这时我们点击Studio Classic进入Jupyter Notebook

 10. 点击Open打开Notebook

11. 我们打开一个新的Notebook,开始编写我们的RAG个性化推荐系统服务,首先我们安装并导入必要模块

%%capture
## Code Cell 1 ##
!pip install opensearch-py-ml accelerate tqdm --quiet
!pip install sagemaker --upgrade --quiet## Code Cell 3 ##import boto3
import os
import time
import json
import pandas as pd
from tqdm import tqdm
import sagemaker
from opensearchpy import OpenSearch, RequestsHttpConnection
from sagemaker import get_execution_role

12. 接下来我们从文件中导入我们推荐系统的源数据文件

## Code Cell 4 ### Read in the Tab delimited data file and print the shape of the resulting data frame.
pd.options.mode.chained_assignment = None
df = pd.read_csv('booksummaries.txt',sep='\t')
print(df.shape)# Add columns headers to the data frame to be able to analyze.
df.columns = ['WikiPediaId','FreeBaseId','title','author','pub_date','genres','plot_summary']# Display entries with null data in any column (NaN).
df[df.isnull().any(axis=1)]

13.  接下来我们运行下面的代码对数据进行处理,删除不需要的列、字符,并丢弃确实数据的行

## Code Cell 5 ### Let's drop any rows that contain null values in any column. In a real production application you would want to replace NaN values with correct data.
df_1 = df.dropna()# clean-up Freebase markup and other unwanted characters in the Genres columm. 
df_1.genres.replace(to_replace='\"\/m\/.{4,7}\"\:', value='', regex=True,inplace=True)  # remove Freebase markup
df_1.genres.replace(to_replace='\\\\u00e0\sclef', value='', regex=True,inplace=True)    # remove utf-8 special characters
df_1.genres.replace(to_replace='\{\s"|"\}', value='', regex=True,inplace=True)          # Remove {" or "}
df_1.genres.replace(to_replace='"', value='', regex=True,inplace=True)                  # Remove double quotes# Only use the first value as the genre
df_2 = df_1['genres'].str.split(',', expand=True, n=1)
df_2.rename( columns={0:'genre'}, inplace=True )
df_2.drop(columns=[1],inplace=True)df_3 = pd.concat([df_1, df_2], axis=1)# Trim the size of the plot summary to 500 characters.
df_3['plot_summary'] = df_3['plot_summary'].apply(lambda x: ' '.join(x[:500].split(' ')[:-1]) if len(x) > 500 else x)
df_3['book_summary'] = df_3[['title','author','genre','plot_summary']].agg(' '.join, axis=1)# Sort by the author column, and to keep the lab within a reasonable time-frame drop the last 5000 rows of data.
# Drop other columns not needed.
df_3.sort_values(by=['author'],inplace = True)
df_3.drop(df_3.tail(5000).index,inplace = True)
df_3.drop(columns=['genres','WikiPediaId','FreeBaseId','plot_summary'],inplace=True)# Create a dictionary of the remaining data to be used for further processing.
wm_list = df_3.to_dict('records')# Let's look at the data now that it has been cleansed and trimmed.
df_3

 14. 接下来我们通过授权,建立和OpenSearch集群的连接

## Update the below <StackName> placeholder with the value from your Lab you copied in an earlier step. 
cloudformation_stack_name = 'LabStack-be9ce4b8-cc71-4dda-bfee-6024c60bb194-udbRjk1euELCeKsbKMeE2y-0'region = 'us-east-1' cfn = boto3.client('cloudformation')def get_cfn_outputs(stackname):outputs = {}for output in cfn.describe_stacks(StackName=stackname)['Stacks'][0]['Outputs']:outputs[output['OutputKey']] = output['OutputValue']return outputsoutputs = get_cfn_outputs(cloudformation_stack_name)
aos_host = outputs['OSDomainEndpoint']outputs## To authenticate to the OpenSearch domain we need to retrieve username and password stored in Secrets Manager.
secrets = boto3.client('secretsmanager')
os_domain_secret = secrets.list_secrets(Filters=[{'Key':'name','Values': ['DomainMasterUser']}]
)['SecretList'][0]['Name']aos_credentials = json.loads(secrets.get_secret_value(SecretId=os_domain_secret)['SecretString'])auth = (aos_credentials['username'], aos_credentials['password'])
print(auth)## The below client will be used in a later step below.
aos_client = OpenSearch(hosts = [{'host': aos_host, 'port': 443}],http_auth = auth,use_ssl = True,verify_certs = True,connection_class = RequestsHttpConnection
)

15. 下面我们定义调用SageMaker将文字转化为向量的函数"query_endpoint_with_json_payload"

## Code Cell 8 ##embedding_endpoint_name = 'jumpstart-dft-hf-textembedding-bloo-20240804-035651'def query_endpoint_with_json_payload(encoded_json, endpoint_name, content_type="application/json"):client = boto3.client("runtime.sagemaker")response = client.invoke_endpoint(EndpointName=endpoint_name, ContentType=content_type, Body=encoded_json)response_json = json.loads(response['Body'].read().decode("utf-8"))embeddings = response_json["embedding"]if len(embeddings) == 1:return [embeddings[0]]return embeddings

 16. 接下来我们定义OpenSearch中的索引,用于更精准的搜索文档里的内容,这里我们定义了保存字段的类型,以及索引算法k-NN

## Code Cell 11 ##knn_index = {"settings": {"index.knn": True,"index.knn.space_type": "cosinesimil","analysis": {"analyzer": {"default": {"type": "standard","stopwords": "_english_"}}}},"mappings": {"properties": {"booksummary_vector": {"type": "knn_vector","dimension": 4096,"store": True},"book_summary": {"type": "text","store": True},"author": {"type": "text","store": True},"title": {"type": "text","store": True},"pub_date": {"type": "text","store": True},"genre": {"type": "text","store": True},}}
}

 17. 我们可以用如下代码,验证和获取我们之前定义的索引

## Code Cell 13 ##aos_client.indices.get(index=index_name)

18. 接下来我们把之前处理过的文档内的数据导入到OpenSearch索引当中

## Code Cell 14 ##def os_import(record, aos_client, index_name):book_summary = record["book_summary"]search_vector = embed_phrase(book_summary)aos_client.index(index=index_name,body={"booksummary_vector": search_vector[0], "book_summary": record["book_summary"],"author":record["author"],"genre":record["genre"],"pub_date":record["pub_date"],"title":record["title"]})print("Loading records...")
for record in tqdm(wm_list): os_import(record, aos_client, index_name)
print("Records loaded.")

19. 打开我们之前在第3步获取的OpenSearch URL,并输入用户名和密码

20. 进入OpenSearch界面中的Stack Management,点击创建索引类型

 21. 为索引类型起一个名字“book_knowledge_base”

 22. 点击创建

 23. 在OpenSearch中点击Discover即可看到我们导入的文档数据

24. 接下来我们定义在OpenSearch中进行近似语义搜索的函数“retrieve_opensearch_with_semantic_search”

## Code Cell 16 ##def retrieve_opensearch_with_semantic_search(phrase, n=2):search_vector = embed_phrase(phrase)[0]osquery={"_source": {"exclude": [ "booksummary_vector" ]},"size": n,"query": {"knn": {"booksummary_vector": {"vector":search_vector,"k":n}}}}res = aos_client.search(index=index_name, body=osquery,stored_fields=["title","author","pub_date", "genre", "book_summary"],explain = True)top_result = res['hits']['hits'][1]result = {"title":top_result['_source']['title'],"author":top_result['_source']['author'],"pub_date":top_result['_source']['pub_date'],"genre":top_result['_source']['genre'],"book_summary":top_result['_source']['book_summary'],}return result

25. 接下来我们运行该函数进行测试,搜索我们输入的内容在文档数据源中进行语义搜索,找到推荐的书籍。我们的问题是:“一本由埃德加·赖斯·巴勒斯(Edgar Rice Burroughs)撰写的、属于科幻类型且涉及人猿泰山的书。”

## Code Cell 17 ##example_request = retrieve_opensearch_with_semantic_search(question_on_book)
print(question_on_book)
print(example_request)

26.  接下来我们定义函数,利用RAG在OpenSearch中进行语义搜索找到相关结果,在用大模型生成最终回复

## Code Cell 21 ##def generate_prompt_to_llm(original_question_on_book):retrieved_documents = retrieve_opensearch_with_semantic_search(original_question_on_book)print("retrieved relevant book per your query is : \n" + str(retrieved_documents))print("------------")one_shot_description_example = "{'book_summary': 'Tarzan tracks down a man who has been mistaken for him. The man is under the delusion that he is Tarzan, and he is living in a lost city inhabited by people descended from early Portuguese explorers. The plot devices of a lost city and a Tarzan double or impostor had been used by Burroughs in some previous Tarzan novels.', 'author': 'Edgar Rice Burroughs', 'title': 'Tarzan and the Madman', 'genre': 'Science fiction', 'pub_date': '1964'}"one_shot_response_example = "It's a real page turning story about Tarzan and how a madman has been impersonating him. The author is Edgar Rice Burroughs and it's a science fiction book with adventure and lots of fun. It was published in the year 1964."prompt = (f" Make a book recommendation that is similar to the {original_question_on_book} The recommendation must include the title of the book, the author and genre: \n"f"Data: {one_shot_description_example} \n Recommendation: {one_shot_response_example} \n"f"Data: {retrieved_documents} \n Recommendation:")return prompt

27. 最后我们定义函数设计大模型输入和输出的格式,得到最终的推荐结果。

## Code Cell 22 ##def generate_llm_input(data, **kwargs):default_kwargs = {"num_beams": 5,"no_repeat_ngram_size": 3,"do_sample": True,"max_new_tokens": 100,"temperature": 0.9,"watermark": True,"top_k": 200,"max_length": 200,"early_stopping": True}default_kwargs = {**default_kwargs, **kwargs}input_data = {"inputs": data,"parameters": default_kwargs}return input_datadef query_llm_with_rag(description, **kwargs):prompt = generate_prompt_to_llm(description)query_payload = generate_llm_input(prompt, **kwargs)response = query_llm_endpoint_with_json_payload(json.dumps(query_payload).encode("utf-8"), endpoint_name=llm_endpoint_name)return response## Code Cell 23 ##recommendation = query_llm_with_rag(question_on_book)
print(question_on_book)
print(recommendation)

以上就是在亚马逊云科技上使用RAG和部署在SageMaker上大语言模型构建个性化推荐服务系统的步骤。欢迎大家关注小李哥,未来获取更多国际前沿的生成式AI开发方案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/391015.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[WUSTCTF2020]朴实无华1

打开题目 扫目录用dirsearch扫&#xff0c;为节省建议只扫常见的目录&#xff0c;配置是&#xff1a; ./dirsearch.py -e bak,zip,txt,tgz,php -u http:..... -s 3 -t 20 访问一下 根据提示&#xff0c;再访问一次 提示不在这&#xff0c;抓包看看 根据提示&#xff0c;改ge…

页面根据sse返回的流,逐句展示内容,达到gpt效果

之前的文章里&#xff0c;我写到了关于怎么获取sse中的流&#xff0c;但是缺少逐句展示的效果&#xff0c;这次来补齐。 比如这种&#xff0c;实现难点在于&#xff0c;当返回的markdown语法&#xff0c;不是完整的语句时&#xff0c;展示的代码块会错乱。 实现代码 app.vue …

P10477 题解

题目传送门 题目传送门&#xff08;洛谷&#xff09; Step1 理解题意 一共有 T T T 组数据有一个地铁&#xff0c;有一个中心车站&#xff08;即为根&#xff09;&#xff0c;有一个人从中心车站出发。对于每组数据&#xff0c;给定两个同样长度的01串 s 1 s_1 s1​ , s …

内网安全:多种横向移动方式

1.MMC20.Application远程执行命令 2.ShellWindows远程执行命令 3.ShellBrowserWindow远程执行命令 4.WinRM远程执行命令横向移动 5.使用系统漏洞ms17010横向移动 DCOM&#xff1a; DCOM&#xff08;分布式组件对象模型&#xff09;是微软的一系列概念和程序接口。它支持不同…

C语言--函数

1. 函数定义 语法&#xff1a; 类型标识符 函数名&#xff08;形式参数&#xff09; {函数体代码 } &#xff08;1&#xff09;类型标识符 --- 数据类型&#xff08;函数要带出的结果的类型&#xff09; 注&#xff1a;数组类型不能做函数返回结果的类型&#xff0c;如果函…

Tomcat 8.5 下载、安装、启动及各种问题

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 本期内容主要介绍 Tomcat 8 的安装&#xff0c;以及可能会遇到的问题 文章目录 1. Tomcat 安装2. 可能会遇到的问题2.…

【vluhub】skywalking

SkyWalking是一个开源监控平台&#xff0c;用于从服务和云原生基础设施收集、分析、聚合和可视化数据 低版本存在sql注入漏洞 访问地址 http://192.168.203.12:8080/graphql burpsuite抓数据包 替换 {"query":"query queryLogs($condition: LogQueryConditi…

机器学习 第9章-聚类

机器学习 第9章-聚类 9.1 聚类任务 在“无监督学习”(unsupervised learning)中&#xff0c;训练样本的标记信息是未知的&#xff0c;目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律&#xff0c;为进一步的数据分析提供基础。此类学习任务中研究最多、应用最广…

计算机毕业设计选题推荐-学生作业管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

errno错误码列举

errno&#xff0c;int变量&#xff0c;表示系统最近一次错误码。 当系统调用和一些库函数发生错误时&#xff0c;会给errno赋值&#xff0c;以指示哪里出了问题。 目录 errno值列表 errno值获取示例 errno值列表 <errno.h>头文件定义了errno的一些值&#xff0c;部分…

【C++ STL】list

文章目录 list1. list的使用1.1 增删查改1.2 功能接口 2. list的模拟实现2.1 list的定义2.2 默认成员函数2.3 迭代器正向迭代器解引用箭头 反向迭代器迭代器接口 2.4 基本功能 3. list对比vector list 与 vector 相比&#xff0c;list 的好处就是每次插⼊或删除 ⼀个 元素 就 …

pydal,一个实用的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个实用的 Python 库 - pydal。 Github地址&#xff1a;https://github.com/web2py/pydal/ 在现代应用开发中&#xff0c;数据库操作是一个核心部分。为了简化与数据库的交互…

PMP–知识卡片--Scrum框架

定义 Scrum框架包含由产品负责人、开发团队、敏捷专家构成的Scrum团队&#xff0c;以及活动工件。框架中的每一个组件都服务于一个特定的目标&#xff0c;且是Scrum成功和运用的基本要素。 Scrum的规则将角色、活动和工件绑定在一起&#xff0c;管理它们之间的关系和交互。 …

【Vue3】组件通信之$parent

【Vue3】组件通信之$parent 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的…

基于Java的网络考试系统的设计与实现

点击下载源码 基于Java的网络考试系统的设计与实现 摘 要 科技在进步&#xff0c;人们生活和工作的方式正发生着改变&#xff0c;不仅体现在人们的衣食住行&#xff0c;也体现在与时俱进的考试形式上。以前的考试需要组织者投入大量的时间和精力&#xff0c;需要对考试的试题…

人工智能与大数据的融合:驱动未来的力量

人工智能与大数据的融合&#xff1a;驱动未来的力量 一、人工智能与大数据的概述二、人工智能与大数据在数据库中的融合三、实际应用案例四、未来发展方向总结 【纪录片】中国数据库前世今生 在数字化潮流席卷全球的今天&#xff0c;数据库作为IT技术领域的“活化石”&#xff…

【Python实战】如何优雅地实现文字 二维码检测?

前几篇&#xff0c;和大家分享了如何通过 Python 和相关库&#xff0c;自动化处理 PDF 文档&#xff0c;提高办公效率。 【Python实战】自动化处理 PDF 文档&#xff0c;完美实现 WPS 会员功能【Python实战】如何优雅地实现 PDF 去水印&#xff1f;【Python实战】一键生成 PDF…

【Linux详解】基础IO:软硬连接 | 动静态库管理

目录 软硬链接 1. 介绍 2.理解 2.1 如何理解硬链接&#xff1f; 2.2 如何理解软连接&#xff1f; 动静态库 1.介绍 1.1 使用 1.2 什么是库&#xff1f; 2.生成 2.1 静态库 2.2 动态库&#xff1a; 软硬链接 1. 介绍 1.1 软连接 是一个独立文件&#xff0c;具有独…

【Python机器学习】支持向量机——利用完整platt SMO算法加速优化

在几百个数据点组成的小规模数据集上&#xff0c;简化版SMO算法的运行是没有什么问题&#xff0c;但是在更大的数据集上的运行速度就会变慢。完整版的platt SMO算法应用了一些能够提速的启动方法。 platt SMO算法时通过一个外循环来选择第一个alpha值的&#xff0c;并且其选择…

内网穿透--ICMP隧道转发实验

实验背景 通过公司带有防火墙功能的路由器接入互联网&#xff0c;然后由于私网IP的缘故&#xff0c;公网无法直接访问内部web服务器主机。通过内网其它主机做代理&#xff0c;穿透访问内网web服务器主机边界路由器或防火墙做静态NAT映射访问内网服务器inux主机&#xff0c;且策…