AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

如何利用 TensorFlow Hub 让 BERT 开发更简单?

  • 2021-01-14
  • 本文字数:3818 字

    阅读完需:约 13 分钟

如何利用TensorFlow Hub 让BERT开发更简单?

在自然语言处理领域,BERT 和其他 Transformer 编码器架构都非常成功,无论是推进学术基准的技术水平,还是在 Google Search 这样的大规模应用中,均是如此。BERT 自 TensorFlow 创建以来一直可用,但它最初依赖于非 TensorFlow 的 Python 代码,以将原始文本转换为模型输入。

 

如今,在 TensorFlow 中构建 BERT 会更加简单。开发者可在 TensorFlow Hub 上使用预训练编码器和匹配的文本预处理模型。在 TensorFlow 中运行 BERT 对文本输入的操作只需要几行代码:

 

# Load BERT and the preprocessing model from TF Hub.preprocess = hub.load('https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/1')encoder = hub.load('https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3')

# Use BERT on a batch of raw text inputs.input = preprocess(['Batch of inputs', 'TF Hub makes BERT easy!', 'More text.'])pooled_output = encoder(input)["pooled_output"]print(pooled_output)

tf.Tensor([[-0.8384154 -0.26902363 -0.3839138 ... -0.3949695 -0.58442086 0.8058556 ] [-0.8223734 -0.2883956 -0.09359277 ... -0.13833837 -0.6251748 0.88950026] [-0.9045408 -0.37877116 -0.7714909 ... -0.5112085 -0.70791864 0.92950743]],shape=(3, 768), dtype=float32
复制代码

 

这些编码器和预处理模型已经用 TensorFlow Model Garden 的 NLP 库构建,并以 SavedModel 格式导出到 TensorFlow Hub。实际上,预处理使用 TF.text 库中的 TensorFlow ops 输入文本进行标记化:允许开发者建立自己的 TensorFlow 模型,将原始文本输入到预测输出,而无需使用 Python 的循环。这样可以提高计算速度,去除样板代码,减少出错的可能性,并且可以将整个文本序列化为输出模型,使得 BERT 在生产环境中更容易使用。

 

为了详细说明这些模型的具体作用,我们发布了两个新的教程:

 

  • 初级教程:解决一项情感分析任务,不需要任何特殊定制,就能得到很好的模型质量。这是最简单的使用 BERT 和预处理模型的方法。

  • 高级教程:解决了在 TPU 上运行 GLUE 基准中的自然语言处理分类任务。它还说明了如何在需要多段输入的情况下使用预处理模型。

 

选择 BERT 模型

 

BERT 模型是在大型文本语料库(例如,Wikipedia 文章的归档)上使用自我监督任务进行预训练的,比如根据上下文预测句子中的单词。这种类型的训练使模型能够在没有标记数据的情况下学习文本语义的强大表示。但是训练它需要大量的计算:在 16 个 TPU 上花费 4 天的时间(如 2018 年 BERT 论文所报道的)。所幸的是,在这种昂贵的预训练完成一次后,我们就可以为许多不同的任务高效地重用这种丰富的表示了。

 

  • 八个 BERT 模型是与 BERT 原始作者发布的训练权重一起提供的。

  • 24 个 Small BERT 具有相同的通用架构,但 Transformer 会更少或更小,这让你可以探索速度、尺寸和质量之间的权衡。

  • ALBERT:这是四种不同大小的“A Lite Bert”,通过在层之间共享参数来减少模型大小(但不是计算时间)。

  • 8 个 BERT Experts 都具有相同的 BERT 架构和大小,但是为预训练域和中间微调任务提供了不同的选择,以便更好地配合目标任务。

  • Electra 具有与 BERT 相同的架构(有三种不同的大小),但在预训练时作为判别器,类似于生成对抗网络(Generative Adversarial Network,GAN)。

  • BERT 与 Talking-Heads Attention 和 Gated GELU [base, large] 对 Transformer 架构的核心进行了两个改进。

  • Lambert 已经接受了一些由 LAMB 优化器和 Roberta 提供的技术训练。

  • .......

 

这些模型是 BERT 编码器。上述链接将可以访问 TF Hub 上的文档,其中提到了各自所使用的正确的预处理模型。我们建议开发者访问这些模型页面,以便了解更多关于每个模型所针对的不同应用场景。基于其通用界面,通过更改编码器模型及其预处理的 URL,可以方便地对不同编码器进行特定任务的性能实验和比较。

预处理模型

 

对于每个 BERT 编码器,都有一个匹配的预处理模型。它使用 TF.text 库提供的 TensorFlow ops,它可以将原始文本转换为编码器所期望的数字输入时序。不像纯 Python 的预处理那样,这些操作可以作为 TensorFlow 模型的一部分,用于直接从文本输入中提供服务。每个 TF Hub 的预处理模型都已经配置了词汇表及其相关的文本归一化逻辑,无需进行进一步的设置。

 

前面我们已经介绍了最简单的预处理模型的使用方法,接下来让我们仔细看看。


preprocess = hub.load('https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/1')input = preprocess(["This is an amazing movie!"]) {'input_word_ids': <tf.Tensor: shape=(1, 128), dtype=int32, numpy=  array([[ 101, 2023, 2003, 2019, 6429, 3185,  999,  102,    0,  ...]])>, 'input_mask': <tf.Tensor: shape=(1, 128), dtype=int32, numpy=  array([[   1,    1,    1,    1,    1,    1,    1,    1,    0,  ...,]])>, 'input_type_ids': <tf.Tensor: shape=(1, 128), dtype=int32, numpy=  array([[   0,    0,    0,    0,    0,    0,    0,    0,    0,  ...,]])>}
复制代码

 

像这样调用 preprocess() 可以将原始文本输入转换为固定长度的 BERT 编码器输入序列。你可以看到,它由一个张量 input_word_ids 组成,其中包含了每个标记化输入的数字 id,包括开始、结束和填充标记,再加上两个辅助张量:一个 input_mask(用于区分非填充和填充标记)和每个标记的 input_type_ids(可以区分每个输入的多个文本段,我们将在下面讨论)。

 

相同的预处理 SavedModel 还提供了更细粒度的 API,支持在编码器的一个输入序列中使用一个或两个不同的文本段。下面我们来看一个句子蕴含任务:

 

text_premises = ["The fox jumped over the lazy dog.",                 "Good day."]tokenized_premises = preprocess.tokenize(text_premises) <tf.RaggedTensor  [[[1996], [4419], [5598], [2058], [1996], [13971], [3899], [1012]],  [[2204], [2154], [1012]]]> text_hypotheses = ["The dog was lazy.",  # Entailed.                   "Axe handle!"]        # Not entailed.tokenized_hypotheses = preprocess.tokenize(text_hypotheses) <tf.RaggedTensor  [[[1996], [3899], [2001], [13971], [1012]],  [[12946], [5047], [999]]]>
复制代码

 

每个标记化的结果是一个数字 token idRaggedTensor,完整地表示每一个文本输入。如果某些前提和假设对太长,无法在下一步用于 BERT 输入的 seq_length 内适应,则可以在这里进行额外的预处理,比如修剪文本段或将其分割成多个编码器输入。

 

然后,将标记化的输入打包为用于 BERT 编码器的固定长度的输入序列:

 

encoder_inputs = preprocess.bert_pack_inputs(   [tokenized_premises, tokenized_hypotheses],   seq_length=18)  # Optional argument, defaults to 128. {'input_word_ids': <tf.Tensor: shape=(2, 18), dtype=int32, numpy=  array([[  101,  1996,  4419,  5598,  2058,  1996, 13971,  3899,  1012,            102,  1996,  3899,  2001, 13971,  1012,   102,     0,     0],         [  101,  2204,  2154,  1012,   102, 12946,  5047,   999,   102,              0,     0,     0,     0,     0,     0,     0,     0,     0]])>, 'input_mask': <tf.Tensor: shape=(2, 18), dtype=int32, numpy=  array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],         [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]])>, 'input_type_ids': <tf.Tensor: shape=(2, 18), dtype=int32, numpy=  array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],         [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]])>}
复制代码

 

打包的结果是已经熟悉的 input_word_idsinput_maskinput_type_ids(第一个和第二个输入分别为 0 和 1)。所有输出都有一个公共的 seq_length(默认为 128)。在打包过程中,超过 seq_length 的输入被截断为大致相等的大小。 

加速模型训练

 

TensorFlow Hub 将 BERT 编码器和预处理模型作为独立的部分,用于加速训练,特别是在 TPU 上。

 

张量处理单元(Tensor Processing Units,TPU)是 Google 定制开发的加速器硬件,它擅长于大规模机器学习计算,比如对 BERT 所需的计算进行微调。TPU 工作在密集的张量上,并期望像字符串这样的可变长度数据,已由主机 CPU 转换为固定大小的张量。

 

由于 BERT 编码器模型与其相关的预处理模型之间的解耦,可以将编码器微调计算作为模型训练的一部分分配给 TPU,而预处理模型则在主机 CPU 上执行。通过使用 tf.data.Dataset.map(),可以在数据集中异步运行预处理计算,并且 TPU 上的编码器模型可以消耗密集的输出。这种异步预处理还可以改善其他加速器的性能。

 

我们的高级 BERT 教程可以在使用 TPU 工作器的 Colab 运行时中运行,并演示了这种端到端的方式。

总结

 

在 TensorFlow 中使用 BERT 和类似的模型已经变得更加简单了。TensorFlow Hub 提供了大量预训练 BERT 编码器文本预处理模型,只需几行代码就能很容易地使用。

 

作者介绍:

 

Arno Eigenwillig,软件工程师。 Luiz GUStavo Martins,开发技术推广工程师。

 

原文链接:

 

https://blog.tensorflow.org/2020/12/making-bert-easier-with-preprocessing-models-from-tensorflow-hub.html

2021-01-14 09:522303
用户头像
赵钰莹 InfoQ 主编

发布了 882 篇内容, 共 644.5 次阅读, 收获喜欢 2679 次。

关注

评论

发布
暂无评论
发现更多内容

30个sql调优及高级sql技巧

威哥爱编程

MySQL oracle #SQL

10款好用的开源 HarmonyOS 工具库

威哥爱编程

鸿蒙 HarmonyOS HarmonyOS NEXT

SD-WAN解决视频会议加速难题

Ogcloud

网络加速 SD-WAN SD-WAN组网 SDWAN 视频会议加速

在 ArkTS 中,如何有效地进行内存管理和避免内存泄漏?

威哥爱编程

鸿蒙 HarmonyOS HarmonyOS NEXT

RPA在物流企微私域场景的应用

京东科技开发者

iPaaS全面选型指南

RestCloud

系统架构 产品开发 ipaas

刘洋,一个爱 drink 的好运程序员|MarsCoders 开发者说

豆包MarsCode

人工智能 程序员 AI 智能

阿里巴巴商品详情API返回值:电商行业发展的新动力

技术冰糖葫芦

API 接口 API 文档 API 测试 API 性能测试

开发游戏直播平台的秘密:看小李如何三天内快速上线!

软件开发-梦幻运营部

探讨微服务治理场景中,Sermant Backend如何管理插件动态配置

华为云开发者联盟

Backend Developer javaagent 微服务、 sermant

如何用AI快速开发一个小程序?

FinFish

小程序开发 AI技术开发 AI生成小程序

C++20中对于并发方面的进步

快乐非自愿限量之名

c++ 并发

ArkTS 和仓颉的特性对比与案例

威哥爱编程

HarmonyOS ArkTS 仓颉 HarmonyOS NEXT

HarmonyOS NEXT 开发之ArkTS基础入门

威哥爱编程

HarmonyOS ArkTS HarmonyOS NEXT

做效能度量,如何避免落入“此消彼长”的怪圈?

思码逸研发效能

程序员 DevOps 研发效能 效能度量 业技融合

现场直击!2023望繁信科技产品发布会精彩回顾

望繁信科技

数字化转型 流程挖掘 流程资产 流程智能 数字北极星

cad设计绘图工具:AutoCAD(CAD2024)中文特别版

你的猪会飞吗

AutoCAD 2024 Mac版 AutoCAD 2024下载 AutoCAD 2024破解

了解final关键字在Java并发编程领域的作用吗?

EquatorCoco

Java 编程

百度AI继续霸榜!百度搜索蝉联国内AI产品第一

Geek_2d6073

HPE Aruba Networking Central扩展AI自动化能力 推出第三方设备及终端用户体验监控功能

科技热闻

「算力包」璀璨亮相2024中国算力大会!

九章云极DataCanvas

域名的命名规则有哪些?注册域名需要注意哪些?

国科云

万界星空科技MES数据的集成方式

万界星空科技

制造业 mes 万界星空科技 万界星空科技mes

SD-WAN:大型集团机构组网方案

Ogcloud

SD-WAN 企业组网 SD-WAN组网 SD-WAN服务商 SDWAN

用JS实现简单的屏幕录像机

京东科技开发者

“元脑企智”EPAI:企业AI应用从“手工作坊”到“工厂高精产线”

脑极体

AI

万界星空科技MES系统与各大系统的集成

万界星空科技

系统集成 mes 万界星空科技mes 生产管理MES系统

Vue状态管理库Pinia详解

威哥爱编程

JavaScript Vue Pinia

尝鲜 HarmonyOS NEXT 开发环境搭建

威哥爱编程

鸿蒙 HarmonyOS HarmonyOS NEXT

快速上手:淘宝/天猫商品快递费用API返回值解析

技术冰糖葫芦

API 接口 API 文档 API 测试 API 性能测试

HarmonyOS NEXT 底部选项卡功能

威哥爱编程

HarmonyOS ArkTS HarmonyOS NEXT

如何利用TensorFlow Hub 让BERT开发更简单?_AI&大模型_Arno Eigenwillig_InfoQ精选文章