IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> huggingface.transformers术语表 -> 正文阅读

[人工智能]huggingface.transformers术语表

诸神缄默不语-个人CSDN博文目录

本文属于huggingface.transformers全部文档学习笔记博文的一部分。
全文链接:huggingface transformers包 文档学习笔记(持续更新ing…)

本部分网址:https://huggingface.co/docs/transformers/master/en/glossary
本部分介绍transformers包相关的术语,包括transformers模型通用的术语,和用于PreTrainedModel输入参数的术语。

1. 通用术语

原文档是用首字母顺序排序的,本文则按照我认为比较合适的顺序来排序。

  1. deep learning:用很多层神经网络的机器学习算法。
  2. RNN / recurrent neural network:一种用a loop over a layer1来处理文本的模型。
  3. self-attention:输入的每一个元素找它们应该attend to2的输入其他元素。
  4. token:一句话的一部分,如一个word,或一个subword(不常见的words常被拆分为subwords)
  5. transformer:基于self-attention的deep learning模型架构。
  6. seq2seq / sequence-to-sequence:通过输入生成一个新序列的任务(如翻译模型或摘要模型,如BartT5)。
  7. multimodal:结合文本与其他形式的输入(如图像等)的任务。
  8. NLP / natural language processing:处理文本相关任务的泛称。
  9. NLG / natural language generation:生成文本的任务(如talk with transformers3和文本翻译)
  10. NLU / natural language understanding:理解文本内容的任务(如对整片文章、个别词语的分类)
  11. pretrained model:在一些数据(如全部Wikipedia数据)上进行预训练后得到的模型。预训练模型包含一些self-supervised objective,如下面的MLM和CLM。
  12. MLM / masked language modeling / autoencoding models:一种预训练任务,模型看到的是corrupted文本。实现方式一般是随机mask一些tokens,然后预测原文。
  13. CLM / causal language modeling / autoregressive models:一种预训练任务,模型按顺序阅读文本,预测下一个单词。实现方式一般是阅读整句话,但用mask隐藏当前timestamp的未来tokens。

2. PreTrainedModel输入参数

每个模型都有所不同,但也有其相通之处。因此绝大多数模型的输入参数是相同的,以下就举例列举:

2.1 Input IDs

Input IDs一般情况下是唯一需要输入模型的参数。
是token的索引,token的数值表示,构建输入模型的sequence。
每种tokenizer的工作方式不同,但其根本工作机制是一样的。以BertTokenizer(一种WordPiece4 tokenizer)为例:

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("mypath/bert-base-cased")
sequence = "A Titan RTX has 24GB of VRAM"

Tokenizer致力于将sequence分解成词表中含有的tokens(words或subwords,非word开头的token前会加上##符号):

tokenized_sequence = tokenizer.tokenize(sequence)
print(tokenized_sequence)

输出:['A', 'Titan', 'R', '##T', '##X', 'has', '24', '##GB', 'of', 'V', '##RA', '##M']

这些tokens可以被转换为模型可读的索引(IDs):

inputs = tokenizer(sequence)

tokenizer返回一个字典,包含所有使对应模型可以运行的必要参数。token索引就在键input_ids下:

encoded_sequence = inputs["input_ids"]
print(encoded_sequence)

输出:[101, 138, 18696, 155, 1942, 3190, 1144, 1572, 13745, 1104, 159, 9664, 2107, 102]

注意tokenizer会自动添加模型需要的special tokens(如BertTokenizer对应的就是BertModel所需的special tokens),解码input ids后可以看出加了什么:

decoded_sequence = tokenizer.decode(encoded_sequence)
print(decoded_sequence)

输出:[CLS] A Titan RTX has 24GB of VRAM [SEP]

2.2 Attention mask

这一参数表明哪些tokens应该被模型attend to,哪些不应该。2

以如下两句一长一短的sequence为例:

sequence_a = "This is a short sequence."
sequence_b = "This is a rather long sequence. It is at least longer than the sequence A."

encoded_sequence_a = tokenizer(sequence_a)["input_ids"]
encoded_sequence_b = tokenizer(sequence_b)["input_ids"]

两个sequence编码得到的数值序列长度不同:

len(encoded_sequence_a), len(encoded_sequence_b)

输出为:(8, 19)

因此,我们无法直接就这样把它们合并为一个tensor,要么把短句pad up到长句长度,要么把长句truncate down到短句长度。

一般来说,这种情况下我们会pad短句,因为truncate会出现信息损失。我们一般只在长句超过最长限长的时候才选择truncate操作。

pad up的情况:

padded_sequences = tokenizer([sequence_a, sequence_b], padding=True)
print(padded_sequences["input_ids"])

输出:[[101, 1188, 1110, 170, 1603, 4954, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 1188, 1110, 170, 1897, 1263, 4954, 119, 1135, 1110, 1120, 1655, 2039, 1190, 1103, 4954, 138, 119, 102]]

可以看到短句的token后面被加了0,以使其与长句的sequence等长,这样就可以直接转换为tensor。
attention mask是一个二元tensor,标明用于pad的索引,模型就不会attend to2它们。这和模型预训练时的操作一致。对BertTokenizer,1表明其对应的值需要被attend to,0表明其对应的值是padded value。attention mask就在tokenizer返回值的键attention mask下:

padded_sequences["attention_mask"]

输出:
[[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]

2.3 Token Type IDs

又名segment IDs。

有些模型的目标是对句子对做分类或QA(question answering),如识别quora上两个问题是否相同,或做natural language inference (NLI) 任务。
这就需要两个sequences在同一input_id tensor中传入模型,这一操作一般用special tokens实现,如classifier ([CLS])或separator ([SEP]) tokens。
举例来说,BertTokenizer就这样构建2个sequences的输入:# [CLS] SEQUENCE_A [SEP] SEQUENCE_B [SEP]

通过将sequences作为2个入参(而非像之前所做的那样,以list形式组合sequences为1个入参),即可自动生成这样的数据:

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("mypath/bert-base-cased")
sequence_a = "HuggingFace is based in NYC"
sequence_b = "Where is HuggingFace based?"

encoded_dict = tokenizer(sequence_a, sequence_b)
decoded = tokenizer.decode(encoded_dict["input_ids"])
decoded

输出:'[CLS] HuggingFace is based in NYC [SEP] Where is HuggingFace based? [SEP]'

有一些模型以这样的数据输入形式就已经可知sequences的开始和结束位置,但对Bert等其他模型来说,还需应用token type IDs,一种区分2个sequences的二元mask。

encoded_dict["token_type_ids"]

输出:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
在QA任务中,第一句就是context(值为0),为第二句就是question(值为1)。

文档中这句话我有点没搞懂啥意思:在这里插入图片描述
我没试过XLNetModel,我也懒得现在就去下文件研究,我觉得意思应该是其他模型可能会使用不同的special tokens。

比如之前在huggingface.transformers速成笔记中使用的sshleifer/distilbart-cnn-12-6模型,就是用<s></s>来作为special tokens的:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("mypath/distilbart-cnn-12-6")
encoding = tokenizer("We are very happy to show you the 🤗 Transformers library.",
                    "We hope you don't hate it.")
print(encoding)
print()
print(tokenizer.decode(encoding['input_ids']))

输出:
{'input_ids': [0, 170, 32, 182, 1372, 7, 311, 47, 5, 8103, 10470, 6800, 34379, 5560, 4, 2, 2, 170, 1034, 47, 218, 75, 4157, 24, 4, 2], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

<s>We are very happy to show you the 🤗 Transformers library.</s></s>We hope you don't hate it.</s>

2.4 Position IDs

RNNs的token位置是自带的,但是transformers本身是无法知道token位置的(这个是transformers模型特点,看过这个模型的应该都能直接理解,这事实上也是模型的核心部分。我以后可能会写相应的模型详解博文),因此模型就需要用position IDs (position_ids)来识别每个token在sequence中的位置。
这是个可选的入参。如果不传入该参数,IDs将自动以absolute positional embeddings形式创建。
absolute positional embeddings在[0, config.max_position_embeddings - 1]中选择。有些模型使用其他形式的positional embeddings,如sinusoidal position embeddings或relative position embeddings。

2.5 Labels

这是个可选的入参。如果传入,模型将自行计算loss。这些labels是模型的期望预测值,模型会使用标准loss来计算真实预测值和期望值(labels)之间的loss。

labels因模型heads而有所不同,举例来说:

  • 对sequence classification模型(如BertForSequenceClassification),labels应该是维度为(batch_size)的、每个值是对应sequence的标签。
  • 对token classification模型(如BertForTokenClassification),labels应该是维度为(batch_size, seq_length)的、每个值是对应token的标签。
  • 对masked language modeling模型(如BertForMaskedLM),labels应该是维度为(batch_size, seq_length)的、每个值是对应token的标签(masked token的token ID,unmasked token的忽略(通常直接用-100))
  • 对seq2seq模型(如BartForConditionalGenerationMBartForConditionalGeneration),labels应该是维度为(batch_size, tgt_seq_length)的、每个值是每个input sequence对应的target sequences。在训练的过程中,BART和T5模型都会自动生成合适的decoder_input_ids(见本文2.6部分介绍)和decoder attention masks,一般不需要手动提供。这跟Encoder-Decoder架构的模型不同,需要看特定模型的文档以了解所需labels的更多信息。

基础模型(如BertModel)不接受labels参数,因为它们是基础transformers模型,只输出特征。

2.6 Decoder input IDs

这个输入仅用于encoder-decoder模型(seq2seq任务,如翻译或摘要),包含了喂进decoder的input IDs,每个模型的构建形式都有所不同。
绝大多数encoder-decoder模型(如BART和T5)都会从labels入参中直接自动构建decoder_input_ids入参,因此建议在训练过程中传递labels入参。

2.7 Feed Forward Chunking

在transformers的每个residual attention block中,self-attention层后一般跟着两个前馈 (feed forward) 层。前馈层的intermediate embedding size一般会比模型的hidden size更大(其实我没太看懂这是啥意思,以后学好transformers模型再回来重新理解),如bert-base-uncased模型。
对于一个维度为[batch_size, sequence_length]的输入张量,用于储存intermediate feed forward embeddings(维度为[batch_size, sequence_length, config.intermediate_size])可能会占用大量内存。Reformer: The Efficient Transformer作者发现,计算过程与sequence_length这一维度无关,计算2个完整的前馈层,与计算把2个前馈层分别拆成[batch_size, config.hidden_size]_0, ..., [batch_size, config.hidden_size]_n(其中n = sequence_length),并分别计算其output embeddings,再将其concat为[batch_size, sequence_length, config.hidden_size]。这一计算方式增加了用时,减少了空间占用,在数学上结果是相同的。
对于应用了apply_chunking_to_forward()函数的模型,chunk_size入参定义了同时计算的output embeddings的数目,定义时间复杂度和空间复杂度之间的trade-off。如chunk_size置0,就不做feed forward chunking操作。
这部分内容我没看懂,原论文我还没看,等我经继续学习后再回来做分析吧


  1. 总之这个应该指的是这张著名图,大概就是,是一层神经网络,但是有个回环(输回前一个timestamp的hidden state):
    在这里插入图片描述
    (图源:一文搞懂RNN(循环神经网络)基础篇 - 知乎??

  2. 时至今日我依然没有届到到底什么才是attend to。
    等我以后了解了再来写。 ?? ?? ??

  3. 这是个什么任务,我谷歌都谷歌不到,我怀疑是写错了。 ??

  4. 原文档中此处给出的参考资料是:Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation
    这篇还没看,以后再看。
    如下内容全部参考这篇科普文章,包括图片:WordPiece: Subword-based tokenization algorithm | Chetna | Towards Data Science
    大致来说,Wordpiece是一种subword-based tokenization algorithm(相对的是word级别和character级别)。
    word-based tokenization的问题是词表太长,有大量OOV token,词语异义问题。character-based tokenization的问题是sequence太长,单独token无意义。subword-based tokenization会split不常用的单词,常用的算法有WordPiece, Byte-Pair Encoding (BPE)5, Unigram 和 SentencePiece。
    WordPiece用于BERT, DistilBERT, Electra等语言模型中,有两种应用:bottom-up and top-bottom。原始的bottom-up方法是基于BPE的。BERT用的是top-bottom方法。本文将介绍bottom-up方法(即从characters聚合成pairs)。
    WordPiece方法最早提出于Japanese and Korean Voice Search (Schuster et al., 2012)

    BPE方法的介绍见5,以下对WordPiece的介绍在假设读者已经看过BPE部分介绍的基础上进行:
    BPE方法的问题在于它可能有多种对同一单词的编码方式。
    举例来说,这是一个subword tokens表,假设这就是一个小语料的词表:在这里插入图片描述
    假设我们要tokenize短语linear algebra,我们有多种tokenize方式:
    linear = li + near or li + n + ea + r
    algebra = al + ge + bra or al + g + e + bra
    有一种解决方法是,不像BPE只用频率,同时也考虑每一步特定byte-pair合并带来的影响。WordPiece和BPE的区别就在于每一步选择往词表中增加哪个byte-pair,WordPiece在每次迭代时会选择合并的likelihood增加最大的byte-pair。增加训练集的likelihood等同于找这样一个byte-pair,它的概率除以它的第一个token后面就是它的第二个token的概率
    (这一段我其实没太看懂。我一开始以为是条件概率,后来看了资料,感觉意思应该是 P ( A B ) P ( A ) P ( B ) \frac{P(AB)}{P(A)P(B)} P(A)P(B)P(AB)?。具体为什么要这么做,直觉上可以说是衡量合并tokens的价值,在理论上可以看这篇资料有他从信息论角度出发做的解释:6
    ,所得的值比其他byte-pair都大。举例来说,如果 es 的概率比 e 的概率乘 s 的概率,要比其他byte-pair的大,那么我们就将 es 加入词表。

    WordPiece的算法是迭代的(与BPE的类似,主要在第三步不同):
    ① 初始化word unit inventory(以characters为单位)
    ② 从①的word inventory中建立语言模型。
    ③ 从当前word inventory中合并2个unit为一个新unit,加入word inventory。这个新的word unit要是所有可能的word units中在增加到语言模型中后训练集的likelihood增加最多的。
    ④ 返回②,直至达到提前确定的word units总数限制或likelihood增加小于特定阈值。

    WordPiece算法的计算代价较大(时间复杂度为 O ( K 2 ) O(K^2) O(K2),其中 K K K是当前word units数),每一次迭代都需要测试所有可能的byte-pair并建立语言模型。有一些加速tricks,如仅测试训练集中真实存在的byte-pair,仅测试有显著可能性是最好byte-pair的 (the ones with high priors) 那些byte-pairs(没说具体怎么做,我也还没查,不知道),每次迭代合并几个clustering steps(对一组不互相影响的pairs是有可能的)(没说具体怎么做,我也还没查,不知道)。
    WordPiece也是贪心算法。

    其他参考资料:WordPiece Tokenization - YouTube
    本视频提及,WordPiece源代码未公开,因此只涉及在文献中讲述的内容。
    视频中所写byte-pair的计算公式:
    在这里插入图片描述
    在视频中还画了WordPiece解码过程,直接从前到后遍历sequence,选择最长的可匹配的词表中的token即可。 ?? ??

  5. 我阅读的科普博文是:Byte-Pair Encoding: Subword-based tokenization | Towards Data Science 以下图片也出自该文。
    大致来说,BPE是一种subword-based tokenization algorithm。
    BPE用于GPT-2, RoBERTa, XLM, FlauBERT等语言模型。其中有些模型用space tokenization(应该是字面意思,就是英语用空格作为简单的分词方式)作为pre-tokenization method,有些用Moses, spaCY, ftfy提供的更先进的方法。
    BPE是一种简单的数据压缩算法,将数据中最常用的byte pair(连续的两个字节)替换成数据中未出现的一个byte(注意下文一个byte指一个token)。最早提出于A New Algorithm for Data Compression。此博文转引BPE维百的示例:原数据aaabdaaabac,用Z替换aa,就得到了ZabdZabac;再用Y替换ab,就得到了ZYdZYac;再用X替换ZY,就得到了XdXac;自此就不能再继续压缩了。
    NLP中用的BPE算法保证常用词在词典中是一个token,非常用词则被分割为2至多个subword tokens,这是符合subword-based tokenization思想4的。

    以示例的形式讲解算法运行过程:
    ①假设我们有一个经过space tokenization后得到的语料单词和频率对应表:{“old”: 7, “older”: 3, “finest”: 9, “lowest”: 4}

    ②在每个单词后加上一个特殊token </w>(用于识别word边界。文中阐释了一些这个token如何重要的理由,我觉得这个比较明显,此处就略去),得到:{“old</w>”: 7, “older</w>”: 3, “finest</w>”: 9, “lowest</w>”: 4}

    ③接下来将所有词拆成characters和</w>token,计算其频率:
    在这里插入图片描述

    ④据此计算出现频率最高的byte pair,将其合并。如此循环迭代,直到抵达token limit或iteration limit。
    合并能帮助你用最少的token数来代表整个语料,达成压缩功效。
    具体步骤:
    ?Ⅰ 最常见的byte pair是es(出现了13次),将其合并为一个新token,更新表为:在这里插入图片描述
    ?Ⅱ 此时最常见的byte pair是est(出现了13次):在这里插入图片描述
    ?Ⅲ 此时最常见的byte pair是est</w>(出现了13次):在这里插入图片描述
    ?Ⅳ 此时最常见的byte pair是ol(出现了10次):在这里插入图片描述
    ?Ⅴ 此时最常见的byte pair是old(出现了10次):在这里插入图片描述
    ?Ⅵ 此时最常见的byte pair是fin(出现了9次),但只有一个单词有这些characters,所以不合并。去掉频率为0的token,最后得到:在这里插入图片描述
    总共有11个token,少于最初的12个token。
    在实践中,随着合并、增加token的过程,总的token数会先增后减。停止标准可以是token数或迭代次数。

    ⑤完成合并迭代后,进行编码和解码工作。
    解码只需合并token为整个的单词即可,如序列 [“the</w>”, “high”, “est</w>”, “range</w>”, “in</w>”, “Seattle</w>”],可以解码为 [“the”, “highest”, “range”, “in”, “Seattle”](注意 </w> token)。
    编码过程则在计算上代价较高。如单词序列为 [“the</w>”, “highest</w>”, “range</w>”, “in</w>”, “Seattle</w>”],我们需要迭代词表中从最长到最短的token来替代单词序列中的substrings。如果最后会剩下一些词表中没有的substrings(训练过程中没有出现过),用unknown tokens代替。

    BPE是贪心算法,是应用最广泛的subword-tokenization algorithms之一。 ?? ??

  6. 理解tokenizer之WordPiece: Subword-based tokenization algorithm - 知乎
    原文中讲解相关原理的部分:在这里插入图片描述 ??

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:30:27  更:2022-03-12 17:32:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:58:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码