解决llama使用AutoTokenizer创建tokenizer缓慢问题

问题

最近在尝试使用lm-evaluation-harness时,在使用llama模型时,发现最开始的速度奇慢无比。其中定位到一部分问题是使用AutoTokenizer创建tokenizer缓慢,大约需要5分钟左右。这个问题该如何解决呢?

本文可以直接在Colab中打开 在Colab中打开

探索

首先安装依赖库

再设置BASE_MODEL为llama-7b

使用LlamaTokenizer验证,可以看到实际执行时间为1s

使用AutoTokenizer,发现会有非常长的时间在执行

在colab的状态栏中,发现如下的代码在持续执行

使用colab CPU实例,整个时间持续了5分49秒

这里发现了一点线索,convert_slow_tokenizer这个调用在transformers中可以看到何时被调用,检索后发现在生成fast的tokenizer时会使用。

于是使用如下代码查看刚才两个tokenizer的is_fast的状态

输出为

这里可以确认,AutoTokenizer默认返回的tokenizer是fast类型的,但LlamaTokenizer返回的是slow类型的

再次手工创建LlamaTokenizerFast来试试

看起来确实是LlamaTokenizerFast带来的问题。默认情况下,它会将slow版转换为fast版,上面的代码执行消耗了6分23秒

经过搜索,看到一个github issue描述创建LlamaTokenizerFast缓慢的问题,其中提到了会有一个一次性转换,转换后将模型保存起来就可以避免再次转换。那问题是不是就在这里呢?

正巧搜到了一个huggingface上的fast tokenizer,那就试一试

输出如下

可以看到,这个外部的tokenizer多了一个tokenizer.json文件,然后加载速度就是秒级的了。

方案

如此一来,需要将转换为fast的tokenizer进行save_pretrained就可以了。使用以下代码进行修复

首先登录huggingface帐号

然后生成LlamaTokenizerFast,再push_to_hub即可

验证一下解决方案有效,实测确实解决了问题

接下来就是批量处理

在colab上执行,修复总共花了1个多小时

不过后来尝试了下在安装了比较新的transformers版本后,转换时间就变成瞬间了,命令如下

结论

在保存llama的tokenizer权重时,需要使用LlamaTokenizerFast也加载一遍,并push_to_hub,即可解决问题

发表评论

为防机器,验证码请直接输入4个数字1

*