你可能已经听说 GPT-3,但是你也不能不知道 BERT —— 跟我一起用 BERT 跑个小用例
本文目录
一、关于 BERT 的一些背景
2018 年 Google 发布 BERT 后迅速在 NLP 领域引起广泛关注。BERT(Bidirectional Encoder Representations from Transformers)是一种自然语言处理(NLP)的深度学习模型,它可以进行语言模型预测、序列标注和问答等任务。BERT 采用双向的 Transformer 编码器架构,使用了大量的数据和计算资源进行训练,因此具有较强的泛化能力。
BERT 的训练方法是通过让模型对给定的输入文本进行自监督学习,即使用未标记的语料进行训练。BERT 可以在很多 NLP 任务中获得较好的性能,并且由于其双向的编码方式,能够更好地理解语境信息。
BERT 的训练需要大量的计算资源,因此它常常被用来作为解决 NLP 问题的预训练模型,可以用来初始化其他模型的权重,使得这些模型能够更快速地收敛。
二、开始一个 BERT 的动手小试验
为了让 conda 使用 Python 3.7,你可以按照这些步骤来操作。
1、安装 Anaconda 来为部署 BERT 做环境准备
先了解几个概念:Anaconda 是一个软件包管理系统,其中包含了 conda 和许多其他的工具。Conda 是 Anaconda 中的一个组件,用于安装和管理软件包。 我们需要用 conda 创建一个环境,在这个环境里去启用我们想要使用的 BERT 所需要的各种依赖。
更新 conda 到最新版本:
conda update -n base conda
使用 Python 3.7 创建一个新的环境:
conda create -n py37 python=3.7
激活这个新环境:
conda activate py37
验证正在使用的是正确版本的 Python
python --version
另外你可能还会用到的 conda 命令有:
# 你之后一定会需要 deactivate 一个环境,命令如下:
conda deactivate py37
# 查看 conda 当前安装的所有库
conda list
2、安装 BERT 所需要的各种依赖
conda install tensorflow==1.14.0
验证 tensorflow 是否安装正确:
import tensorflow as tf
print(tf.__version__)
3、下载一个预训练(Pre-Train)过的 BERT 模型
官方的模型在这里浏览:https://github.com/google-research/bert#pre-trained-models
也有一些中文的模型,以下是 ChatGPT 推荐的三个:
- BERT-Base, Chinese:这是 Google 官方提供的中文 BERT 模型,在中文 NLP 任务中表现良好。你可以从 这里下载这个模型。
- ERNIE:这是由中科院自然语言所提供的中文 BERT 模型,包含了额外的语义信息。你可以从 这里下载这个模型。
- RoBERTa-wwm-ext:这是由清华大学自然语言处理实验室提供的中文 BERT 模型,在多种中文 NLP 任务中表现良好。你可以从 这里下载这个模型。
4、安装 BERT 的服务端和客户端
这里我们使用 bert-as-service,bert-as-service 是一种将 BERT 模型部署为服务的方式。该工具使用 TensorFlow Serving 来运行 BERT 模型,并允许通过 REST API 进行调用。根据 bert-as-service 的文档,它已经在 TensorFlow 1.14.0 上测试过。
在你激活的环境里,安装 bert-as-service
:
# 安装服务端和客户端
# 更多关于 bert-serving-server 的信息可以参考:https://bert-serving.readthedocs.io/en/latest/index.html
conda install bert-serving-server bert-serving-client
验证 bert-as-service 是否安装成功
bert-serving-start -h
5、启动 BERT 服务端
# 命令行下启动BERT服务
# -num_worker 表示启动几个worker服务,即可以处理几个并发请求,超过这个数字的请求将会在LBS(负载均衡器)中排队等待
bert-serving-start -model_dir /模型/的/绝对/路径 -num_worker=4
6、在 PyCharm 中使用 Conda 的环境
在 PyCharm 中启用 Interpreter 为 Anaconda,macOS 上具体地是在「Preference - Project - Python Interpreter - Add Interpreter - Add Local Interpreter - Conda Environment」。
接下来还有一项重要的步骤就是选择该 project 要加载包文件的路径。如果不进行这一步,那该 project 还是从系统环境变量中的路径来搜索你要加载的包,这样在你用 Anaconda 新建的这个环境中所特有的包就会出现无法加载的问题。单击菜单栏 Run 选择 Edit Configuration。在Environment variables中添加一个新的 Path。新的路径为你用 Anaconda 新建的环境的文件夹中的「/Users/captain/opt/anaconda3/bin/python」
。
配置 PyCharm 这里参考:https://docs.anaconda.com/anaconda/user-guide/tasks/pycharm/
7、编写程序实现 BERT 客户端
这里有一些客户端例子可以参考:https://blog.csdn.net/qq_18256855/article/details/123860126
from bert_serving.client import BertClient
import numpy as np
# 定义类
class BertModel:
def __init__(self):
try:
self.bert_client = BertClient(ip='127.0.0.1', port=5555, port_out=5556) # 创建客户端对象
# 注意:可以参考API,查看其它参数的设置
# 127.0.0.1 表示本机IP,也可以用localhost
except:
raise Exception("cannot create BertClient")
def close_bert(self):
self.bert_client.close() # 关闭服务
def sentence_embedding(self, text):
'''对输入文本进行embedding
Args:
text: str, 输入文本
Returns:
text_vector: float, 返回一个列表,包含text的embedding编码值
'''
text_vector = self.bert_client.encode([text])[0]
return text_vector # 获取输出结果
def caculate_similarity(self, vec_1, vec_2):
'''根据两个语句的vector,计算它们的相似性
Args:
vec_1: float, 语句1的vector
vec_2: float, 语句2的vector
Returns:
sim_value: float, 返回相似性的计算值
'''
# 根据cosine的计算公式
v1 = np.mat(vec_1)
v2 = np.mat(vec_2)
a = float(v1 * v2.T)
b = np.linalg.norm(v1) * np.linalg.norm(v2)
cosine = a / b
return cosine
if __name__ == "__main__":
# 创建bert对象
bert = BertModel()
while True:
# --- 输入语句 ----
input_a = input('请输入语句1: ')
if input_a == "N" or input_a == "n":
bert.close_bert() # 关闭服务
break
input_b = input('请输入语句2: ')
# --- 对输入语句进行embedding ---
a_vec = bert.sentence_embedding(input_a)
print('a_vec shape : ', a_vec.shape)
b_vec = bert.sentence_embedding(input_b)
print('b_vec shape : ', b_vec.shape)
# 计算两个语句的相似性
cos = bert.caculate_similarity(a_vec, b_vec)
print('cosine value : ', cos)
print('\n\n')
# 如果相似性值大于0.85,则输出相似,否则,输出不同
if cos > 0.85:
print("2个语句的含义相似")
else:
print("不相似")
在使用 bert-serving-client
连接 bert-serving-server
时,你需要确保 bert-serving-server
使用的模型和 bert-serving-client
使用的模型是匹配的,否则会出现错误。
程序正常运行后,将要求你输入两句话,然后 BERT 计算两句话的相似性。
请输入语句1:
请输入语句2:
两句输入好确认后,得到如下形式的结果:
a_vec shape : (768,)
b_vec shape : (768,)
cosine value : 0.8691698561422959
其实这个小试验蛮没意思的,而且准确性也比较令人质疑。
三、BERT 模型的优劣势及其原因
论文地址:《BERT: Pre-Training of Deep Bidirectional Transformers for Language Understanding》 。
1、BERT 的优势是很明显的
复旦大学的邱锡鹏教授层评价 BERT 的「里程碑意义」在于:
证明了一个非常深的模型可以显著提高 NLP 任务的准确率,而这个模型可以从无标记数据集中预训练得到。
1.1、MLM 和 NSP 预训练能够捕捉到自然语言中的各种复杂细节
因为 BERT 采用了双向的自注意力机制,这里的「双向」意味着 BERT 模型可以同时利用输入文本的前后文信息来预测下一个词是什么、下一句是什么。这样 BERT 模型就可以捕捉到自然语言中的各种隐藏的细节,比如语义关系、语法结构、语义暗示等等。
具体地,BERT 采用了 Masked Language Model(MLM)来做「下一个词是什么」的预训练,采用了 Next Sentence Prediction(NSP)来做「下一句是什么」的预训练。MLM 的方式其实就很像英语考试里的「完形填空」,而 NSP 的方式,就像整句的完形填空。
1.2、识别并专注于较重要的部分进行文本处理
这要得益于因为 BERT 采用了自注意力机制。自注意力机制,通过计算输入单元的权重值,来确定在一个输入序列中哪些输入单元是重要的。具体地,一个输入单元与其他单元的相似性越高,按照我们自然语言的逻辑,那么这部分是在被重复、强调、翻来覆去用不同的方式在解释,那么这部分就是重要的,权重值就更高。
1.3、快速构建针对具体任务的 NLP 系统
因为 BERT 采用了预训练模型,能够在没有监督标注数据的情况下从大量文本中学习语言模型。因为我们认为上下文信息本身就能推测出某个词,所以大量的文本数据本身就是一种「自带标注」的数据,所以 BERT 能够无监督学习。
2、BERT 模型的劣势及其原因
2.1、随机挖 MASK 的完形填空题是有隐患的
对于上面提到的 MLM、NSP 方法做预训练,那么问题也就显而易见了,如果我们挖掉的一组 MASK 完形填空词,是强关联的(非条件独立),那么这一组词的预测就都会出现问题。
2.2、NSP 任务有必要吗?
论文《Crosslingual language model pretraining》中提到 BERT 的 NSP 可能是非必要的,针对这个问题,后续出现的模型都移除了 NSP 任务,比如 RoBERTa、spanBERT、ALBERT。
2.3、针对两个或以上词组成的连续词的词义被丢失
比如 cutting-edge,MLM 的方式可能会割裂这两个子词的相关性,导致模型丢失这个词的词义,针对这个问题 Google 后来发表了 BERT-WWM,WWM 即 Whole Word Masking,从字面就能理解针对的问题。哈尔滨工业大学的科大讯飞联合实验室后来推出了 Chinese-BERT-WWM 专门针对中文解决了这个问题。
2.4、需要的算力高
算力高,自然需要的计算成本运行更高。不过算力成本高这种问题总有办法优化,通常来说不是模型本身所处理问题的局限性和先决条件的局限性(比如依赖大量人工工作)就非常好了。
2.5、需要的模型大
模型大,自然存储成本也就高了。这也类似于上一点,而且算力、存储成本高,可以在大型应用中把成本均摊下来,比如 BERT 如果支持的某个 AGI 应用得到广泛普及。
四、一些关于 BERT 的问题
1、BERT 模型的所谓「双向」与 BiLSTM 的「双向」是啥区别?
BiLSTM 是把句子再倒序一遍,而 BERT 的双向是指在 Encoder 的自注意力机制下编码一个 token 时「同时利用上下文」的 token。
2、为什么 BERT 可以比 RNN 更好地并行化
RNN 因为有时序概念,即后面的特征计算,依赖于前面计算的结果,所以就形成了循环(Recurrent)。而 BERT 采用了自注意力机制则没有时序概念,每个词特征都依赖其上下文独立计算,因此更容易并行化。
Reference
- https://arxiv.org/abs/1810.04805
- https://github.com/google-research/bert
- https://github.com/ymcui/Chinese-BERT-wwm
- https://zhuanlan.zhihu.com/p/195723105
- https://www.jiqizhixin.com/articles/2018-10-24-13