分词器tokenizer属性与特殊字符详解

以小模型gpt2为例:

先查看tokenizer从配置文件中加载的属性:

  1. vocab_size【50256】: Tokenizer 的词汇表大小
  2. pad_token【空】unk_token【<|endoftext|>bos_token【<|endoftext|>eos_token【<|endoftext|>mask_token【空】: 分别对应填充标记、未知标记、序列开头标记、序列结尾标记、掩码标记。
  3. special_tokens_map{'bos_token': '<|endoftext|>', 'eos_token': '<|endoftext|>', 'unk_token': '<|endoftext|>'}: 特殊标记到 token ID 的映射。
  4. added_tokens_encoder【{'<|endoftext|>': 50256}added_tokens_decoder【{50256: AddedToken("<|endoftext|>", rstrip=False, lstrip=False, single_word=False, normalized=True, special=True)}: 添加的特殊标记到 token ID 和 token 的映射
  5. model_max_length【1024】: Tokenizer 接受的最大长度。
  6. padding_side【'right'pad_token_id【空】: 填充的位置、填充的 token ID、填充的 token。
    #  <|endoftext|>是词汇表中50256对应的token,同时也是初始化中唯一的默认特殊字符【added_tokens_decoder属性用于存储特殊字符

---------------------------------- 验证 ------------------------------------

gpt2词汇表的总数是50257,里面对应token字符--id,下标从0-50256

tokenizer.vocab_size ----- 50257 # 词汇表数

len(tokenizer) ------ 50257            # 词汇数+额外添加的特殊字符【不包括默认|endoftext|】

tokenizer.convert_ids_to_tokens(50256) ------  <|endoftext|>        # 50256对应的字符

# config.json配置文件包含两个特殊字符的属性eos_token和bos_token,并且将它们的特殊字符对应id设置为50256。

这里只是将两个属性的token_id值设置为50256,访问属性返回对应id映射的token,但这并没添加额外的特殊字符,没太大意义

# tokenizer加载的属性/根据id返回token

tokenizer.eos_token = '<|endoftext|>'  

tokenizer.bos_token = '<|endoftext|>'

tokenizer.convert_tokens_to_ids('<|endoftext|>')    #  50256

tokenizer.convert_ids_to_tokens(50256)                #  '<|endoftext|>'

# 字符表以外的token,转换成id返回的值均为50256。

tokenizer.convert_tokens_to_ids('<|EOS|>')    # 50256

tokenizer.convert_tokens_to_ids('<|BOS|>')    # 50256

tokenizer.convert_tokens_to_ids('<|KKKKK|>')    # 50256

tokenizer.convert_tokens_to_ids('<|ABCDEF|>')    # 50256

tokenizer.convert_tokens_to_ids('v50KFCGOOD')    # 50256

# 当然,像上面这种如果没有添加新的token为 <|EOS|> 时,在tokenize()分词时就会被分割成 < | E O S | >,更不会进行到后面的convert_tokens_to_id这一步!

------------------------------------ 如何添加特殊字符避免被拆分? ---------------------------------

    tokenizer.add_special_tokens({'pad_token':"<|PAD|>"})  
    tokenizer.add_special_tokens({'eos_token':"<|EOS|>"})
    tokenizer.add_special_tokens({'bos_token':"<|BOS|>"})

add_special_toen添加特殊字符,key值是上面tokenizer的特殊字符属性,value是分割成整体的字符

添加的字符添加到属性added_tokens_encoder中,并扩充特殊字符词汇表,当然,原词汇表大小不会变

len(tokenizer) = tokenizer.vocab_size + special_token【添加的特殊字符】

----------------------------------------------------------------------------------------------------------------

解释一下 为什么有时候分词器会要求设置tokenizer.pad_token = tokenizer.eos_token?

这样处理往往是针对batch操作的,generate是允许batch处理,因此无论如何必须先设置好pad_token,默认pad_toekn是空,那怎么填充?往往会将属性pad_toekn设置成eos_token同一token,填充成<|endoftext|>,在convert_tokens_to_ids再转化成50256

-------------------------------------------------------------------------------------------------------------

添加的特殊字符有什么用?

在问答训练时会添加特殊字符框架协同训练,经过微调模型就知道这样的框架是在做问答,在推理时,只要将文本加入特殊字符组成的问答框架就可以进行回答。

同时,使用特殊字符,也能帮助模型训练时区分每一个句子间的层次关系。

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值