MindNLP模型微调超级笔记

乱七八糟的学习参考

已完成的bloom模型微调

pull链接这里面只有训练的部分结果,然后讲的是实现了bloom-3b在databricks-dolly-15k数据集上面的lora微调,不知道这个pytorch的训练过程是从哪来的,然后发现lora微调是一种微调方法,然后这里能够找到他fork的仓库,在mindNLP仓库是看不到改动的,需要去他提交pullrequst的fork的仓库,然后在这里点击可以到他fork的仓库fork的仓库,同时可以看到这里fork后的仓库重新创建的分支叫做intern,然后查看commit改冲在哪里,找到发现在这里mindnlp/llm/finetune/bloom/bloom-3b-qlora,也就是说任务是微调的话就把代码放在llm/finetune这个目录下,然后对比官方的mindspore的仓库发现确实这里pull requst之后就没有合进去mindnlp/llm/finetune/bloom

。总结就是这是提交代码的方法。

然后这个mindNLP做的是什么?这里面有模型和训练好的参数,clone到本地之后可以用,其中的开源的模型,是华为自己开发的,然后提供了lora和peft微调的工具,之后我们就可以基于这个mindNLP进行操作,和他功能类似的还有huggingface 的transform库

  • LoRA 是一种通过低秩分解实现参数高效微调的技术。
  • PEFT 是一类参数高效微调技术的统称,包括 LoRA、Adapter、Prefix Tuning 等。
  • 在实际应用中,LoRA 是最常用的 PEFT 方法之一,适合大模型的微调任务。如果你需要快速实现参数高效微调,可以使用 Hugging Face 的 peft 库,结合 LoRA 或其他 PEFT 方法。

如何进行模型微调

分割网络MaskRCNN微调,这个好

MobileNetV2微调

从头开始训练网络,需要消耗大量的时间与计算能力,模型容易陷入局部极小值和过拟合。

大部分任务都会选择预训练模型,在其上做微调(也称为Fine Tune)。预训练模型选择的常见的OpenImage、ImageNet、VOC、COCO等公开大型数据集

不同数据集和任务中特征提取层(卷积层)分布趋于一致,但是特征向量的组合(全连接层)不相同,分类数量(全连接层output_size)通常也不一致。

  • 在微调时,只加载与训练特征提取层参数,不加载与训练全连接层参数;
  • 在微调训练模式下,需要将预训练模型加载入backbone_net子网络,并且冻结backbone_net中的参数, param.requires_grad = False,不参与训练。
  • 在微调与初始训练时,加载与训练 特征提取层参数与全连接层参数。

根据微调的参数占比分为:

  1. 全量微调(Full Fine-Tuning)

全量微调利用特定任务数据调整预训练模型的所有参数,以充分适应新任务。它依赖大规模计算资源,但能有效利用预训练模型的通用特征。

  1. 参数高效微调(Parameter-Efficient Fine-Tuning, PEFT)

PEFT旨在通过最小化微调参数数量和计算复杂度,实现高效的迁移学习。它仅更新模型中的部分参数,显著降低训练时间和成本,适用于计算资源有限的情况。PEFT技术包括Prefix Tuning、Prompt Tuning、Adapter Tuning等多种方法,可根据任务和模型需求灵活选择。

Prefix Tuning

    方法:在输入前添加可学习的virtual tokens作为Prefix。

    特点:仅更新Prefix参数,Transformer其他部分固定。

    优点:减少需要更新的参数数量,提高训练效率。

Prompt Tuning

    方法:在输入层加入prompt tokens。

    特点:简化版的Prefix Tuning,无需MLP调整。

    优点:随着模型规模增大,效果接近full fine-tuning。

P-Tuning

    方法:将Prompt转换为可学习的Embedding层,并用MLP+LSTM处理。

    特点:解决Prompt构造对下游任务效果的影响。

    优点:提供更大的灵活性和更强的表示能力。

P-Tuning v2

    方法:在多层加入Prompt tokens。

    特点:增加可学习参数数量,对模型预测产生更直接影响。

    优点:在不同任务和模型规模上实现更好的性能。

Adapter Tuning

    方法:设计Adapter结构并嵌入Transformer中。

    特点:仅对新增的Adapter结构进行微调,原模型参数固定。

    优点:保持高效性的同时引入少量额外参数。

LoRA

    方法:在矩阵相乘模块中引入低秩矩阵来模拟full fine-tuning。

    特点:更新语言模型中的关键低秩维度。

    优点:实现高效的参数调整,降低计算复杂度。

因果语言模型(Causal Language Model, CLM)

概念

因果语言模型是一种生成式模型,用于预测序列中下一个词(或 token)的概率分布。它的特点是:

  • 自回归(Autoregressive):模型根据前面的词生成后面的词,每次生成一个词。
  • 单向上下文:模型只能利用当前词之前的上下文信息,而不能利用后面的信息。

典型应用

  • 文本生成:如故事生成、对话生成、代码生成等。
  • 语言建模:计算一段文本的概率,或生成符合语言规律的文本。

示例

  • 给定输入序列 ["I", "love", "to"],模型会预测下一个词可能是 "eat""play" 等。

常见模型

  • GPT 系列(如 GPT-2、GPT-3):OpenAI 开发的因果语言模型。
  • Bloom:BigScience 开发的多语言因果语言模型。
  • LLaMA:Meta 开发的高效因果语言模型。

分词器(Tokenizer)

概念

分词器是将原始文本转换为模型可以理解的输入格式的工具。它的主要功能包括:

  • 分词(Tokenization):将文本分割成词或子词(subword)。
  • 编码(Encoding):将分词后的结果转换为模型输入的数字 ID(input_ids)。
  • 解码(Decoding):将模型输出的数字 ID 转换回文本。

分词方式

  1. 词级别分词

    • 将文本按空格或标点符号分割成词。
    • 例如:"I love NLP"["I", "love", "NLP"]
  2. 子词级别分词

    • 将词进一步分割为更小的子词单元,以解决未登录词(OOV)问题。
    • 例如:"unhappiness"["un", "happiness"]
  3. 字符级别分词

    • 将文本分割为单个字符。
    • 例如:"NLP"["N", "L", "P"]

常见分词器

  • Byte-Pair Encoding (BPE):如 GPT 系列使用的分词器。
  • WordPiece:如 BERT 使用的分词器。
  • SentencePiece:如 Bloom 和 LLaMA 使用的分词器。

一个模型对应一个分词器?

模型和分词器的匹配:一个模型通常对应一个特定的分词器,分词器的词汇表和分词方式必须与模型一致。是的,一个模型通常对应一个特定的分词器。原因如下:

(1)分词器和模型的匹配

  • 分词器的分词方式和词汇表(vocabulary)必须与模型训练时使用的分词器一致。
  • 如果分词器不匹配,模型可能无法正确理解输入,导致性能下降。

(2)词汇表的一致性

  • 模型的输入是分词器生成的 input_ids,这些 ID 是基于分词器的词汇表映射的。
  • 如果分词器的词汇表与模型不匹配,input_ids 的映射会出错。

(3)特殊 token 的处理

  • 分词器会添加一些特殊 token(如 [CLS][SEP][PAD]),这些 token 在模型中有特定的含义。
  • 如果分词器不匹配,特殊 token 的处理可能会出错。

示例

  • Bloom 模型:必须使用 BloomTokenizerFastBloomTokenizer
  • GPT 模型:必须使用 GPT2TokenizerGPT2TokenizerFast
  • BERT 模型:必须使用 BertTokenizerBertTokenizerFast

如何加载模型和分词器?

以 Hugging Face 的 transformers 库为例:

加载模型和分词器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from transformers import AutoModelForCausalLM, AutoTokenizer

# 加载模型和分词器
model_name = "bigscience/bloom-560m"
model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)


tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
tokenizer("Using a Transformer network is simple")

# 输出
'''
{'input_ids': [101, 7993, 170, 11303, 1200, 2443, 1110, 3014, 102],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}
'''

使用分词器

1
2
3
4
5
6
7
8
9
10
# 分词和编码
text = "I love NLP"
inputs = tokenizer(text, return_tensors="pt") # 返回 PyTorch 张量
print(inputs)
# 输出:{'input_ids': tensor([[ 100, 123, 4567]]), 'attention_mask': tensor([[1, 1, 1]])}

# 解码
output_ids = model.generate(inputs["input_ids"])
output_text = tokenizer.decode(output_ids[0], skip_special_tokens=True)
print(output_text)

开始实践

支持微调的模型和数据集大型语言模型通过微调可以适应不同任务,而中文微调数据集为模型在中文领域的应用提供了关键资源。

图片

常用中文微调数据集可能包括:

中文问答数据集(如CMRC 2018、DRCD等),用于训练问答系统。

中文情感分析数据集(如ChnSentiCorp、Fudan News等),用于训练情感分类模型。

中文文本相似度数据集(如LCQMC、BQ Corpus等),用于训练句子对匹配和相似度判断任务。

中文摘要生成数据集(如LCSTS、NLPCC等),用于训练文本摘要生成模型。

中文对话数据集(如LCCC、ECDT等),用于训练聊天机器人或对话系统。

这里有一个huggingface的文档,特别好

mindNLP中有的数据集

这个huggingface支持各种任务

(1) 序列分类任务(Sequence Classification)

  • 特点:将文本分类到预定义的类别(如情感分类、垃圾邮件检测),输出层仅需添加一个分类头,结构简单。
  • 优势
    • 计算量小:仅需调整分类头参数,训练速度快。
    • 数据要求低:通常需要较少的标注数据即可达到较好效果。
    • 显存占用低:输入文本可截断或填充至固定长度,资源消耗可控911。
  • 推荐场景:入门级任务,适合快速验证模型微调流程。

(2) 条件生成任务(Conditional Generation)

  • 特点:生成与输入相关的文本(如摘要、翻译),需处理长序列依赖。
  • 挑战
    • 自回归生成:逐词生成需多次前向计算,训练和推理速度较慢。
    • 显存占用高:长文本输入需更大的上下文窗口,内存消耗显著增加38。
  • 适用场景:需生成连贯长文本的任务(如文档摘要)。

(3) 问题回答任务(Question Answering)

  • 特点:从长文本中定位答案,需同时处理问题和上下文。
  • 复杂度
    • 长文本处理:BigBird的稀疏注意力机制适合长文本,但训练需处理问答对间的复杂交互,计算量较大810。
    • 数据标注要求高:需精确的答案位置标注(如SQuAD数据集)。

(4) CausalLM任务(因果语言建模)

  • 特点:预测下一个词(自回归生成),适用于文本续写或对话生成。
  • 缺点
    • 训练效率低:需处理完整序列的生成,显存和计算资源消耗高。
    • 长文本挑战:需结合BigBird的稀疏注意力优化,但整体速度仍低于分类任务810。

2. 任务推荐与数据集选择

推荐任务:序列分类任务

  • 简单性:仅需调整分类头,无需复杂生成逻辑。
  • 速度优势:训练速度快,显存占用低(例如,使用LoRA微调时显存可控制在42G内)9。
  • 数据集推荐
    • IMDb影评分类:二分类任务(正面/负面情感),适合验证模型基础能力11。
    • SMSSpamCollection:垃圾短信分类(二分类),数据量小(747条/类),适合快速实验11。
    • GLUE基准的子任务(如CoLA、MRPC):标准化评测集,适合对比模型性能12。

其他任务备选数据集

  • 条件生成:CNN/Daily Mail(长文本摘要任务)3。
  • 问题回答:SQuAD(斯坦福问答数据集)8。
  • CausalLM:WikiText-103(长文本语言建模)10。

模型微调总结

【开源实习】peft_ia3_seq2seq模型微调

这个实习的任务是用peft库中的ia3方法,对seq2seq进行微调。代码放在mindnlp/llm/peft]/ia3/seq_2_seq

然后写了两个ipynb,一个是pytoch的利用transformers库,并且规定使用GPU,另一个使用mindspore,没指定设备,然后写了一个https://hf-mirror.com用于获得数据集。最后有一个md写了mindNLP的准确率没有pytorch的高

IA3(论文:Few-Shot Parameter-Efficient Fine-Tuning is Better and Cheaper than In-Context Learning),通过学习向量来对激活层加权进行缩放,从而获得更强的性能,同时仅引入相对少量的新参数,如下图左边所示,它的诞生背景是为了改进 LoRA。

【开源实习】peft_lora_seq2seq模型微调

这个这里没有写位置,但是找到在mindnlp/llm/peft/dora/,感觉可抄

原来任务底下提供了huggingface的微调的文件参考,使用transformers和对应的微调方法进行测试的

【开源实习】dna_lm模型微调

利用 PEFT 文库中的参数高效微调技术 (PEFT) 来微调 DNA 语言模型 (DNA-LM)。微调后的 DNA-LM 将用于解决核苷酸基准数据集中的任务。

【开源实习】dora_finetuning模型微调

Lora想必大家都熟悉,本质上就是把大矩阵拆成两个小矩阵的乘法.而DoRA(Weight-Decomposed Low-Rank Adaptation)的主要思想是将预训练权重分解为幅度(magnitude)和方向(direction),并利用LoRA来微调方向矩阵

【开源实习】image_classification_timm_peft_lora模型微调

使用 PEFT 的 🤗 LoRA 来微调图像分类模型,只需使用模型原始可训练参数的 0.77%。LoRA 将低秩的 “update matrices” 添加到底层模型的某些块(在本例中为 attention blocks),并且仅在微调期间训练这些矩阵。在推理过程中,这些更新矩阵将与原始模型参数合并。

【开源实习】multilayer_perceptron_lora模型微调

展示了如何将 LoRA 应用于简单的多层感知器,并使用它来训练模型以执行分类任务。PEFT 支持微调任何类型的模型,只要支持的层是支持的。例如,该模型不必是 transformers 模型。

【开源实习】sequence_classification/fourier ft模型微调

使用 FourierFT 在序列分类任务上微调 Roberta (base)。

以上是上一期的,主要针对PEFT库和对应的huggingface例程进行测试PEFT

以下是上一期的,主要针对新的模型进行测试微调

【开源实习】bert模型微调

commit记录,但是这里看不到ipynb

看这里吧

修改在llm/finetune/bert/bert_for_classification.py

给出这样的结果Results

my results on mindspore

Model Variant Accuracy on Dev Set
BERT (no finetuning) 81.25%
BERT (with finetuning) 90.07%

requirements:

  • Ascend 910B
  • Python 3.9
  • MindSpore 2.3.1
  • MindNLP 0.4.1

my results on pytorch

Model Variant Accuracy on Dev Set
BERT (no finetuning) 81.03%
BERT (with finetuning) 89.84%

requirements:

  • GPU 1080ti
  • CUDA 11.1.1
  • Python 3.9
  • Pytorch 1.10.2
  • Transformers 4.45.2

Original results from the repo

Model Variant Accuracy on Dev Set
BERT (no finetuning) 82.59%
BERT (with finetuning) 88.29%

requirements:

  • Python 3.6
  • Pytorch 1.2.0
  • Transformers 2.0.0

【开源实习】blip模型微调

看这里吧

这个没有写他的transformers的结果来源,而是只有一个mindspore的ipynb,应该还需要一个pytorch的,这里应该是他找到了但是没有贴上来,毕竟把一个pytorch的ipynb放在mindspore的仓库里有点奇怪

后来去问他

github的pytorch参考在这,是他自己艘的,然后改动到其他数据集

如果没有这样的pytorch微调的,就自己挑一个数据集用mindspore和pytorchMindspore分别进行训练和评估

my results on mindspore

20 epochs:

  • train loss: 0.0132
  • val loss: 0.0126

requirements:

  • Ascend 910B
  • Python 3.9
  • MindSpore 2.3.1
  • MindNLP 0.4.1

my results on pytorch

10 epochs:

  • train loss: 0.0135
  • val loss: 0.0125

requirements:

  • GPU 1080ti
  • CUDA 11.1.1
  • Python 3.9
  • Pytorch 1.10.2
  • Transformers 4.45.2

Original results from the repo

20 epochs:

  • train loss: 1.3579
  • val loss: 1.3584

【开源实习】bloom模型微调

实现了bloom-3b在databricks-dolly-15k数据集上面的lora微调,这个文件也很不清晰啊,pytorch的不知道在那