我的目的是要手动添加“<|endoftext|>”这个GPT-2规定的终止符。本来用下面这个命令就能加进去:
tokenizer.add_special_tokens({"eos_token": "<|endoftext|>"})
但是,我发现加进去以后
tokenizer.eos_token: "<|endoftext|>"
tokenizer.eos_token_id: None
就是,我加进去这个符号了,但是tokenizer类里面并没有给它分配id,导致在后面的token_to_id的时候报错。
dedededebug了半天,最后我找到:
if (
token != self.unk_token
and self.convert_tokens_to_ids(token) == self.convert_tokens_to_ids(self.unk_token)
and token not in tokens_to_add
):
tokens_to_add.append(token)
代码是在***/transformers/tokenization_utils.py:419的位置
我发现“<|endoftext|>”已经在tokenizer.unk_token里面了,导致这个判断的第一个条件通不过,也就没有更新词表。
最后的我的做法是:
tokenizer.unk_token = None
tokenizer.add_special_tokens({"eos_token": "<|endoftext|>"})
先把unk_token清空了,再重新add_special_token,加完以后,tokenizer.eos_token_id不为None了,成了我希望的tokenizer.vocab_size了。
这样很粗暴,也很不美观,但确实有效。
有一个保留问题就是,这个eos_token_id在tokenizer_config.json文件里面是有设置的,但是加载的时候就是没有加载进去,它就非得是None,咱不理解,不想整了。有好心人路过麻烦解答一下,
这是我的模型目录和tokenizer_config.json文件,可以看到,该有的config文件都有,eos_token_id也设置了具体的值。所以是下面这行代码在加载的时候不会读取tokenizer_config.json吗?
tokenizer = GPT2Tokenizer.from_pretrained(para.model_path)