Huggingface Trainer:Removed shared tensor while saving问题的解决

bug概述:【踩坑记录📝】Removed shared tensor while saving.
简单来说,这个bug的危害是trainer.save()无法正确存储权重。这篇博文的作者也给出了两种处理方法,但要么要改transformers版本,要么要包裹Trainer类,太麻烦了。

我使用transformers版本4.38.0,deepspeed zero 0/1/2复现了这篇博文所述bug,研究得知bug的具体原因后,给出以下解决思路:

第一步:获得正确的state_dict

trainer调用_save方法时,默认入参state_dict=None,然后_save方法通过self.model.state_dict()获得state_dict,导致报错。原因是此时self.model是通过accelerator加载的,state_dict需要用self.accelerator.get_state_dict(self.model)的方式获得。

解决思路是提前在调用_save之前提前通过self.accelerator.get_state_dict(self.model)把state_dict取出,然后直接带state_dict入参来调用_save方法,实现权重存储。

我在这里借鉴了QWen-VL仓库finetune.py的写法,参考代码如下:

def safe_save_model_for_hf_trainer
### 使用 Hugging Face Trainer 进行模型训练 #### 准备工作 为了利用 `Trainer` 模块进行模型的微调,首先需要安装必要的库并导入所需的模块。通常情况下,这涉及到安装 Transformers 库以及可能使用的 Datasets 和 Evaluate 库。 ```bash pip install transformers datasets evaluate ``` 接着,在 Python 脚本或 Jupyter Notebook 中引入这些包: ```python from transformers import AutoTokenizer, AutoModelForSequenceClassification, TrainingArguments, Trainer import numpy as np from datasets import load_dataset, load_metric ``` #### 数据处理 对于自定义的数据集来说,应该先将其转换成适合输入给定预训练模型的形式。这里以情感分析为例说明如何准备数据集[^1]。 ```python raw_datasets = load_dataset("imdb") # 假设使用IMDB电影评论作为例子 tokenizer = AutoTokenizer.from_pretrained('bert-base-cased') def preprocess_function(examples): return tokenizer(examples['text'], truncation=True) tokenized_datasets = raw_datasets.map(preprocess_function, batched=True) small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select([i for i in list(range(0, 100))]) small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select([i for i in list(range(0, 100))]) ``` #### 定义评估指标 为了让 `Trainer` 可以计算验证期间的表现情况,还需要指定评价标准。比如可以采用准确率来衡量二元分类的效果。 ```python metric = load_metric("accuracy") def compute_metrics(eval_pred): logits, labels = eval_pred predictions = np.argmax(logits, axis=-1) return metric.compute(predictions=predictions, references=labels) ``` #### 设置训练参数 创建一个 `TrainingArguments` 实例用于配置训练的具体选项,如批量大小、学习率等超参设置。 ```python training_args = TrainingArguments( output_dir="./results", evaluation_strategy="epoch", learning_rate=2e-5, per_device_train_batch_size=8, per_device_eval_batch_size=8, num_train_epochs=3, weight_decay=0.01, ) ``` #### 初始化 Trainer 对象 最后一步就是实例化 `Trainer` 类,并传入之前定义好的组件——包括模型架构、优化器参数、训练/测试数据集以及性能度量函数。 ```python model = AutoModelForSequenceClassification.from_pretrained('bert-base-cased', num_labels=2) trainer = Trainer( model=model, args=training_args, train_dataset=small_train_dataset, eval_dataset=small_eval_dataset, compute_metrics=compute_metrics ) ``` 此时已经准备好启动训练过程了! ```python trainer.train() ``` 上述代码展示了基于 BERT 的序列分类任务(即情感分析),但同样的方法也适用于其他类型的 NLP 问题,只需调整相应的模型结构和前处理逻辑即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值