使用亚马逊SageMaker功能存储,个性化您的生成型AI应用程序

使用亚马逊SageMaker存储功能,个性化您的生成型AI应用程序

大型语言模型(LLMs)正在改变搜索引擎、自然语言处理(NLP)、医疗保健、机器人技术和代码生成等领域。这些应用还延伸到零售领域,在那里它们可以通过动态聊天机器人和AI助手提升客户体验,并在数字营销领域组织客户反馈并基于描述和购买行为推荐产品。

个性化的LLM应用可以通过整合最新的用户信息来实现,通常涉及整合多个组件。其中一个组件是特征存储库,它是一种用于存储、共享和管理机器学习(ML)模型特征的工具。特征是在ML模型的训练和推断过程中使用的输入。例如,在一个推荐电影的应用中,特征可以包括以前的评分、偏好类别和人口统计学信息。亚马逊SageMaker特征存储库是一个专门设计用于存储、共享和管理ML模型特征的完全托管的存储库。另一个重要的组件是适合快速工程和管理不同子任务的编排工具。生成式AI开发人员可以使用诸如LangChain的框架,该框架提供了与LLMs和任务管理和提示工程相关的模块。

基于动态获取最新数据以生成个性化内容的概念,LLMs在推荐系统的最近研究中引起了重大关注。这些方法的基本原理包括构建涵盖推荐任务、用户配置文件、物品属性和用户-物品互动的提示。然后将这些特定任务的提示输入LLM,LLM负责预测特定用户和物品之间的互动可能性。如在论文“通过提示大型语言模型进行个性化推荐”中所述,推荐驱动和参与引导的提示组件在使LLMs专注于相关内容并与用户偏好一致方面起着关键作用。

在本文中,我们阐述了将用户配置文件和物品属性组合以使用LLMs生成个性化内容推荐的简单而强大的想法。正如本文中所示,这些模型在生成高质量的、与上下文相关的输入文本方面具有巨大的潜力,从而导致更好的推荐。为了说明这一点,我们将指导您通过将特征存储库(代表用户配置文件)与LLM集成,以生成这些个性化推荐。

解决方案概述

让我们设想一个场景,一个电影娱乐公司通过电子邮件活动向不同的用户推广电影。该推广包含25部知名电影,我们希望根据用户的兴趣和以前的评分行为为每个用户选择前三个推荐的电影。

例如,根据用户对不同电影类型(如动作、浪漫和科幻)的兴趣,我们可以让AI系统确定特定用户的前三个推荐电影。此外,系统还可以为每个用户生成根据其喜好定制的个性化消息。本文稍后将包含一些个性化消息的示例。

该AI应用程序将包括多个协同工作的组件,如下图所示:

  1. 用户配置文件引擎接收用户的先前行为并输出反映他们兴趣的用户配置文件。
  2. 特征存储库维护用户配置文件数据。
  3. 媒体元数据存储库保持推广电影列表的最新状态。
  4. 一个语言模型接收当前的电影列表和用户配置文件数据,并根据用户的偏好以其喜好的语气输出每个用户的前三个推荐电影。
  5. 一个编排代理协调不同的组件。

简而言之,智能代理可以使用与用户和物品相关的数据构建提示,并向用户提供定制的自然语言响应。这将代表一个典型的基于内容的推荐系统,根据用户的配置文件向用户推荐物品。用户的配置文件存储和维护在特征存储库中,围绕他们的喜好和口味。通常基于他们的以前行为(如评分)来确定。

以下图示了它的工作原理。

“`html

该应用程序按照以下步骤为用户的推荐提供响应:

  1. 用户配置引擎以用户的历史电影评级作为输入,输出用户兴趣,并将其存储在SageMaker Feature Store中。这个过程可以以计划的方式进行更新。
  2. 代理以用户ID作为输入,搜索用户兴趣,并根据用户的兴趣完成提示模板。
  3. 代理从媒体元数据存储中获取推广项目列表(电影名称、描述、类型)。
  4. 将兴趣提示模板和推广项目列表提供给LLM以用于电子邮件广告活动。
  5. 代理向最终用户发送个性化的电子邮件广告活动。

用户配置引擎为每个用户构建个人资料,捕捉他们的偏好和兴趣。这个个人资料可以表示为一个包含元素映射到电影类型等特征的向量,其中值表示用户的兴趣水平。特征存储中的用户配置使系统能够建议与他们的兴趣相匹配的个性化推荐。用户配置是推荐系统中研究广泛的领域。为了简化,可以使用用户在不同类别上的先前评级构建回归算法推断他们的整体偏好。可以使用像XGBoost这样的算法来实现。

代码演示

在本节中,我们提供代码的示例。完整的代码演示可在GitHub仓库中找到。

从用户配置引擎获取用户兴趣特征后,我们可以将结果存储在特征存储中。SageMaker特征存储支持批量特征摄取和实时推理的在线存储。对于摄取,数据可以以离线模式进行更新,而推理需要在毫秒级别内完成。SageMaker特征存储确保离线和在线数据集保持同步。

对于数据摄取,我们使用以下代码:

from sagemaker.feature_store.feature_group import FeatureGroup
feature_group_name = 'user-profile-feature-group'
feature_group = FeatureGroup(name=feature_group_name, feature_definitions=feature_definitions, sagemaker_session=sess)
# 摄取数据
feature_group.ingest(data_frame=data_frame, max_workers=6, wait=True)

对于实时在线存储,我们可以使用以下代码根据用户ID提取用户配置:

feature_record = featurestore_runtime_client.get_record(FeatureGroupName=feature_group_name, RecordIdentifierValueAsString=customer_id)
print(feature_record)

然后,我们对前三个感兴趣的电影类别进行排序,以供下游推荐引擎使用:

用户ID:42 前3个类别:[‘动画’,’惊悚’,’冒险’]

我们的应用程序包含两个主要组件。第一个组件从特征存储中检索数据,第二个组件从元数据存储获取电影推广列表。这些组件之间的协调由LangChain的Chains来管理,它代表对组件的一系列调用。

<p p="" 值得一提的是,在复杂情况下,应用程序可能需要多个llm或其他工具的固定调用顺序以上所述。配备一套工具的代理使用llm来确定要执行的操作的顺序。而chains则编码了硬编码的一系列操作,代理使用语言模型的推理能力来规定操作的顺序和性质。

不同数据源之间的连接,包括SageMaker特征存储,可在以下代码中演示。所有检索到的数据被整合到一个广泛的提示中,作为LLM的输入。我们将在下一节中深入探讨提示设计的具体内容。以下是一个与多个数据源进行交互的提示模板定义:

from langchain.prompts import StringPromptTemplate
class FeatureStorePromptTemplate(StringPromptTemplate):
    feature_group_name = 'user-profile-feature-group'
    def format(self, **kwargs) -> str:
        user_id = kwargs.pop("user_id")
        feature_record = self.fetch_user_preference_from_feature_store(user_id)
        user_preference = self.rank_user_preference(feature_record)
        kwargs["promotion_movie_list"] = self.read_promotion_list()
        kwargs["user_preference"] = user_preference
        return prompt.format(**kwargs)
    
    def fetch_user_preference_from_feature_store(self, user_id):
        boto_session = boto3.Session()
        featurestore_runtime_client = boto_session.client('sagemaker-featurestore-runtime')
        feature_record = featurestore_runtime_client.get_record(FeatureGroupName=self.feature_group_name, RecordIdentifierValueAsString=str(user_id))
        return feature_record['Record']
        
    # 为给定用户的偏好排序前三类别
    def rank_user_preference(self, data) -> str:
        # 参考笔记中的细节
        return str(top_categories_df.values.tolist())
        
    # 从元数据存储中获取推广电影列表
    def read_promotion_list(self,) -> str:
        # 参考笔记中的细节
        return output_string

此外,我们使用Amazon SageMaker来托管我们的LLM模型,并将其作为LangChain SageMaker端点。为了部署LLM,我们使用Amazon SageMaker JumpStart(有关更多详细信息,请参阅Llama 2基础模型现已在Amazon SageMaker JumpStart中可用)。模型部署完成后,我们可以创建LLM模块:

from langchain import PromptTemplate, SagemakerEndpointfrom langchain.llms.sagemaker_endpoint import LLMContentHandlerclass ContentHandler(LLMContentHandler):    def transform_input(self, prompt: str, model_kwargs: dict) -> bytes:        #请参阅笔记中的详细信息            def transform_output(self, output: bytes) -> str:        #请参阅笔记中的详细信息content_handler = ContentHandler()sm_llm = SagemakerEndpoint(    endpoint_name = endpoint_name,    region_name = aws_region,    model_kwargs = parameters,    endpoint_kwargs={"CustomAttributes": 'accept_eula=true'},    content_handler = content_handler,)

在我们的应用程序上下文中,代理程序运行一系列步骤,称为LLMChain。它集成了一个提示模板、模型和防护措施,用于格式化用户输入,将其传递给模型,获得响应,然后验证(如果需要,纠正)模型输出。

from langchain.chains import LLMChainllmchain = LLMChain(llm=sm_llm, prompt=prompt_template)email_content = llmchain.run({'user_id': 4})print(email_content)

在下一部分中,我们将详细介绍LLM的提示工程,以输出预期结果。

LLM推荐提示与结果

遵循研究论文《通过提示大型语言模型进行个性化推荐》中描述的以用户参与为导向的提示的高级概念,我们提示策略的基本原则是在创建提示时集成用户偏好。这些提示旨在引导LLM更有效地识别与用户偏好一致的内容描述属性。为了更进一步说明,我们的提示包括以下几个组成部分:

  • 上下文相关性 – 我们的提示模板的初始部分包含媒体元数据,如项目名称(电影标题)、描述(电影简介)和属性(电影类别)。通过整合这些信息,提示为LLM提供了更广泛的上下文和更全面的内容理解。这种上下文信息有助于LLM更好地通过描述和属性来理解项目,从而增强其在内容推荐场景中的实用性。
  • 用户偏好对齐 – 通过考虑表示用户偏好的用户配置文件,潜在推荐更好地定位于识别与目标用户相关的内容特征和特点。这种对齐增加了项目描述的实用性,因为它增强了推荐与用户偏好相关的项目的效率。
  • 增强的推荐质量 – 通过用户偏好识别相关的促销项目的参与引导提示。我们还可以使用用户偏好调整LLM的语气以获得最终输出。这可以产生准确、信息丰富和个性化的体验,从而提高内容推荐系统的整体性能。

以下代码显示了一个示例提示模板:

prompt_template = """ 我们的公司“经典影城”经常推广我们希望向客户推荐的电影。这个月,我们有几部热门电影正在促销。

作为一个AI代理,你的任务是协助“经典影城”制定一封电子邮件活动,向用户推荐相关的电影。推荐应遵循几个准则,包括上下文相关性,确保推荐严格来自我们的促销电影清单。此外,推荐应与用户偏好保持一致,建议与用户喜欢的类别相关并和谐。你需要提供精确的三部热门推荐电影。最后,请草拟电子邮件以反映用户偏好类别的语气。电子邮件字数不得超过100个单词。

推荐的电影应该来自于这个上下文相关的电影清单: {promotion_movie_list}。

用户对{user_preference}表达了兴趣。

请确保推荐与之关联,并且电子邮件的语气反映了对于{user_preference}电影类别感兴趣的人的口味。

确保信件吸引那些对于{user_preference}电影类别感兴趣的人,并将电子邮件的内容限制在100个字以内。 """

以下是一个以科幻、冒险和战争类型为用户偏好的示例结果:

主题:探索经典电影前沿,与我们一起畅游科幻、冒险和战争电影!

亲爱的[姓名],准备好踏上一段穿越时空、感受心跳加速的动作,见证战场英雄的勇敢了吗?别再寻找了!经典电影自豪地为您呈现我们精心策划的科幻、冒险和战争电影精选,专为您的兴趣而量身定制。

首先,我们有标志性的《星球大战第五集:帝国反击战》(1980年)。这部星球大战系列的经典作品讲述了卢克·天行者成为绝地武士的旅程,而他的朋友们则与邪恶帝国展开对决。凭借突破性的特效和令人难忘的角色,这部电影是任何该类型影迷不可错过的。

接下来,我们推荐《星际穿越》(2014年),这是一部思考性和视觉震撼的电影,深入探索时间和空间的奥秘。一群探险家踏上拯救人类的任务,他们将会遇到令人惊叹的风景,并揭示宇宙的秘密。

最后,我们有《拯救大兵瑞恩》(1998年),一部扣人心弦、紧张刺激的战争剧情片,讲述了一群士兵危险的任务,他们要找到并解救一名兄弟在行动中殒命的伞兵。这部备受赞誉的影片是对二战英雄的强大致敬。别错过这些影片的视觉杰作!立即观看它们,体验冒险的刺激、科幻的奇妙和战争英雄的勇气。祝您观影愉快,愿原力与您同在!

此致,经典电影团队

以下是一个以纪录片、音乐剧和戏剧类型为用户偏好的另一个示例结果:

主题:经典电影推荐给纪录片、音乐剧和戏剧爱好者

亲爱的[姓名],希望您一切安好,并且享受我们平台上丰富多样的电影。在经典电影,我们自豪于迎合顾客多样化的口味,我们挑选了三部杰出的电影,相信它们会与您在纪录片、音乐剧和戏剧方面的兴趣产生共鸣。

首先,我们有《肖申克的救赎》(1994年),一部充满力量和令人振奋的戏剧,讲述了两名囚犯在腐败而无情的监狱体系中找到希望和救赎的旅程。凭借引人入胜的故事情节、出色的演绎和永恒的主题,这部电影是任何喜欢精心打造的戏剧的人必看的。

接下来,我们推荐《指环王:护戒使者》(2001年),一部史诗般的冒险影片,融合了令人惊叹的视觉效果、令人难忘的角色和一个丰富详尽的世界。这部电影是故事讲述的典范,具有深厚的历史和文化感,将您带入中土世界,并让您欲罢不能。

最后,我们建议观看《钢琴家》(2002年),一部深刻动人的纪录片,讲述了波兰犹太钢琴家弗拉迪斯拉夫·什皮尔曼在二战期间努力生存的真实故事。这部影片有力地提醒着我们,即使面对难以想象的悲剧,人类精神也具有韧性和希望。我们希望这些推荐与您的兴趣产生共鸣,并为您带来愉快而充实的观影体验。别错过这些永恒的经典作品,立即观看,发现经典电影的魅力!此致,经典电影团队

我们进行了Llama 2 7B-Chat(请参见下面的代码示例)和Llama 70B的测试以进行比较。两个模型表现良好,得出了一致的结论。通过使用带有最新数据的提示模板进行测试,我们发现更容易测试任意LMLM,并帮助我们在性能和成本之间找到正确的平衡。我们还进行了几项值得注意的共同观察。

首先,我们可以看到,这些推荐与用户的偏好真实地相符。电影推荐是由我们应用程序内的各种组件引导的,最重要的是存储在特征存储中的用户配置文件。

此外,电子邮件的语气也与用户的偏好相对应。由于LLM具备先进的语言理解能力,我们可以自定义电影描述和电子邮件内容,以满足每个用户的需求。

此外,最终的输出格式可以设计到提示中。例如,在我们的情况下,问候语“亲爱的[姓名]”需要由电子邮件服务进行填写。重要的是要注意,尽管我们避免在生成式AI应用程序中公开个人可识别信息(PII),在后处理过程中有可能重新引入该信息,前提是授予了正确的权限级别。

清理

为了避免不必要的成本,删除您作为解决方案的一部分创建的资源,包括特征存储和使用SageMaker JumpStart部署的LLM推断端点。

结论

LLM在生成个性化推荐方面的能力是巨大且具有变革性的,尤其是与合适的工具相结合时。通过集成SageMaker特征存储和LangChain以进行提示工程,开发人员可以构建和管理高度定制的用户配置文件。这将产生高质量、有上下文意识的输入,大大提高推荐的性能。在我们的示例情景中,我们看到了如何将此应用到根据个人用户偏好定制电影推荐,从而产生高度个性化的体验。

随着LLM领域的不断发展,我们预计会看到更多使用这些模型提供更加有吸引力、个性化的体验的创新应用。可能性是无限的,我们期待您将通过这些工具创造出什么样的成果。有了SageMaker JumpStart和Amazon Bedrock等资源来加速生成式AI应用程序的开发,我们强烈建议尝试使用LLM在AWS上构建推荐解决方案。