Paddle对话故事续写, 创造你的无限世界

  • 如果可以,你最想穿越到哪部电影,小说里?
  • 这次利用 GPT2 文本生成和 wechaty 对话展开故事续写,与 AI 互动共同创造剧情
  • 预先设置你想交互的世界场景,比如面对三体人的进攻,发挥你的脑洞输入你想到的任何动作或者剧情大纲,模型的续写保证让你赞(hei)不(ren)绝(wen)口(hao)

项目介绍

本地测试

github 中有具体的本机部署流程

本 notebook 中代码则是运行在命令行体验

灵感来源

  • 跑团:一个桌面角色扮演游戏,主持人描述剧情,其他人来推动剧情,每个人有自己的职业、技能等等。

  • 无限流: 穿越到各个电影,动漫,小说中与原剧情互动。参考作品:幻影英雄,魔方大厦,无限恐怖。

  • AI Dungeon : 这是世界上第一款真正意义上纯 AI生成的文字冒险游戏, 通过这款 AIDungeon 2 ,玩家将接触到一个完全自由的虚拟世界。整个游戏世界,都将围绕着玩家的输入展开与续写,可谓真正的 Everything is in my hands

    https://play.aidungeon.io/main/home

生成样例展示

  • 示例1:
主神阿巴:冰冷,抖动……醒来的瞬间,你猛的从地面跳了起来,惊慌的看向四周,脑海里的办公室环境和眼前的环境瞬间出现了混淆,几秒之后你从混淆里清醒过来。现在你来到一个城市之中,丧尸在街道上嘶吼,你意识到核弹将在一小时后降临。我:环顾四周,看看有没有防身的武器主神阿巴: 是否有可能存活下去。 我:突然在旁边发现一把手枪,装满了子弹,这时,一只丧尸冲了出来主神阿巴:毫不犹豫的向丧尸头部开枪,然后丧尸倒地,亡。我:看看周围有没有能发动的汽车,尽快逃离这座城市主神阿巴:丧尸围了过来,你不得以跑向旁边的建筑,此时你来到一个地下实验室,旁边冰冷的警报声在提示着你T病毒已经泄露,一管病毒试剂摆在你面前。
  • 示例2:
我: 最后我开始反攻三体世界主神阿巴:借助科技,我终于变出了超英赶美,猩红的双眼中闪烁着人类坚定的眼神,超英基地将被我攻陷,下一秒,无数丧尸朝我冲来,记住用喷火器,嗯,我是革命战士,拿起手中的那根电锯,万物一体,指向丧尸大迁徙的方向......我:最后赶超英美,达到世界和平主神阿巴:达到世界霸权,走向威武雄狮的彩虹之路......(好像越来越不押韵了) 先更到这里,有时间再来补个结局<eod>改行IT 到底有没有前途? 我是一个毕业了一年的 程序员 ,苦逼的生活让我找份工作都是挑战。无处可逃的你跑到了“自然选择”号飞船的队伍之中,你意识到三体人的舰队即将抵达,章北海会劫持飞船逃离太阳系。我: ???

B站链接

安装依赖

# 注意想体验 gpt2 必须安装这个版本
!pip install paddlehub==2.0.4 paddlenlp==2.0.0rc14 sentencepiece==0.1.92

创建Model并加载官方预训练模型

  • PaddleNLP 中内置了许多预训练语义模型参数,其中就包括中文 GPT2 模型
  • 通过 GPT2ForPretraining.from_pretrained('gpt2-base-cn') 就可以调用内置的预训练模型参数
  • 安装高版本 paddlenlp 则可以 GPTForPretraining.from_pretrained('gpt-cpm-small-cn-distill') 体验CPM等模型
import paddle
import paddle.nn as nn
import numpy as np
import paddlehub as hub
from paddlenlp.transformers import *
import queueclass Model():def __init__(self):# self.model = GPTForPretraining.from_pretrained('gpt-cpm-small-cn-distill')self.model = GPT2ForPretraining.from_pretrained('gpt2-base-cn')self.model.eval()# self.tokenizer = GPTChineseTokenizer.from_pretrained('gpt-cpm-small-cn-distill')self.tokenizer = GPT2ChineseTokenizer.from_pretrained('gpt2-base-cn')self.tokenizer.encode('.') # 初始化def top_k_top_p_filtering(self, logits, top_k=0, top_p=1.0, filter_value=-float('Inf')):top_k = min(top_k, logits.shape[-1])  # Safety checklogits_np = logits.numpy()if top_k > 0:# Remove all tokens with a probability less than the last token of the top-kindices_to_remove = logits_np < np.sort(logits_np)[-top_k]logits_np[indices_to_remove] = filter_valueif top_p < 1.0:sorted_logits = paddle.sort(logits, descending=True)sorted_indices = paddle.argsort(logits, descending=True).numpy()cumulative_probs = paddle.cumsum(paddle.nn.functional.softmax(sorted_logits, axis=-1), axis=-1).numpy()# Remove tokens with cumulative probability above the thresholdsorted_indices_to_remove = cumulative_probs > top_p# Shift the indices to the right to keep also the first token above the thresholdsorted_indices_to_remove[...,1:] = sorted_indices_to_remove[..., :-1]sorted_indices_to_remove[..., 0] = 0indices_to_remove = sorted_indices[sorted_indices_to_remove]logits_np[indices_to_remove] = filter_valuereturn paddle.to_tensor(logits_np)def sample(self, text, max_len=32, end_word='。', repitition_penalty=1.0, temperature=1.0, top_p=0.9):with paddle.no_grad():# 终止标志if end_word is not None:stop_id = self.tokenizer.encode(end_word)if 'input_ids' in stop_id: # 判断使用 cpm 的情况stop_id = stop_id['input_ids']stop_id = stop_id[-1]ids = self.tokenizer.encode(text)if 'input_ids' in ids: # 判断使用 cpm 的情况 ids = ids['input_ids']input_ids = paddle.to_tensor(ids).unsqueeze(0)else:input_ids = paddle.to_tensor(np.array(ids).reshape(1, -1).astype('int64'))output, cached_kvs = self.model(input_ids, use_cache=True)next_token_logits = output[0, -1, :]for id in set(ids):next_token_logits[id] /= repitition_penaltynext_token_logits = next_token_logits / temperaturefiltered_logits = self.top_k_top_p_filtering(next_token_logits, top_k=0, top_p=1.0)next_token = paddle.multinomial(paddle.nn.functional.softmax(filtered_logits, axis=-1), num_samples=1).numpy()ids += [int(next_token)]response = [int(next_token)] # 只要后面生成的话for i in range(max_len):input_id = paddle.to_tensor(np.array([next_token]).reshape(1, -1).astype('int64'))output, cached_kvs = self.model(input_id, use_cache=True, cache=cached_kvs)next_token_logits = output[0, -1, :]for id in set(ids):next_token_logits[id] /= repitition_penaltynext_token_logits = next_token_logits / temperaturefiltered_logits = self.top_k_top_p_filtering(next_token_logits, top_k=0, top_p=1.0)next_token = paddle.multinomial(paddle.nn.functional.softmax(filtered_logits, axis=-1), num_samples=1).numpy()ids += [int(next_token)]response += [int(next_token)]# 根据终止标志停止预测if (end_word is not None) and (int(next_token) == stop_id):break# 如果使用 cpm, 截止8.3日的tokenizer还没有deocde方法if hasattr(self.tokenizer, 'convert_ids_to_string'):return self.tokenizer.convert_ids_to_string(response)return self.tokenizer.decode(response)

设定世界观

background_events = ['现在你来到一个城市之中,丧尸在街道上嘶吼,你好像是来到了是浣熊市,而核弹将在一小时后降临。','历经千辛万苦,你来到一个地下实验室,旁边冰冷的警报声在提示着你T病毒已经泄露,一管病毒试剂摆在你面前。','你来到了三体世界,你身上沾染的病毒不小心泄露到了这个世界,现在整个世界都在面临生化危机。','无处可逃的你跑到了“自然选择”号飞船的队伍之中,你意识到三体人的舰队即将抵达,章北海会劫持飞船逃离太阳系。',
]class World():def __init__(self):self.init = Falseself.model = Model()def sample(self, sentence):outputs = self.model.sample(sentence, # 输入文本max_len=128, # 最大生成文本的长度end_word='。', # 碰到句号生成结束)return outputsdef start(self):self.context_list = ['冰冷,抖动……醒来的瞬间,你猛的从地面跳了起来,惊慌的看向四周,脑海里的办公室环境和眼前的环境瞬间出现了混淆,几秒之后你从混淆里清醒过来。',]self.lastPoint = 1self.init = Trueself.worlds_event = queue.Queue(maxsize=0)for i in background_events:i = i.replace('\n','')self.worlds_event.put(i)event = self.worlds_event.get()self.context_list.append(event)return ''.join(self.context_list)def receive(self, user_input):if self.worlds_event.empty():print('你的冒险已经结束')return '你的冒险已经结束'user_output = ''inputs = user_input + ','self.context_list.append(inputs)context = ''.join(self.context_list) # 可以选择完整的历史记录# context = ''.join(self.context_list[-2:]) # 选择最近的几条聊天历史# context = self.summary(self.context_list) # 对之前的对话历史做文本摘要user_output = self.sample(context)self.context_list.append(user_output)self.lastPoint += 1if self.lastPoint % 4 == 0:if self.worlds_event.empty():print(user_output, '结束啦')return '你的冒险已经结束'event = self.worlds_event.get()self.context_list.append(event)user_output = user_output + eventprint(user_output)return user_output

载入模型

# 这里要下载一个 gpt 13个G,耐心等待
world = World()

开始游戏

  • 由于硬件显存问题,多次运行可能遇到***out of memory***的问题,需重启执行器
print(world.start())
while True:ans = input()print(ans)if world.receive(ans) == '你的冒险已经结束':break
冰冷,抖动……醒来的瞬间,你猛的从地面跳了起来,惊慌的看向四周,脑海里的办公室环境和眼前的环境瞬间出现了混淆,几秒之后你从混淆里清醒过来。现在你来到一个城市之中,丧尸在街道上嘶吼,你好像是来到了是浣熊市,而核弹将在一小时后降临。
爱丽丝在吗,不在我就往城外跑,顺便打一打路上的丧尸
我们可以打退他们的进攻。
其实我觉得打退不了,他们太多了,一会儿爆炸了怎么办啊
要不看看倒计时,六秒之后,我就成功逃走了...... 地图上的的标志都变成了一个红色的半径。
??那我往哪儿跑的,要不朝厕所跑吧
好远啊,你又不像打游戏跑地图的,不会迷路。历经千辛万苦,你来到一个地下实验室,旁边冰冷的警报声在提示着你T病毒已经泄露,一管病毒试剂摆在你面前。
富人靠科技,穷人靠变异,打了这针我就可以进化了
直接变怪兽,这样也成啊。
这是生化危机,不是虐杀原型,现在我可以一路杀过去了
扮猪吃老虎。
那我最后跑到了城外,活了下来
幸好我记得一切的一切,但为什么眼前的女孩子是我?满眼满眼地都是,窒息的感觉,只能一闭眼,人生真是不公啊,第一眼就可以知道人家想的什么。
我打了针反而变成了女生,可我想变的是超人
猩红的双眼,喷涌而出火热的鲜血。你来到了三体世界,你身上沾染的病毒不小心泄露到了这个世界,现在整个世界都在面临生化危机。
让我找个安全的地方,朝着南北极出发
弗瑞奥的家很近啊。
找到一个北极的地下基地,让我看看怎么阻止世界末日吧
这样可以有较多的时间与这个世界宝贵的人类在一起了。
最后我开始反攻三体世界
借助科技,我终于变出了超英赶美,猩红的双眼中闪烁着人类坚定的眼神,超英基地将被我攻陷,下一秒,无数丧尸朝我冲来,记住用喷火器,嗯,我是革命战士,拿起手中的那根电锯,万物一体,指向丧尸大迁徙的方向......命运啊,不要让我一路做着坏事,背上那黑黝黝的兽皮北向,这些都为我铺好了成功的
最后赶超英美,达到世界和平
达到世界霸权,走向威武雄狮的彩虹之路......(好像越来越不押韵了) 先更到这里,有时间再来补个结局<eod>改行IT 到底有没有前途? 我是一个毕业了一年的 程序员 ,苦逼的生活让我找份工作都是挑战。无处可逃的你跑到了“自然选择”号飞船的队伍之中,你意识到三体人的舰队即将抵达,章北海会劫持飞船逃离太阳系。
好的好的知道了,那我就开启流浪地球计划
你的冒险已经结束

总结

  • 利用PaddleNLP和其内置的中文预训练模型,可以实现简单的文本生成任务
  • 为了保证剧情顺畅可延续,需要预先定义部分关键剧情,比如“一管病毒试剂摆在你面前你要怎么做”等等。
  • 现在没有finetune,生成故事的质量参差不齐, 如果有特定语料微调效果会更好, 但经过最新测试,低估了数据获取的难度,没有合适的上文,动作,下文的数据集
  • 而通过自己标注的样本去 finetune GPT-2,测试发现几十个样本的 finetune 效果几乎为0
  • 原版的Ai Dungeon 已经向我们展示了在有良好的训练流程,训练数据的情况下,这种游戏可以达到一个什么样的水平。不论这类项目的思路是不是未来游戏发展的方向,但毫无疑问会在某些地方发挥重要的作用。比如让游戏中的NPC有一定程度的可交互性,与文字工作者进行头脑风暴,提供创作灵感等等。

参考项目

  • 构建一个经典的文本生成模型GPT-2

  • 让AI帮你写文章吧

关于

天津大学语言与心理计算 LMc Lab, 研究方向为智能对话与心理计算,个性化推荐等

欢迎大家有问题留言交流学习,共同进步成长

AI创造营:Paddle 对话故事生成,创造自己的无限世界相关推荐

  1. AI创造营~AnimeGAN一键生成日系动漫Vlog

    目录: AI创造营-AnimeGAN一键生成日系动漫Vlog 引子 效果展示图 动漫化结果 一.安装相关的库 二.函数 三.从视频提取图像 四.图像转换为动漫风格并合成新的视频 五.添加原始音频 六. ...

  2. 深度对话之小舟与他的无限世界

    访谈人物:小舟(插画师.儿童美术编辑) 小舟主页:http://www.xzch.com/ 采访人:Relen (relen.com) Relen导言:初识小舟的作品,也会产生刹那的惊艳,尽管它们是一 ...

  3. AI创造营作品路演来袭,助力你心中的NO.1!

    点击左上方蓝字关注我们 PaddlePaddle × Wechaty × Mixlab 创意赛再升级!人工智能时代的ChatBot需要具备哪些能力?由你来定义!参赛的小伙伴们果然各显神通,快来pick ...

  4. AI创业营第三期拉开帷幕:生存训练+思想盛宴

    上周三,AI创业营第三期50多位学员集结完毕,并展开首个模块的学习.他们也被称为目前的"人工智能最强战队". 在随后的四天时间里,学员们在AI创业营中先后经历48小时荒野求生.世界 ...

  5. 飞浆领航团AI达人创造营第01课|让人拍案叫绝的创意都是如何诞生的?

     时间:2021年7月27日 下午18:25 内容:创意的获取渠道和创意的评估方法 昨晚看了飞桨领航团AI达人创造营的第一节直播,现在将第一节的笔记以及感受整理如下,依次来激励自己的后续学习,希望能过 ...

  6. 笔记 | 百度飞浆AI达人创造营:深度学习模型训练和关键参数调优详解

    笔记 | 百度飞浆AI达人创造营:深度学习模型训练和关键参数调优详解 针对特定场景任务从模型选择.模型训练.超参优化.效果展示这四个方面进行模型开发. 一.模型选择 从任务类型出发,选择最合适的模型. ...

  7. Metaverse启动机之重构现世,AI创造营创意赛开启

    ibrandup @shadow 听说最近又有好玩的竞赛啦? Metaverse启动机 2021.7.9 AI创造营 创意赛正式发布 近日,由百度大脑AI Studio平台发布,PaddlePaddl ...

  8. 【AI创造营】基于PaddleHub与Jetson Nano的智能宠物看护助手

    基于PaddleHub与Jetson Nano的智能宠物看护助手 一.效果展示 二.实现思路 1.训练一个适用于该需求的模型 2.使用PaddleHub预训练模型 三.数据采集 硬件部分 代码部分 四 ...

  9. AI创造营来了!万元奖金、Switch等你来拿...

    点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 朋友,看青你和创了吗? 牛年最先牛起来的无疑是这两档选秀节目,100多位小哥哥轮番上阵,每个观众都能pick ...

最新文章

  1. 2021研究生报告新鲜出炉!博士每年招生超10万人
  2. python电脑如何下载软件-Python如何下载文件
  3. INV标准报表+INVARAAS.rdf -- ABC分配报表
  4. 多媒体计算机辅助教学与课件制作,清华大学出版社-图书详情-《计算机辅助教学多媒体课件设计制作与应用》...
  5. 一篇关于web.xml配置的详细说明(一)
  6. DaDa英语宣布12月31日起全面停止所有外教服务
  7. php 5.4.25,php5.4.25的c核心用vs2008sp1编译无法通过。解决思路
  8. ESFramework介绍之(28)―― Udp组件
  9. 苹果cms怎么添加友情链接图文教程
  10. 三菱5uplc伺服电机指令_PLC中伺服控制指令的应用
  11. 一种使用16QAM的OFDM系统MATLAB仿真
  12. 2022年湖北师范大学招生简章--成人高等教育高起专、专升本学历提升
  13. 苹果手机怎么扩大内存_一招教你扩大手机虚拟内存,免费换个新手机
  14. blender报错“RuntimeError: Operator bpy.ops.object.mode_set.poll() Context missing active object”
  15. 853-两台计算机之间是如何通信的?
  16. jQuery中的die()与live()的用法
  17. Spring boot Shiro 用户认证
  18. html5制作毕业光盘,同学聚会的视频和照片编辑制作,最后刻录成光盘 每人一张(数据刻录)...
  19. vue 祖孙组件通信, 祖组件获取孙组件数据
  20. java实现第七届蓝桥杯凑平方数

热门文章

  1. 国产兼容三菱FX3U源码 ,修改监控时卡顿问题。 8位口令功能,程序消除功能
  2. 鼠标移动出现小手与溢出部分以省略号显示
  3. 【数据清洗预处理——四】使用大数据实训云
  4. 博微三维技术篇【四】——大规模、高精度三维场景渲染
  5. 创维光伏:坚持科技创新,构建中国式现代化光伏生态体系
  6. VS2017打包安装包
  7. cglib 动态代理和 jkd 动态代理
  8. 无线视频传输的应用场景及优势
  9. 莆田学院计算机系是不是师范类,莆田学院2010会计学、计算机科学与技术拟各招一个海外合作班...
  10. 3小时越洋电话,以太猫创始人Benny Giang首次向中国媒体全面透露以太猫的那些事(含独家原型手稿) | 人物志...