使用 LoRA 在 vi​​ggo 数据集上微调 Microsoft phi-2 小语言模型

一、说明

        Microsoft 的基于 Transformer 的小语言模型。它可以根据 MIT 许可在HuggingFace上使用。

        它在 96 个 A100 GPU 上使用 1.4T 令牌进行了 14 天的训练。Phi-2 是一个 27 亿个参数的预训练 Transformer,不使用 RLHF 或指示微调。它进行下一个标记预测,并可用于问答、聊天格式和代码生成中的文本生成。

        事实证明,phi-2 在多个基准测试和编码和数学等任务上优于许多具有 7B 和 13B 参数的模型。

        小语言模型之所以具有优异的性能,是因为使用了经过提炼的高质量训练数据或“教科书质量”的数据。小语言模型使用知识蒸馏。也就是说,他们接受了从 LLMS 中提取的核心/基本知识的培训。然后采用剪枝和量化技术来删除模型的非必要部分。训练数据通常是综合数据集的混合物,这些数据集是专门创建的,旨在教导模型执行科学、日常活动、心理理论等领域的常识推理和一般知识。它还可能包含具有高教育意义的选择性网络数据价值和质量。小语言模型使用创新技术进行扩展。

        接下来,我们将看到有关如何使用 HuggingFace 中的 phi-2 进行提示的分步 Python 代码,然后我们将在 veggo 数据集上对其进行微调。我使用 T4 GPU 在 Google Colab 免费层上运行了此代码笔记本。

二、安装依赖库

        我的代码借鉴自 GitHub 上Harper Carrol 的这篇优秀教程。

  1. 安装所需的库
#@title Install required libraries
!pip install accelerate==0.25.0
!pip install bitsandbytes==0.41.1
!pip install datasets==2.14.6
!pip install peft==0.6.2
!pip install transformers==4.36.2
!pip install torch==2.1.0
!pip install einops==0.4.1  
!pip install huggingface_hub

2.所需进口

import torch
import transformers
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, pipeline, logging
from datasets import Dataset

3.我们将使用Google Colab Free tier(T4)上的cuda设备来运行模型

torch.set_default_device("cuda")

4.创建模型和分词器

#create the model object and the corresponding tokenizer
model = AutoModelForCausalLM.from_pretrained("microsoft/phi-2", torch_dtype="auto", trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained("microsoft/phi-2", trust_remote_code=True)

5. 让我们运行一些提示并查看模型响应

# https://huggingface.co/microsoft/phi-2
# This prompt is for code completion
# here the prompt is written within the tokenizer()
inputs = tokenizer('''def fibonacci(n):
   """
   This function prints the terms in Fibonacci series upto n
   """''', return_tensors="pt", return_attention_mask=False)

outputs = model.generate(**inputs, max_length=100)
text = tokenizer.batch_decode(outputs)[0]
print(text)
#https://huggingface.co/microsoft/phi-2
# here a string containing the prompt is defined separately from the tokenizer() and then passed to it
prompt = '''def fibonacci(n):
   """
   This function prints the terms in Fibonacci series upto n
   """'''
inputs = tokenizer(prompt, return_tensors="pt", return_attention_mask=False)
outputs = model.generate(**inputs, max_length=100)
text = tokenizer.batch_decode(outputs)[0]
print(text)
# here we see the output of phi-2 for a question-answering prompt
prompt = 'What is thee relevance of mathematics for understanding physics?'
inputs = tokenizer(prompt, return_tensors="pt", return_attention_mask=False)
outputs = model.generate(**inputs, max_length=200)
text = tokenizer.batch_decode(outputs)[0]
print(text)

三、在HuggingFace的veggo微调 phi-2 模型 

现在我们将在HuggingFace 的“veggo”数据集上

ViGGO是视频游戏领域的英文数据到文本生成数据集。目标响应以会话形式以意义表示形式呈现。该数据集大约有 5,000 个非常干净的数据点,因此该数据集可用于评估神经模型的迁移学习、低资源或少样本能力。

6. 让我们设置加速器来加速训练/微调

#@title Set up accelerator to speed up the training/finetuning
from accelerate import FullyShardedDataParallelPlugin, Accelerator
from torch.distributed.fsdp.fully_sharded_data_parallel import FullOptimStateDictConfig, FullStateDictConfig

fsdp_plugin = FullyShardedDataParallelPlugin(
    state_dict_config=FullStateDictConfig(offload_to_cpu=True, rank0_only=False),
    optim_state_dict_config=FullOptimStateDictConfig(offload_to_cpu=True, rank0_only=False),
)

accelerator = Accelerator(fsdp_plugin=fsdp_plugin)

7. 使用有效的 HuggingFace 访问令牌登录您的 Huggingface 帐户。

        您应该在 HuggingFace 上有一个帐户,然后您可以创建一个免费的访问令牌。

#@title login to your huggingface account using your access token
# you can find your access token at https://huggingface.co/settings/tokens
from huggingface_hub import notebook_login
notebook_login()

8.加载viggo数据集

#@title load viggo dataset
from datasets import load_dataset

train_dataset = load_dataset('gem/viggo', split='train')
eval_dataset = load_dataset('gem/viggo', split='validation')
test_dataset = load_dataset('gem/viggo', split='test')

9. 加载基础模型phi-2

#@title load base model microsoft/phi-2 
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForLanguageModeling

base_model_id = "microsoft/phi-2"
model = AutoModelForCausalLM.from_pretrained(base_model_id, 
                                             load_in_8bit=True, 
                                             torch_dtype=torch.float16, 
                                             trust_remote_code=True)

10. 在下面的代码单元中,我们设置 tokenizer 对象, tokenize() 函数将 tokenizer 应用于每个提示,并创建一个“labels”列,其值与数据中的“input_ids”列相同。

        generate_and_tokenize_prompt() 函数将每个数据点转换为适合传递给 phi-2 模型的提示格式。它从数据点中提取“目标”和“含义表示”。最后,我们使用 map() 函数将此函数应用于 train 和 val 数据集中的每个数据点。

#@title set up the tokenizer for base model
tokenizer = AutoTokenizer.from_pretrained(
    base_model_id,
    add_eos_token=True,
    add_bos_token=True, 
    use_fast=False, # needed for now, should be fixed soon
)

#@title setup tokenize function to make labels and input_ids the same for the self-supervised fine-tuning.
def tokenize(prompt):
    result = tokenizer(prompt)
    result["labels"] = result["input_ids"].copy()
    return result

#@title convert each sample into a prompt
 
def generate_and_tokenize_prompt(data_point):
    full_prompt =f"""Given a target sentence construct the underlying meaning representation of the input sentence as a single function with attributes and attribute values.
                This function should describe the target string accurately and the function must be one of the following ['inform', 'request', 'give_opinion', 'confirm', 'verify_attribute', 'suggest', 'request_explanation', 'recommend', 'request_attribute'].
                   The attributes must be one of the following: ['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating', 'genres', 'player_perspective', 'has_multiplayer', 'platforms', 'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier']

                 ### Target sentence:
                 {data_point["target"]}

                  ### Meaning representation:
                  {data_point["meaning_representation"]}
                 """
    return tokenize(full_prompt)




#@title Reformat the prompt and tokenize each sample:

tokenized_train_dataset = train_dataset.map(generate_and_tokenize_prompt)
tokenized_val_dataset = eval_dataset.map(generate_and_tokenize_prompt)

11. 模型的输入张量通常使用 max_length 参数将每个输入填充到统一长度。

        为了确定该参数的值,我们可以绘制每个 input_id 的长度分布,并将 max_length 设置为等于最长 input_id 的长度。在本例中,选择的 max_length 为 320。

12. 接下来,我们将再次应用 tokenize(),并将 max_length 参数设置为 320。

max_length = 320 # appropriate max length for this dataset

# redefine the tokenize function and tokenizer

tokenizer = AutoTokenizer.from_pretrained(
    base_model_id,
    padding_side="left",
    add_eos_token=True,  
    add_bos_token=True,  
    trust_remote_code=True,
    use_fast=False, # needed for now, should be fixed soon
)
tokenizer.pad_token = tokenizer.eos_token


def tokenize(prompt):
    result = tokenizer(
        prompt,
        truncation=True,
        max_length=max_length,
        padding="max_length",
    )
    result["labels"] = result["input_ids"].copy()
    return result


#@title tokenize train and validation datasets using generate_and_tokenize_prompt function
tokenized_train_dataset = train_dataset.map(generate_and_tokenize_prompt)
tokenized_val_dataset = eval_dataset.map(generate_and_tokenize_prompt)

四、使用LoRA来微调phi-2

        13.让我们使用LoRA(低阶适应)来微调phi-2

        低秩适应是一种快速微调大型语言模型的技术。它冻结预训练的模型权重,并将可训练的秩分解矩阵注入到 Transformer 架构的每一层中,从而减少下游任务的可训练参数的数量。它可以将可训练参数的数量减少10000倍,将GPU内存需求减少3倍。

        要使用 LoRA 微调模型,您需要:

  1. 实例化基本模型。
  2. 创建一个配置 ( LoraConfig),在其中定义 LoRA 特定参数。
  3. 用 包裹基本模型get_peft_model()以获得可训练的PeftModel.
  4. PeftModel像平常训练基本模型一样训练。

   LoraConfig允许您通过以下参数控制 LoRA 如何应用于基础模型:

  • r:更新矩阵的秩,以 表示int。较低的秩会导致较小的更新矩阵和较少的可训练参数。
  • target_modules:应用 LoRA 更新矩阵的模块(例如,注意力块)。
  • alpha:LoRA 比例因子。
  • bias:指定是否bias应训练参数。可以是'none''all'或者'lora_only'
  • modules_to_save:除了 LoRA 层之外的模块列表,要设置为可训练并保存在最终检查点中。这些通常包括模型的自定义头,该头是为微调任务随机初始化的。
  • layers_to_transform:LoRA 转换的层列表。如果未指定,target_modules则变换中的所有图层。
  • layers_patterntarget_modules:如果layers_to_transform指定,则匹配 中图层名称的模式。默认情况下,PeftModel将查看公共层模式(layershblocks等),将其用于奇异和自定义模型。
  • rank_pattern:从图层名称或正则表达式到与 指定的默认排名不同的排名的映射r
  • alpha_pattern:从图层名称或正则表达式到 alpha 的映射,与 指定的默认 alpha 不同lora_alpha

        我们将把 LoRA 应用到模型的 Wqkv、fc1、fc2 层。

from peft import LoraConfig, get_peft_model

config = LoraConfig(
    r=8,
    lora_alpha=16,
    target_modules=[
        "Wqkv",
        "fc1",
        "fc2",
    ],
    bias="none",
    lora_dropout=0.05,  # Conventional
    task_type="CAUSAL_LM",
)

model = get_peft_model(model, config)


# Apply the acceleratort to the model for faster traning. 
model = accelerator.prepare_model(model)

五、 使用 LoRA 微调/训练模型

        您将需要设置训练参数或配置参数,例如保存模型的输出目录。我正在将微调后的模型保存/推送到我的 HuggingFace 帐户,您也可以将微调后的模型保存在本地目录或 Colab 目录中。

        其他训练参数包括warmup_steps、per_device_train_batch_size、gradient_accumulation_steps、max_steps、learning_rate、logging_steps、optim、logging_dir、save_strategy、save_steps、evaluation_strategy、eval_steps、do_eval、push_to_hub、report_to、run_name等。

        maz_steps 确定要执行的最大训练步骤,越长,您的模型就越精细,完成训练所需的时间也越长。当 max_steps = 1000 时,我花了 90 分钟在免费的 Google Colab 上进行训练。学习率也会影响训练时间。

#Train the model and push each check point to Huggingface
import transformers


tokenizer.pad_token = tokenizer.eos_token

trainer = transformers.Trainer(
    model=model,
    train_dataset=tokenized_train_dataset,
    eval_dataset=tokenized_val_dataset,
    args=transformers.TrainingArguments(
        output_dir="./phi2-finetunedonviggodataset",
        warmup_steps=5,
        per_device_train_batch_size=1,
        gradient_accumulation_steps=4,
        max_steps=500,
        learning_rate=2.5e-5, 
        logging_steps=50,
        optim="paged_adamw_8bit",
        logging_dir="./logs",        # Directory for storing logs
        save_strategy="steps",       # Save the model checkpoint every logging step
        save_steps=50,                # Save checkpoints every 50 steps
        evaluation_strategy="steps", # Evaluate the model every logging step
        eval_steps=50,               # Evaluate and save checkpoints every 50 steps
        do_eval=True,                # Perform evaluation at the end of training
        push_to_hub=True,

    ),
    data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False),
)

model.config.use_cache = False  
trainer.train()

        现在您已经在 viggo 数据集上微调了 phi-2,并将其保存在 output_dir 或您的 Huggingface 帐户中。

16.接下来,我们将比较基本模型(没有微调)和微调模型(上面训练过的)上示例提示的性能

#Load the base model
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

base_model_id = "microsoft/phi-2"

base_model = AutoModelForCausalLM.from_pretrained(
    base_model_id,
    load_in_8bit=True,
    device_map="auto",
    trust_remote_code=True,
    torch_dtype=torch.float16,
)

eval_tokenizer = AutoTokenizer.from_pretrained(
    base_model_id,
    add_bos_token=True,
    trust_remote_code=True,
    use_fast=False,
)

#create a sample prompt for evaluation on base model
eval_prompt = """Given a target sentence construct the underlying meaning representation of the input sentence as a single function with attributes and attribute values.
This function should describe the target string accurately and the function must be one of the following ['inform', 'request', 'give_opinion', 'confirm', 'verify_attribute', 'suggest', 'request_explanation', 'recommend', 'request_attribute'].
The attributes must be one of the following: ['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating', 'genres', 'player_perspective', 'has_multiplayer', 'platforms', 'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier']

### Target sentence:
Earlier, you stated that you didn't have strong feelings about PlayStation's Little Big Adventure. Is your opinion true for all games which don't have multiplayer?

### Meaning representation:
"""

# tokenize the above prompt and generate the response from base model
model_input = eval_tokenizer(eval_prompt, return_tensors="pt").to('cuda')
base_model.eval()
with torch.no_grad():
    print(eval_tokenizer.decode(base_model.generate(**model_input, max_new_tokens=100)[0], skip_special_tokens=True))

17. 现在让我们从我的 HuggingFace 帐户加载经过微调的模型,并在其上测试相同的提示。

from peft import PeftModel
ft_model = PeftModel.from_pretrained(base_model, "nimrita/phi2-finetunedonviggodataset", force_download=True)


eval_prompt = """Given a target sentence construct the underlying meaning representation of the input sentence as a single function with attributes and attribute values.
This function should describe the target string accurately and the function must be one of the following ['inform', 'request', 'give_opinion', 'confirm', 'verify_attribute', 'suggest', 'request_explanation', 'recommend', 'request_attribute'].
The attributes must be one of the following: ['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating', 'genres', 'player_perspective', 'has_multiplayer', 'platforms', 'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier']

### Target sentence:
Earlier, you stated that you didn't have strong feelings about PlayStation's Little Big Adventure. Is your opinion true for all games which don't have multiplayer?

### Meaning representation:
"""

model_input = eval_tokenizer(eval_prompt, return_tensors="pt").to('cuda')
ft_model = ft_model.to('cuda')
ft_model.eval()
with torch.no_grad():
    print(eval_tokenizer.decode(ft_model.generate(**model_input, max_new_tokens=100)[0], skip_special_tokens=True))

        您刚刚微调了 phi-2。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/371178.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法笔记刷题日记——3.简单入门模拟 3.1简单模拟

刷题日记 3.1 简单模拟 此类题型根据题目描述进行代码的编写,考察代码能力,刷题记录如下: B1001 B1032 B1016 B1026 B1046 B1008 B1012 B1018 A1042 A1046 A1065 B1010 A1002 A1009 错题记录 B1008 数组元素循环右移问题 一个数组_A_中存有…

Axios设置token到请求头的三种方式

1、为什么要携带token? 用户登录时,后端会返回一个token,并且保存到浏览器的localstorage中,可以根据localstorage中的token判断用户是否登录,登录后才有权限访问相关的页面,所以当发送请求时,都要携带to…

ARM PAC指针认证的侧信道攻击——PACMAN安全漏洞

目录 Q1. PACMAN论文的内容是什么? Q2. Arm处理器是否存在漏洞? Q3. 受Arm合作伙伴架构许可设计的处理器实现是否受到影响? Q4. Cortex-M85受到影响吗? Q5. Cortex-R82受到影响吗? Q6. 指针认证如何保护软件&…

VC++添加菜单学习

新建一个单文档工程; 完成以后看一下有没有出现如下图的 资源视图 的tab;如果没有,在文件列表中找到xxx.rc2文件; 点击 资源视图 的tab,或者双击 .rc2 文件名,就会转到如下图的资源视图;然后展…

AI助力农作物自动采摘,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建作物生产场景下番茄采摘检测计数分析系统

去年十一那会无意间刷到一个视频展示的就是德国机械收割机非常高效自动化地24小时不间断地在超广阔的土地上采摘各种作物,专家设计出来了很多用于采摘不同农作物的大型机械,看着非常震撼,但是我们国内农业的发展还是相对比较滞后的&#xff0…

MySQL 架构和性能优化

重点: 视图,函数,存储过程,触发器,事件( 了解 ) 用户管理,密码管理 grant revoke 权限管理 MySQL 架构( 了解 ) 存储引擎:MyISAM 和 InnoDB …

黑豹程序员-ElementPlus支持树型组件带图标以及icon避坑

效果 vue代码 参数说明&#xff1a;node当前节点&#xff0c;data当前节点后台传入数据。 el-tree自身不支持图标&#xff0c;需要自己去利于实现&#xff0c;并有个坑&#xff0c;和elementui写法不同。 <el-col :span"12"><el-form-item label"绑定…

Unity类银河恶魔城学习记录1-12 PlayerComboAttack源代码 P39

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili PlayerPrimaryAttack.cs using System.Collections; using System.Collect…

k8s学习-Kubernetes的网络

Kubernetes作为编排引擎管理着分布在不同节点上的容器和Pod。Pod、Service、外部组件之间需要⼀种可靠的方找到彼此并进行通信&#xff0c;Kubernetes网络则负责提供这个保障。1.1 Kubernetes网络模型 Container-to-Container的网络 当Pod被调度到某个节点&#xff0c;Pod中的…

贪心算法篇

“靠漫步&#xff0c;将生趣填饱~” 贪心算法简介&#xff1f; 贪心算法&#xff08;Greedy Algorithm&#xff09;&#xff0c;也称为贪婪算法&#xff0c;是一种在解决问题时采取贪心策略的方法。其基本原理是很简单的&#xff1a; “在每个决策点上都选择当下看似最好的选项…

kvm qemu 优化 windows 虚拟机速度

主要优化磁盘 io 和网络 io 都选为 virtio windows 驱动下载 https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.185-2/virtio-win-0.1.185.iso I also had incredibly slow performance with my virtual HDD. The followin…

Open CASCADE学习|分割曲线

1、通过参数进行分割 分别获得曲线的 FirstParameter 和 LastParameter &#xff0c;然后对参数进行分割&#xff0c;获得n个ui&#xff0c;并对每个ui调用D0&#xff08;获得这个点的坐标值&#xff09;或D1&#xff08;获得这个点的坐标值和切向量&#xff09;。这个方法的优…

【算法】排序——蓝桥杯、排个序、图书管理员、错误票据、分数线划定

文章目录 蓝桥杯排个序图书管理员错误票据分数线划定 蓝桥杯 排个序 题目标签&#xff1a;冒泡排序 题目编号&#xff1a;1264 排个序 我们尝试对数组a中的元素进行重新排序&#xff0c;以满足特定的条件。具体来说&#xff0c;它试图将数组a排序为升序&#xff0c;但有一个…

STM32定时器中断

定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时发出中断 定时器就是一个计数器 预分频器&#xff1a;对系统时钟进行分频得到定时器时钟频率 自动重装在值&#xff1a;计数多少个进入中断 基本定时器两个&#xff0c;tim6和7&#xff0c;挂载在apb1 通…

设计模式-行为型模式(上)

行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式&#xff0c;前者采用继承机制来在类间分派行为&…

Electron实战(二):将Node.js和UI能力(app/BrowserWindow/dialog)等注入html

文章目录 设置webPreferences参数安装electron/remotemain进程中初始化html中使用dialog踩坑参考文档 上一篇&#xff1a;Electron实战(一)&#xff1a;环境搭建/Hello World/打包exe 设置webPreferences参数 为了能够在html/js中访问Node.js提供fs等模块&#xff0c;需要在n…

第五讲:函数与类库

第五讲:函数与类库 第五讲:函数与类库函数定义实参变量的作用域返回值代码复用类创建和使用类继承导入类模块与库概念标准库第三方库

MySQL-----约束

目录​​​​​ 约束 一 主键约束 1-1 操作-添加单列主键 1-2 操作-添加多列主键 1-3 修改表结构添加主键 1-4 删除主键约束 二 自增长约束 2-1 指定自增长字段的初始值 2-2 删除自增列 三 非空约束 3-1 创建非空约束 3-2 删除非空约束 四 唯一约束…

26.云原生ArgoCD高级之ApplicationSet

云原生专栏大纲 文章目录 ApplicationSet介绍ApplicationSet 特性ApplicationSet 安装ApplicationSet 工作原理ApplicationSet 生成器列表类型生成器集群生成器基础使用方法Label Selector 指定集群Values 字段传递额外的参数 git生成器git目录生成参数排除目录git文件生成器矩…

NLP入门系列—词嵌入 Word embedding

NLP入门系列—词嵌入 Word embedding 2013年&#xff0c;Word2Vec横空出世&#xff0c;自然语言处理领域各项任务效果均得到极大提升。自从Word2Vec这个神奇的算法出世以后&#xff0c;导致了一波嵌入&#xff08;Embedding&#xff09;热&#xff0c;基于句子、文档表达的wor…