【问题标题】:Tokenizers change vocabulary entry分词器改变词条
【发布时间】:2021-12-15 05:36:45
【问题描述】:

我有一些文本,我想对其执行 NLP。为此,我下载了一个预训练的标记器,如下所示:

import transformers as ts

pr_tokenizer = ts.AutoTokenizer.from_pretrained('distilbert-base-uncased', cache_dir='tmp')

然后我用我的数据创建自己的标记器,如下所示:

from tokenizers import Tokenizer
from tokenizers.models import BPE
tokenizer = Tokenizer(BPE(unk_token="[UNK]"))

from tokenizers.trainers import BpeTrainer
trainer = BpeTrainer(special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"])

from tokenizers.pre_tokenizers import Whitespace
tokenizer.pre_tokenizer = Whitespace()

tokenizer.train(['transcripts.raw'], trainer)

现在是我感到困惑的部分...我需要更新预转录标记器 (pr_tokenizer) 中的条目,它们的键与我的标记器 (tokenizer) 中的相同。我已经尝试了几种方法,所以这里是其中一种:

new_vocab = pr_tokenizer.vocab
v = tokenizer.get_vocab()

for i in v:
    if i in new_vocab:
        new_vocab[i] = v[i]

那我现在该怎么办?我在想这样的事情:

pr_tokenizer.vocab.update(new_vocab)

pr_tokenizer.vocab = new_vocab

都不行。有谁知道这样做的好方法吗?

【问题讨论】:

    标签: python python-3.x nlp huggingface-transformers huggingface-tokenizers


    【解决方案1】:

    为此,您只需从 GitHub 或 HuggingFace website 将标记器源下载到与您的代码相同的文件夹中,然后在加载标记器之前编辑词汇表:

    new_vocab = {}
    
    # Getting the vocabulary entries
    for i, row in enumerate(open('./distilbert-base-uncased/vocab.txt', 'r')): 
        new_vocab[row[:-1]] = i
    
    # your vocabulary entries
    v = tokenizer.get_vocab()
    
    # replace common (your code)
    for i in v:
        if i in new_vocab:
            new_vocab[i] = v[i]
    
    with open('./distilbert-base-uncased/vocabb.txt', 'w') as f:
        # reversed vocabulary
        rev_vocab = {j:i for i,j in zip(new_vocab.keys(), new_vocab.values())}
        # adding vocabulary entries to file
        for i in range(len(rev_vocab)):
            if i not in rev_vocab: continue
            f.write(rev_vocab[i] + '\n')
    
    # loading the new tokenizer
    pr_tokenizer = ts.AutoTokenizer.from_pretrained('./distilbert-base-uncased')
    

    【讨论】:

    • 你们知道吗,我不明白你们两个为什么需要这样做,你们不会使用预训练模型吗?为什么 AutoTokenizer.from_pretrained('./distilbert-base-uncased') 还不够?
    • @bitbang 我想“微调”标记器,这似乎是我在互联网上找到的唯一 wat。
    • 我相信token只是NLP模型使用的整数,并通过他们的理解将它们转换为向量
    • @user9102437 仅供参考,您也可以训练一个新的分词器,而不是编辑现有的分词器
    • @SilentCloud 当然可以,但它可能不如使用强大的机器对大数据进行训练的那个(如果数据相似的话)。
    【解决方案2】:

    如果你能在你的电脑中找到 distilbert 文件夹,你可以看到词汇表基本上是只包含一列的 txt 文件。你可以做任何你想做的事。

    # i download the model with pasting this line to python terminal (or your main cli)
    # git clone https://huggingface.co/distilbert-base-uncased
    
    import os
    path= "C:/Users/...../distilbert-base-uncased"
    print(os.listdir(path))
    
    # ['.git',
    # '.gitattributes',
    # 'config.json',
    # 'flax_model.msgpack',
    # 'pytorch_model.bin',
    # 'README.md', 'rust_model.ot',
    # 'tf_model.h5',
    # 'tokenizer.json',
    # 'tokenizer_config.json',
    # 'vocab.txt']
    

    【讨论】:

    • 是的,你可以在这个文件中添加单词,但是如果我们想从这个分词器中删除一些词?这可以做到吗?模型还能正常运行吗?
    • 模型将单词理解为您所知道的标记,205(token) = some word。如果您将第 205 个标记更改为其他单词,则需要使用新词汇和新标记重新训练您的模型
    猜你喜欢
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    • 2021-10-25
    • 2020-06-11
    • 2019-01-10
    相关资源
    最近更新 更多