赞
踩
由于经常下载别人的开源模型来做一些自己的小工具,苦于下载速度慢、环境配置繁琐的问题,希望能够手动下载模型并且把模型放在跟项目一起的文件夹,所以在这里总结一下经验。
(来自开源项目https://github.com/OleehyO/TexTeller)
只需关注其中的
def from_pretrained(cls, model_path)
和def get_tokenizer(cls, tokenizer_path)
from pathlib import Path from models.globals import ( VOCAB_SIZE, FIXED_IMG_SIZE, IMG_CHANNELS, ) from transformers import ( ViTConfig, ViTModel, TrOCRConfig, TrOCRForCausalLM, RobertaTokenizerFast, VisionEncoderDecoderModel, ) class TexTeller(VisionEncoderDecoderModel): REPO_NAME = 'OleehyO/TexTeller' def __init__(self, decoder_path=None, tokenizer_path=None): encoder = ViTModel(ViTConfig( image_size=FIXED_IMG_SIZE, num_channels=IMG_CHANNELS )) decoder = TrOCRForCausalLM(TrOCRConfig( vocab_size=VOCAB_SIZE, )) super().__init__(encoder=encoder, decoder=decoder) # 关注下面两个函数---------------------!!! @classmethod def from_pretrained(cls, model_path: str = None): if model_path is None or model_path == 'default': return VisionEncoderDecoderModel.from_pretrained(cls.REPO_NAME) model_path = Path(model_path).resolve() return VisionEncoderDecoderModel.from_pretrained(str(model_path)) @classmethod def get_tokenizer(cls, tokenizer_path: str = None) -> RobertaTokenizerFast: if tokenizer_path is None or tokenizer_path == 'default': return RobertaTokenizerFast.from_pretrained(cls.REPO_NAME) tokenizer_path = Path(tokenizer_path).resolve() return RobertaTokenizerFast.from_pretrained(str(tokenizer_path))
模型权重的下载靠的是这样一行代码:(参考:huggingface官方文档)
VisionEncoderDecoderModel.from_pretrained(str(model_path))
往前追溯可以发现model_path
就是REPO_NAME = 'OleehyO/TexTeller'
而VisionEncoderDecoderModel
是一个在transformers
库中定义的类
而当你把OleehyO/TexTeller
这个链接放到浏览器里打开,可以发现,这就是开源项目在huggingface里的位置!
点到“Files”里面就包含了所有需要下载的文件,点击下载按钮就可以一个个手动下载下来了。(注意,所有文件都要下载下来并放在一个文件夹,不能只下载权重文件)
但是你突然发现,这里好像有两个很大的模型权重文件,一个是.safetensors
,一个是.bin
,两个文件的区别是什么呢?自己查。要下载哪个呢?经我的测试两个都能用,任意下载一个就好了。
from_pretrained()
加载我们下载下来的文件在默认情况下,from_pretrained(path)
会自动从线上的开源项目里下载文件,下载下来的文件会存放在C:\Users\<用户名>\.cache\huggingface\hub
,这里的<用户名>
不同电脑各不相同,按下图方式查找(我的用户名是pc)
那么如何加载自己下载的文件呢?把from_pretrained(path)
里的path
改成本地路径就好了。
在我的示例中,我把下载下来的文件放在了名为load_model
的文件夹,并把文件夹放在了工作目录的下级。(这意味着这个文件夹的相对路径是'./load_model'
)
然后我在代码中这样修改REPO_NAME = './load_model'
,也就是把'OleehyO/TexTeller'
改成了 './load_model'
,这时运行
VisionEncoderDecoderModel.from_pretrained(str(model_path))
实际上就是运行
VisionEncoderDecoderModel.from_pretrained('./load_model')
程序会从本地的load_model
文件夹加载文件。此时就已经大功告成了。
但接下来我想知道from_pretrained()
到底是如何解析这个地址的?因为'OleehyO/TexTeller'
本身也可以作为一个相对路径来解读,但为什么这里却直接从线上加载了呢?难道是因为少了个./
?
经过我的测试
'OleehyO/TexTeller'
这个相对路径在本地存在时,程序会优先在本地寻找文件,假如文件不存在,就会报错。假如文件存在则成功运行。'OleehyO/TexTeller'
这个相对路径在本地不存在时,就会到线上寻找项目,加载过程就是一开始那样。所以这跟./
没有关系,纯粹取决于你文件夹路径存不存在罢了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。