### **【概述】**
Qwen1.5大模型微调、基于PEFT框架LoRA微调,在数据集[HC3-Chinese](https://modelscope.cn/datasets/simpleai/HC3-Chinese/dataPeview)上实现文本分类。
运行环境:[Kaggle - Notebook](https://www.kaggle.com/code/xinglingchen/qwen-fine-tune)
### **【数据处理】**
#### **1.【数据下载】**
```python
import modelscope
from modelscope.msdatasets import MsDataset
#【下载数据集】
HC3=MsDataset.load('simpleai/HC3-Chinese',subset_name='baike',split='train') #调用HC3数据集
dataset=HC3.to_hf_dataset() #将MsDataset转换成huggingface dataset格式,方便后续处理
print("【数据集下载完成】")
print(dataset)
print(dataset[0])
```
输出信息:
```text
Dataset({
features: ['id', 'question', 'human_answers', 'chatgpt_answers'],
num_rows: 4617
})
{
'id': '0',
'question': '我有一个计算机相关的问题...',
'human_answers': ['硬盘安装就是...'],
'chatgpt_answers': ['硬盘安装是指...']
}
```
#### **2.【格式调整】**
将数据调整成形如`{label: 0/1, text: '...'}` 的格式,在 $9234$ 组数据中随机选 $5000$ 个,按照 $8:1:1$ 的比例划分训练集、验证集、测试集。
```python
from datasets import Dataset
#【调整数据集格式】
def data_init(dataset):
ds=[]
cnt=dataset.num_rows
for i in range(cnt):
example=dataset[i]
ds.append({"label":0,"text":example["human_answers"][0]})
ds.append({"label":1,"text":example["chatgpt_answers"][0]})
return Dataset.from_list(ds)
dataset=data_init(dataset) # 调整数据集内容
print(dataset)
dataset=dataset.shuffle(seed=233).select(range(5000)) #随机选一部分
#数据集划分 train:val:test=8:1:1
data_=dataset.train_test_split(train_size=0.8,seed=233) #数据集划分
data_train=data_["train"]
data__=data_["test"].train_test_split(train_size=0.5,seed=233)
data_val=data__["train"]
data_test=data__["test"]
print("【data_train】",data_train)
print("【data_val】",data_val)
print("【data_test】",data_test)
```
输出信息:
```text
Dataset({
features: ['label', 'text'],
num_rows: 9234
})
【data_train】 Dataset({
features: ['label', 'text'],
num_rows: 4000
})
【data_val】 Dataset({
features: ['label', 'text'],
num_rows: 500
})
【data_test】 Dataset({
features: ['label', 'text'],
num_rows: 500
})
```
### **【模型】**
#### **1.【分词器】**
文本信息在输入模型前,需要先用tokenizer分词。使用Dataset.map()函数快速处理。
```python
from transformers import AutoTokenizer,AutoModelForSequenceClassification,TrainingArguments,Trainer,DataCollatorWithPadding
#【加载分词器】
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen1.5-0.5B")
tokenizer.pad_token_id = tokenizer.eos_token_id #Qwen特性,需要指定一下pad_token_id
def tokenize_function(examples):
return tokenizer(examples["text"],padding="max_length",truncation=True,max_length=512)
token_train=data_train.map(tokenize_function, batched=True)
token_val=data_val.map(tokenize_function, batched=True)
train_dataset = token_train
eval_dataset = token_val
```
#### **2.【加载模型】**
用`AutoModelForSequenceClassification`载入模型进行文本分类任务。`num_labels`为要分类的标签数量。
`from_pretrained()` 支持的模型在[这里](https://huggingface.co/models?sort=trending)可以找到。
> 报错 `KeyError: ‘qwen2’` 应该是 `transformers` 版本太旧。
```python
#【加载模型】
id2label = {0: "human", 1: "chatgpt"}
label2id = {"human": 0, "chatgpt": 1}
#使用Qwen1.5模型
model = AutoModelForSequenceClassification.from_pretrained("Qwen/Qwen1.5-0.5B",num_labels=2,id2label=id2label,label2id=label2id)
model.config.pad_token_id=model.config.eos_token_id #这里也要指定一下pad_token_id,不然训练时会报错 "ValueError: Cannot handle batch sizes > 1 if no padding token is defined."
print("【model】\n",model)
print("【model.config】\n",model.config)
```
输出信息可以看到模型结构,以及 `pad_token_id`(如果没有指定的话可以看到 `config` 里没有这个变量)
```text
【model】
Qwen2ForSequenceClassification(
(model): Qwen2Model(
(embed_tokens): Embedding(151936, 1024)
(layers): ModuleList(
(0-23): 24 x Qwen2DecoderLayer(
(self_attn): Qwen2SdpaAttention(
(q_proj): Linear(in_features=1024, out_features=1024, bias=True)
(k_proj): Linear(in_features=1024, out_features=1024, bias=True)
(v_proj): Linear(in_features=1024, out_features=1024, bias=True)
(o_proj): Linear(in_features=1024, out_features=1024, bias=False)
(rotary_emb): Qwen2RotaryEmbedding()
)
(mlp): Qwen2MLP(
(gate_proj): Linear(in_features=1024, out_features=2816, bias=False)
(up_proj): Linear(in_features=1024, out_features=2816, bias=False)
(down_proj): Linear(in_features=2816, out_features=1024, bias=False)
(act_fn): SiLU()
)
(input_layernorm): Qwen2RMSNorm()
(post_attention_layernorm): Qwen2RMSNorm()
)
)
(norm): Qwen2RMSNorm()
)
(score): Linear(in_features=1024, out_features=2, bias=False)
)
【model.config】
Qwen2Config {
"_name_or_path": "Qwen/Qwen1.5-0.5B",
"architectures": [
"Qwen2ForCausalLM"
],
"attention_dropout": 0.0,
"bos_token_id": 151643,
"eos_token_id": 151643,
"hidden_act": "silu",
"hidden_size": 1024,
"id2label": {
"0": "human",
"1": "chatgpt"
},
"initializer_range": 0.02,
"intermediate_size": 2816,
"label2id": {
"chatgpt": 1,
"human": 0
},
"max_position_embeddings": 32768,
"max_window_layers": 21,
"model_type": "qwen2",
"num_attention_heads": 16,
"num_hidden_layers": 24,
"num_key_value_heads": 16,
"pad_token_id": 151643,
"rms_norm_eps": 1e-06,
"rope_theta": 1000000.0,
"sliding_window": 32768,
"tie_word_embeddings": true,
"torch_dtype": "bfloat16",
"transformers_version": "4.41.2",
"use_cache": true,
"use_sliding_window": false,
"vocab_size": 151936
}
```
### **【训练】**
#### **1.【训练参数】**
```python
#【训练参数】
from datasets import load_metric
import numpy as np
training_args = TrainingArguments(
output_dir="pt_save_pretrained",
evaluation_strategy="epoch", #每跑完一个epoch输出一下测试信息
num_train_epochs=2,
per_device_train_batch_size=4, # 一共要跑 len(dataset)/batch_size * epoch 个step
# [模型=Qwen1.5-0.5B, batch_size=4]:完全微调显存13.3GB,LoRA微调显存8.7GB
save_strategy="no", #关闭自动保存模型(Kaggle上磁盘空间不太够)
)
metric=load_metric('accuracy') #评估指标
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictions=predictions, references=labels)
def get_trainer(model):
return Trainer(
model=model,
args=training_args,
tokenizer=tokenizer,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
compute_metrics=compute_metrics,
data_collator=DataCollatorWithPadding(tokenizer=tokenizer, padding=True,return_tensors="pt"), #给数据添加padding弄成batch
)
```
#### **2.【完全微调】**
直接开始训练:
```python
#【完全微调】
print("【开始训练】")
trainer=get_trainer(model)
trainer.train()
#tokenizer.save_pretrained("./full_model_tokenizer")
#model.save_pretrained("./full_model")
#Kaggle注意:
每次训练之后restart以释放显存!
factory也reset一下,不然磁盘空间会爆!
```
训练效果:
![](./src/train_full.PNG)
#### **3.【LoRA微调】**
添加 LoRA 参数,调用peft框架:
```python
#【PEFT-LoRA微调】
from peft import LoraConfig, get_peft_model
peft_config = LoraConfig(
task_type="SEQ_CLS", #任务类型:分�
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Qwen1.5大模型微调、基于PEFT框架LoRA微调,在数据集HC3-Chinese上实现文本分类_Qwen-fine-tune.zip (8个子文件)
Qwen-fine-tune-main
doc
深度学习导论实验四.pdf 105KB
LoRA Low-Rank Adaptation of Large Language Models.pdf 1.53MB
src
train_full.PNG 5KB
train_peft.PNG 7KB
report-Qwen.pdf 351KB
qwen_fine_tune.ipynb 54KB
qwen_chat.py 6KB
README.md 13KB
共 8 条
- 1
资源评论
2401_87496566
- 粉丝: 988
- 资源: 5143
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功