参考:bert-as-service 详细使用指南写给初学者-CSDN博客
GitHub - ymcui/Chinese-BERT-wwm: Pre-Training with Whole Word Masking for Chinese BERT(中文BERT-wwm系列模型)
下载:https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
bert base chinese
首先讲了下学习bert-as-service的起因,因为实际业务中需要使用bert做线上化文本推理服务,所以经过调研选择bert-as-service开源项目;然后从理论的角度详解了bert-as-service,很纯粹的输入一条文本数据,返回对应的embedding表示。
参考:https://zhuanlan.zhihu.com/p/156941424
bert-as-service开源项目为我们提供线上的文本分类服务,所以一些基础的bert知识必不可少。
BERT这种预训练+微调两阶段模型和端到端模型的区别。
端到端模型就是使用任务相关的数据训练一个模型完成对应的任务。
而BERT这种两阶段模型属于迁移学习的范畴。
预训练阶段是通过无监督学习的方式学习海量的文本数据从而获得语言学知识;
而微调阶段则是利用预训练阶段学习到的语言学知识结合任务相关的数据去做不同的NLP任务。
预训练阶段因为要从海量的文本数据中学习语言学知识,所以需要大量的时间和计算资源。
虽然预训练阶段耗时耗资源,但是可以理解为一次性的。谷歌使用4-16个TPU花费4天才完成预训练模型。
计算机学习到了这些语言学知识后可以将这些“知识”以模型的方式存储起来,然后其他人可以直接使用这个模型结合各自的需求微调模型完成各自下游的任务。
2. BERT模型
BERT模型由输入层embedding、编码层Transformer encoder和输出层三部分组成。
输入层将文本数据转化为词编码、句子对关系编码和位置编码三层embedding
编码层使用Transformer作为特征抽取器来获取文本语句的embedding表示
输出层则是根据下游的NLP任务来输出你想要的结果,可以是文本分类、命名体识别、翻译等等
主要是使用BERT模型来对用户搜索query和浏览资讯news等文本数据进行文本分类
离线文本分类服务
在线文本分类服务
bert-as-service简单来说就是通过Tensorflow和ZeroMQ来提供BERT线上化服务从而获取语句的embedding向量。
2. 获得有效的embedding向量表示
Max Pooling(最大池化)和Average Pooling(平均池化)是卷积神经网络(CNN)中两种常用的下采样(subsampling)方法,它们都属于池化操作,用于减少输入数据的空间维度(如图像的高度和宽度),同时保留关键的特征信息。
-
Max Pooling:
- 在一个池化窗口(例如2x2)内,Max Pooling会选择该窗口内所有元素的最大值作为输出。这样做的好处是可以突出重要的局部特征,比如在识别物体时可能特别关注对象边缘或最显著的特征点。
- Max Pooling对于输入中的噪声具有一定的鲁棒性,因为它只传递每个区域的最大响应,从而对微小变化不敏感。
- 由于它选择的是最大激活值,因此能够捕获到强烈、独特的特征信号,有助于提高模型的泛化能力。
-
Average Pooling:
- Average Pooling则是计算池化窗口内所有元素的平均值作为输出。
- 相比于Max Pooling,Average Pooling更侧重于保留整个区域的统计特性,而不是仅仅关注最大响应。这使得它能提供更加平滑的输出特征图,可能更有利于表达图像的全局信息或者背景信息。
- 在某些场景下,Average Pooling可以降低由于个别极端值造成的偏差,并且其运算相对于Max Pooling更为稳定。
使用场景:
-
Max Pooling通常用在需要强调局部最大特征或者对噪声有较强抵抗力的场合,特别是在图像分类、目标检测等任务中被广泛采用。
-
Average Pooling则更多地应用于那些希望保持整体特征强度均衡的任务,或者当模型设计者想要避免过度重视单个最大响应时。例如,在DenseNet架构中,模块间的连接常采用Average Pooling来保持信息的有效传递。
此外,近年来还有其他形式的池化层出现,如Global Average Pooling,它在ResNet、Inception等现代网络结构的末尾经常被用来将整个特征图的尺寸压缩为一维向量,直接与全连接层进行对接,从而减少参数数量并增强模型的稳健性。
2W条资讯数据主要分成四类。整体来看,不同的pooling方式得到的embedding表示结果有一定差异。同时,查看各自的pooling方式下相邻层之间的embedding表示类似;第一层和最后一层的embedding表示差距很大;最后一层embedding的表示最接近词编码,能最好的保留初始的词语信息。
3. 解耦bert模型和下游网络
Bert-as-service项目将bert预训练网络和下游网络解耦。将bert预训练网络放在配置GPU资源的服务端,同时服务多用户;下游网络一般是简单的轻量级模型,不需要复杂的深度学习库,放在CPU或者手机终端上使用。
通过解耦bert模型和下游网络,当特征提取成为瓶颈时可以通过使用或者增加GPU资源来优化服务端,同理当下游网络成为瓶颈时可以添加CPU或者量化操作来优化客户端。当训练数据没有更新或者定义发生变化时只需在服务端重新训练BERT模型即可满足下游网络获取更新后的特征向量。这种请求汇集在一个地方的方法可以使服务端的GPU利用率大大提高。
5. 降低线上服务内存占用
Bert-as-service项目只需要在第一次收到新请求时生成一个新的BERT模型,后续只需要在事件循环中监听请求并提供服务即可。
6. 高可用的服务方式
当服务端收到多个客户端的请求后,主要通过ventilator组件来进行批处理调度和负载均衡。当收到多个客户端请求后,ventilator首先会将这些请求划分成多个小任务,然后将这些小任务分别发送给工人们。工人们收到这些小任务后开始工作,工作内容就是使用bert进行预测,预测完之后会将结果统一发送给sink组件。sink组件会将所有工人的预测结果统一装配,同时检查ventilator组件中各个客户端请求的完整性,如果某个客户端请求的数据已经全部预测完成了,那么就返回预测结果给对应的客户端完成本次请求。通过这种方式,可以轻松解决上面小任务调度体验问题。
模型角度分析了不同的pooling策略对embedding向量的影响。通过解耦bert和下游网络、提供快速的预测服务、降低线上服务内存占用和高可用的服务方式,bert-as-service可以又快又好的提供线上推理服务。
实战bert-as-service
bert-serving-start -model_dir/tmp/english_L-12_H-768_A-12/ -num_worker=4
这里有两个参数需要说明下,一个是num_worker,这是分配的worker数目,一般分配的worker数目要少于GPU的颗数;另一个是model_dir,这是预训练模型的地址。
然后通过如下三行代码,我们就能轻松返回语句的embedding表示,简单到没朋友:
咱们就能使用BERT预训练模型得到文本的embedding表示向量。
3. 获取文本分类的结果
上面已经得到BERT模型最重要的encodding编码向量。实际业务中我们是文本分类任务,其实就是添加了一层全连接层的一个微调的模型。通过如下命令即可实现bert-as-service项目用于文本分类任务: