2.1 基于Transformers的NLP解决方案

目录

1 基础组件知识回顾

2 基于Transformers的NLP解决方案

3 显存优化策略,4G显存跑BERT-Large

3.1 缩小batch_size,设置gradient_accumulation_steps=32:

3.1.1 原因: 

3.1.2 效果:

3.2 设置 gradient_checkpointing=True

3.2.1 原因:

3.2.2 效果: 

3.3 设置optim="adafactor" 

3.3.1 原因:

3.3.2 效果:

3.4 Freeze Model冻结参数: 

3.4.1 原因:

3.4.2 效果:

3.5 缩小max_length:

3.5.1 原因:

3.5.2 效果:

4 最后的对比图: 


1 基础组件知识回顾

2 基于Transformers的NLP解决方案

3 显存优化策略,4G显存跑BERT-Large

模型训练之前:

好家伙,用这个哈工大的模型“hfl/chinese-macbert-large”直接爆内存了。

这是博主4090的显存:

果然,我这个废物的1650是跑不起来的 

那么,如何让我们这个4g的也能跑起来呢?

3.1 缩小batch_size,设置gradient_accumulation_steps=32:

3.1.1 原因: 

原因:

由于内存限制或其他原因,无法同时处理大批量的训练样本。那么就需要我们缩小batch_size,减少每个训练步骤中处理的样本数量。但这样这可能会导致梯度估计的不准确性,因为梯度是根据每个小批量样本计算得出的。梯度的不准确性可能会影响模型的训练效果。

为了缓解这个问题。这时,可以使用梯度累积策略(Gradient Accumulation)来解决这个问题。梯度累积策略将大批量的训练样本拆分成多个小批量,在每个小批量上计算梯度并累积,最后再根据累积的梯度来更新模型参数。

gradient_accumulation_steps参数指定了梯度累积的步数,也就是每次更新模型参数之前累积的小批量数。例如,如果gradient_accumulation_steps设置为32,那么模型会在累积了32个小批量的梯度之后才进行参数更新。这样做可以有效减小内存占用,并使得模型能够处理更大的批量大小,同时保持相对较小的内存需求。

需要注意的是,梯度累积不会改变训练的效果,只是改变了参数更新的频率。在计算损失函数和梯度时,会考虑累积的小批量样本的平均效果。因此,梯度累积可以看作是一种近似方式,使得模型在每次参数更新时更接近于使用完整批量样本进行训练的效果。

3.1.2 效果:

你会发现显存占用从原来的15+掉到了7+,减小了近乎一半。 

3.2 设置 gradient_checkpointing=True

3.2.1 原因:

gradient_checkpointing 是一个用于优化模型内存占用的技术。当你在训练大型模型或者使用较大的批量大小时,模型的内存需求可能会非常高。为了解决这个问题,可以启用梯度检查点(gradient checkpointing)。

梯度检查点是一种技术,它允许在反向传播过程中临时释放一部分中间激活值的内存,从而减少内存占用。在正向传播过程中,模型会计算并保留所有中间激活值以供后续的反向传播使用。但是,在反向传播过程中,并不需要保留所有中间激活值,只需要保留一部分用于计算梯度的值即可。

启用 gradient_checkpointing=True 参数会在模型中使用梯度检查点技术。这样,当进行反向传播计算梯度时,只会保留必要的中间激活值,而释放其他不需要的中间激活值的内存。这可以显著减少模型的内存占用,特别是对于具有大量参数和复杂结构的模型。

3.2.2 效果: 

可以看到这个确实也能减少一些内存开销,只是效果没有之前那个那样明显 

3.3 设置optim="adafactor" 

3.3.1 原因:

optim="adafactor" 表示你选择使用 Adafactor 优化器来训练模型。Adafactor 是一种自适应学习率优化器,它在处理稀疏梯度时表现出色,并且对学习率的自适应调整具有一定的稳定性。

Adafactor 优化器在训练过程中会自动调整学习率,并根据梯度的稀疏性进行自适应。相比于传统的优化器(如 Adam、SGD 等),Adafactor 具有以下特点:

  1. 自适应学习率:Adafactor 会根据梯度的变化情况自动调整学习率,从而更好地适应不同参数的更新需求。

  2. 稀疏梯度支持:Adafactor 在处理稀疏梯度时表现出色,这对于处理具有大量参数的模型(如 Transformer)尤为重要。

  3. 参数矩阵自适应:Adafactor 会自适应地调整参数矩阵的学习率和正则化项,以适应不同参数的特性。

Adafactor 是一种较新的优化器,相对于传统的优化器来说,它可能在某些任务和模型上表现更好。然而,选择优化器时仍然需要根据具体任务和模型的特点进行评估和实验,以确定最合适的优化器。

注意,huggingface并不支持所有的优化器,但是对于adafactor还是支持的。

3.3.2 效果:

可以看到up主的电脑上显存以及降到了5.0g。

同时,我的4g显存电脑上终于也可以跑这个模型了 ,不过时间确实要很久:

3.4 Freeze Model冻结参数: 

注意这次是在设置Trainer的代码块中修改,非参数设置模块

3.4.1 原因:

遍历模型 model 中 BERT 的参数,并将它们的 requires_grad 属性设置为 False,从而冻结了这些参数。参数冻结是指在训练过程中保持参数的数值不变,不更新它们的梯度。

通过将参数的 requires_grad 属性设置为 False,你告诉模型在训练过程中不需要计算和更新这些参数的梯度。这样做的目的通常是为了固定预训练模型的参数,以免在微调过程中不必要地改变它们的权重。

参数冻结可以有几个用途:

  1. 加速训练:冻结一些参数可以减少计算量和内存需求,从而加快训练速度。
  2. 防止过拟合:在微调预训练模型时,冻结一些参数可以防止模型在小样本数据上过拟合。
  3. 保持预训练模型的特征提取能力:预训练模型通常在大规模数据上进行训练,学习了丰富的特征表示。通过冻结预训练模型的参数,可以保留这些特征提取能力,而不会在微调过程中过度调整它们。
3.4.2 效果:

可以看到不仅显存降低了很多,而且训练速度也得到了增强

3.5 缩小max_length:

3.5.1 原因:

缩小 max_length 意味着限制输入序列的最大长度。在自然语言处理任务中,输入序列的长度可能对模型的训练和推理过程产生影响。通过缩小 max_length,可以减少模型对长序列的处理需求,从而可能提高训练速度和节省内存。

要缩小 max_length,需要根据你的数据集和任务的特点进行调整。以下是一些可能的方法:

  1. 截断序列:对于超过 max_length 的输入序列,可以选择截断它们到指定的最大长度。这样做可能会导致信息的丢失,特别是对于长文本来说,但有时这是必要的权衡。

  2. 选择合适的 max_length 值:根据数据集和任务的特点,选择一个适当的 max_length 值。这需要考虑到输入序列的平均长度、文本的语义完整性以及模型的要求等因素。

  3. 动态调整 max_length:如果数据集中的序列长度差异很大,可以考虑动态调整 max_length。例如,可以根据每个具体样本的长度设置不同的 max_length 值。

需要注意的是,缩小 max_length 可能会导致信息的丢失或模型对长序列的处理能力下降。因此,在调整 max_length 时,需要权衡模型性能和输入序列的完整性之间的平衡。确保选择一个合适的 max_length 值,以满足任务需求并保持模型的有效性。

3.5.2 效果:

这个虽然在占用显存上的效果不太直观,但是其实时间还是缩小了不少。

4 最后的对比图: 

up主的,这些策略还是非常有效的,时间换空间

当然还有其他的高效微调策略,敬请期待下个章节 

最后的最后,我们在跑一个较大模型的时候,如果自由组合上述策略还不行(buff叠满了),那就只能寻求类似功能的小模型,做一个取舍

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于PyTorch的自然语言处理(Natural Language Processing,NLP)是一种利用PyTorch框架进行文本处理和语言理解的技术。PyTorch是一个开源的深度学习框架,它提供了丰富的工具和库,使得构建和训练NLP模型变得更加简单和高效。 在基于PyTorch的NLP中,常用的任务包括文本分类、情感分析、命名实体识别、机器翻译等。以下是一些常见的PyTorch库和技术,用于构建NLP模型: 1. torchtext:torchtext是一个用于数据预处理和加载的库,它提供了一些方便的功能,如文本分词、词向量加载、数据集划分等。 2. torch.nn:torch.nn是PyTorch中用于构建神经网络的模块,它提供了各种层和激活函数,可以用于构建文本分类、序列标注等任务的模型。 3. transformerstransformers是一个用于自然语言处理的库,它提供了各种预训练的模型,如BERT、GPT等。这些模型可以直接加载并在自己的任务上进行微调。 4. torchtext.data:torchtext.data是torchtext库中用于处理数据的模块,它提供了一些方便的功能,如数据加载、数据预处理、数据迭代器等。 5. torchtext.vocab:torchtext.vocab是torchtext库中用于处理词汇表的模块,它提供了一些常用的词向量加载和词汇表构建的功能。 6. torch.optim:torch.optim是PyTorch中用于优化模型的模块,它提供了各种优化算法,如SGD、Adam等。 7. torchtext.datasets:torchtext.datasets是torchtext库中用于加载常见NLP数据集的模块,如IMDB、SNLI等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值