刘知远大模型学习笔记-大模型微调(fine-tune)

本文介绍了如何使用HuggingFace的Transformers库在VSCode中通过虚拟环境部署情感分析应用,包括使用pipeline快速应用预训练模型,以及如何对预训练模型进行微调以适应特定数据集。作者详细展示了从数据加载、tokenization、模型训练到错误解决的全过程。
ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

Transformers:

       由Hugging Face提出,包括许多预训练大模型,能够通过pipeline轻松实现部署应用,我在VSCode中通过虚拟环境实现,需要先pip install transformers。
比如一个小例子:

from transformers import pipeline
classifier = pipeline("sentiment-analysis")
res = classifier("春天就要结束了.")
print(res)

Fine-tune:

       目的:在预训练大模型上使用自己的数据集进行微调,让模型在特有领域表现更好。

数据集tokenize:

from datasets import load_dataset, load_metric
dataset = load_dataset("glue", 'sst2')
metric = load_metric('glue', 'sst2')

       datasets库包括了许多常用的数据集,通过(load_dataset)就可以完成数据集的下载与加载,且load_metric能够加载该数据集对应的评价指标以便计算,其中glue是“General Language Understanding Evaluation”(通用语言理解评估)的缩写,它是一个用于评估和比较自然语言理解(NLU)系统性能的benchmark。GLUE包括了多种不同的任务,如文本蕴含、情感分析、句子相似性匹配等,旨在覆盖广泛的语言理解能力。而sst2是其中一个进行情感分析的数据集。

展示metric的计算使用:
import numpy as np

fake_preds = np.random.randint(0, 2, size=(64,))
fake_labels = np.random.randint(0, 2, size=(64,))
metric.compute(predictions=fake_preds, references=fake_labels)#传入我们随机生成的模型结果与真实结果,计算准确性


       插播一点NLP token小知识(我对NLP之前完全不了解): Tokenization:语言任务中的分词处理,比如RNN使用空格进行分词,Transformer架构中发现这种方法对于词典里没有的词语表现效果很差,使用一种BPE的方法,类似于英文单词中的词根,通过统计词根的词频,提高了对新单词的效果。
       进行微调时需要自己写一些模型加载以及数据处理等的代码,transformers对此流程进行了统一和简化。

Tokenization

from transformers import AutoTokenizer
# 利用tokenizer处理数据集
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased') #可以去官网查看不同模型的名字
def preprocess_function(examples):
    return tokenizer(examples['sentence'], truncation=True, max_length=512)#bert不能处理长度超过512的序列
# 用preprocess_function来处理整个数据集
encoded_dataset = dataset.map(preprocess_function, batched=True)

看下tokenizer生成的是什么东西吧:

tokenizer("Tsinghua University is located in Beijing.")

结果为:
{‘input_ids’:[ ],‘token_type_ids’:[ ],‘attention_mask’:[ ]}三部分,attention_mask要对补长的对应部分设置为0,这些内容不需要处理。

Fine-tune 模型

from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)

       目标任务是情感分类,所以label=2,label数量决定了最后的全连接层数量。
       接下来使用前面提到过的Hugging Face中的trainer类实现:

from transformers import TrainingArguments

batch_size=16
args = TrainingArguments(
    "bert-base-uncased-finetuned-sst2",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=5,
    weight_decay=0.01,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy"
)

def compute_metrics(eval_pred):
    logits, labels = eval_pred                 # predictions: [batch_size,num_labels], labels:[batch_size,]
    predictions = np.argmax(logits, axis=1)    # 将概率最大的类别作为预测结果
    return metric.compute(predictions=predictions, references=labels)

from transformers import Trainer
trainer = Trainer(
    model,
    args,
    train_dataset=encoded_dataset["train"],
    eval_dataset=encoded_dataset["validation"],
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)


每个参数的含义:

第一个参数:本次训练的名称
evaluation_strategy=“epoch”:在每个epoch结束的时候在validation集上测试模型效果
save_strategy=“epoch”:在每个epoch结束的时候保存一个checkpoint
learning_rate=2e-5:优化的学习率
per_device_train_batch_size=batch_size:训练时每个gpu上的batch_size
per_device_eval_batch_size=batch_size:测试时每个gpu上的batch_size
num_train_epochs=5:训练5个epoch
weight_decay=0.01:优化时采用的weight_decay
load_best_model_at_end=True:在训练结束后,加载训练过程中最好的参数
metric_for_best_model=“accuracy”:以准确率作为指标

开始训练~

trainer.train()

此时trainer相当于一个pipeline。

补充:我在自己VSCode中运行这个demo时遇到报错:

packages/torch/utils/data/dataloader.py", line 183, in __init__
    assert prefetch_factor > 0
TypeError: '>' not supported between instances of 'NoneType' and 'int'

大致能看出是关于dataloader中prefetch_factor的问题,参考github和优快云:这篇文章,终于找到了解决办法!:

 """ if num_workers == 0 and prefetch_factor != 2:
            raise ValueError('prefetch_factor option could only be specified in multiprocessing.'
                             'let num_workers > 0 to enable multiprocessing.')
        assert prefetch_factor > 0 """

        if num_workers > 0:
            if prefetch_factor is None:
                prefetch_factor = 2   # default value
        else:
            if prefetch_factor is not None:
                raise ValueError('prefetch_factor option could only be specified in multiprocessing.' 
                         'let num_workers > 0 to enable multiprocessing, otherwise set prefetch_factor to None.')

大家能够看到,解决办法是将dataloader.py中原始的这段代码替换成了新代码:

if num_workers > 0:
            if prefetch_factor is None:
                prefetch_factor = 2   # default value
        else:
            if prefetch_factor is not None:
                raise ValueError('prefetch_factor option could only be specified in multiprocessing.' 
                         'let num_workers > 0 to enable multiprocessing, otherwise set prefetch_factor to None.')

已经成功解决,并且完美运行demo!

完整代码

在文章末尾我给出本demo的完整代码:

from transformers import AutoTokenizer
# 利用tokenizer处理数据集
from datasets import load_dataset, load_metric
from transformers import TrainingArguments
from transformers import AutoModelForSequenceClassification
from transformers import Trainer
import numpy as np

dataset = load_dataset("glue", 'sst2', cache_dir="./datasets_cache)
metric = load_metric('glue', 'sst2')
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased') #可以去官网查看不同模型的名字
def preprocess_function(examples):
    return tokenizer(examples['sentence'], truncation=True, max_length=512)#bert不能处理长度超过512的序列
# 用preprocess_function来处理整个数据集

encoded_dataset = dataset.map(preprocess_function, batched=True)
print(preprocess_function(dataset['train'][:5]))


model = AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)


# Rest of your code

batch_size=16
args = TrainingArguments(
    "bert-base-uncased-finetuned-sst2",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=5,
    weight_decay=0.01,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy"
 
)

def compute_metrics(eval_pred):
    logits, labels = eval_pred                 # predictions: [batch_size,num_labels], labels:[batch_size,]
    predictions = np.argmax(logits, axis=1)    # 将概率最大的类别作为预测结果
    return metric.compute(predictions=predictions, references=labels)


trainer = Trainer(
    model,
    args,
    train_dataset=encoded_dataset["train"],
    eval_dataset=encoded_dataset["validation"],
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)

trainer.train()

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

### 关于清华大学刘知远老师的大模型课程中的Prompt Learning笔记 在相关资料中提到的学习笔记涵盖了大模型公开课的内容,其中包括第四讲(L4)涉及的 **Prompt learning 和 Delta learning** 的主题[^1]。这些笔记可能包含了关于如何设计有效的提示词以及通过微调等方式提升模型性能的关键知识点。 具体而言,Prompt Learning 是一种利用自然语言指令引导大型预训练模型完成特定任务的技术方法。它强调无需大量数据重新训练整个模型即可实现高效适配新场景的能力。根据已有的参考资料描述,这类技术通常会讨论以下核心概念: - 如何构建高效的 Prompt 结构来指导模型行为; - 使用少量样本调整模型参数的方法及其应用场景; - 对比传统 Fine-tuning 方法的优势与局限性分析。 以下是基于上述理论框架的一个简单 Python 实现案例展示如何自定义 prompt 并测试其效果: ```python def generate_prompt(input_text, task_instruction=""): """Generate a formatted prompt with optional task instruction.""" return f"{task_instruction}\nInput: {input_text}\nOutput:" # Example usage of the function to create prompts for different tasks. if __name__ == "__main__": input_example = "Translate 'hello' into Spanish." custom_task_instr = "You are an AI assistant that translates English words into their corresponding meanings in other languages." full_prompt = generate_prompt(input_example, custom_task_instr) print(full_prompt) ``` 此脚本展示了创建个性化提示的基本逻辑,可以根据实际需求修改 `generate_prompt` 函数内的模板字符串以适应更多类型的 NLP 作业要求。 此外,在强化学习领域也有研究探索人类反馈机制优化对话系统的可能性[^2],这或许可以作为进一步理解交互式 Prompt 设计思路的一种补充视角。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值