Transformers 加速的一些常用技巧

Transformers 是一个强大的架构,但模型因其采用的自注意力机制,虽然能够有效地处理序列数据并捕获长距离依赖关系,但同时也容易导致在训练过程中出现OOM(Out of Memory,内存不足)或者达到GPU的运行时限制。

主要是因为:

  1. 参数数量庞大:Transformer模型通常包含大量的参数,尤其是在模型层面进行扩展时(例如,增加层数或头数)。这些参数需要大量的内存来存储权重和梯度。
  2. 自注意力计算:自注意力机制需要对输入序列的每个元素与其他所有元素计算其相互关系,导致计算复杂度和内存需求随着输入长度的增加而显著增加。对于非常长的序列,这一点尤其突出。
  3. 激活和中间状态存储:在训练过程中,需要存储前向传播中的中间激活状态,以便于反向传播时使用。这增加了额外的内存负担。

为了解决这些问题,我们今天来总结以下一些常用的加速策略。

固定长度填充

图片

在处理文本数据时,由于文本序列的长度可能各不相同,但许多机器学习模型(尤其是基于Transformer的模型)需要输入数据具有固定的尺寸,因此需要对文本序列进行固定长度填充(padding)。

在使用Transformer模型时,填充部分不应影响到模型的学习。因此通常需要使用注意力掩码(attention mask)来指示模型在自注意力计算时忽略这些填充位置。通过这种固定长度填充和相应的处理方法,可以使得基于Transformer的模型能够有效地处理不同长度的序列数据。在实际应用中,这种方法是处理文本输入的常见策略。

 def fixed_pad_sequences(sequences, max_length, padding_value=0):    
    padded_sequences = []    
    for sequence in sequences:        
        if len(sequence) >= max_length:            
            padded_sequence = sequence[:max_length] # Trim the sequence if it exceeds max_length        
        else:            
            padding = [padding_value] * (max_length - len(sequence)) # Calculate padding            
            padded_sequence = sequence + padding # Pad the sequence        
        padded_sequences.append(padded_sequence)    
     return padded_sequences

这种方式会将所有的序列填充成一个长度,这样虽然长度相同了,但是因为序列的实际大小本来就不同,同一批次很可能出现有很多填充的情况,所以就出现了动态填充策略。

动态填充是在每个批处理中动态填充输入序列到最大长度。与固定长度填充不同,在固定长度填充中,所有序列都被填充以匹配整个数据集中最长序列的长度,动态填充根据该批中最长序列的长度单独填充每个批中的序列。

图片

这样虽然每个批次的长度是不同的,但是批次内部的长度是相同的,可以加快处理速度。

 def pad_sequences_dynamic(sequences, padding_value=0):    
    max_length = max(len(seq) for seq in sequences) # Find the maximum length in the sequences    
    padded_sequences = []    
    for sequence in sequences:        
        padding = [padding_value] * (max_length - len(sequence)) # Calculate padding        
        padded_sequence = sequence + padding # Pad the sequence        
        padded_sequences.append(padded_sequence)    
    return padded_sequences

等长匹配

等长匹配是在训练或推理过程中将长度相近的序列分组成批处理的过程。等长匹配通过基于序列长度将数据集划分为桶,然后从这些桶中采样批次来实现的。

图片

从上图可以看到,通过等长匹配的策略,减少了填充量,这样也可以加速计算:

 def uniform_length_batching(sequences, batch_size, padding_value=0):    
    # Sort sequences based on their lengths    
    sequences.sort(key=len)    
    
    # Divide sequences into buckets based on length    
    buckets = [sequences[i:i+batch_size] for i in range(0, len(sequences), batch_size)]    

    # Pad sequences within each bucket to the length of the longest sequence in the bucket    
    padded_batches = []    
    for bucket in buckets:        
        max_length = len(bucket[-1]) # Get the length of the longest sequence in the bucket        
        padded_bucket = []        
        for sequence in bucket:            
            padding = [padding_value] * (max_length - len(sequence)) # Calculate padding            
            padded_sequence = sequence + padding # Pad the sequence            
            padded_bucket.append(padded_sequence)        
        padded_batches.append(padded_bucket)    
    return padded_batches

自动混合精度

图片

自动混合精度(AMP)是一种通过使用单精度(float32)和半精度(float16)算法的组合来加速深度学习模型训练的技术。它利用了现代gpu的功能,与float32相比,使用float16数据类型可以更快地执行计算,同时使用更少的内存。

在这里插入图片描述
在这里插入图片描述

AMP在训练过程中动态调整计算精度,允许模型在大多数计算中使用float16,同时自动将某些计算提升为float32,以防止下流或溢出等数值不稳定问题。

图片

Fp16 vs Fp32

图片

双精度(FP64)消耗64位。符号值为1位,指数值为11位,有效精度为52位。

单精度(FP32)消耗32位。符号值为1位,指数值为8位,有效精度为23位。

半精度(FP16)消耗16位。符号值为1位,指数值为5位,有效精度为10位。

所以Fp16可以提高内存节省,并可以大大提高模型训练的速度。考虑到Fp16的优势和它在模型使用方面的主导区域,它非常适合推理任务。但是fp16会产生数值精度的损失,导致计算或存储的值不准确,考虑到这些值的精度至关重要。

另外就是这种优化师针对于分类任务的,对于回归这种需要精确数值的任务Fp16的表现并不好。

总结

以上这些方法,可以在一定程度上缓解内存不足和计算资源的限制,但是对于大型的模型我们还是需要一个强大的GPU。

读者福利:如果大家对大模型感兴趣,这套大模型学习资料一定对你有用

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

包括:大模型学习线路汇总、学习阶段,大模型实战案例,大模型学习视频,人工智能、机器学习、大模型书籍PDF。带你从零基础系统性的学好大模型!

😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

👉AI大模型学习路线汇总👈

大模型学习路线图,整体分为7个大的阶段:(全套教程文末领取哈)

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

👉大模型实战案例👈

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉大模型视频和PDF合集👈

观看零基础学习书籍和视频,看书籍和视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述
在这里插入图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

👉获取方式:

😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值