【Datawhale AI 夏令营】第四期 基于2B源大模型 微调

2024-08-22 10:12

本文主要是介绍【Datawhale AI 夏令营】第四期 基于2B源大模型 微调,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定位:代码复现贴
教程:https://datawhaler.feishu.cn/wiki/PLCHwQ8pai12rEkPzDqcufWKnDd

模型加载

model = AutoModelForCausalLM.from_pretrained(path, device_map="auto", torch_dtype=torch.bfloat16, trust_remote_code=True
)
  • AutoModelForCausalLM.from_pretrained(path):

    • 这是 transformers 库中的一种通用方法,用于从预训练模型路径(path)加载一个因果语言模型(Causal Language Model,CLM)。
    • 因果语言模型是一种序列到序列的模型,通常用于生成任务,例如自动完成或文本生成。
  • device_map="auto":

    • 该参数用于自动选择计算设备(如 GPU 或 CPU)来加载模型。设置为 "auto" 后,模型会根据可用资源自动映射到适当的设备。
  • torch_dtype=torch.bfloat16:

    • 这将模型的计算精度设置为 bfloat16(一种 16 位浮点格式),这通常用于加速计算和减少显存占用,同时保持数值稳定性。
  • trust_remote_code=True:

    • 这个参数表示信任远程代码,允许加载自定义模型结构。如果预训练模型所在的路径中包含自定义的模型定义文件(而不是标准的 transformers 库模型),这个选项允许这些自定义代码被执行。

输出的模型如下:
在这里插入图片描述

模型结构分析

Yuan 在 Transformer 的 Decoder 进行改进,引入了一种新的注意力机制 Localized Filtering-based Attention(LFA)

在这里插入图片描述

  • YuanForCausalLM:

    • 这是一个自定义的因果语言模型类,可能来自于远程代码定义。该模型包含了实际的 YuanModel 和一个 lm_head(语言模型的输出头)。
  • YuanModel:

    • 该模型是 YuanForCausalLM 的核心部分,包含嵌入层、多个解码器层(YuanDecoderLayer)、和一个归一化层。
  • embed_tokens:

    • 这是词嵌入层,用于将输入的标记(tokens)转换为高维向量表示。这里的词表大小为 135040,每个标记被嵌入到一个 2048 维的向量空间中。
  • layers:

    • 这是模型的主体,由 24YuanDecoderLayer 组成,每个解码器层包含自注意力机制、MLP(多层感知器)层、和归一化层。
  • YuanAttention:

    • 这是一个自注意力机制模块,包含了查询(q_proj)、键(k_proj)、值(v_proj)的线性投影,以及一个旋转嵌入(rotary_emb)和本地过滤模块(lf_gate)。
  • YuanMLP:

    • 这是一个 MLP 层,包含了向上和向下的线性投影(up_projdown_proj),以及一个激活函数 SiLU
  • YuanRMSNorm:

    • 这是一个归一化层,使用 RMSNorm(Root Mean Square Layer Normalization)来稳定训练过程。
  • lm_head:

    • 这是模型的输出层,用于将解码器层的输出转换为预测的词概率分布。它是一个线性层,输入维度为 2048,输出维度为 135040(与词表大小一致)。

配置Lora

from peft import LoraConfig, TaskType, get_peft_modelconfig = LoraConfig(task_type=TaskType.CAUSAL_LM, target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],inference_mode=False, # 训练模式r=8, # Lora 秩lora_alpha=32, # Lora alaph,具体作用参见 Lora 原理lora_dropout=0.1# Dropout 比例
)

我们输出config,可以观测到其中的完整配置选项。

LoraConfig(peft_type=<PeftType.LORA: 'LORA'>, auto_mapping=None, base_model_name_or_path=None, revision=None, task_type=<TaskType.CAUSAL_LM: 'CAUSAL_LM'>, inference_mode=False, r=8, target_modules={'k_proj', 'down_proj', 'o_proj', 'up_proj', 'gate_proj', 'v_proj', 'q_proj'},lora_alpha=32, lora_dropout=0.1, fan_in_fan_out=False, bias='none', use_rslora=False, modules_to_save=None, init_lora_weights=True, layers_to_transform=None, layers_pattern=None, rank_pattern={}, alpha_pattern={}, megatron_config=None, megatron_core='megatron.core', loftq_config={}, use_dora=False, # <=== doralayer_replication=None, runtime_config=LoraRuntimeConfig(ephemeral_gpu_offload=False)) 

没想到后面还有一个use_dora的选项,碰巧之前浏览过这块,可以分享一下:

DoRA

首先对预训练模型的权重进行分解,将每个权重矩阵分解为幅度(magnitude)向量和方向(direction)矩阵

在微调过程中,DoRA使用LoRA进行方向性更新,只调整方向部分的参数,而保持幅度部分不变。这种方式可以减少需要调整的参数数量,提高微调的效率。

在这里插入图片描述

后面,我们构建一个 PeftModel并且查看对应的训练参数量占比:

# 构建PeftModel
model = get_peft_model(model, config)
model.print_trainable_parameters()

输出如下:

trainable params: 9,043,968 || all params: 2,097,768,448 || trainable%: 0.4311

总参数量为 2,097,768,448(~ 21亿参数),使用LoRA后只需要微调的参数量为 9,043,968(~904万参数),约占总参数量的0.4311%

但是后面微调还是爆了,所以稍微去除一点不太重要的微调目标模块(个人观点),但是肯定会损耗微调性能的。

config = LoraConfig(task_type=TaskType.CAUSAL_LM, target_modules=["q_proj", "k_proj", "v_proj"],inference_mode=False, # 训练模式r=4, # Lora 秩lora_alpha=32, # Lora alaph,具体作用参见 Lora 原理lora_dropout=0.1# Dropout 比例
)

后续输出微调的参数占比为:

trainable params: 2,359,296 || all params: 2,091,083,776 || trainable%: 0.1128

当然,也降低了批处理大小 (牺牲速度):

# 设置训练参数
args = TrainingArguments(output_dir="./output/Yuan2.0-2B_lora_bf16",per_device_train_batch_size=6, # <===== 12gradient_accumulation_steps=1,logging_steps=1,save_strategy="epoch",num_train_epochs=3,learning_rate=5e-5,save_on_each_node=True,gradient_checkpointing=True,bf16=True
)

微调成功之后效果如下,即便增加了一些其他信息,也能保持相关的抽取。

在这里插入图片描述
(但是多次几次依旧容易翻车,会输出极其符合数据集分布的答案。)

数据集中的组织名和姓名是互斥的,且中国难识别归类到国籍。

在这里插入图片描述

关于更多的微调知识,感觉可以参考这篇知乎大佬的笔记:https://zhuanlan.zhihu.com/p/696837567

这篇关于【Datawhale AI 夏令营】第四期 基于2B源大模型 微调的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095981

相关文章

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Pytorch微调BERT实现命名实体识别

《Pytorch微调BERT实现命名实体识别》命名实体识别(NER)是自然语言处理(NLP)中的一项关键任务,它涉及识别和分类文本中的关键实体,BERT是一种强大的语言表示模型,在各种NLP任务中显著... 目录环境准备加载预训练BERT模型准备数据集标记与对齐微调 BERT最后总结环境准备在继续之前,确

Spring AI ectorStore的使用流程

《SpringAIectorStore的使用流程》SpringAI中的VectorStore是一种用于存储和检索高维向量数据的数据库或存储解决方案,它在AI应用中发挥着至关重要的作用,本文给大家介... 目录一、VectorStore的基本概念二、VectorStore的核心接口三、VectorStore的

Spring AI集成DeepSeek三步搞定Java智能应用的详细过程

《SpringAI集成DeepSeek三步搞定Java智能应用的详细过程》本文介绍了如何使用SpringAI集成DeepSeek,一个国内顶尖的多模态大模型,SpringAI提供了一套统一的接口,简... 目录DeepSeek 介绍Spring AI 是什么?Spring AI 的主要功能包括1、环境准备2

Spring AI集成DeepSeek实现流式输出的操作方法

《SpringAI集成DeepSeek实现流式输出的操作方法》本文介绍了如何在SpringBoot中使用Sse(Server-SentEvents)技术实现流式输出,后端使用SpringMVC中的S... 目录一、后端代码二、前端代码三、运行项目小天有话说题外话参考资料前面一篇文章我们实现了《Spring

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2