tokenizers 当use_fast=True时,Llama分词器在未规范化的标记后添加空格,

8xiog9wr  于 3个月前  发布在  其他
关注(0)|答案(8)|浏览(78)

在我的当前项目中,我想添加一个特殊的标记,它不会在下一个标记前插入空格。目前,我需要指定 use_fast=False 才能使此功能正常工作。然而:

  • 我不明确为什么我应该期望慢速和快速分词器以不同的方式表现
  • 这一发现并不适用于例如 gemma 分词器,它从不添加这样的空格
  • 也许这应该是分词器_kwargs 中的一个显式选项?
7hiiyaii

7hiiyaii1#

哦,等等,@ArthurZucker,这是你在#1568里修复的问题吗?

9rygscc1

9rygscc12#

对于未归一化的非特殊标记,也存在相同的问题:

from tokenizers import AddedToken
from transformers import AutoTokenizer
tok_name = "meta-llama/llama-2-7b-hf"
fast_tokenizer = AutoTokenizer.from_pretrained(tok_name, use_fast=True)
slow_tokenizer = AutoTokenizer.from_pretrained(tok_name, use_fast=False)
tok = "<special>"
t = AddedToken(
    tok, normalized=False, special=False
 )
fast_tokenizer.add_tokens([t])
slow_tokenizer.add_tokens([t])
s = f'hello:{tok}->'
print(f"fast: {fast_tokenizer.tokenize(s)}\nslow: {slow_tokenizer.tokenize(s)}")
>>> fast: ['▁hello', ':', '<special>', '▁->']
>>> slow: ['▁hello', ':', '<special>', '->']
a0zr77ik

a0zr77ik3#

当你添加特殊标记normalized=True时,差异更大...

from tokenizers import AddedToken
from transformers import AutoTokenizer
tok_name = "meta-llama/llama-2-7b-hf"
fast_tokenizer = AutoTokenizer.from_pretrained(tok_name, use_fast=True)
slow_tokenizer = AutoTokenizer.from_pretrained(tok_name, use_fast=False)
tok = "<special>"
t = AddedToken(
    tok, normalized=True, special=True
 )
fast_tokenizer.add_tokens([t], special_tokens=True)
slow_tokenizer.add_tokens([t], special_tokens=True)
s = f'hello:{tok}->'
print(f"fast: {fast_tokenizer.tokenize(s)}\nslow: {slow_tokenizer.tokenize(s)}")
>>> fast: ['▁hello', ':', '<', 'special', '>', '->']
>>> slow: ['▁hello', ':', '<special>', '->']
zte4gxcn

zte4gxcn4#

此外,如果您指定了 add_prefix_space 参数,分词器实际上使用的是慢速实现,这会导致上述代码的行为不同! https://github.com/huggingface/transformers/blob/9485289f374d4df7e8aa0ca917dc131dcf64ebaf/src/transformers/models/llama/tokenization_llama_fast.py#L154

ne5o7dgx

ne5o7dgx5#

$10.5-3x=7$ 得:$x=1.1667$

8ftvxx2r

8ftvxx2r7#

嘿,@ArthurZucker,谢谢你的回答。我正在使用0.19.1版本,它应该有修复。
我现在真的很困惑。为什么use_fast改变分词器的行为不是一个问题?
我的更实际的问题是,有没有一种方法可以添加一个token,使得:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model, ...) # magic kwargs
# magically add <special>
s = f'a:<special>->'
print(tokenizer.tokenize(s)})

总是打印出[ {whatever}, '<special>', '->'],关键点是这里有一个-> token,而不是一个_-> token。

6psbrbz9

6psbrbz98#

是的,这是由于 legacy 标志的影响,因为在我们修复问题之前 Llama 已经被添加了。

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model, legacy=False) # magic kwargs
# magically add <special>
s = f'a:<special>->'
print(tokenizer.tokenize(s)})

当你将 legacy 设置为 False 时,你可能并不总是能从慢速转换中获得结果,这就迫使 legacy 属性实际上被考虑在内!

相关问题