你的位置:滚球app官网 > 新闻资讯 > Python机器学习作家科普长文:重新构建类GPT文分内类器

新闻资讯
Python机器学习作家科普长文:重新构建类GPT文分内类器
发布日期:2024-10-07 05:20    点击次数:202

近日,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 滚球app官网 @2013-2022 RSS地图 HTML地图