Pytorch——AutoTokenizer载入本地tokenizer权重
由于众所周知的原因,国内很难使用huggingface去下载权重,但现在的大模型的权重以及相关的分词器配置都放在huggingface的仓库中。当我们使用 AutoTokenizer.from_pretrained 去载入相关分词器和模型时,会访问huggingface自动下载模型。但随着大模型的发布,很多模型的tokenizer都以tokenizer.model的方式保存,并且使用自己的.py文件去加载自定义的tokenizer类。因此tokenizer_config.json(tokenizer配置类)变得至关重要。下面就是我遇到的使用AutoTokenizer载入本地tokenizer时的坑。
场景:我使用ChatGLM这个大语言模型,于是从huggingface镜像网站中(HF-Mirror - Huggingface 镜像站)下载了其对应的模型参数以及tokenizer。使用以下命令行 a = AutoTokenizer.from_pretrained(r"D:\git_project\chatglm", trust_remote_code=True) 载入模型的tokenizer时,表示无法从本地载入(确定本地存在tokenizer的相关文件),并且每次都去请求huggingface的官网去下载这个模型(但由于屏蔽,导致了请求失败),因此无法使用,遂追寻AutoTokenizer.from_pretrained的源码寻求原因。
以下是文件D:\git_project\chatglm文件夹中的内容:
直接说结论:AutoTokenizer.from_pretraine中传入的本地文件路径,一定要和tokenizer_config.json中的以下配置对应:
解释:通过追踪源码(省略版),我们发现AutoTokenizer只会从传入的路径(我们传入的是D:\git_project\chatglm)去找到tokenizer_config.json文件,当找到之后,所有的加载内容都以tokenizer_config.json中内容为准,这里的“auto_map”就是告诉加载器要去哪里找对应的tokenizer类,前半段的路径标记的就是去哪里找.py文件,使用--分割后面的就是指的对应的python文件中的Tokenizer类(上图就是会去D:\git_project\chatglm这个路径中去找,tokenization_chatglm.py这个文件,并加载这个.py文件中的ChatGLMTokenizer对象)。
注意事项(坑):
1、并不是所有的tokenizer载入都会使用自定义的方式(通过一个.py文件去得到自定义的Tokenizer对象),更多的时候是直接一个tokenizer.json或者vocab.txt即可,因此他们的tokenizer_config.json中都没有这个“auto_map”参数,更多的是tokenizer_class去指定让AutoTokenizer使用已经配置好的Tokenizer。
2、transformers中已经集成了非常多的Tokenizer类,而AutoTokenizer在载入时会根据tokenizer_config.json中的“tokenizer_class”去找是否已经存在了内置的Tokernizer对象,比如上面例子中我们“tokenizer_class”参数是“ChatGLMTokenizer”,因此在载入时会先在使用tokenizer_class_from_name方法去TOKENIZER_MAPPING_NAMES常量中寻找是否已经有内置的Tokernizer类,如果有则初始化,如果没有,就会使用“auto_map”这个参数去找到底应该拿什么类。(很明显transformers中并没有集成ChatGLMTokenizer,并且auto_map也没有找到对应的路径,因此他会去一直请求huggingface去仓库中下载模型)
3、一般使用自定义的tokenizer类都会使用sentencepiece这个包,但是这个包加载tokenizer.model时不支持中文地址!!!!