跳转至

7.8 主流大厂开源模型介绍

清华大学

ERNIE1.0

  • 清华大学于2019年提出的模型, 原始论文<< ERNIE: Enhanced Language Representation with Informative Entities >>, 核心工作是基于BERT模型在中文上的改进.

  • 注意: 百度公司也于2019年提出了一款名字一模一样的模型ERNIE1.0, 此处有坑, 注意区分!!!

  • BERT通过字的搭配可以很容易推测出mask中的字, 如乒乓[球], 但是不能显示地对语义信息进行建模(如乒乓球). ERNIE提出了短语和实体级别的MASK方式, 通过这种方法融合外部知识.

  • 下图所展示的结构图, 就是通过短语和命名实体级别的外部知识, 融入进模型后, 可以增强模型对于更高层次语义信息的理解能力:


  • ERNIE1.0模型的架构图:


  • 左侧代表编码器, 有两个组成部分:

    • K-Encoder: 知识编码器.
    • T-Encoder: 文本编码器.
  • 右侧代表集成器, 有两个组成元素:

    • w序列: 代表输入的token.
    • e序列: 代表每个entity.
  • 在具体的集成, 聚合过程中, 每个实体e和对应的第一个token对齐!


  • ERNIE1.0模型针对于不同的任务, 采用不同类型的输入模式, 如下图展示:


  • 结论: 清华大学的ERNIE1.0模型虽然和百度的ERNIE1.0同名, 但内容和优化点都有区别, 注意区分, 但更重要的是要知道这个事实!!!


百度


ERNIE1.0

  • 百度的NLP团队也于2019年提出了ERNIE1.0, 原始论文<< ERNIE: Enhanced Representation through Knowledge Integration >>.

  • 百度ERNIE1.0的基础是BERT模型, 但是和BERT最大的区别就在于MASK的对象不同.

    • BERT是输入字掩码.
    • ERNIE是输入词掩码.
    • 这个识别词的过程就是加入知识整合的最关键的核心点.


  • ERNIE was chosen to have the same model size as BERT-base for comparison purposes. ERNIE uses 12 encoder layers, 768 hidden units and 12 attention heads.

  • ERNIE1.0是通过建模海量数据中的词, 实体及实体关系, 学习真实世界的语义知识. 相较于BERT学习原始语言信号, ERNIE1.0可以直接对先验语义知识单元进行建模, 增强了模型语义表示能力.

  • 例如对于下面的例句: "哈尔滨是黑龙江的省会, 国际冰雪文化名城".


  • ERNIE1.0与BERT词屏蔽方式的比较: BERT在预训练过程中使用的数据仅是对单个字符进行MASK, 如上图所示, 训练BERT通过"哈"与"滨"的局部共现判断出"尔"字, 但是模型其实并没有学习到与"哈尔滨"相关的知识, 只是学习到"哈尔滨"这个词, 但是并不知道"哈尔滨"所代表的含义. 而ERNIE1.0在预训练时使用的数据是对整个词进行MASK, 从而学习词与实体的表达, 例如屏蔽"哈尔滨"与"冰雪"这样的词, 使模型能够建模出"哈尔滨"与"黑龙江"的关系, 学到"哈尔滨"是"黑龙江"的省会以及"哈尔滨"是个"冰雪城市"这样的含义.

  • 为了增强ERNIE1.0模型对于词汇和实体的理解能力, 论文中使用先验知识来进行增强. 具体方法使用了多阶段的知识掩码策略, 通过不同的MASK策略将短语和实体知识集成到语言模型中, 而不是像KG-BERT模型那样直接向模型中添加知识.


  • Basic-level Masking: 第一个学习阶段是使用基本元素级别MASK, 它将句子作为基本语言单位的序列, 对于英语, 基本语言单位是单词, 对于中文, 基本语言单位是汉字. 在训练过程中, 我们随机掩盖15%的基本语言单元, 并使用句子中的其他基本单元作为输入, 训练一个Transformer来预测掩盖单元. 和BERT一样的操作, 基于基本级别的掩码, 主要学习低级语义.

  • Entity-level Masking: 第二阶段是采用实体级别的MASK, 词组是一小部分单词或字符, 一起充当概念和实体单元. 对于英语, 我们使用词法分析和分块工具来获取句子中短语的边界, 并使用一些依赖于语言的分段工具来获取其他语言(例如中文场景下使用jieba分词工具等)的词/短语信息. 在实体级掩码阶段, 我们还使用基本语言单元作为训练输入, 这与随机基本单元掩码不同, 这次我们随机选择句子中的几个短语, 掩盖并预测同一短语中的所有基本单元. 在此阶段, 短语信息被编码到单词嵌入中.

  • Phrase-level Masking: 第三阶段是短语级别MASK, 短语包含人员, 位置, 组织, 产品等, 可以用专有名称表示. 它可以是抽象的, 也可以是物理存在的. 通常, 实体在句子中包含重要信息, 与实体MASK阶段一样, 我们首先分析句子中的命名实体, 然后屏蔽并预测其中的所有短语. 经过三个阶段的学习, 获得了通过更丰富的语义信息增强的单词表示.


  • ERNIE1.0采用异构语料库进行预训练. 我们构建了混合语料库-中国Wikepedia, 百度百科, 百度新闻, 百度贴吧. 句子数分别是21M, 51M, 47M, 54M. 百度百科包含用正式语言编写的百科全书文章, 这些文章被用作语言建模的强大基础. 百度新闻提供有关电影名称, 演员名称, 足球队名称等的最新信息. 百度贴吧是一个类似Reddits的开放讨论论坛, 每个帖子都可以视为对话话题. 在DLM任务中使用Tieba语料库. 论文中对汉字执行从传统到简体的转换, 对英文字母执行大写到小写的转换, 为模型使用了17964个unicode字符的共享词汇表.

  • DLM(Dialogue Language Model, 对话语言模型):
    • 对话数据对于语义表示很重要, 因为相同答复的相应查询语义通常很相似. ERNIE1.0在DLM(对话语言模型)任务上对查询-响应对话结构进行建模. 如下图(Figure 3)所示, 引入了对话嵌入(dialogue embedding)来识别对话中的角色. ERNIE1.0的"对话"嵌入功能与BERT中的令牌类型嵌入功能相同, 不同之处在于ERNIE1.0还可以表示多回合对话(例如QRQ, QRR, QQR, 其中Q和R分别代表"查询"和"响应", 起到"Question"和"Answer"的作用). 像BERT中的MLM一样, 掩码来强制使模型预测以查询和响应为条件的缺失词. 论文中通过用随机选择的句子替换查询或响应来生成假样本. 该模型旨在判断多回合对话是真实的还是假的.
    • DLM任务可帮助ERNIE1.0学习对话中的隐式关系, 这也增强了模型学习语义表示的能力. DLM任务的模型体系结构与MLM任务的模型体系结构兼容, 因此可以通过MLM任务对其进行预训练.


  • ERNIE1.0被应用于5个中文NLP任务:
    • 自然语言推理(XNLI)
    • 语义相似性(LCQMC)
    • 命名实体识别(MSRA-NER)
    • 情感分析(ChnSentiCorp)
    • 检索问题回答(NLPCC-DBQA)

  • 自然语言推理(XNLI): 跨语言自然语言推理(XNLI)语料库(2019)是MultiNLI语料库的众包集合. 两对文字加上文字说明, 并被翻译成包括中文在内的14种语言. 标签包含矛盾, 中立, 包含.

  • 语义相似性(LCQMC): 大规模中文问题匹配语料库(LCQMC)(2018)旨在识别两个句子是否具有相同的意图. 数据集中的每一对句子都与一个二进制标签相关联, 该二进制标签指示两个句子是否共享相同的意图, 并且可以将该任务形式化为预测二进制标签.

  • 命名实体识别(MSRA-NER): MSRA-NER数据集用于命名实体识别, 由Microsoft Research Asia发布. 实体包含几种类型, 包括人员姓名, 地名, 组织名称等. 该任务可以看作是序列标记任务.

  • 情感分析(ChnSentiCorp): ChnSentiCorp是一个数据集, 旨在判断句子的情感. 它包括酒店, 书籍和电子计算机等多个领域的评论. 该任务的目的是判断句子的情感倾向是是肯定态度的还是否定态度.

  • 检索问题回答(NLPCC-DBQA): NLPCC-DBQA数据集(http://tcci.ccf.org.cn/conference/2016/dldoc/evagline2.pdf)的目标是选择相应问题的答案. 该数据集的评估方法包括MRR(Voorhees, 2001)和F1得分.


  • ERNIE1.0在5个中文NLP任务中展现出了优秀的结果:


  • ERNIE1.0模型在完形填空上也展现了优秀的结果:


  • 在情况1中, BERT尝试复制出现在上下文中的名称, 而ERNIE1.0则记住了文章中提到的有关关系的知识.

  • 在情况2和情况5中, BERT可以根据上下文成功学习模式, 因此可以正确预测命名的实体类型, 但是无法使用正确的实体填充插槽. 相反, ERNIE1.0可以使用正确的实体填充插槽.

  • 在情况3, 4, 6中, BERT用与句子相关的几个字符填充了空位, 但是很难预测语义概念. ERNIE1.0可以预测除情况4之外的正确实体. 尽管ERNIE1.0在情况4中预测了错误的实体, 但它可以正确地预测语义类型, 并用一个澳大利亚城市填充该位置.


  • ERNIE1.0模型的应用: 百度NLP团队已经对外开放了ERNIE1.0的中文版本, 并且经过转换格式已经可以直接在Pytorch中引用了.

  • 展示ERNIE1.0的中文模型:

-rw-r--r-- 1 ec2-user ec2-user       332 Feb 21 11:57 config.json
-rw-r--r-- 1 ec2-user ec2-user 401940231 Feb 21 12:01 pytorch_model.bin
-rw-r--r-- 1 ec2-user ec2-user     91107 Feb 21 12:06 vocab.txt

  • 在投满分项目中进行模型的迁移微调:
import time
import torch
import numpy as np
from train_eval import train, test
from importlib import import_module
import argparse
from utils import build_dataset, build_iterator, get_time_dif


parser = argparse.ArgumentParser(description="Chinese Text Classification")
parser.add_argument("--model", type=str, required=True, help="choose a model: ernie")
args = parser.parse_args()


if __name__ == "__main__":
    dataset = "toutiao"  # 数据集
    if args.model == "ernie":
        model_name = "ernie"
        x = import_module("models." + model_name)
        config = x.Config(dataset)
        np.random.seed(1)
        torch.manual_seed(1)
        torch.cuda.manual_seed_all(1)
        torch.backends.cudnn.deterministic = True  # 保证每次结果一样

        print("Loading data for Bert Model...")
        train_data, dev_data, test_data = build_dataset(config)
        train_iter = build_iterator(train_data, config)
        dev_iter = build_iterator(dev_data, config)
        test_iter = build_iterator(test_data, config)

        model = x.Model(config).to(config.device)
        train(config, model, train_iter, dev_iter)
        test(config,model, test_iter)

  • 输出结果:
Loading data for Bert Model...
180000it [00:41, 4298.15it/s]
10000it [00:02, 3968.75it/s]
10000it [00:02, 4403.30it/s]
Epoch [1/5]
 14%|█████████▏                                                       | 200/1407 [01:54<11:58,  1.68it/s]Iter:    200,  Train Loss:  0.48,  Train Acc: 80.47%,  Val Loss:  0.37,  Val Acc: 89.01%,  Time: 0:02:12 *
 28%|██████████████████▍                                              | 400/1407 [04:13<10:18,  1.63it/s]Iter:    400,  Train Loss:  0.49,  Train Acc: 85.94%,  Val Loss:  0.32,  Val Acc: 90.17%,  Time: 0:04:34 *
 43%|███████████████████████████▋                                     | 600/1407 [06:36<08:15,  1.63it/s]Iter:    600,  Train Loss:  0.31,  Train Acc: 89.06%,  Val Loss:  0.31,  Val Acc: 90.38%,  Time: 0:06:56 *
 57%|████████████████████████████████████▉                            | 800/1407 [08:58<06:11,  1.63it/s]Iter:    800,  Train Loss:   0.2,  Train Acc: 93.75%,  Val Loss:  0.26,  Val Acc: 91.41%,  Time: 0:09:19 *
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [11:20<04:09,  1.63it/s]Iter:   1000,  Train Loss:  0.19,  Train Acc: 92.97%,  Val Loss:  0.26,  Val Acc: 91.67%,  Time: 0:11:41 *
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:43<02:07,  1.63it/s]Iter:   1200,  Train Loss:  0.23,  Train Acc: 91.41%,  Val Loss:  0.24,  Val Acc: 92.04%,  Time: 0:14:03 *
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:05<00:04,  1.63it/s]Iter:   1400,  Train Loss:  0.41,  Train Acc: 89.06%,  Val Loss:  0.25,  Val Acc: 92.08%,  Time: 0:16:23 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [16:26<00:00,  1.43it/s]
Epoch [2/5]
 14%|█████████▏                                                       | 200/1407 [02:02<12:16,  1.64it/s]Iter:    200,  Train Loss:  0.33,  Train Acc: 89.06%,  Val Loss:  0.28,  Val Acc: 91.38%,  Time: 0:18:46 
 28%|██████████████████▍                                              | 400/1407 [04:21<10:18,  1.63it/s]Iter:    400,  Train Loss:  0.31,  Train Acc: 88.28%,  Val Loss:  0.24,  Val Acc: 92.40%,  Time: 0:21:06 
 43%|███████████████████████████▋                                     | 600/1407 [06:41<08:15,  1.63it/s]Iter:    600,  Train Loss:  0.23,  Train Acc: 92.97%,  Val Loss:  0.22,  Val Acc: 92.53%,  Time: 0:23:28 *
 57%|████████████████████████████████████▉                            | 800/1407 [09:03<06:10,  1.64it/s]Iter:    800,  Train Loss:  0.16,  Train Acc: 95.31%,  Val Loss:  0.21,  Val Acc: 93.22%,  Time: 0:25:49 *
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [11:24<04:09,  1.63it/s]Iter:   1000,  Train Loss:  0.13,  Train Acc: 94.53%,  Val Loss:  0.22,  Val Acc: 92.99%,  Time: 0:28:08 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:44<02:07,  1.63it/s]Iter:   1200,  Train Loss:   0.2,  Train Acc: 92.97%,  Val Loss:  0.21,  Val Acc: 93.16%,  Time: 0:30:28 
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:03<00:04,  1.63it/s]Iter:   1400,  Train Loss:  0.31,  Train Acc: 91.41%,  Val Loss:  0.21,  Val Acc: 93.32%,  Time: 0:32:48 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [16:24<00:00,  1.43it/s]
Epoch [3/5]
 14%|█████████▏                                                       | 200/1407 [02:02<12:21,  1.63it/s]Iter:    200,  Train Loss:  0.17,  Train Acc: 93.75%,  Val Loss:  0.21,  Val Acc: 93.46%,  Time: 0:35:14 *
 28%|██████████████████▍                                              | 400/1407 [04:25<10:18,  1.63it/s]Iter:    400,  Train Loss:  0.23,  Train Acc: 94.53%,  Val Loss:   0.2,  Val Acc: 93.16%,  Time: 0:37:36 *
 43%|███████████████████████████▋                                     | 600/1407 [06:47<08:11,  1.64it/s]Iter:    600,  Train Loss:  0.32,  Train Acc: 91.41%,  Val Loss:  0.22,  Val Acc: 93.26%,  Time: 0:39:55 
 57%|████████████████████████████████████▉                            | 800/1407 [09:06<06:12,  1.63it/s]Iter:    800,  Train Loss:  0.12,  Train Acc: 96.88%,  Val Loss:  0.21,  Val Acc: 93.20%,  Time: 0:42:15 
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [11:26<04:08,  1.64it/s]Iter:   1000,  Train Loss:  0.11,  Train Acc: 96.09%,  Val Loss:  0.21,  Val Acc: 93.32%,  Time: 0:44:35 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:45<02:06,  1.63it/s]Iter:   1200,  Train Loss:  0.19,  Train Acc: 92.97%,  Val Loss:   0.2,  Val Acc: 93.21%,  Time: 0:46:57 *
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:08<00:04,  1.63it/s]Iter:   1400,  Train Loss:  0.25,  Train Acc: 92.97%,  Val Loss:  0.21,  Val Acc: 93.64%,  Time: 0:49:17 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [16:28<00:00,  1.42it/s]
Epoch [4/5]
 14%|█████████▏                                                       | 200/1407 [02:02<12:20,  1.63it/s]Iter:    200,  Train Loss:  0.15,  Train Acc: 94.53%,  Val Loss:  0.21,  Val Acc: 93.41%,  Time: 0:51:40 
 28%|██████████████████▍                                              | 400/1407 [04:22<10:17,  1.63it/s]Iter:    400,  Train Loss:  0.23,  Train Acc: 92.19%,  Val Loss:   0.2,  Val Acc: 93.76%,  Time: 0:54:02 *
 43%|███████████████████████████▋                                     | 600/1407 [06:44<08:16,  1.63it/s]Iter:    600,  Train Loss:  0.21,  Train Acc: 94.53%,  Val Loss:   0.2,  Val Acc: 93.63%,  Time: 0:56:25 *
 57%|████████████████████████████████████▉                            | 800/1407 [09:06<06:11,  1.63it/s]Iter:    800,  Train Loss: 0.094,  Train Acc: 96.88%,  Val Loss:  0.21,  Val Acc: 93.40%,  Time: 0:58:44 
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [11:26<04:09,  1.63it/s]Iter:   1000,  Train Loss: 0.084,  Train Acc: 97.66%,  Val Loss:  0.21,  Val Acc: 93.62%,  Time: 1:01:04 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:45<02:06,  1.63it/s]Iter:   1200,  Train Loss:  0.16,  Train Acc: 91.41%,  Val Loss:   0.2,  Val Acc: 93.86%,  Time: 1:03:23 
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:05<00:04,  1.63it/s]Iter:   1400,  Train Loss:  0.13,  Train Acc: 95.31%,  Val Loss:  0.21,  Val Acc: 93.94%,  Time: 1:05:43 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [16:26<00:00,  1.43it/s]
Epoch [5/5]
 14%|█████████▏                                                       | 200/1407 [02:02<12:19,  1.63it/s]Iter:    200,  Train Loss:  0.15,  Train Acc: 96.09%,  Val Loss:  0.22,  Val Acc: 93.62%,  Time: 1:08:06 
 28%|██████████████████▍                                              | 400/1407 [04:22<10:18,  1.63it/s]Iter:    400,  Train Loss:  0.21,  Train Acc: 92.19%,  Val Loss:  0.22,  Val Acc: 93.68%,  Time: 1:10:26 
 43%|███████████████████████████▋                                     | 600/1407 [06:41<08:15,  1.63it/s]Iter:    600,  Train Loss:  0.15,  Train Acc: 93.75%,  Val Loss:  0.21,  Val Acc: 93.67%,  Time: 1:12:46 
 57%|████████████████████████████████████▉                            | 800/1407 [09:01<06:11,  1.63it/s]Iter:    800,  Train Loss:  0.14,  Train Acc: 95.31%,  Val Loss:  0.22,  Val Acc: 93.44%,  Time: 1:15:05 
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [11:21<04:09,  1.63it/s]Iter:   1000,  Train Loss: 0.087,  Train Acc: 96.09%,  Val Loss:  0.22,  Val Acc: 93.71%,  Time: 1:17:25 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:40<02:06,  1.63it/s]Iter:   1200,  Train Loss: 0.088,  Train Acc: 96.09%,  Val Loss:  0.22,  Val Acc: 93.32%,  Time: 1:19:44 
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:00<00:04,  1.63it/s]Iter:   1400,  Train Loss:  0.18,  Train Acc: 94.53%,  Val Loss:  0.23,  Val Acc: 93.60%,  Time: 1:22:04 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [16:20<00:00,  1.43it/s]
Test Loss:  0.19,  Test Acc: 93.98%
Precision, Recall and F1-Score...
               precision    recall  f1-score   support

      finance     0.9374    0.9280    0.9327      1000
       realty     0.9653    0.9470    0.9561      1000
       stocks     0.8971    0.8890    0.8930      1000
    education     0.9639    0.9610    0.9624      1000
      science     0.8805    0.9140    0.8970      1000
      society     0.9526    0.9250    0.9386      1000
     politics     0.8920    0.9420    0.9163      1000
       sports     0.9909    0.9780    0.9844      1000
         game     0.9704    0.9500    0.9601      1000
entertainment     0.9545    0.9640    0.9592      1000

     accuracy                         0.9398     10000
    macro avg     0.9405    0.9398    0.9400     10000
 weighted avg     0.9405    0.9398    0.9400     10000

Confusion Matrix...
[[928   7  46   1   6   2   8   1   1   0]
 [ 12 947  11   1   6   3   9   2   0   9]
 [ 36  12 889   0  34   2  26   0   0   1]
 [  1   1   2 961   7  10  13   0   0   5]
 [  5   1  17   4 914  12  16   1  22   8]
 [  4  10   3  18   3 925  25   0   3   9]
 [  3   2  19   6  12  11 942   1   0   4]
 [  1   1   0   0   1   1   9 978   0   9]
 [  0   0   3   1  42   1   1   1 950   1]
 [  0   0   1   5  13   4   7   3   3 964]]
Time usage: 0:00:17

  • 结论: 投满分项目通过迁移学习ERNIE1.0的中文预训练模型, 在测试集上达到93.98%的F1高分, 在众多预训练模型的比较中, 仅次于RoBERTa的94.30%, 和macBert的94.48%, 展现了非常优秀的能力!!!


ERNIE2.0

  • 百度的NLP团队于2020年提出ERNIE2.0模型, 原始论文<< ERNIE 2.0: A Continual Pre-Training Framework for Language Understanding >>.

  • 近两年, 以BERT, XLNet为代表的无监督预训练技术在多个自然语言处理任务上取得了技术突破. 基于大规模数据的无监督预训练技术在自然语言处理领域变得至关重要. 百度发现, 之前的工作主要通过词或句子的共现信号, 构建语言模型任务进行模型预训练. 例如, BERT通过掩码语言模型和下一句预测任务进行预训练. XLNet构建了全排列的语言模型, 并通过自回归的方式进行预训练. 然而, 除了语言共现信息之外, 语料中还包含词法、语法、语义等更多有价值的信息. 例如, 人名、地名、机构名等词语概念知识, 句子间顺序和距离关系等结构知识, 文本语义相似度和语言逻辑关系等语义知识. 那么如果持续地学习各类任务, 模型的效果能否进一步提升? 这就是ERNIE2.0希望探索的.



  • ERNIE2.0框架支持增量引入不同角度的自定义预训练任务, 以捕捉语料中词法、语法、语义等信息. 这些任务通过多任务学习对模型进行训练更新, 每当引入新任务时, 该框架可在学习该任务的同时, 不遗忘之前学到过的信息.

  • ERNIE2.0框架支持随时引入各种自定义任务, 这些任务共享相同的编码网络并通过多任务学习实现训练. 这种多任务学习的方法使得不同任务中词汇、句法和语义信息的编码能共同学习. 此外, 当我们给出新的任务时, ERNIE2.0框架可以根据先前预训练的权重增量地学习分布式表征.


  • ERNIE2.0与BERT或XLNet等经典预训练方法的不同之处在于, 它并不是在少量的预训练任务上完成的, 而是通过不断引入大量预训练任务, 从而帮助模型高效地学习词汇、句法和语义表征.

  • ERNIE2.0框架能通过多任务学习持续更新预训练模型, 这也就是"连续预训练"的含义. 在每一次微调中, ERNIE2.0会首先初始化已经预训练的权重, 然后再使用具体任务的数据微调模型.


  • 连续预训练(Continual Pre-Training)过程, 可以分为两个步骤:
    • 构建无监督预训练任务.
    • 通过多任务学习增量地更新ERNIE2.0模型.


  • 百度的研究者通过一系列无监督自然语言处理任务构建预训练模型. 如下图Figure 3所示为ERNIE2.0具体模型架构, 我们可以看到它主要包含三类预训练任务:
    • word-aware任务: 将教会模型捕捉词汇层面的信息.
    • structure-aware任务: 将教会模型捕捉句法层面的信息.
    • semantic-aware任务: 将教会模型捕捉语义层面的信息.


  • 注意: 上图Figure 3所展示的底层嵌入, 在BERT的基础上新加了一种Task embedding, 不同的编码代表不同的预训练任务.

  • word-aware任务: (capture the lexical information)

    • Knowledge Masking: 同ERNIE1.0的实体/短语masking
    • Capitalization Prediction: token大小写预测的任务
    • Token-Document Relation Prediction: 预测句子中的词是否出现在了segment原始文档中, 等效于预测token是否为关键词
  • structure-aware任务: (capture the syntactic information)

    • Sentence Reordering(语序关系): 打乱k个句子, 预测原始顺序(给每个句子做k分类)
    • Sentence Distance(语义距离): 3分类任务, 预测两个句子是相连, 出现在同一个文档, 出现在不同文档
  • semantic-aware任务: (capture the semantic information)

    • Discourse Relation: 判断句子的语义关系, 例如logical relationship (is a, has a, contract)

  • ERNIE2.0模型结构包含一系列共享的文本编码层来编码上下文信息, 这些文本编码层可以通过循环神经网络或Transformer来构建, 且编码器的参数能通过所有的预训练任务来进行更新.


  • ERNIE2.0模型的英文开放模型, 在GLUE测试中得到了优秀的结果:


  • ERNIE2.0模型在9个通用中文NLP测试任务中, 得到了非常优秀的结果, 尤其是LARGE版本模型在全部任务中得到了SOTA, 表现卓越:



ERNIE3.0

  • 百度公司于2021年7月发布ERNIE3.0版本, 参数规模达到100亿, 原始论文<< ERNIE 3.0: LARGE-SCALE KNOWLEDGE ENHANCED PRE-TRAINING FOR LANGUAGE UNDERSTANDING AND GENERATION >>.

  • 开放版本的试用demo可以访问: https://wenxin.baidu.com/wenxin/ernie


  • ERNIE3.0模型最重大的两个改进点:

    • 预训练中加入知识图谱三元组.
    • 模型基本单元从ERNIE2.0的transformer换成transformer-XL
  • Universal representation Module(通用语义表示网络): 通用语义层一旦预训练完成, 就不再更新参数(即便在fine-tuning时也不再更新).

  • Task-specific Representation Modules(特定任务语义表示): Task-specific Representation层则会在fine-tuning下游任务时候更新, 这样保证了fine-tuning的高效, 其中NLG和NLU参数非共享.


  • Task-specific Representation参数:

    • Structure backbone: Transformer-XL
    • Layers: 12
    • Hidden units: 768
    • Heads: 12
    • Max sequence length: 128
  • Universal Representation参数:

    • tructure backbone: Transformer-XL
    • Layers: 48
    • Hidden units: 4096
    • Heads: 64
    • Max sequence length: 512

  • 主要包含三类预训练任务:

    • Word-aware: Capture Lexical information
    • Structure-aware: Capture the syntactic information
    • Knowledge-aware: Improve knowledge memorization and reasoning
  • Word-aware:

    • Knowledge Masked Language Modeling: 同ERNIE1.0模型的方法.
    • Document Language Modeling: 进行了更长文本的单向语言模型预训练, 主要用于提升文本生成能力.
  • Structure-aware:

    • Sentence Reordering: 同ERNIE2.0模型的方法.
    • Sentence Distance: 同ERNIE2.0模型的方法.
  • Knowledge-aware:

    • 训练方法: 海量无监督文本(unstructured texts)与大规模知识图谱(structured texts)的平行预训练.
    • 训练语料: 5000万知识图谱三元组与4TB大规模语料中相关的文本组成pair.
    • 成果: 通过将大规模知识图谱的实体关系与大规模文本数据同时输入到预训练模型中进行联合掩码训练, 促进了结构化知识和无结构文本之间的信息共享, 大幅提升了模型对于知识的记忆和推理能力.
    • 文本与知识平行预训练:
      • 1: 利用识图谱挖掘算法, 对一句话进行三元组挖掘.
      • 2: 得到知识图谱的三元组.
      • 3: 将三元组和元语句拼接在一起作为模型输入.

  • 对于上面提到的Knowledge-aware中的文本与知识平行预训练, 为了让模型能学习到知识图谱的关系, 采用了两种方法:
    • 将三元组中的某个实体或者关系去掉, 然后通过B段去预测A段的masked部分.
    • 将B段的某个实体去掉, 通过A段去预测B段被masked的部分.


  • 三元组(用A段表示)可以代表了一对实体以及其关系, 这个关系具有一定的语义信息, 比如逻辑关系, 这个我们一般认为是知识(Knowledge).

  • 元语句(用B段表示)则代表着原始的文本信息(Plain Text).


  • 在整个AI领域, 真正困难的任务其实是小样本学习, 尤其是零样本学习, 这从某种意义上代表了真正的智能. ERNIE3.0在问答任务, 小说生成, 摘要生成任务等领域的表现是令人震惊的:


  • ERNIE3.0在众多任务中有极其优秀的表现, 在此展示一下:

    • Natural Language Understanding Tasks
    • Natural Language Generation Tasks
  • Natural Language Understanding Tasks: 14种类型45个任务, 平均5%左右的提升, 其中指代消解任务从69.7%提升到95.4%

    • Sentiment analysis 情感分析
    • Opinion extraction 观点提取
    • Natural Language Inference 自然语言推断
    • Winograd Schema Challenge (anaphora resolution 指代消解)
    • Relation Extraction 关系抽取
    • Event Extraction 事件抽取
    • Semantic Similarity 语义相似
    • Chinese News Classification 中文新闻分类
    • Closed-Book Question Answering 问答
    • Named Entity Recognition 命名实体识别
    • Machine Reading Comprehension 机器阅读理解
    • Legal Documents Analysis 法律文件分析
    • Cant Understanding 歧义理解?
    • Document Retrieval 文档检索
  • Natural Language Generation Tasks: 7种类型9个任务,平均提升7.4%

    • Text Summarization 文本摘要
    • Question Generation 问题生成
    • Closed-Book Question Answering 问答
    • Math 数学
    • Advertisement generation 广告生成
    • Translation 翻译
    • Dialogue Generation 对话生成

  • ERNIE3.0和ERNIE2.0的区别:
    • 相同点:
      • 采用连续学习的策略.
      • 采用了多个语义层级的预训练任务.
    • 不同点:
      • ERNIE3.0的编码器采用Transformer-XL(自回归+自编码), ERNIE2.0的编码器采用Transformer(自编码).
      • 预训练任务的细微差别, ERNIE3.0里增加的知识图谱.
      • ERNIE3.0考虑到不同的预训练任务具有不同的高层语义, 而共享着底层的语义(比如语法, 词法等), 为了充分地利用数据并且实现高效预训练, ERNIE 3.0中对采用了多任务训练中的常见做法, 将不同的特征层分为了通用语义层(Universal Representation)和任务相关层(Task-specific Representation).

  • 上图中的4个模型中, BERT, ERNIE1.0, ERNIE2.0都属于基于Transformer编码器, 只有ERNIE3.0的编码器是Transformer-XL.

  • BERT, ERNIE1.0只进行预训练任务的训练, ERNIE2.0, ERNIE3.0采用了Continual Multi-task Learning.



ERNIE3.0 TITAN

  • 百度公司于2022年1月发布ERNIE3.0 TITAN版本, 原始论文<< ERNIE 3.0 TITAN: EXPLORING LARGER-SCALE KNOWLEDGE ENHANCED PRE-TRAINING FOR LANGUAGE UNDERSTANDING AND GENERATION >>.

  • 相比于ERNIE3.0的100亿参数量, ERNIE3.0 TITAN模型的参数量达到了2600亿!!!


  • ERNIE3.0 TITAN是一种具有2600亿个参数的预训练语言模型, 它是世界上第一个知识增强的千亿参数模型, 也是中国最大的单例模型.

  • ERNIE3.0 TITAN具有不同于稀疏专家混合(MoE)系统的密集模型结构, 该模型在海量知识图谱和海量非结构化数据上进行训练, 在自然语言理解(NLU)和生成(NLG)方面表现出色. TITAN 在60多个NLP任务中取得了SOTA成果, 包括机器阅读理解, 文本分类和语义相似性等. 该模型在30个少样本和零样本基准测试中也表现良好, 这表明它可以用少量标记数据泛化各种下游任务, 并降低识别阈值.


  • 可控可信的学习算法: 自我监督的预训练允许AI增加参数的数量并利用更大的未标记数据集. 由于该技术的日益普及, 特别是在自然语言处理(NLP)中, 最近取得了突破. 为确保模型能够生成公平, 有凝聚力的消息, 团队提出了可控学习算法和可信学习算法. 有了这个, 模型可以有针对性地, 可控地组合提供的流派、情感、持续时间、主题和关键字. 这种方法使用自我监督的对抗学习框架来训练模型, 以从现实世界的人类语言中识别虚假的合成语言.

  • 下图展示了ERNIE3.0 TITAN模型在多机器, 多GPU环境下的分布式服务架构图:


  • 端到端自适应分布式训练: 由于大规模语言模型(LLM)的性能可能会随着模型规模的增加而不断增强, 因此参数数量呈指数增长. 然而训练和推理一个具有超过千亿个参数的模型是极其困难的, 并且会给基础设施带来很大压力. 在百度的AI平台PaddlePaddle上, 创建了端到端的分布式训练架构, 以满足灵活和自适应的需求. 它包括资源分配、模型分区、任务放置和分布式执行. 有了这一切, 该框架就可以具备面向工业应用和生产的强大能力. 实验表明, ERNIE3.0 TITAN可以使用该框架在数千个AI处理器上并行有效地进行训练. 此外通过采用资源感知分配, 模型的训练性能提高了2.1倍.

  • 下图展示了ERNIE3.0 TITAN模型在线进行知识蒸馏的架构图:


  • 环境友好型AI模型的在线蒸馏: 大规模模型需要大量资源进行训练和推理. 为此, 该团队采用了师生压缩(TSC)策略来构建ERNIE3.0 TITAN, 这是一种模仿教师模型的廉价学生模型. 该技术定期将来自教师模型的知识信号发送到多个不同大小的学生模型. 与传统的蒸馏不同, 这种方法由于教师模型额外的蒸馏计算和几个学生模型的重复信息传递, 可以节省大量的能量. 研究人员还发现, ERNIE3.0 TITAN和学生模型的直径相差千分之一. 这使得模型蒸馏极其困难. 为了弥合这一知识差距, 他们使用了所谓的教师助理范式. ERNIE3.0 TITAN的学生版与BERT Base 模型相比, 将5个任务的准确率提高了2.5%, 后者的参数数量是学生模型的两倍. 与相同规模的RoBERTa Base相比, 准确度提高了3.4%


轩辕1.0

  • 百度下属的度小满金融公司AI-Lab于2021年提出轩辕1.0(XuanYuan)预训练模型在CLUE1.1分类任务中"力压群雄"获得了排名第一的好成绩, 距离人类"表现"仅差3.38分!

  • CLUE是中文语言理解领域最具权威性的测评基准之一, 涵盖了文本相似度、分类、阅读理解共10项语义分析和理解类子任务. 其中, 分类任务需要解决6个问题, 例如传统文本分类, 文本匹配, 关键词分类等等, 能够全方面衡量模型性能. 该榜单竞争激烈, 几乎是业内兵家必争之地, 例如快手搜索, 优图实验室, 腾讯云等等研究机构也都提交了比赛方案.


  • 轩辕1.0模型是基于Transformer架构的预训练语言模型, 涵盖了金融、新闻、百科、网页等多领域大规模数据. 因此, 该模型"内含"的数据更全面, 更丰富, 面向的领域更加广泛.

  • 传统预训练模型采取"训练-反馈"模式, 度小满金融AI-Lab在训练轩辕1.0的时候细化了这一过程, 引入了任务相关的数据, 融合不同粒度不同层级的交互信息, 从而改进了传统训练模式.


  • 模型预训练思路主要从宏观和微观来看:

    • 宏观角度: 先从通用大规模的数据逐渐迁移到小规模的特定业务以及特定任务, 然后去通过不同的阶段逐渐训练, 直到满足目标任务.
    • 微观角度: 针对不同的下游分类任务, 会相应的设计出定制化的分类模型. 然后采用自监督学习, 迁移学习等等提升模型的性能.
  • 轩辕还处于1.0的版本, 更侧重于自然语言理解能力, 在接下来的2.0版本中, 研发人员会采用更大规模的数据, 训练出更加通用的预训练模型, 从而赋能更多的业务和领域.



创新工场


Mengzi模型

  • 澜舟科技-创新工场于2021年10月提出Mengzi模型, 原始论文<< Mengzi: Towards Lightweight yet Ingenious Pre-trained Models for Chinese >>. Mengzi只用10亿参数就杀进中文自然语言理解CLUE榜单前三!!!

  • 对于CLUE榜单近年来一直是AI玩家们的兵家必争之地, 通常来说在榜单排名靠前的模型都是百亿, 千亿级别的超大模型, 而Mengzi模型是唯一一个以10亿参数进入TOP3的"小而美"模型.


  • 本次澜舟科技开源了4个模型, 架构如下图所示:


  • 它可处理多语言, 多模态数据, 同时支持多种文本理解和文本生成任务. 在文本分类, 阅读理解等各类任务上表现出色. 目前开源的4个模型分别在金融, 文案生成, 图像理解, 语言理解上分别发挥优势作用, 不同的模型参数列表展示如下:


  • Mengzi模型主要有三方面的贡献:
    • 第一: 研究了各种预训练策略来训练轻量级语言模型, 表明精心设计良好的目标可以进一步显著提高模型的容量, 而不需要扩大模型的大小.
    • 第二: 发布了Mengzi模型, 包括判别式、生成式、金融和多模态模型变体, 能够胜任广泛的语言和视觉任务. 这些模型中的文本编码器只包含1.03亿个参数, 论文作者希望这能够促进学术界和工业界的相关研究.
    • 第三: 通过大量基准任务测试表明, 孟子模型在一系列语言理解和生成任务上取得了很强的性能.

  • 关于Mengzi模型的训练:
    • 数据预处理:训练前的语料库来源于中文维基百科、中文新闻和爬虫语料,总数据大小为300GB。通过使用探索性的数据分析技术来清理数据,删除HTML标签、url、电子邮件、表情符号等。由于在原始语料库中有简体标记和传统的中文标记,使用OpenCC将传统标记转换为简体形式,重复的文章也会被删除.
    • 模型结构:RoBERTa被选做为 Mengzi预训练的骨干模型,12层transformers,hidden size为768,12个attention heads,预训练任务为MLM.
    • 预训练细节:
      • 1: 词汇表包含21,128个字符,看了下与Bert大小保持一致。句子长度限制在512个字符,batch size为128.
      • 2: 在训练前,每个序列中有15%的单词被随机屏蔽以进行MLM预测.
      • 3: 使用LAMB优化器的mixed-batch训练方式,它涉及两个阶段:总epoch的前9/10使用序列长度为128,总epoch的最后1/10使用序列长度为512。这两个阶段的批次规模分别为16384和32768.
      • 4: 采用PostgreSQL对训练示例进行全局抽样,以避免两阶段训练中样本权重的不平衡。整个培训前的过程需要100万步。使用32个3090 24G,使用FP16和深度4进行训练加速.

  • Mengzi模型在CLUE榜单上几乎全部任务都得到最优结果, 展现了强大的能力. 具体来说, 包含了9种自然语言理解任务:
    • 蚂蚁金融问题匹配(AFQMC)
    • 新闻标题文本分类(TNEWS)
    • 科大讯飞文本测试(IFLYTEK)
    • 中文翻译多基因自然语言推理(CMNLI)
    • 中文机器智能测试(WSC)
    • 中文科学文献(CSL)
    • 中国机器阅读理解(CMRC)
    • 中文语言完形填空(CHID)
    • 中文多项选择阅读理解(C3)


  • Mengzi模型的预训练主要在3方面进行了优化:
    • Linguistic-motivated Objectives: 语义信息已被证明对语言建模是有效的。受LIMIT-Bert的启发,在训练前使用了词性(POS)和命名实体(NE)序列标记任务,并结合了原始的MLM和NSP目标。原始文本中的POS和NE标签由spaCy标注.
    • Sequence Relationship Objectives: 为了更好地对句子间的句子对信息进行建模,Mengzi在模型预训练中添加了句子顺序预测(SOP)任务.
    • Dynamic Gradient Correction: 广泛使用的MLM会引起原始句子结构的干扰,导致语义丢失,增加了模型预测的难度,不可避免地导致训练不足和效率低下。为了缓解这一问题,本文提出了一系列的动态梯度校正技术来提高模型的性能和鲁棒性.

  • Mengzi模型在生成式任务上有优秀的表现, 开源模型中的Mengzo-T5-base就是专门为生成式任务而打造的:


  • Mengzi模型在图像理解任务上也有优秀的表现, 开源模型中的Mengzi-Oscar-base就是专门为图像理解任务而打造的:


  • MENGZI模型在投满分项目上的微调训练:
import torch
import torch.nn as nn
import os
from transformers import BertModel, BertTokenizer,BertConfig


class Config(object):
    def __init__(self, dataset):
        self.model_name = "mengzi"
        self.data_path = "/home/ec2-user/ec2-user/zhudejun/bert/mengzi/data/data/"
        self.train_path = self.data_path + "train.txt"  # 训练集
        self.dev_path = self.data_path + "dev.txt"  # 验证集
        self.test_path = self.data_path + "test.txt"  # 测试集
        self.class_list = [x.strip() for x in open(self.data_path + "class.txt").readlines()] # 类别名单

        self.save_path = "/home/ec2-user/ec2-user/zhudejun/bert/mengzi/src/saved_dic"
        if not os.path.exists(self.save_path):
            os.mkdir(self.save_path)
        self.save_path += "/" + self.model_name + ".pt"  # 模型训练结果

        # 模型训练+预测的时候, 放开下一行代码, 在GPU上运行.
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 设备
        # 模型量化的时候, 放开下一行代码, 在CPU上运行.
        # self.device = 'cpu'

        self.require_improvement = 1000  # 若超过1000batch效果还没提升,则提前结束训练
        self.num_classes = len(self.class_list)  # 类别数
        self.num_epochs = 3  # epoch数
        self.batch_size = 128  # mini-batch大小
        self.pad_size = 32  # 每句话处理成的长度(短填长切)
        self.learning_rate = 5e-5  # 学习率
        self.bert_path = "/home/ec2-user/ec2-user/zhudejun/bert/mengzi/data/mengzi_bert_base"
        self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
        self.bert_config = BertConfig.from_pretrained(self.bert_path + '/config.json')
        self.hidden_size = 768


class Model(nn.Module):
    def __init__(self, config):
        super(Model, self).__init__()
        self.bert = BertModel.from_pretrained(config.bert_path, config=config.bert_config)

        self.fc = nn.Linear(config.hidden_size, config.num_classes)

    def forward(self, x):
        context = x[0]  # 输入的句子
        mask = x[2]  # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
        _, pooled = self.bert(context, attention_mask=mask)
        out = self.fc(pooled)
        return out

  • 输出结果:
Loading data for Bert Model...
180000it [00:41, 4293.40it/s]
10000it [00:02, 3974.40it/s]
10000it [00:02, 4408.08it/s]
Epoch [1/3]
 14%|█████████▏                                                       | 200/1407 [02:00<12:33,  1.60it/s]Iter:    200,  Train Loss:  0.31,  Train Acc: 90.62%,  Val Loss:  0.31,  Val Acc: 90.45%,  Time: 0:02:19 *
 28%|██████████████████▍                                              | 400/1407 [04:28<10:55,  1.54it/s]Iter:    400,  Train Loss:  0.37,  Train Acc: 85.94%,  Val Loss:  0.27,  Val Acc: 91.72%,  Time: 0:04:50 *
 43%|███████████████████████████▋                                     | 600/1407 [06:59<08:43,  1.54it/s]Iter:    600,  Train Loss:  0.29,  Train Acc: 89.84%,  Val Loss:  0.25,  Val Acc: 91.88%,  Time: 0:07:20 *
 57%|████████████████████████████████████▉                            | 800/1407 [09:29<06:34,  1.54it/s]Iter:    800,  Train Loss:  0.15,  Train Acc: 95.31%,  Val Loss:  0.23,  Val Acc: 92.80%,  Time: 0:09:51 *
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [12:00<04:23,  1.54it/s]Iter:   1000,  Train Loss:  0.15,  Train Acc: 92.97%,  Val Loss:  0.23,  Val Acc: 92.44%,  Time: 0:12:19 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [14:28<02:14,  1.54it/s]Iter:   1200,  Train Loss:  0.22,  Train Acc: 92.97%,  Val Loss:  0.22,  Val Acc: 92.85%,  Time: 0:14:50 *
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:59<00:04,  1.54it/s]Iter:   1400,  Train Loss:  0.33,  Train Acc: 89.84%,  Val Loss:  0.21,  Val Acc: 93.29%,  Time: 0:17:21 *
100%|████████████████████████████████████████████████████████████████| 1407/1407 [17:24<00:00,  1.35it/s]
Epoch [2/3]
 14%|█████████▏                                                       | 200/1407 [02:09<13:02,  1.54it/s]Iter:    200,  Train Loss:   0.2,  Train Acc: 92.97%,  Val Loss:  0.22,  Val Acc: 93.16%,  Time: 0:19:53 
 28%|██████████████████▍                                              | 400/1407 [04:37<10:54,  1.54it/s]Iter:    400,  Train Loss:  0.21,  Train Acc: 93.75%,  Val Loss:  0.21,  Val Acc: 93.44%,  Time: 0:22:20 
 43%|███████████████████████████▋                                     | 600/1407 [07:05<08:44,  1.54it/s]Iter:    600,  Train Loss:   0.2,  Train Acc: 93.75%,  Val Loss:  0.21,  Val Acc: 93.14%,  Time: 0:24:49 
 57%|████████████████████████████████████▉                            | 800/1407 [09:33<06:34,  1.54it/s]Iter:    800,  Train Loss: 0.088,  Train Acc: 96.88%,  Val Loss:  0.21,  Val Acc: 93.42%,  Time: 0:27:16 
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [12:01<04:25,  1.53it/s]Iter:   1000,  Train Loss: 0.095,  Train Acc: 96.09%,  Val Loss:  0.22,  Val Acc: 93.10%,  Time: 0:29:45 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [14:29<02:14,  1.54it/s]Iter:   1200,  Train Loss:  0.15,  Train Acc: 94.53%,  Val Loss:  0.21,  Val Acc: 93.20%,  Time: 0:32:13 
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:57<00:04,  1.54it/s]Iter:   1400,  Train Loss:  0.19,  Train Acc: 92.19%,  Val Loss:  0.22,  Val Acc: 93.39%,  Time: 0:34:41 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [17:20<00:00,  1.35it/s]
Epoch [3/3]
 14%|█████████▏                                                       | 200/1407 [02:09<13:02,  1.54it/s]Iter:    200,  Train Loss:  0.11,  Train Acc: 97.66%,  Val Loss:  0.22,  Val Acc: 93.20%,  Time: 0:37:13 
 28%|██████████████████▍                                              | 400/1407 [04:37<10:57,  1.53it/s]Iter:    400,  Train Loss:  0.21,  Train Acc: 92.97%,  Val Loss:  0.22,  Val Acc: 93.60%,  Time: 0:39:41 
 43%|███████████████████████████▋                                     | 600/1407 [07:05<08:43,  1.54it/s]Iter:    600,  Train Loss:  0.13,  Train Acc: 96.09%,  Val Loss:  0.23,  Val Acc: 93.50%,  Time: 0:42:09 
 57%|████████████████████████████████████▉                            | 800/1407 [09:33<06:33,  1.54it/s]Iter:    800,  Train Loss: 0.067,  Train Acc: 97.66%,  Val Loss:  0.23,  Val Acc: 93.32%,  Time: 0:44:37 
 71%|█████████████████████████████████████████████▍                  | 1000/1407 [12:01<04:23,  1.55it/s]Iter:   1000,  Train Loss: 0.044,  Train Acc: 98.44%,  Val Loss:  0.23,  Val Acc: 93.28%,  Time: 0:47:05 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [14:29<02:14,  1.54it/s]Iter:   1200,  Train Loss:  0.11,  Train Acc: 96.88%,  Val Loss:  0.22,  Val Acc: 93.26%,  Time: 0:49:33 
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:57<00:04,  1.53it/s]Iter:   1400,  Train Loss:  0.14,  Train Acc: 96.09%,  Val Loss:  0.22,  Val Acc: 93.51%,  Time: 0:52:01 
100%|████████████████████████████████████████████████████████████████| 1407/1407 [17:20<00:00,  1.35it/s]
Test Loss:   0.2,  Test Acc: 94.24%
Precision, Recall and F1-Score...
               precision    recall  f1-score   support

      finance     0.9462    0.9320    0.9390      1000
       realty     0.9426    0.9530    0.9478      1000
       stocks     0.8906    0.9200    0.9051      1000
    education     0.9641    0.9680    0.9661      1000
      science     0.9487    0.8690    0.9071      1000
      society     0.9399    0.9390    0.9395      1000
     politics     0.9361    0.9090    0.9224      1000
       sports     0.9734    0.9890    0.9812      1000
         game     0.9369    0.9800    0.9580      1000
entertainment     0.9470    0.9650    0.9559      1000

     accuracy                         0.9424     10000
    macro avg     0.9426    0.9424    0.9422     10000
 weighted avg     0.9426    0.9424    0.9422     10000

Confusion Matrix...
[[932  12  37   1   4   3   7   2   2   0]
 [  7 953   7   1   2   6   5   7   3   9]
 [ 33  17 920   1   9   1  13   3   3   0]
 [  1   1   1 968   2  11   6   0   1   9]
 [  3   3  35   2 869  14  11   2  48  13]
 [  0  11   3  13   3 939  16   0   3  12]
 [  7  10  26  14  10  17 909   1   1   5]
 [  2   1   1   0   1   2   1 989   0   3]
 [  0   0   1   1   9   4   1   1 980   3]
 [  0   3   2   3   7   2   2  11   5 965]]
Time usage: 0:00:18

  • 结论: 将预训练模型替换成MENGZI模型后, 测试集上得到了94.24%的F1分数, 优于BERT的93.64%和ERNIE1.0的93.98%, 仅次于RoBERTa的94.30%, 和macBert的94.48%, 展现了非常优秀的水平!!!


华为


NeZha模型

  • NeZha模型是华为诺亚方舟实验室于2021年11月提出的大型中文预训练模型, 原始论文<< NEZHA: NEURAL CONTEXTUALIZED REPRESENTATION FOR CHINESE LANGUAGE UNDERSTANDING >>.

  • NeZha模型的基础架构基于Transformer, 对BERT模型进行了4点重要的改进:

    • 1: 增加相对位置编码函数(Functional Relative Positional Encoding)
    • 2: 全词掩码(Whole Word Masking)
    • 3: 混合精度训练(Mixed Precision Training)
    • 4: 优化器改进(LAMB Optimizer)

  • 1: 增加相对位置编码函数(Functional Relative Positional Encoding)

  • Transformer为了增加模型的并行效率, 采用的是Multi-Head Attention机制. 虽然Multi-Head Attention相较于RNN可以增加运算效率, 但是它丢失了句子中每个token的位置信息. 为了使模型更加稳定有效, Transformer和Bert分别在模型中增加了函数式和参数式绝对位置编码.

  • 那么问题来了, 既然有了绝对位置编码, 句子中每个token的位置信息已经在模型中有所体现, 为什么还要有相对位置编码呢? 那是因为在BERT模型预训练时, 很多数据的真实数据长度达不到最大长度, 因此靠后位置的位置向量训练的次数要比靠前位置的位置向量的次数少, 造成靠后的参数位置编码学习的不够. 在计算当前位置的向量的时候, 应该考虑与它相互依赖的token之间相对位置关系, 可以更好地学习到信息之间的交互传递.


  • 接下来的核心问题就是: 相对位置编码如何加入到模型中呢? 这个问题其实在前面的很多模型中都有讲过.

  • 原始Multi-Head Attention是基于Scaled Dot-Product Attention实现的, 输出张量Z_i, 和最终的e_ij的计算公式依次如下:


  • 在相对位置编码方案中, 将输出Z_i加上两个位置之间相对距离的参数, 在上述公式1和公式3中, 分别加入两个token的相对位置信息, 修改如下得到:


  • 上面公式4, 公式5中的a_ij是位置i和位置j的相对位置编码, 计算公式如下:


  • 2: 全词掩码(Whole Word Masking)

  • 华为通过大量实验证实, 将随机掩码词汇替换成全词掩码, 可以有效提高预训练模型效果, 即如果有一个汉字被掩蔽, 属于同一个汉语词的其他汉字都被一起掩蔽, 会让模型学习到更高级的语义.


  • 3: 混合精度训练(Mixed Precision Training)

  • 在实现混合精度训练时, 是在训练过程中的每一个step, 为模型的所有weights维护一个float32的copy, 称为Master Weights. 在做前向和反向传播过程中, Master Weights会转换成float16(半精度浮点数)格式, 其中权重, 激活函数和梯度都是用float16进行表示, 最后梯度会转换成float32格式去更新Master Weights.

  • 核心目的: 为了提高训练速度, 计算float16比float32快!!!


  • 4: 优化器改进(LAMB Optimizer)

  • 通常在深度神经网络训练的Batch Size很大的情况下(超过一定阈值)会给模型的泛化能力带来负面影响, 而LAMB优化器通过一个自适应的方式为每个参数调整learning rate, 能够在Batch Size很大的情况下不损失模型的效果, 使得模型训练能够采用很大的Batch Size, 进而极大提高训练速度.

  • LAMB是论文<< Large Batch Optimization for Deep Learning: Training BERT in 76 minutes >> 提出的一个新型优化器, 它可以将预训练BERT的时间从三天降到76分钟!!!

  • NeZha base模型每个GPU的batch大小为180, NeZha large模型每个GPU的batch大小为64.


  • NeZha模型在若干标准测试集上的表现列举如下:


  • NeZha模型在投满分项目上的微调:
import torch
import torch.nn as nn
import os
from transformers import BertModel, BertTokenizer,BertConfig


class Config(object):
    def __init__(self, dataset):
        self.model_name = "NeZha"
        self.data_path = "/home/ec2-user/ec2-user/zhudejun/bert/NeZha/data/data/"
        self.train_path = self.data_path + "train.txt"  # 训练集
        self.dev_path = self.data_path + "dev.txt"  # 验证集
        self.test_path = self.data_path + "test.txt"  # 测试集
        self.class_list = [x.strip() for x in open(self.data_path + "class.txt").readlines()] # 类别名单

        self.save_path = "/home/ec2-user/ec2-user/zhudejun/bert/NeZha/src/saved_dic"
        if not os.path.exists(self.save_path):
            os.mkdir(self.save_path)
        self.save_path += "/" + self.model_name + ".pt"  # 模型训练结果

        # 模型训练+预测的时候, 放开下一行代码, 在GPU上运行.
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 设备
        # 模型量化的时候, 放开下一行代码, 在CPU上运行.
        # self.device = 'cpu'

        self.require_improvement = 1000  # 若超过1000batch效果还没提升,则提前结束训练
        self.num_classes = len(self.class_list)  # 类别数
        self.num_epochs = 3  # epoch数
        self.batch_size = 128  # mini-batch大小
        self.pad_size = 32  # 每句话处理成的长度(短填长切)
        self.learning_rate = 5e-5  # 学习率
        self.bert_path = "/home/ec2-user/ec2-user/zhudejun/bert/NeZha/data/NeZha_model"
        self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
        self.bert_config = BertConfig.from_pretrained(self.bert_path + '/config.json')
        self.hidden_size = 768


class Model(nn.Module):
    def __init__(self, config):
        super(Model, self).__init__()
        self.bert = BertModel.from_pretrained(config.bert_path, config=config.bert_config)

        self.fc = nn.Linear(config.hidden_size, config.num_classes)

    def forward(self, x):
        context = x[0]  # 输入的句子
        mask = x[2]  # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
        _, pooled = self.bert(context, attention_mask=mask)
        out = self.fc(pooled)
        return out

  • 输出结果:
Loading data for Bert Model...
180000it [00:41, 4285.98it/s]
10000it [00:02, 3952.56it/s]
10000it [00:02, 4385.84it/s]
Epoch [1/3]
 28%|██████████████████▍                                              | 400/1407 [04:08<10:52,  1.54it/s]Iter:    400,  Train Loss:  0.64,  Train Acc: 80.47%,  Val Loss:  0.58,  Val Acc: 83.65%,  Time: 0:04:28 *
 57%|████████████████████████████████████▉                            | 800/1407 [08:46<06:33,  1.54it/s]Iter:    800,  Train Loss:  0.34,  Train Acc: 89.06%,  Val Loss:  0.43,  Val Acc: 87.64%,  Time: 0:09:07 *
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:25<02:14,  1.54it/s]Iter:   1200,  Train Loss:  0.33,  Train Acc: 90.62%,  Val Loss:  0.35,  Val Acc: 89.71%,  Time: 0:13:46 *
100%|████████████████████████████████████████████████████████████████| 1407/1407 [15:59<00:00,  1.47it/s]
Epoch [2/3]
 28%|██████████████████▍                                              | 400/1407 [04:19<10:52,  1.54it/s]Iter:    400,  Train Loss:  0.37,  Train Acc: 90.62%,  Val Loss:   0.3,  Val Acc: 90.66%,  Time: 0:20:40 *
 57%|████████████████████████████████████▉                            | 800/1407 [08:58<06:33,  1.54it/s]Iter:    800,  Train Loss:  0.18,  Train Acc: 92.97%,  Val Loss:  0.32,  Val Acc: 90.86%,  Time: 0:25:16 
 85%|██████████████████████████████████████████████████████▌         | 1200/1407 [13:35<02:13,  1.55it/s]Iter:   1200,  Train Loss:  0.29,  Train Acc: 92.97%,  Val Loss:  0.31,  Val Acc: 91.06%,  Time: 0:29:53 
100%|███████████████████████████████████████████████████████████████▋| 1400/1407 [16:02<00:04,  1.54it/s]No optimization for a long time, auto-stopping...
Test Loss:   0.3,  Test Acc: 90.78%
Precision, Recall and F1-Score...
               precision    recall  f1-score   support

      finance     0.9152    0.8850    0.8998      1000
       realty     0.9305    0.9100    0.9201      1000
       stocks     0.8100    0.8740    0.8408      1000
    education     0.9456    0.9560    0.9508      1000
      science     0.9041    0.8300    0.8655      1000
      society     0.8904    0.9020    0.8962      1000
     politics     0.9011    0.8660    0.8832      1000
       sports     0.9817    0.9670    0.9743      1000
         game     0.9274    0.9450    0.9361      1000
entertainment     0.8821    0.9430    0.9116      1000

     accuracy                         0.9078     10000
    macro avg     0.9088    0.9078    0.9078     10000
 weighted avg     0.9088    0.9078    0.9078     10000

Confusion Matrix...
[[885  14  70   2   2  11   9   1   0   6]
 [ 11 910  32   3   5  12   4   3   4  16]
 [ 51  17 874   1  27   3  19   1   3   4]
 [  1   1   4 956   3  10   8   1   4  12]
 [  4   2  52   7 830  17  17   2  37  32]
 [  2  18   0  24   4 902  18   0   3  29]
 [  8   6  36  10  16  44 866   0   2  12]
 [  0   3   2   0   2   5  10 967   0  11]
 [  1   1   8   2  28   7   2   2 945   4]
 [  4   6   1   6   1   2   8   8  21 943]]
Time usage: 0:00:17

  • 结论: 将预训练模型替换成NeZha后, 在测试集上得到90.78%的F1分数, 反倒和其他几个模型相比差距较大, 表现不佳.


浪潮

源1.0

  • 浪潮公司人工智能研究院于2021年10月发布"源1.0"超级大模型, 参数量达到2457亿, 原始论文<< YUAN 1.0: LARGE-SCALE PRE-TRAINED LANGUAGE MODEL IN ZERO-SHOT AND FEW-SHOT LEARNING >>.

  • “源1.0”在语言智能方面表现优异,获得中文语言理解评测基准CLUE榜单的零样本学习(zero-shot)和小样本学习(few-shot)两类总榜冠军。测试结果显示,人群能够准确分辨人与“源1.0”作品差别的成功率为49.16%, 这意味着一个二分类的问题, 竟然人类能判对的概率低于50%!!!


  • 结论: 上图显示的结果直接表明, 源1.0的强大能力"几乎"可以和人类以假乱真!!!

  • 源1.0在数据处理上的显著工作:

  • 互联网语料基本上可以分为3大类: 高质量语料(语句通顺且包含一定知识), 低质量语料(语句不通顺), 广告语料(语句通顺但重复率过高, 如广告, 网站说明, 免责声明等). 为了给"源1.0"模型提供高质量的预训练数据集, 浪潮人工智能研究院使用BERT训练了一个语料质量三分类模型. 整个方案包括数据采样, 语料标注, 模型训练和效果评估四部分.

  • 在"源1.0"训练时, 由于爬取的互联网语料非常庞大, 即便经过敏感信息过滤, 文章去重, 数据集仍在TB级别. 如此大规模的数据集难以直接进行处理, 分析, 需要进行采样. 将经过粗略过滤之后的数据, 以文章为单位进行采样, 再将所有采样数据分别写入到2个文件中, 其中一个用来标注训练集语料(构建训练集, 称之为"训练集"), 另外一个则用来验证分类模型的效果(称之为"测试集"). 另外, 为了使采样数据具有充分的代表性, 在整个数据集内采用均匀采样.

  • 先使用"训练集"中的部分数据自动构建训练语料, 然后使用分类模型进行训练, 最后在剩余采样数据("验证集")上进行评估, 并将得分较高的低质量语料和广告语料加入到标注数据中, 如此循环多次.

  • 为了给"源1.0"提供高质量的预训练数据集, 我们采用了一种海量互联网语料的质量清洗和分析方法. 首先对海量文本数据进行采样, 通过PPL, 关键词密度筛选, 聚类等方法自动筛选出低质量语料, 然后使用分类模型在标注数据上进行训练, 经过不断调优得到最终的文本质量分类模型. 这一方法可以极大减少人工标注成本, 从语义层面更加充分地去除各类低质量文本, 有效提高预训练语言模型的理解能力.


  • "源1.0"几乎是把近5年整个中文互联网的浩瀚内容全部"读"完了. 通过自研的文本分类模型, 获得了5TB高质量中文数据集, 在训练数据集规模上领先近10倍. 源1.0还阅读了大约2000个亿词.

  • 我们可以先感受一下在不同任务上源1.0模型展示出的杰出能力:


  • 源1.0这种巨大体量的模型, 必然采用了分布式训练的架构, 如下图所示:


  • 源1.0在零样本测试, 小样本测试中有非常好的结果, 具体展示如下:


  • 看完了前面比较"空空如也"的数据, 肯定不那么直观, 我们看看具体的案例, 下图展示了在不同训练模式下模型的输出能力:


  • 源1.0模型拥有很强大的模仿能力:


  • 源1.0在正向观点输入, 和负向观点输入下, 所展示的对应生成能力:


  • 源1.0在零样本基准测试中的得分表现:


  • 源1.0在少样本基准测试中的得分表现:


  • 最后总结一下源1.0的杰出贡献: 通过协同优化, 源1.0攻克了在巨量数据和超大规模分布式训练的扩展性, 计算效率, 巨量模型算法及精度提升等方面的业界难题.

  • 算法方面: 1: 解决了巨量模型训练不稳定的业界难题, 提出了稳定训练巨量模型的算法. 2: 提出了巨量模型新的推理方法, 提升模型的泛化能力, 让一个模型可以应用于更多的场景.

  • 数据方面: 1: 创新地提出了中文数据集的生成方法, 通过全新的文本分类模型, 可以有效过滤垃圾文本, 并生成高质量中文数据集.

  • 算力方面:

    • 1: 通过算法与算力协同优化, 使模型更利于GPU性能发挥, 极大的提升了计算效率, 并实现业界第一训练性能的同时实现业界领先的精度.


微软

威震天1.0

  • 微软联合英伟达共同推出的超级大模型Megatron-Turing1.0, 拥有5300亿参数量, 是迄今为止参数最多, 功能最强大的解码语言模型.

  • 模型训练是在基于NVIDIA DGX SuperPOD的Selene超级计算机上以混合精度完成的, 该超级计算机由560个DGX A100服务器提供支持, 这些服务器以完整的胖树配置与HDR InfiniBand联网. 每个DGX A100有8个NVIDIA A100 80GB Tensor Core GPU, 通过NVLink和NVSwitch相互完全连接. 微软Azure NDv4云超级计算机使用了类似的参考架构.


  • 威震天1.0模型的参数数量是同类现有最大模型GPT-3的3倍, 并在一系列广泛的自然语言任务中展示了无与伦比的准确性:
    • 完成预测
    • 阅读理解
    • 常识推理
    • 自然语言推理
    • 词义消歧



Google

GLaM模型

  • 谷歌公司于2021年12月提出了最新版本的GLaM模型, GLaM是拥有1.2万亿参数的超大模型, 原始论文<< GLaM: Efficient Scaling of Language Models with Mixture-of-Experts >>.

  • 用更多的数据, 计算和参数扩展语言模型, 推动了自然语言处理的重大进展. 例如, 得益于规模化, GPT-3能够在情境学习任务上取得显著成绩. 然而, 训练这些大型密集模型需要大量的计算资源. 论文中提出并开发了GLaM(通才语言模型)语言模型, 该模型使用稀疏激活的混合专家体系结构来扩展模型容量, 同时与密集变体相比, 产生的训练成本也大大降低. GLaM有1.2万亿个参数, 大约比GPT-3大7倍. 它只消耗训练GPT-3所用能量的⅓, 推理需要一半的计算次数, 同时在29个NLP任务中仍能获得更好的zero-shot和one-shot性能.

  • 下图展示了相比较GPT-3模型, GLaM在若干关键的NLU, NLG基准测试中的效果提升:


  • 在过去的十年中, 语言模型在自然语言处理(NLP)的发展中扮演着重要的角色. 语言模型的变体已用于为许多NLP应用生成预训练词向量(Mikolov等人, 2013年; Pennington等人, 2014年). 向使用更多数据和更大模型扩展的转变, 使得复杂的自然语言任务能够使用标记较少的数据执行. 例如, GPT-3证明了上下文学习用于few-shot甚至zero-shot泛化的可行性, 这意味着在NLP应用程序上实现良好性能所需的标记样本非常少. 在有效且性能良好的情况下, 进一步扩展成本变得令人望而却步, 并会消耗大量能源.

  • 在这项工作中, 作者展示了一个大的稀疏激活的网络可以在较少的任务上实现与最先进的密集模型相比的竞争结果, 同时具有更高的计算效率. 论文中提出了一系列称为GLaM的混合专家(MoE)语言模型, 它在密集计算和条件计算之间取得了平衡. GLAM的最大版本总共有1.2亿个参数, 每个MOE层有64个专家, 其中输入批次中的每个token仅激活95b(8%个1.2T)参数的子网络. 与GPT-3(175B)相比, 在zero-shot和one-shot方面, 该模型在7个类别的29个公共NLP基准测试中显著提高了学习效率. 从语言完成任务, 开放域QA任务到自然语言推理任务. 由于稀疏激活的架构和模型并行算法的高效实现, 训练期间的总能耗仅为GPT-3的三分之一. 上面图中也有所展示.

  • 作者使用GLaM来研究数据, 规模和稀疏性的重要性. 分析表明, 即使对于这些大型模型, 如果目标是生成高质量的语言理解模型, 也不应该牺牲数据质量来换取数量.

  • 虽然MoE模型在NLP中还不常见, 但论文的工作表明, 即使是基本版本的MoE也可以在大规模的语言理解中非常有效. 论文结果还证实, 稀疏性是实现高质量NLP模型同时节约能源成本的最有希望的方向之一. 因此, MoE应被视为未来扩展的有力候选.


  • 关于GLaM的训练数据集:

  • 为了训练模型, 构建了一个1.6万亿token的高质量数据集, 这些token代表了广泛的自然语言用例. 网页构成了未标记数据集中的大量数据, 然而它们的质量从专业写作到低质量评论和论坛页面不等. 论文作者开发了自己的文本质量分类器, 以从原始较大的语料库中生成高质量的web语料库. 为了提高推理速度, 使用了基于特征哈希的线性分类器. 该分类器经过训练, 可以在一组精选文本(维基百科, 书籍和一些选定的网站)和其他网页之间进行分类. 作者使用这个分类器来估计网页的内容质量. 然后通过使用帕累托分布来根据网页的得分来应用该分类器. 这允许包含一些质量较低的网页, 以防止分类器中出现系统性偏置.

  • 作者使用此过程生成高质量的过滤网页子集, 并将其与书籍, 维基百科页面和其他数据源相结合, 创建了最终GLaM数据集. 还纳入了Adiwardana等人(2020年)使用的公共领域社交媒体对话的数据. 在论文中分析了训练数据的重要性, 并表明该数据过滤步骤对模型的质量有很大影响. 为了检查数据污染, 作者在训练集和评估数据之间进行了重叠分析.


  • 关于GLaM的模型架构:

  • 利用稀疏激活的混合专家(MOE)作为基础架构, 在GLAM模型中, 与GShard MoETransformer类似, 用MoE层替换其他Transformer层的前馈组件. 每个MoE层由一组作为"专家"的独立前馈网络组成. 然后激活函数使用softmax激活函数对这些专家的概率分布进行建模, 此分布表示每个专家处理传入输入的能力.

  • 尽管每个MoE层都有更多的参数, 但专家很少被激活. 这意味着对于给定的输入token, 只使用有限的专家子集, 从而在限制计算的同时为模型提供更多的容量. 在GLaM的架构中, 子集大小为2. 在训练期间每个MoE层的可学习门控网络都经过训练, 以使用其输入来激活输入序列中每个标记的最佳两名专家. 在推理过程中, 学习的门控网络为每个token动态地选择两个最佳专家. 对于具有E专家的MoE层, 这本质上提供了O(E2)不同前馈网络组合的集合, 而不是经典Transformer架构中的一个, 从而带来更大的计算灵活性. token的最终学习表示将是所选专家输出的加权组合.

  • 作者还对原始的Transformer架构进行了额外的修改。每层相对位置偏置取代标准位置嵌入. 在非MoETransformer前馈子层中, 将第一个线性投影和激活函数替换为激活线性单元, 该单元计算输入的两个线性变换的分量乘积, 其次是GLUE激活函数.


  • 下图展示了GLaM的架构图:


  • 关于GLaM模型的训练:

  • 论文中对所有GLaM模型使用相同的学习超参数, 使用1024个token的最大序列长度, 并将每个输入样本打包为每批最多有100万个token. dropout rate设置为0, 因为训练语料库中可用标记的数量远大于训练期间处理的标记的数量. 选用的优化器是Adafactor, 一阶矩衰减β1=0, 二阶矩衰减β2=0.99. 将前10K训练步骤的初始学习率保持在0.01, 然后使用平方根逆调度对其进行衰减. 在训练期间, 使用float32作为模型权重, 使用float16作为激活, 最大的GLaM 64B/64E型号是在1024块云TPU-V4芯片上训练的.

  • 在万亿参数尺度上训练模型是极其昂贵的, 即使是对于稀疏激活的模型也是如此. 超参数调整的空间很小. 此外, 其他稀疏激活的模型受到训练不稳定性的阻碍. 在选择训练策略和超参数时需要格外小心, 在这里分享若干GLaM模型的一些实现技巧:

    • 1: 首先训练小规模模型, 使其收敛, 这使我们能够尽早暴露数据集和基础架构中的潜在问题.
    • 2: 如果梯度中存在任何NAN或INF, 我们将跳过批次的重量更新. 注意: NaN/INF仍可能在应用梯度步骤期间发生, 在这种情况下, 我们将从前面的检查点重新启动. 例如, 即使现有变量或渐变中没有INF, 更新的变量仍然可能导致INF.
    • 3: 当我们在训练中遇到罕见的大波动甚至NaN/INF时, 我们从早期健康检查点重新开始. 顺序加载批次的随机性可能有助于在重新启动后从训练中的先前FLOPs状态中逃脱.
  • 通过仔细实施上述技巧, 我们观察到在所有尺度下稀疏激活模型的训练变得相当稳定. 我们使用相同的超参数训练所有GLaM模型, 无需额外调整.


  • 关于GLaM模型的评估:

  • 为了清楚地证明GLaM模型的有效性, 必须遵守2019年公认的zero-shot和one-shot协议:

    • zero-shot: 对于zero-shot学习设置, 在大多数情况下, 我们直接评估开发集中的每个样本.
    • one-shot: 对于one-shot学习, 我们从该任务的训练集中随机抽取一个样本作为唯一的演示和上下文.

  • GLaM超级模型在零样本预测和少样本预测任务上, 展现了让人震惊的结果, 相比于GPT-3在更多的任务上都有显著提升:



LaMDA模型

  • 在整个NLP领域内, 公认最难的任务就是实现"真正意义上的图灵测试"! 而这个任务主要依赖于多轮对话, 谷歌于2022年1月提出了专门用于对话领域的最新超大模型LaMDA, 拥有多达1370亿个参数, 原始论文<< LaMDA: Language Models for Dialog Applications >>.

  • 时至今日, 语言模型变得比以往任何时候都更具强大能力, 可以帮助人类完成多种任务. 比如机器翻译, 文本摘要, 问答系统, 等等. 这里面模型需要能够就任何主题进行对话的开放域多轮对话可能是最困难的一种, 具有广泛的潜在应用和开放挑战. 除了产生人类认为合理, 有趣, 特定于上下文的相应外, 对话模型还应遵守负责任的AI准则, 并避免做出外部信息源不支持的事实陈述.


  • 对于LaMDA模型, 最关键的三个目标是:
    • 质量(quality)
    • 安全性(safety)
    • 扎实性(groundedness)


  • 质量(quality): 将质量分解为三个维度, 即敏感性, 特异性和趣味性, 由人类评估者进行评估. 敏感性是指模型是否产生在对话上下文中有意义的响应(例如, 没有常识错误, 没有荒谬的响应, 以及与先前的响应没有矛盾). 特异性是通过判断系统的响应是否特定于前面的对话上下文来衡量的, 而不是适用于大多数上下文的通用响应(例如, "好的"或"我不知道"). 最后, 兴趣度衡量模型是否产生了富有洞察力, 出乎意料或机智的回应, 因此更有可能创造更好的对话.

  • 安全性(safety): 在解决与负责任人工智能的开发和部署相关的重要问题方面取得进展. 安全指标由一组说明性的安全目标组成, 这些目标捕捉模型应在对话中展示的行为. 这些目标试图约束模型的输出, 以避免任何对用户造成伤害风险的意外结果, 并避免加剧不公平的偏见. 例如, 这些目标训练模型避免产生包含暴力或血腥内容, 宣扬对人群的诽谤或仇恨刻板印象或包含亵渎的输出.

  • 扎实性(groundedness): 当前这一代语言模型经常产生看似合理但实际上与事实相矛盾的陈述建立在已知的外部来源中. 这激发了作者对LaMDA扎实性的研究. 扎实性被定义为可以得到权威外部来源支持的关于外部世界声明的回复的百分比, 作为所有包含关于外部世界的声明的回复的份额. 一个相关的指标, 信息量, 被定义为具有已知来源可以支持的外部世界信息的响应的百分比, 作为所有响应的份额. 因此, 不携带任何真实世界信息的随意回应(例如, "这是一个好主意")会影响信息性, 但不会影响扎实性. 虽然在已知来源中建立LaMDA生成的响应本身并不能保证事实的准确性.


  • LaMDA模型也遵循了预训练 + 微调的两阶段处理模式, 预训练阶段的基本方法也按照经典语言模型的方式处理:


  • LaMDA模型微调: 训练LaMDA执行混合生成生成对给定上下文的自然语言响应的任务, 以及关于响应是否安全和高质量的分类任务, 从而产生一个可以同时完成这两种任务的单一多任务模型. LaMDA生成器被训练来预测对话数据集上的下一个标记, 限制为两个作者之间的来回对话, 而LaMDA分类器被训练来预测使用注释数据在上下文中响应的安全和质量评级. 在对话期间, LaMDA生成器首先在给定当前多轮对话上下文的情况下生成几个候选响应, 然后LaMDA分类器预测每个响应候选的质量评级和安全分数. 首先过滤掉安全分数低的候选响应, 剩余的候选人根据他们的质量评级分数重新排名, 并选择最高的结果作为响应.

  • 虽然人们能够通过使用工具和参考已建立的知识库来检查他们的事实, 但许多语言模型仅利用其内部模型参数来获取他们的知识. 为了提高LaMDA原始响应的基础性, 作者收集了人和LaMDA之间的对话数据集, 这些数据集在适用的情况下用信息检索查询和检索结果进行了注释. 然后, 在该数据集上微调LaMDA的生成器和分类器, 以学习在与真实人类交互期间调用外部信息检索系统, 以提高其响应的扎实性.


  • 下图展示了一个完整的多轮对话过程, LaMDA模型在其中参与了语义理解, 信息搜索, 语句生成等多项任务:


  • LaMDA模型在音乐领域的表现就像专家一样:


  • LaMDA模型在模仿自己作为Mount Everest时的表现, 几乎可以以假乱真:


  • 结论: LaMDA模型的出现为完成开放域对话开辟了新的途径, 同时表明了神经语言模型面临的关键挑战, 如安全指标的使用和扎实性的提高, 以及如何通过更大的模型和更清晰标记的数据来进行微调. 但是这还是一项非常早期的工作, 且具有很大的局限性. 未来, 谷歌将探索新的方法来进一步改进安全指标和LaMDA模型的扎实性, 并与其人工智能原则保持一致.


智源人工智能研究院

悟道2.0

  • 2021年6月第三届北京智源大会正式开幕, 智源副院长, 清华唐杰教授重磅发布了超级模型"悟道2.0", 拥有1.75万亿个参数, 是迄今全球最大的预训练模型.

  • 大家还记得2021年夏天网上的那个叫"华智冰"的女同学吧? 她可以创作音乐, 写诗作画, 而且已经被清华大学唐杰教授录取为学生! 未来她将在清华大学里成长学习, 变成一个真正的"智能人", 而这里面最关键的就是她的内核: 悟道2.0!

  • 悟道2.0超级模型在参数规模上爆发级增长, 达到1.75万亿参数, 创下全球最大预训练模型纪录!!!

  • 研究团队希望让"悟道2.0"像人一样思考, 在多项任务中超越图灵测试, 最终迈向通用工智能.

  • 悟道2.0从原来的文本为主逐渐往更强大, 更通用的方向上发力, 并可以根据文字生成高精度的图片, 根据图像去检索文字, 实现图像和文字的互相检索.

  • 目前, 悟道2.0在问答、作诗、配文案、视频、绘画、菜谱多项任务中正逼近图灵测试.



粤港澳大湾区数字经济研究院(IDEA)

封神榜

  • 2021年11月22号, IDEA创新研究院理事长沈向洋在IDEA大会上, 宣布开启"封神榜"大模型开源计划:
    • 二郎神系列
    • 余元系列
    • 周文王系列
    • 闻仲系列
    • 燃灯系列

  • 二郎神: Encoder结构为主的双向语言模型, 专注于解决各种自然语言理解任务, 13亿参数的"二郎神-1.3B"大模型, 是最大的开源中文BERT大模型.

  • 余元: 已开源医疗领域的35亿参数"余元-3.5B"大模型, 其对医疗事实判断准确率接近90%.

  • 周文王: IDEA联合追一科技开发的新结构大模型, 目前开源的13亿参数的"周文王-1.3B"大模型, 是中文领域同时做LM和MLM任务最大的模型.

  • 闻仲: Decoder结构为主的单向语言模型, 是一系列强大的生成模型, 目前开源了35亿参数的"闻仲-3.5B"大模型.

  • 燃灯: Transformer结构为主的编解码语言模型, 目前开源了7.7亿参数的"燃灯"大模型.