云南章参电子商务有限公司

Python机器学习作家科普长文:重新构建类GPT文分内类器
发布日期:2024-10-18 14:43    点击次数:144

Python机器学习作家科普长文:重新构建类GPT文分内类器

近日,Sebastian Raschka 又共享了一篇长文,主题为《重新入手构建一个 GPT 作风的 LLM 分类器》。

著作展示了如何将预查考的大型讲话模子(LLM)升沉为庞大的文分内类器。机器之心对著作施行进行了不变嫌情愿的编译、整理:

为什么要眷注分类呢?起始,针对分类任务,对预查考模子进行微调是一个浅近灵验的 LLM 常识初学形势。其次,文分内类有很多买卖诓骗场景,比如:垃圾邮件检测、情谊分析、客户反映分类、主题分类等等。

阅读完本文,你将找到以下 7 个问题的谜底:

1. 需要查考通盘层吗?

2. 为什么微调终末一个 token,而不是第一个 token?

3. BERT 与 GPT 在性能上有何比较?

4. 应该禁用因果掩码吗?

5. 扩大模子限制会有什么影响?

6. LoRA 不错带来什么矫正?

7. Padding 还是不 Padding?

完好代码不错从 GitHub 找到:https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb

Different categories of finetuning

微调的不同种类

指示微合股分类微调是最常见的讲话模子微调秩序。指示微调是用特定任务查考模子,擢升它理解和履行当然讲话领导中所边幅任务的才调,如下图 1 所示。

图 1:指示微调的两种场景。上方:模子的任务是判断文本是否为垃圾邮件;下方:模子的任务是将英词句子翻译成德语。

在分类微调中,模子被查考用于识别特定的类别标签,比如「垃圾邮件」和「非垃圾邮件」。分类任务还包括从图像中识别不同的植物、给新闻按体育、政事或科技等主题分类,从医学影像中差别良性和恶性肿瘤等等。

不外进程分类微调的模子只可判断类别,不可对输入的文本作出其他判断。

图 2:一个使用 LLM 进行垃圾邮件分类的示例。针对垃圾邮件分类微调的模子在输入时不需要异常的指示,关系词,与指示微调模子比拟,它的陈述只关联词「垃圾邮件」和「非垃圾邮件」。

指示微调的模子每每大约履行更宽绰的任务。咱们不错将分类微调的模子视为是高度专科化的模子,一般来说,设备一个专用模子比设备一个在多样任务上发扬风雅的通用模子更容易。

使用预查考权重驱动化模子

下图中展示了将通用预查考 LLM 转移为专诚用于分类任务的 LLM 需要作念的修改:

图 3:在此跳过技艺 1-5,胜利参预技艺 6(将不才一节入手)。

在作念修改之前,让咱们先浅近了解一下正在使用的预查考 LLM。为便捷起见,假定咱们竖立了如下代码来加载该模子:

model = GPTModel (BASE_CONFIG) load_weights_into_gpt (model, params) model.eval ()

在将模子权重加载到 GPT 后,使用下列文本生成的函数库,确保模子生成连贯的文本:

from chapter04 import generate_text_simple from chapter05 import text_to_token_ids, token_ids_to_text text_1 = "Every effort moves you" token_ids = generate_text_simple ( model=model, idx=text_to_token_ids (text_1, tokenizer), max_new_tokens=15, context_size=BASE_CONFIG ["context_length"] ) print (token_ids_to_text (token_ids, tokenizer))

凭据以下输出,咱们不错看到模子生成了连贯的文本,这标明模子权重已正确加载:

Every effort moves you forward. The first step is to understand the importance of your work

让咱们先望望模子是否不错通过指示微调完成垃圾邮件的分类:

text_2 = ( "Is the following text'spam'? Answer with 'yes' or 'no':" "'You are a winner you have been specially" "selected to receive $1000 cash or a $2000 award.'" ) token_ids = generate_text_simple ( model=model, idx=text_to_token_ids (text_2, tokenizer), max_new_tokens=23, context_size=BASE_CONFIG ["context_length"] ) print (token_ids_to_text (token_ids, tokenizer))

模子的输出如下所示:

Is the following text'spam'? Answer with 'yes' or 'no': 'You are a winner you have been specially selected to receive $1000 cash or a $2000 award.' The following text'spam'? Answer with 'yes' or 'no': 'You are a winner

不错赫然看出模子在准确辞退指示方面碰到了一些挑战。这是不错预料的,因为它仅进程了预查考,零落指示微调。

加入分类头

咱们将原始输出层(这层的功能是将模子里面生成的荫藏暗意调度为一个包含 50,257 个 tokens 的词表)替换为一个较小的输出层,该层映射到两个类别:0(非垃圾邮件)和 1(垃圾邮件),如下图 4 所示。

图 4:此图展示了如何通过变嫌架构将 GPT 模子适配为垃圾邮件分类。当先,模子的线性输出层将 768 个荫藏单位映射到一个包含 50,257 个 tokens 的词汇表。为了进行垃圾邮件检测,这一层被替换为一个新的输出层,该层将雷同的 768 个荫藏单位映射到两个类别,分别暗意「垃圾邮件」和「非垃圾邮件」。

输出层节点

从技艺上讲,因为这是一个二元分类任务,不错只用一个输出节点。关系词,这将需要修改耗费函数。因此,咱们选拔一种更通用的秩序,匹配输出节点与分类的数目。举例,关于一个分三类的问题,如将新闻著作分类为「科技」、「体育」或「政事」,使用三个输出节点,以此类推。

在尝试进行图 4 中所示的修改之前,先通过 print (model) 输出模子架构:

GPTModel ( (tok_emb): Embedding (50257, 768) (pos_emb): Embedding (1024, 768) (drop_emb): Dropout (p=0.0, inplace=False) (trf_blocks): Sequential ( ... (11): TransformerBlock ( (att): MultiHeadAttention ( (W_query): Linear (in_features=768, out_features=768, bias=True) (W_key): Linear (in_features=768, out_features=768, bias=True) (W_value): Linear (in_features=768, out_features=768, bias=True) (out_proj): Linear (in_features=768, out_features=768, bias=True) (dropout): Dropout (p=0.0, inplace=False) ) (ff): FeedForward ( (layers): Sequential ( (0): Linear (in_features=768, out_features=3072, bias=True) (1): GELU () (2): Linear (in_features=3072, out_features=768, bias=True) ) ) (norm1): LayerNorm () (norm2): LayerNorm () (drop_resid): Dropout (p=0.0, inplace=False) ) ) (final_norm): LayerNorm () (out_head): Linear (in_features=768, out_features=50257, bias=False) )

如上所示,GPTModel 由镶嵌层和 12 个雷同的 transformer 块构成,为简单起见,仅泄漏终末一个块,然后是最终的 LayerNorm 和输出层 out_head。

接下来,咱们将 out_head 替换为一个新的输出层,如图 4 所示,咱们将对这一层进行微调。

选拔微调特定层与微调通盘层

咱们毋庸对模子每一层进行微调,因为神经蚁集的较低层捕捉到的基本的讲话结构和语义是通用的,不错在很多不同的任务和数据勾通阐扬作用。

因此,咱们仅微调终末几层(聚集输出的层)就够了,这些层更具体于幽微的讲话口头和任务特征。这种秩序在策动上也将愈加高效。

为了准备进行分类微调,起始咱们冻结模子,行将通盘层竖立为不可查考:

for param in model.parameters (): param.requires_grad = False

然后,如图 4 所示,咱们修改输出层 model.out_head :

torch.manual_seed (123) num_classes = 2 model.out_head = torch.nn.Linear ( in_features=BASE_CONFIG ["emb_dim"], out_features=num_classes )

防备,在上述代码中,咱们使用了 BASE_CONFIG ["emb_dim"],它的值在 “gpt2-small(124M)” 模子中为 768。这么作念的探讨是为了让后续的代码愈加通用,雷同的代码也能处分其他型号的 GPT-2 模子。

新的 model.out_head 输出层的 requires_grad 属性默许竖立为 True,这意味着这是模子中独一会在查考期间更新的层。

从技艺上讲,只查考刚刚添加的输出层就阔气了。关系词,我在实验中发现,微调异常的层,不错显贵擢升微调模子的估量性能。

此外,咱们将终末一个 transformer 块以及相连该块与输出层的 LayerNorm 模块竖立为可查考,如图 5 所示。

图 5:用我的技艺设备的 GPT 模子包含 12 个访佛的 transformer 块。除了输出层,咱们将终末的 LayerNorm 和终末一个 transformer 块竖立为可查考,而其余 11 个 transformer 块和镶嵌层保合手为不可查考。

为了作念到这点,咱们将它们各自的 requires_grad 竖立为 True:

for param in model.trf_blocks [-1].parameters (): param.requires_grad = True for param in model.final_norm.parameters (): param.requires_grad = True

尽管咱们添加了一个新的输出层,并将某些层竖立为不可查考,咱们仍然不错使用这个模子。举例,咱们不错像之前那样输入一段示例文本:

inputs = tokenizer.encode ("Do you have time") inputs = torch.tensor (inputs).unsqueeze (0) print ("Inputs:

友情链接:

Powered by 云南章参电子商务有限公司 @2013-2022 RSS地图 HTML地图

Copyright Powered by365站群 © 2013-2024