网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

623次阅读
没有评论

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

导读本文将分享网易伏羲在游戏AI Bot方向的一些工作。我们的工作称为AIGA,它是另一种形式的AIGC,生成的内容是agent的action。我们在游戏场景方面做了一些AIGA相关的工作。今天的分享将重点围绕AIGA技术手段的应用展开。

主要包括以下三个方面:

1. 从AIGC到AIGA

2. 游戏AI Bot拟人化和风格化研究进展

3. RLHF微调游戏AI Bot模型分享嘉宾|胡裕靖博士 网易 人工智能研究员

编辑整理|徐谦

出品社区|DataFun

01

AIGCAIGA

AIGC是指AI生成内容,已经被广泛了解。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

AIGC有着广泛的应用,包括图像生成和对话。微软基于OpenAIGPT技术,开发了一系列惊艳的工具。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

AIGC技术发展迅速,包括基于模型和深度学习的AIGC。但在游戏领域中,很早就对GC(生成内容)进行了研究。这些研究主要集中在应用方面,而不是理论方法方面。很多早期应用研究被称为PCG(程序生成),如关卡生成、武器装备生成和场景建筑生成等。从技术手段上来将主要使用了启发式方法和遗传算法,不过效果不如目前的AIGC惊艳。从这个角度来看,AIGC与游戏是有着深厚的渊源的。 

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

AIGA是将AIGC中的C换成了A,即AI生成的行为(AI Generated Action)。更准确地说,应该称为AI生成的智能体AI Generated Agent)。AIGA并不是一个新概念,其实就是游戏中的AI Bot,俗称程序控制的小人,能自动做出一些行为。

游戏AI Bot在游戏中有什么用呢?先看第一个例子,在足球游戏FIFA中,游戏可以联网在线玩,几个队友一起打游戏。但一个队总共需要十一个人踢,所以在队伍中经常会有一些AI Bot,来和你控制的角色进行配合。这里面就用到了程序的自动化控制。

再看第二个例子,在经典游戏暗黑破坏神中,里面的雇佣兵会跟随玩家一起活动。这里面可能用了简单的一些基于规则的方法来控制这些雇佣兵,比如:自动机、行为树等方法。但这里也还是AI Bot的范畴,能给玩家提供一个游戏伙伴。

再看第三个例子,在很多单机游戏中,如老头环和战神中,有很多BOSS或者小兵,也是程序控制的,也是AI Bot。这里不一定要用强化学习去实现,它的主要目标仅仅是给玩家提供一些挑战即可,不需要很复杂的一些操作。

但是在网游中,如网易的一些游戏,如逆水寒、永劫无间里面,以及最近要上线的篮球游戏里面,也有很多AI Bot。这些AI Bot就是强化学习方法训练出来的游戏会基于AI Bot专门设计一些玩法,比如提供一些新手玩家的福利局。

所以,对于游戏来讲,游戏AI Bot是非常重要的,是不可或缺的。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

网易的很多游戏中都会有一些AI Bot,也就是所谓的AIGA。

02

游戏AI Bot拟人化和风格化研究进展

本文将重点介绍AIGA在游戏需求中的核心应用。我们在许多项目中发现,游戏AI Bot有两个非常重要的需求:拟人化和风格化。AI Bot的行为具有明显的风格特征,并且是多样化的风格特征。

本小节中,我们将整体介绍一下关于这两个需求的相关研究。

拟人化和风格化,这两点的目标虽然不同,但是其实现方式是基本一样的。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

游戏AI Bot的拟人化和风格化,有哪些作用呢?从玩家的角度来讲,一个好的AI Bot,可以让玩家有一个好的心流体验。心流,是指玩家在游玩过程中的心理起伏变化过程。

我们希望玩家在玩游戏的过程中,他的心流曲线是一个上升的过程。强化学习能够训练出很强的机器人,远远超过人类的水平。但是如果作为对手的话,玩家就会觉得机器人太强了,游戏体验不是很好。最终玩家会感觉到焦虑,它的心流就会到这个焦虑区间。这就表明拟人化做的不够好。

另一方面,如果机器人行为不够丰富,行为特征不明显,行为特征很单一话,玩家心流会到这个Boredom的区间中。玩家这样的心流也不是我们想要的。拟人化和风格化这两点,会影响玩家的心流和体验。。这方面的研究工作虽然已经有了一些,我们之前也有很多的探索,但是还没有形成统一的方法论,通用性还不够。

比如,我们在开发永劫无间游戏机器人时,实现了一个巡路功能的机器人,它可以自动完成游戏角色的寻路任务。我们在设计这个机器人时,花费了很多时间调整奖励权重,以使它的行为更加接近真实玩家。最终,我们实现了一个可以自动执行复杂操作的机器人,做到了左图中一个效果,它可以在游戏中执行一些人类玩家才会做的复杂行为,而不仅仅是简单地寻路导航。

这是原始的永劫无间中的巡逻机器人,它使用规则编写,会一直跳来跳去。虽然也能到达目的地,但是玩家一眼就能够看出这是机器人,就不想玩了,导致体验不佳。我们使用的强化学习方法训练出来的机器人,则可能看起来更自然,玩家体验更好。但问题在于,我们在进行强化学习训练的过程中,耗费了大量人力和时间去调整算法相关奖励权重和参数,才能够达到现在的效果。同时,这样的方法不具备可复制性。换一个任务的话,我们调出来的参数和权重就不能用了。

我们在多样化,或者行为多风格化方面做了很多工作,提出了一些方法,如多联盟训练、Reward Shaping、进化算法和多目标优化等。这些方法虽然有一些论文发表,但计算复杂度高,成本较高,实现周期长,线上成本也高,不是我们想要的。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索我们的游戏AI机器人具有拟人化和多风格化的特点。我们后来发现游戏AI机器人与其他AI技术路径是相似的。因为评估这些AI时,没有客观的统一标准,最终需要人类主观判断的。此外,从技术手段上来说,存在调参和调整reward等问题,我们希望实现更通用的自动化技术方案。另一个目标是提升业务效果。

1.拟人化

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

拟人化虽然是主观的,但是需要有客观量化的指标来指导算法研究并提出通用化的方案,以评估AI是否拟人。围绕客观性和可靠性方面,我们提出了一个框架,可以指导游戏AI机器人的研究。可以对人类玩家的行为特征进行统计,并将其与AI机器人训练出来的行为特征进行比较,以进行统计学上的匹配。可以计算有多少行为是相匹配的,以评估AI机器人的拟人化程度。

第二个方面是多样性指标。人类的行为具有多样性,游戏中的行为也应具有多样性,否则将不够拟人。可以通过策略分布和动作分布等方式来衡量。

第三个方面是竞技性指标。AI的强度将提高游戏的竞技性能。但对于AI机器人来说,我们不要求过高的竞技性,而是要求在一定水平上达到要求。即使是随意玩游戏,也需要有一定的目标和阈值。

第四个方面是领域相关指标。不同游戏需要不同的拟人化评估标准,因此需要根据游戏的特点设定特殊的指标。

这些指标也可以通过游戏中的一些行为分布来体现。只不过,我们需要从游戏本身出发来统计这些指标,而不是单一地使用统计学的方法。比如说很多动作类游戏,我们可以通过统计玩家的连招释放率来衡量游戏的难度和玩家的技巧水平。这与人类的行为类似。比如说在一些篮球游戏或足球游戏中,玩家的跑位非常重要。我们可以通过分析游戏中不同位置的热力图来判断游戏的合理性。这也可以用来衡量游戏的难度和玩家的技巧水平。

最终,这四个指标只是一些量化的指标,我们还需要通过主观评判来判断游戏是否真正与人类的行为相匹配。最后的图灵测试是一个重要的评判标准。

这个框架可以帮助我们在做算法迭代的过程中,通过量化的指标来评估算法的进步情况。例如,我们可以通过比较迭代前后的结果来判断算法是否真正有所提升。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

如果将这些指标展示为可视化雷达图,我们可以通过面积的大小来判断不同算法方案的拟人性。

从可视化的雷达图中可以看出,如绿色部分所示,强化学习训练出的Bot在竞技性方面可能更强,但在多样性和客观性方面可能不够好。

从可视化的雷达图中可以看出,如红色部分所示,通过模仿学习方法训练出的Bot在拟人化程度方面比强化学习更高。

通过可视化的雷达图,我们可以直观地看出这些指标反映出Bot的拟人化程度的多少。雷达图的面积越大,拟人化程度可能越高。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

在具体做法方面,我们需要基于人类数据来做拟人化。模仿学习可以帮助我们模仿人类数据的分布,但这样得到的强度可能有限。单纯的模仿学习可能无法得到合理的行为,最主要的缺点是强度比较低。

因此,我们需要进行修正,将模仿学习和强化学习结合起来,通过强化学习加上模仿学习的整合来做拟人化。这样可以提高游戏算法的强度和多样性,从而更好地模拟人类行为。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

整个优化方案非常简洁,我们希望通过自动化过程来实现优化过程。

在方案中,目标参数由两部分组成,一部分是强化学习,另一部分是模仿学习,通过权重进行关联。我们使用一些规则化方法,来自动调整这里的权重。具体来讲,我们首先使用强化学习来调整AI Bot的强度水平,然后再使用模仿学习来提高AI Bot各个维度的拟人指标。

我们使用一些规则化的方式来实现这一目标。在训练过程中,我们如果发现AI Bot的胜率或强度低于我们设定的阈值,我们通过降低模仿学习的权重,进行AI Bot的强度优化。当AI Bot的强度上升后,我们再调高模仿学习的权重,来优化AI Bot的拟人性。

通过这种方法,在训练过程中,AI Bot会先优化胜率。当AI Bot强度达到一定水平时,再调高模仿学习的权重,来提高模仿学习效果。最终,AI Bot的强度会自动缓慢提高。这是一种超参数设置的自动化方法。可能还有其他复杂的自动化方法,但对于游戏应用来说,这种方法已经足够了。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

在即将上线的篮球游戏《全明星街球派对》中,我们就使用了拟人化的方法来提高AI Bot的强度。我们对比了模仿学习和强化学习的效果,发现强化学习可以提高AI Bot的强度,但其他指标不如模仿学习方法;使用模仿学习可以提高AI Bot的其他指标,但强度不如强化学习的方法。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

在篮球游戏中,AI Bot的投篮次数、传球和移动的频率等领域相关指标,模仿学习比强化学习的效果更好。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

对于领域指标,如传球次数、投篮次数等,我们可以将游戏数据中的人类玩家的数值做为模仿学习的优化目标,自动化进行权重调节。这样,不仅可以用于拟人化优化,还可以用于任意风格化的优化,如降低传球次数或增加传球次数。我们在后续风格化的技术探索中,也用了类似方法。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

这里展示了篮球游戏中拟人化的最终效果。

然而,我们又遇到了一个新的问题:虽然从客观指标上,能够看出来相对于强化学习提升很大。但是主观感受上,对于一般人而言,并没有感觉到提升。如果不是游戏资深玩家,无法主观上分辨出游戏机器人的拟人效果。因为我们最终目标是主观拟人性的提升。虽然客观提升很大,但也不是我们的最终目标。这个问题,我们后面再来回答。

2.多风格化

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

风格化也是类似的情况。游戏AI Bot的哪些行为能够反应出其风格呢?我们提出一个框架。首先定义游戏AI Bot的State,如球员的移动轨迹分布,位置热力图分布。这些State的变化情况,反应了对应的Action,从而代表了不同的风格。

以篮球游戏为例,如挡拆次数、投篮次数,盖帽次数这些Action,代表了不同的防守风格,如防守风格严密等。

从结果上,也对应了强化学习的Reward效果。如两分球得分率、三分球得分率、榜首成功率等结果,可以对应不同的Reward效果。

State、Action、结果这几个维度,常常会交织在一起。我们将它们拆分开,来表示不同的游戏AI Bot风格。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

在游戏《逆水寒》中,我们进行了这种尝试。

首先尝试多风格化。最开始,我们想用一个模型将所有的风格训练出来。这个在理论上可以办到,但是在风格维度比较多时,会有一个打地鼠的现象。在一个模型中同时实现激进的风格和保守型的风格。这两个维度本身就是冲突的,几乎不可能同时实现。。由于游戏AI Bot的多风格化,重点是在它在风格化,而不是在于多。因此对于多,我们通过其他的方式来实现。

如何才能把风格很好地体现出来的呢?对于玩家而言,在玩一个游戏的过程中,遇到的风格相对来讲不会很多,有几种或者十几种风格就足够了。重点在于游戏的风格特征需要比较明显。于是我们转换了一种思路,先把游戏AI Bot的风格做出来。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

我们做了一个简单的实验。在强化学习的典型游戏Breakout中,我们训练了一个AI模型,来观察不同风格所呈现的分布情况。

首先,我们考察移动次数这个风格。整体上,每一局的移动次数是差不多的,符合正态分布的情况,均值在十五到十六。但是,有的EPISODE上移动次数很少,有时移动次数非常多。

于是,我们希望基于这个模型得到一个移动比较多的AI Bot。我们基于移动次数指标来划分样本,再对原来的模型做fine tune。如果要训练移动次数多的AI Bot,我们划一条线,只保留移动次数25以上的样本,丢弃其它样本。再用这部分样本,来fine tune原来的模型,这样就能够得到一个移动次数一直比较多的AI Bot——Active Bot。同理,我们也可以得到一个移动比较少的AI Bot。我们丢弃中间的样本,将移动次数很少的样本取出来,最后得到一个Lazy Bot。这样,我们就得到了两个风格化的AI Bot。

一般来讲,我们先预训练一个基模型,基模型的行为符合正态分布。然后,我们根据需求,提取出一部分样本出来,基于基模型做风格化的finetune,即自模仿学习的方式。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

我们用SIL(Self-Imitation Learning,自模仿学习)的方法,从自己的样本里做模仿,再根据需求风格和指标做样本提取,同时使用RL(强化学习)方法来保证强度。

多风格化过程和拟人化是基本一样的,主要区别是多风格化中的样本是来自于AI Bot自己的样本,而拟人化的样本是来自于人类样本。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

基于这个思路,我们在篮球游戏中进行了一些体验,并开发了一个专门投三分球的游戏AI Bot。这个AIBot只会投三分球,或者更准确地说,它会在游戏中尽可能地去投三分球。

在游戏画面中,我们可以看到这个AI的角色是库里。了解篮球的人应该清楚,库里的三分球能力是非常出色的。因此,这个AI Bot的特点就是能够尽可能地去投三分球。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

此外,我们还有专门投两分球的AI Bot,这是非常有意思。以库里为例,虽然他的三分球能力非常出色,但通过我们使用的自模仿学习、强化等训练方法,这个AI Bot却选择投两分球。即使在投两分球后被盖帽,它仍然会继续往篮下冲。这是一个非常有趣的现象,说明风格并不一定与强度或直观感受一致。然而,这个AI Bot仍然能够完成我们设定的目标。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

前面介绍了投篮风格,这里我们再举个挡拆风格的例子。在篮球游戏中,我们通过强化学习训练的方式,发现一开始挡拆并不容易实现。这是因为游戏本身的机制和一些设定。如果防守方表现出色,或者进攻方表现不错,挡拆可能并不是必要的。强化学习可能会认为这不是一个必要的东西,于是就会直接去做其他动作。

我们可以通过提取挡拆样本的方式,让中锋球员在比赛中更多地运用挡拆风格。通过模型自模仿,我们可以将这种行为朝着挡拆方向进行引导。这样,中锋球员的挡拆次数就会变得更多。这些技巧和方法是可以实现并发挥作用的。

03

RLHF微调游戏AI Bot模型

我们前面提到的问题是关于主观感受和客观指标之间的差距。尽管我们的客观指标可能会得到很大提升,但在主观上可能并没有明显的感受,甚至可能觉得好像并没有什么提升。因此,我们需要找到这个差距(GAP)所在,以便更好地弥合主观和客观之间的鸿沟。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

在模型训练完成后,我们使用客观指标来进行评估。然而,这个客观指标并没有直接反馈到模型的训练中,而只是提供了一种参考。最终,仍然需要人类进行评判,然后根据这些评判来调整模型。例如,如果我认为某个指标表现不够好,我可以调整模型以改善该指标。

我们的最终目标是,让客观指标能够直接反馈到模型的训练中。如果模型的客观指标表现不佳,能够直接反馈并优化模型。然而,大部分客观指标并不能直接用于模型的优化。

另一个问题是,客观指标无法完全反映模型的拟人化程度和风格化程度。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

现有方案的思路是在宏观的数据层面进行优化,通过模仿学习或自我模仿学习,将AI的行为引导到我们想要的数据统计分布方向,使其拟合得更好。

然而,对于主观目标,人类并不是从数据分布方面去评判的。无论你在数据统计方面做得多么出色,如果有一次没有做对,那么人类会认为你和他们的认识不太符合,从而判定你的模型不正确,认为你使用的是机器人。即使模型在客观指标上有一万次的成功率,但只要有一次失败,就会影响人类对模型拟人化或风格化的判定。

因此,我们考虑是否可以从人类的主观反馈中学习。已经证明,这是可行的。如果行为做得不理想,我们会提供一些标签或其他反馈。这些反馈会形成新的数据,反映人类的反馈和主观评价。这些数据将用于进行RHLF (基于人类反馈的强化学习),从而进一步优化模型。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

我们进行了一些初步的实验,目前也在进行整体优化。我们发现从主观上讲,该模型的跟防不太好,防守时跟的比较远,不够严密。

因此,我们考虑使用pair-wise的标签来判断左边做得好还是右边防守做得好,然后通过这种方式进行标注,形成数据。

数据被转化为奖励函数(reward function),然后用于进行强化学习的fine tune。在训练过程中,我们发现RLHF过程的训练会使Bot的跟防距离不断下降,最终达到一个不错的水平。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

让我们来看一下左右对比。左边是通过RLHF训练后的结果,它会及时跟上,比如库里这个球员去防守。而右边如果仔细看的话,会发现它中间有一段时间朝里面跑了。因为它的对位球员实际上在跑向这边,而这个库里应该直接跑到那边去防守。所以这个跟防在右边的表现稍微差一些。因此,通过RLHF这种方法,我们可以进行一些调整。

因此,右边的跟防表现得稍微差一些,但通过RLHF这种方法,我们可以进行一些调整来改善这种情况。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

我们的整个方案pipeline就是这样的。首先进行数据采集,但在数据采集之前,我们可以使用强化学习的方式对模型进行预训练。然后,基于我们设定的目标,我们可以进行自我模仿学习。为了确保强度,我们会加上强化学习的保障措施。

然后,在训练出模型之后,我们再通过主观评判的方式,使用HRHF进行微调。这个过程可以不断迭代,因为像ChatGPT一样,可能需要不断调整和完善模型的效果。

如果这个闭环能够建立起来,AI工程师就可以较少地介入调整奖励和参数等问题,从而在一定程度上实现通用化生产,而无需进行复杂的操作。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

非常感谢大家的参与。这个技术非常有趣,它们可以在我们的游戏生产pipeline中发挥作用。其中,一些现有的技术可以为我们提供帮助。

04

问答环节

问题一:语音助手的回复风格化也是类似的思路吗?

语音助手风格,我觉得也可以用这种方式进行。语音助手可以采用多种风格,比如甜言蜜语型或犀利型等。为了将这些风格数据分开,需要设定一些数据指标,并使用模仿学习或监督学习的方式,将风格化的数据更多地用于训练模型。基模型可以通过Lora或其他方式提取出想要的风格化数据,然后快速进行风格变化。在游戏开发中,我们也采用了类似的方式,取得了不错的效果。基模型建立后,提取出风格化数据,大概只需要几个小时就可以完成训练目标。

问题二:多目标学习是如何实现的?

多目标学习,目的是在一个模型中实现多种风格。我们可以先从一个模型实现一种风格开始,然后逐渐扩大模型,加入风格化的变量,将不同的风格区分开来,避免目标之间的冲突。模型中需要有一个体现风格目标的嵌入变量。另外,还可以通过在已有模型上叠加不同的Lora模型来实现多目标,因为Lora是一个比较轻量级的网络,可以不断往上添加。

问题三:对于多目标强化学习若干个目标之间还有比较强的联系。那您这块有什么建议吗?

对于多目标强化学习,多个目标之间存在较强的联系,可以考虑将它们视为一个整体,使用传统的multi-objective方法进行求解。这种方法可以通过优化一个总体目标来综合考虑多个目标,寻求一个多目标最优解。

同时,也可以考虑采用优先级层次结构或权重的奖励函数等方法,将多个目标整合为一个总体目标,并根据优先级或权重进行优化。

然而,这些方法可能会增加计算的复杂度,特别是对于实际应用中的大规模问题。因此,在选择方法时需要权衡计算复杂度和求解效果。此外,还需要根据具体问题进行调整和优化,以获得更好的结果。

以上就是本次分享的内容,谢谢大家。

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

分享嘉宾

INTRODUCTION

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

胡裕靖 博士

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

网易

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

人工智能研究员

网易伏羲游戏AI Bot的拟人化和风格化:AIGA赋能游戏探索

胡裕靖先后在2010年和2015年于南京大学计算机科学与技术系获得学士和博士学位。胡裕靖于2016年加入阿里巴巴,从事强化学习在搜索推荐方面的应用研究工作;又于2018年加入网易伏羲实验室,担任人工智能研究员,主要从事在强化学习在游戏AI方面的研究工作。胡裕靖目前为网易伏羲强化学习研究负责人,已在人工智能和机器学习国际顶级会议和期刊上发表论文30余篇,包括:NeurIPS、ICML、ICLR、IJCAI、AAAI、AAMAS、KDD等

🎁限时福利

🎁观看学习视频满10分钟,可免费领取DataFunPro会员年卡1张

👇点击阅读原文”,进群直播间,并查看领取方式

 

Read More 

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 
评论(没有评论)
Generated by Feedzy