解决huggingface模型加载问题及评价指标加载优化

释放双眼,带上耳机,听听看~!
本文讨论了解决huggingface模型加载问题的方法,以及优化评价指标加载的技巧,帮助提高模型加载效率和运行速度。

分析问题

问题的起源

事情起因是这样的,我们要使用huggingface,但是日常因为联网问题无法加载模型。因为是服务器集群,搭梯子让我们在docker里弄,所以像我这种懒人,docker?算了,我还是直接手动下载吧,具体看这:服务器huggingface联网通用方案

  • 问题:不能联网下模型,不想搭梯子

  • 解决:缓存模型

但是我是个懒人,我解决的方法只直接在系统默认缓存位置的.cache里缓存文件。

这会带来另一个问题。模型加载过程中会有很大一部分在加载模型。

因为如果你没修改过from_pretrainedforce_download (bool, optional, defaults to False),那么他加载模型的逻辑是这样的:

需要加载模型的时候:
去缓存里找-->找不到-->去huggingface下载-->下载不下来-->去缓存里找-->没找到-->报错
    |                                                   |
    -->找到-->加载模型                           -->找到-->加载模型

我的实验用到4个预训练模型,以及n个huggingface的评价指标。

这个过程会耗费大量的时间。

耗费大量时间,根本无所谓,毕竟我懒,根本不想改代码。

但是。问题来了。在我6卡V100跑了两个多周之后,师兄跑来问我是不是实验卡了。

解决huggingface模型加载问题及评价指标加载优化

因为他采样时候是这样的,只占一捏捏缓存,GPU是不用的。

解决huggingface模型加载问题及评价指标加载优化

为了不挨骂,我决定改一下代码。

修改

评价指标

先说评价指标:

def compute_perplexity(all_texts_list, model_id='gpt2-large'):
    torch.cuda.empty_cache() 
    perplexity = load("perplexity", module_type="metric")
    results = perplexity.compute(predictions=all_texts_list, model_id=model_id, device='cuda')
    return results['mean_perplexity']

我这段代码里需要加载评价指标perplexity加载模型gpt2-large

现看加载评价指标的load:

解决huggingface模型加载问题及评价指标加载优化

这里写的:

a local path to processing script or the directory containing the script (if the script has the same name as the directory),e.g. './metrics/rouge' or './metrics/rouge/rouge.py'

需要你把评价指标外嵌套一个同名的文件夹。所以文件应该如下放置。

解决huggingface模型加载问题及评价指标加载优化

为了确保准确,我这里传入绝对位置,需要借助os

# 获得当前文件夹的目录
import os
cur_dir = os.path.split(__file__)[0]

os.path.split(__file__): __file__ 是Python中的一个内置变量,它指向当前脚本文件的路径。os.path.split() 函数将这个路径分为两部分,第一部分是文件所在的目录,第二部分是文件名。例如,如果 __file__ 的值是'https://b2.7b2.com/path/to/script.py',那么 os.path.split(__file__) 将返回 ('/path/to', 'script.py')

cur_dir = os.path.split(__file__)[0]: 这一行代码获取了当前脚本文件所在的目录,即 '/path/to'。它将目录部分提取出来并存储在变量 cur_dir 中。

f"{cur_dir}/perplexity"即可获得我当前目录存的perplexity。

模型

因为perplexity需要用到预训练模型,我们可以看到我们传入的model_id是模型名,点进这个计算函数看一下。

解决huggingface模型加载问题及评价指标加载优化

可以看到传入的model_id直接在这里进行了模型加载。

from_pretrained实现代码注释这样写。

解决huggingface模型加载问题及评价指标加载优化

A string, the model id of a predefined tokenizer hosted inside a model repo on huggingface.co. Valid model ids can be located at the root-level, like bert-base-uncased, or namespaced under auser or organization name, like dbmdz/bert-base-german-cased.

传入本地文件夹包含模型文件即可。

所以我们只需要将缓存中的模型及其配置新建个文件夹放进去即可。

看一下文件夹嵌套就知道为什么传入绝对地址了。

解决huggingface模型加载问题及评价指标加载优化

compute_perplexity是evaluation.py的函数,但是这个函数引用了同目录下的perplexity/perplexity.py,但是这个perplexity.py要load上上级文件夹下的模型。为了防止混乱,我们还是使用os.path获取位置比较方便。

import os

model_id = "gpt2-large"
cur_dir = os.path.split(__file__)[0]
model_dir = '/'.join(cur_dir.split('/')[:-1])
print(f"{model_dir}/assist_model/{model_id}")

这段代码用于获取当前脚本文件所在目录的上级目录(parent directory)的路径,通常用于构建文件路径或定位相关资源文件。

cur_dir.split('/'): 这一行代码使用斜杠 / 分割 cur_dir 中的路径字符串,将其拆分成一个列表。例如,如果 cur_dir 的值是 '/path/to',那么 cur_dir.split('/') 将返回 ['', 'path', 'to']

[:-1]: 这是一个切片操作,它用于获取列表中除了最后一个元素之外的所有元素。在这里,[:-1] 表示获取拆分后列表中的所有元素,除了最后一个元素 'to'

'/':这是字符串,用于将列表中的元素连接起来,形成一个新的路径字符串。

最终,model_dir 的值将是当前脚本文件所在的目录的上级目录的路径,具体取决于当前脚本文件的位置和文件系统的路径分隔符。

这样我们就能在evaluation.py获取到上级文件夹的模型。

修改之后的代码如下,我们就可以全部从本地文件夹直接加载了。

import os

cur_dir = os.path.split(__file__)[0]
model_dir = '/'.join(cur_dir.split('/')[:-1])

def compute_perplexity(all_texts_list, model_id='gpt2-large'):
    torch.cuda.empty_cache()
    perplexity = load(f"{cur_dir}/perplexity", module_type="metric")
    model_id = f"{model_dir}/assist_model/{model_id}"
    results = perplexity.compute(predictions=all_texts_list, model_id=model_id, device='cuda')
    return results['mean_perplexity']

总结

  1. 找到loadfrom_pretrained

  2. 把模型丢个文件夹里

  3. os.path传入绝对路径

其他

问题1

提问:

为什么要在项目里搞个本地文件夹加载模型和评价指标?直接load的时候从本地缓存加载不就行了。

回答:

我都要load本地地址了,我为什么不搞个好load的,还要搞那一长串缓存地址?

C:Usersann.cachehuggingfacehubmodels–gpt2-largesnapshots97935fc1a406f447320c3db70fe9e9875dca2595

D:ld4_offmodelgpt2-large

1和2我选2.

问题2

提问: 嫌弃默认的.cache,为什么不改个缓存地址?

回答: 确实,

from transformers import set_cache_dir, AutoModel

# 设置全局的缓存目录
set_cache_dir('/path/to/cache/directory')

# 使用from_pretrained函数加载模型(确保引用全局缓存目录)
model = AutoModel.from_pretrained('bert-base-uncased',cache_dir='/path/to/model/cache')

# 此时模型将从缓存加载,如果缓存不存在,它将尝试从缓存加载,而不重新下载

这样可以修改缓存位置,但是,他好像还是缓存啊……,还是从缓存里读的那个逻辑,还是要走他那个从cache加载的逻辑,不如直接load本地模型吧。我个人感觉是直接加载本地模型更快。

信我,速改,改完以后极其丝滑:

解决huggingface模型加载问题及评价指标加载优化

解决huggingface模型加载问题及评价指标加载优化

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

AI领域新趋势及对软件开发的影响

2023-11-20 21:10:14

AI教程

GPT-4: 人工智能AI革命的绝世神功

2023-11-20 21:29:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索