当前位置: 首页 > news >正文

MindSpore应用案例——AI诗人

我们深知一款没应用的平台软件是缺乏生命力的,因此我们会陆续推出一些使用案例,一方面让大家更直观地了解MindSpore的应用场景,也能帮助用户端到端地上手。

l 首先看下案例效果:

该案例目前支持三种模式:随机生成、续写诗句和藏头诗,使用MindSpore官网提供的预训练checkpoint在古诗词数据集上Fine-tuning 20个epoch,可获得如下效果

随机生成:

大堤柳暗,春深树根。

东望一望,断回还家。

山色渐风雨,东风多雨禾。

无情与去,万里所思。

续写天下为公:

天下为公少,唯君北向西。

远山无路见,长水见人偏。

一路巴猿啸,千峰楚客啼。

幽深有诗策,无以话年华。

藏头诗人工智能:

人君离别难堪望,工部张机自少年。

智士不知身没处,能令圣德属何年。

l 性能数据:

BERT网络对于数据的利用率是偏低的,一句样本只使用了15%的信息用于训练,而BERT训练的数据集又是容易大量获取的,那么提高训练吞吐量就是一个显而易见的决定性问题。MindSpore将BERT模型作为benchmark网络之一进行调优,通过例如算子融合、集合通信优化等手动,从提高计算效率,降低通信开销等多个方面提高性能,同时配合硬件亲和的算子优化等方法,在单机8卡的标准昇腾服务器,实现了每秒处理超过2700条样本。实际使用过程中根据不同场景还可以利用梯度累加等手段进一步提升吞吐量。

具体测试环境及数据如下:

网络结构

运行环境

版本

吞吐量

L=24,H=1024, A=16 Seq_length=128

8 * Ascend910

0.7.0

2712.44
sequence/sec

业界其他开源框架数据可参考

BERT For TensorFlow:github.com/NVIDIA/DeepL

本案例中,MindSpore使用了当前业界NLP领域的当红炸子鸡模型BERT:

图 1 BERT模型结构[1]

BERT模型结构如图 1所示,模型的输入是两“句”话,这里的一“句”话并不是以句号分隔,一段连续的话(包含若干个句号)都是一“句”话。以中文为例,一“句”话的每一个字都对应为一个token,会在首位插入[CLS],在两“句”话中间插入[SEP],这两个特殊标识位。

深度学习模型无法直接处理汉字或者单词,需要将汉字/单词映射为词向量,在BERT-base模型中,每一个token会被映射为一个768维度的向量,每一个汉字/单词都有其对应的词向量,此词向量也是需要被更新的参数。

如果只有一个词向量,那么输入中不同位置上的同样的字就会映射为相同的向量,所以需要加入其对应的位置信息。而位置信息包含两个部分,每个字所处的绝对位置以及这个字处于那一“句”话,会将这两个位置信息都映射为其对应的向量。所以每一个token对应的向量是

Input_vector = word_vector + position_vector + token_type_vector

BERT模型是基于Encoder 的结构,关于Transformer结构的详细介绍可以参考Jay Alammar的博客[2]。BERT-base模型是12层Encoder,词向量维度是768;BERT-large模型是24层的Encoder,词向量维度是1024,对应的参数量分别是1.1亿和3.4亿个。

每一个token对应的输入向量经过模型处理之后,得到一个对应的输出向量,维度保持不变,此输出向量包含了高维的语义信息,可以用来做后续任务。

l 模型的训练的两个阶段:Pre-training和Fine-tuning

Pre-training

Pre-training阶段会用海量的无标签数据进行自编码训练,期望通过海量的数据训练,让BERT学到人类语言的一般规律,因此训练任务的设计尤为重要。BERT中的Pre-training包含两项任务MLM(Masked Language Model)和NSP(Next Sentence Prediction)。

MLM任务是在输入时,随机将部分token置换为一个特殊标识符[MASK],然后由其对应的输出词向量预测此原始输入token。这个任务不需要额外的标签,而且迫使模型通过遮盖token的上下文推断出原始token,这样必须要理解一些语义信息,学习上下文的对应关系。

BERT的输入是两“句”相连的话A和B,NSP任务是以50%的概率随机替换掉B,使得A与B不是相连的两“句”话,然后由[CLS]对应的输出向量判断输入的两“句”话是否是相连的。在MLM基础上再增加一个NSP任务,是考虑到实际任务中并没有MLM这种任务,增加一个更符合实际任务类型的预训练任务。

从上述描述中可以看出,Pre-training并不需要任务数据标签,通过预训练阶段的任务设置,BERT可以从无标签数据中学到基础语义逻辑,然后配合Finetune过程完成特定任务训练。

Fine-tuning

在Pre-training中,并没有针对特定下游任务训练,会得到一个通用模型,此模型在不同下游任务上表现不尽相同,因此增加一个针对特定下游任务的Fine-tuning过程。Fine-tuning会使用特定下游任务的有标签的数据,进行少量训练。

通常情况下,Pre-training需要极大的数据与算力,而Fine-tuning是在相对小型的数据集上进行微调,大家可以在MindSpore官网下载BERT的预训练ckpt[3]。

l 模型改造:

BERT采用双向注意力机制即当前token可以看到它之前和之后的所有token,这样可以更好地理解整个输入的语义,从而可以更好地对输入做推断任务。然而对于生成式任务来说,当前token应当只能看到它之前的token,在之前token的基础上生成下一个token,因此需要对BERT模型的注意力机制进行调整。

BERT中是通过attention_mask来控制注意力机制,对应位置为1表示可以看到此token,默认attention_mask是全1的,即每个token之间都可以互相看到。要改为生成式模型,需要控制此attention_mask为下三角矩阵,即每个token只能看到自己及之前的token。

数据集为40000多首古诗词,取一首古诗词作为输入,经过BERT模型得到对应输出向量,训练任务设置为让每一个token的对应输出向量尽可能接近其下一个输入token,如图 2所示。当前设置[CLS]直接映射为第一个输入token其实略显草率,后续对此位置做优化调整。

图 2 训练流程示意图

如此一来,我们改造后的BERT模型就可以胜任智能写诗的任务了。在推理时,每次生成一个字,然后拼接起来作为下一次的输入,循环往复,直至生成完整诗句。

l 以Serving方式部署推理服务:

MindSpore目前还提供了部署推理服务—MindSpore Serving,这是一个轻量级、高性能的服务模块,旨在帮助MindSpore开发者在生产环境中高效部署在线推理服务。上述的智能写诗模型的训练及部署预测服务,具体流程如图 3所示。

图 3 训练及部署流程图

在云侧或本地服务器训练完毕后,可以将模型导出为MINDIR格式,然后通过MindSpore Serving在服务器侧启动部署推理服务,用户在网页上发出推理任务申请,通过MindSpore Serving在服务器侧完成推理并将生成的诗句返回给用户。

l 完整样例代码介绍:

模型相关代码及部署推理服务相关代码均可由此点击下载,代码结构如下

└─BERT_poetry
├── src
├── BERT_for_pre_training.py # 封装BERT-Base正反向网络类
├── BERT_model.py # 定义BERT正向网络结构
├── finetune_config.py # Fine-tuning配置文件
├── fused_layer_norm.py # 定义fused_layer_norm
├── __init__.py # __init__
├── utils.py # 定义Fine-tuning正向网络结构
├── poetry_dataset.py # 部分代码取自[4],解析poetry.txt,生成所需dataset
├── vocab.txt # 词汇表
├── generator.py # 部分代码取自[4],推理生成诗句使用函数
├── poetry.py # 训练、推理、导出函数
├── serving
├── ms_serving # 启动服务器侧serving
├── BERT_flask.py # 服务器侧接收requests请求
├── poetry_client.py # 客户端代码
├── ms_service_pb2_grpc.py # 定义了grpc相关函数供BERT_flask.py使用
└── ms_service_pb2.py # 定义了protocol buffer相关函数供BERT_flask.py使用

先在环境中安装BERT4keras[5],会用到其中的分词器Tokenizer和加载词表的函数load_vocab,使用的数据集可以从[4]中下载poetry.txt。

l 参考资料

[1] BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding

[2] jalammar.github.io/illu

[3] https://www.MindSpore.cn/docs/zh-CN/master/network_list.html

[4] github.com/AaronJny/Dee

[5] github.com/bojone/BERT4 

相关文章:

  • cordova 使用
  • 常见ai智能机器人呼叫中心等如何让短信营销更加有价值?
  • 极端气候肆虐催化,碳中和带出了一个“再生时代”
  • Cyclopropene-PEG-MAL Maleimide|环丙烯-聚乙二醇-马来酰亚胺
  • 大学生入学该准备哪些东西?Ipad好用电容笔测评
  • Redis 启动失败,appendonly.aof 损坏
  • 教育管理系统功能点
  • arthas调查内存溢出 kibana宕机导致内存溢出
  • pandas分析数据常用代码【自用】
  • web逆向 知识小结
  • nestjs typeorm Error: Entity metadata was not found错误解决。
  • div实现长按功能。长按事件
  • IDEA 2021 自动导包设置
  • C++ 完美转发是啥
  • 面包屑实现路由跳转
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • 07.Android之多媒体问题
  • CSS实用技巧干货
  • HashMap ConcurrentHashMap
  • JavaScript-Array类型
  • Vue.js 移动端适配之 vw 解决方案
  • 解决iview多表头动态更改列元素发生的错误
  • 经典排序算法及其 Java 实现
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 前端之Sass/Scss实战笔记
  • 使用putty远程连接linux
  • 首页查询功能的一次实现过程
  • 因为阿里,他们成了“杭漂”
  • 与 ConTeXt MkIV 官方文档的接驳
  • Nginx实现动静分离
  • 阿里云服务器如何修改远程端口?
  • ​2021半年盘点,不想你错过的重磅新书
  • #《AI中文版》V3 第 1 章 概述
  • #include
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (0)Nginx 功能特性
  • (MATLAB)第五章-矩阵运算
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (附源码)ssm码农论坛 毕业设计 231126
  • (三)docker:Dockerfile构建容器运行jar包
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (循环依赖问题)学习spring的第九天
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • .apk 成为历史!
  • .net core 依赖注入的基本用发
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .NET4.0并行计算技术基础(1)
  • .NET连接MongoDB数据库实例教程
  • @Autowired和@Resource的区别
  • @Bean注解详解
  • @WebServiceClient注解,wsdlLocation 可配置
  • [android] 手机卫士黑名单功能(ListView优化)
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)