June 10, 2020

自然语言处理的两件神兵之(1): nlp library

自然语言处理的两件神兵之(1): nlp library
  • nlp 和 tokenizers 简介
nlp 和 tokenizers 是 Huggingface 出品的另外两个自然语言处理方面非常方便、有用的库
  • 缘起
Huggingface 最初是抓住了 BERT 横空出世的机会,Pytorch 是 Facebook 推出的深度学习框架, 所以腹黑的推断一下在 Pytorch 下 Facebook 理论上推出官方对 BERT 的支持的时效性可能比较差, 而社区中对 Pytorch 版本的 BERT 又非常之需要,所以 Huggingface 出马,率先实现了 BERT/Transformer with Pytorch 版本,之后又再接再厉,在此基础上继续紧跟 BERT 家族在 NLP 领域的 优势。

Huggingface 最初是抓住了 BERT 横空出世的机会,Pytorch 是 Facebook 推出的深度学习框架, 所以腹黑的推断一下在 Pytorch 下 Facebook 理论上推出官方对 BERT 的支持的时效性可能比较差, 而社区中对 Pytorch 版本的 BERT 又非常之需要,所以 Huggingface 出马,率先实现了 BERT/Transformer with Pytorch 版本,之后又再接再厉,在此基础上继续紧跟 BERT 家族在 NLP 领域的 优势。

随着基于 Transformer 架构的 BERT-like 模型井喷,Huggingface 也干脆把自己的 BERT 封装库 重新命名为 Transformers,并在模型输入输出标准化和社区假设上下大功夫,到目前为止, Huggingface 的 Transformers 已经囊括了 100+ 模型,学术和工业界最新的思路都会被以最快的方式添加进来。

而且 Transformers 打通了 Tensorflow 和 Pytorch 两大主流深度学习框架,实现了两大主流框架模型 的相互转换和融合访问。Huggingface 的 Transformers 俨然已经成为 NLP 领域不可或缺的生产力工具。

Transformers 已经获得了足够的关注并被广泛应用于 NLP 领域的科研和工业级应用上,但实际上 Huggingface 在 2020 年上半年疫情左右的这段时间内还推出了分别应用于 NLP 预料管理的 nlp 和应用于预料预处理、分词的 tokenizers 两个库,其中前者 nlp 库主要提供了 nlp 语料管理nlp 测评标准 两个重要的功能。

了解 nlp 的同学都清楚,在实际的工作中如何定义一个实际的场景、如何把该场景抽象出来定义好问题的衡量标准, 以及如何整理、清洗数据,获取有效的特征集,是比单纯的设计模型更耗时且更加关乎最终的上线结果的事情。可惜的是目前我们获得的媒体讯息上大部分都单纯的拿最新的论文,断章取义的在某个特定的认为指标上强调一个 并不健壮的指标,给大众一个 AGI 都要快实现的错觉...

除开吐槽抱怨不谈, Huggingface 的 nlp 库截至目前提供了 160+ 个经典的语料可供下载调用研究,包括巨大的用于 T5 的 C4,可以预见的,很快也会加入 GPT3 的语料。

Tokenizers 是 Huggingface 社区天才们工作的另一个结晶,我们都知道在使用一个 nlp 的模型时,首先就需要 获得该模型对应的词表(vocabulary),由此才能进一步将我们需要处理的句子转化成 tokens,这个步骤是如此的 必须且频繁,以至于我们在工业级线上应用的时候为了执行效率优化而不得不仔细的考虑 tokenizing 这个过程所 消耗的时间和资源。

Huggingface tokenizers 库基于 transformers 收集、训练的模型,借鉴了早期类似 Bert-as-service 等库的架构,最重要的是用 Rust 写就,这几点保证了 tokenizers 库在拥有足够的灵活性和兼容性的同时,性能上 做到了最优,跟直接的 Python 实现比肯定是秒杀;跟类似的 Cython、C++/Pybind11 方案比性能也不遑多让, 而且 Rust 是目前系统级编程的新贵,在吸引普遍以喜新厌旧为荣的优秀开发者方面有着得天独厚的优势。

接下来分别看下两个库是如何玩转的

首先,在安装 nlp 包的同时会安装 pyarrow(Apache pyarrow 是一个语言无关框架无关的内存内计算框架,language-agnostic/framework-agnostic/In-Mem Computing),这里我们只需要了解 nlp 选用的这个 Apache Arrow 比 TF Record 效率更好一些就可以了。

接下来我们一步步探索一下 nlp 包究竟可以帮我们做些什么:

  • 查看下截至目前(2020-06-10)内置了哪些数据集和指标,可以看到 nlp 包已经内置好了 116 个数据集信息和 11 种 nlp 指标:
import nlp

datasets = nlp.list_datasets()
metrics = nlp.list_metrics()

print(f"🤩 Currently {len(datasets)} datasets are available on HuggingFace AWS bucket: \n" 
      + '\n'.join(str(index)+":"+dataset.id for index,dataset in enumerate(datasets)) + '\n')
print(f"🤩 Currently {len(metrics)} metrics are available on HuggingFace AWS bucket: \n" 
      + '\n'.join(metric.id for metric in metrics))

输出结果如下:

🤩 Currently 116 datasets are available on HuggingFace AWS bucket: 
0:aeslc
1:ai2_arc
2:anli
3:arcd
4:art
5:billsum
6:blended_skill_talk
7:blimp
8:blog_authorship_corpus
9:boolq
10:break_data
11:c4
12:cfq
13:civil_comments
14:cmrc2018
15:cnn_dailymail
16:coarse_discourse
17:com_qa
18:commonsense_qa
19:coqa
20:cornell_movie_dialog
21:cos_e
22:cosmos_qa
23:crime_and_punish
24:csv
25:definite_pronoun_resolution
26:discofuse
27:drop
28:empathetic_dialogues
29:eraser_multi_rc
30:esnli
31:event2Mind
32:flores
33:fquad
34:gap
35:germeval_14
36:gigaword
37:glue
38:hansards
39:hellaswag
40:imdb
41:jeopardy
42:json
43:kor_nli
44:lc_quad
45:lhoestq/c4
46:librispeech_lm
47:lm1b
48:math_dataset
49:math_qa
50:mlqa
51:movie_rationales
52:multi_news
53:multi_nli
54:multi_nli_mismatch
55:natural_questions
56:newsroom
57:openbookqa
58:opinosis
59:para_crawl
60:qa4mre
61:qangaroo
62:qanta
63:qasc
64:quarel
65:quartz
66:quoref
67:race
68:reclor
69:reddit
70:reddit_tifu
71:scan
72:scicite
73:scientific_papers
74:scifact
75:sciq
76:scitail
77:sentiment140
78:snli
79:social_i_qa
80:squad
81:squad_es
82:squad_it
83:squad_v1_pt
84:squad_v2
85:super_glue
86:ted_hrlr
87:ted_multi
88:tiny_shakespeare
89:trivia_qa
90:tydiqa
91:ubuntu_dialogs_corpus
92:webis/tl_dr
93:wiki40b
94:wiki_qa
95:wiki_split
96:wikihow
97:wikipedia
98:wikitext
99:winogrande
100:wiqa
101:wmt14
102:wmt15
103:wmt16
104:wmt17
105:wmt18
106:wmt19
107:wmt_t2t
108:wnut_17
109:x_stance
110:xcopa
111:xnli
112:xquad
113:xsum
114:xtreme
115:yelp_polarity

🤩 Currently 11 metrics are available on HuggingFace AWS bucket: 
bertscore
bleu
coval
gleu
glue
rouge
sacrebleu
seqeval
squad
squad_v2
xnli
  • 我们拿 squad_v2 数据集做例子看下里面有什么:
from dataclasses import asdict

for key, value in asdict(datasets[84]).items():
    print('👉 ' + key + ': ' + str(value))

输出如下:

这里我们可以清楚的看到 squad v2 数据集的描述、大小、结构、引用等 meta 信息,nlp 库 帮我们把这 116 个 dataset,包括 C4 都整理好了,使用的时候只要准备好你的外网链接就可以随时开始你的 nlp 冒险之旅了。

  • 接下来我们真正把squad2 数据集下载下来,并划分 10% 的数据作为验证集:
dataset = nlp.load_dataset('squad_v2', split='validation[:10%]')

这个数据集不大,一共大约 45m 左右,解压后大约 ~120m,所以直接通过国内运营商的网络访问也还可以等,但稍微大一点的或者很大的数据集的话,基本下载这一步就歇菜,这也是为什么我们一直强调最好把实验环境放在可以更方便访问 AWS/GCP 服务的地方对工作效率至关重要,接下来我们会专门针对这个点做说明。

另外,nlp 会把下载好的语料数据缓存在本地,~/.cache 下。

如上面所说,nlp 是基于 Apach Arrow 做内存运算的,所以我们上面载入的 squad v2  版 dataset 实际上就是 Arrow 的一张或者几张表,这就意味着我们可以充分的利用 Apache Arrow 的设计优势加速我们的实验,比如理论上我们不需要考虑 RAM 多大的问题,因为直到上面这一步,我们的 dataset 其实并没有真正 load 到 RAM 来,可以理解成是一个 iterator 。

其他可以在 dataset 上执行的,类似 spark 的 map 操作(当然,huggingface 的人说是灵感来自 tf.data 的 map 函数)

底下的细节部分大体就这样,接下来就是常规的提取特征、扔到一个模型中 fine-tune,过程大同小异不再赘述了。

下一次我们探索下 tokenizers 。

以上实验详细内容可以参考 这个colab