环境:conda python=3.10 下载数据 使用 modelscope ,Hugging Face 需要科学上网。
大模型微调
大型模型的全面微调(Fine-tuning)涉及调整所有层和参数,以适配特定任务。
需要了解几个概念:目前分2个微调方式
- 全量微调:使用完整数据集调整所有参数,算力消耗大但能力改造彻底,适合全量指令微调(如生成对话能力)。
- 高效微调:(Parameter-Efficient Fine-Tuning,PEFT)仅调整部分参数(如LoRA),轻量化且灵活,适合特定领域优化。
PEFT包括LoRA、QLoRA、适配器调整(Adapter Tuning)、前缀调整(Prefix Tuning)、提示调整(Prompt Tuning)、P-Tuning及P-Tuning v2等多种方法。
微调实际上是迁移学习的一个实例,其中预训练的模型(通常在大型通用数据集上训练)被用作特定任务的起点。这种方法使得即使是对于小数据集的任务,也可以实现高效的学习。
LoRA适配器
LoRA适配器(Low-Rank Adaptation)是一种用于微调大型语言模型的技术,旨在通过低秩分解优化模型参数,从而减少显存和计算资源的需求,同时保持模型的性能。 在微调时需要配置这个参数。
可以将 LoRA 想象成给一个大型通用模型添加一小组专门的指令。与重新训练整个模型(既昂贵又耗时)不同,LoRA 允许你高效地为模型添加新功能。
PEFT(Parameter-Efficient Fine-Tuning,参数高效微调)是 Hugging Face 的一个库,用于实现像 LoRA 这样的高效模型微调技术。 pip install peft
微调中的LoRA适配器 配置:
# 2. 添加LoRA适配器
peft_config = LoraConfig(
r=8, # r是LoRA算法中的超参数,它控制了权重矩阵的秩。
lora_alpha=32, # lora_alpha是LoRA算法中的超参数,它控制了权重矩阵的缩放因子。
target_modules=["q_proj", "k_proj", "v_proj"], # target_modules是LoRA算法中的关键参数,它指定了需要做LoRA适配的层。
lora_dropout=0.05, # lora_dropout是LoRA算法中的超参数,它控制了权重矩阵的随机化程度。
bias="none", # bias是LoRA算法中的超参数,它控制了权重矩阵的偏置项。
task_type="CAUSAL_LM" # task_type是LoRA算法中的超参数,它控制了权重矩阵的初始化方式。
)
window完整微调代码
# -*- coding: utf-8 -*-
# file: data_ready.py
# author: laich
"""
数据集准备
# 安装依赖
pip install langchain torch transformers modelscope peft
如果ImportError: cannot import name 'get_metadata_patterns' from 'datasets.data_files' 是 datasets版本过高
pip install datasets==3.3.0
数据集描述:https://www.modelscope.cn/datasets/AI-ModelScope/alpaca-gpt4-data-zh 可以通过git下载到本地。
"""
from modelscope import AutoTokenizer, AutoModelForCausalLM
from peft import LoraConfig, get_peft_model
import torch
# 1. 加载模型和tokenizer
#model_id = "qwen/qwen2-1.5b-instruct"
model_id = r"E:\soft\model\qwen\Qwen\Qwen2___5-0___5B-Instruct"
# AutoTokenizer.from_pretrained用于加载预训练的tokenizer,负责将文本转换为模型可理解的数字形式。
tokenizer = AutoTokenizer.from_pretrained(
pretrained_model_name_or_path=model_id,
#model_id,
trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_id, # model_id,
torch_dtype=torch.bfloat16, # 设置模型精度
device_map="auto", # 设置模型在哪个设备上运行,这里设置为自动选择
trust_remote_code=True # 是否信任远程代码,如果模型是私有的,需要设置为False
)
# 2. 添加LoRA适配器
peft_config = LoraConfig(
r=8, # r是LoRA算法中的超参数,它控制了权重矩阵的秩。
lora_alpha=32, # lora_alpha是LoRA算法中的超参数,它控制了权重矩阵的缩放因子。
target_modules=["q_proj", "k_proj", "v_proj"], # target_modules是LoRA算法中的关键参数,它指定了需要做LoRA适配的层。
lora_dropout=0.05, # lora_dropout是LoRA算法中的超参数,它控制了权重矩阵的随机化程度。
bias="none", # bias是LoRA算法中的超参数,它控制了权重矩阵的偏置项。
task_type="CAUSAL_LM" # task_type是LoRA算法中的超参数,它控制了权重矩阵的初始化方式。
)
model = get_peft_model(model, peft_config)
# 3. 准备训练数据(关键修改部分)
def tokenize_function(examples):
# 构造训练格式:instruction + input -> output
prompts = [
f"Instruction: {inst}\nInput: {inp}\nOutput: {out}"
for inst, inp, out in zip(
examples["instruction"], # instruction
examples["input"], # input
examples["output"]
)
]
return tokenizer(prompts, truncation=True, max_length=512)
# 从ModelScope加载数据
from modelscope.msdatasets import MsDataset
dataset = MsDataset.load(
# 'AI-ModelScope/alpaca-gpt4-data-zh',
r'F:\temp\alpaca-gpt4-data-zh\train.csv',
split='train'
).to_hf_dataset().select(range(4)) # 取1000条示例 很费时间
tokenized_dataset = dataset.map(
tokenize_function, # 上面的tokenize_function 训练数据
batched=True,
remove_columns=dataset.column_names
)
# 4. 定义数据整理器(解决label_names问题)
from transformers import DataCollatorForLanguageModeling
data_collator = DataCollatorForLanguageModeling(
tokenizer=tokenizer,
mlm=False # 因果语言模型用mlm=False
)
# 5. 训练配置
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir="./qwen2-0.5b-finetuned",
per_device_train_batch_size=2, # 4 设置batch_size 每个 GPU/CPU 的训练批次大小
gradient_accumulation_steps=2, # 设置梯度累积
learning_rate=2e-5, # 学习率
num_train_epochs=1, # 设置训练轮数 3
logging_steps=10, # 设置日志记录步数
save_strategy="epoch", # 设置保存策略
fp16=False, # 使用半精度 True 是否启用混合精度训练(需 GPU 支持)
remove_unused_columns=False,
label_names=["input_ids"] # 明确指定标签列
)
trainer = Trainer(
model=model,
args=training_args, # 训练参数
train_dataset=tokenized_dataset, ## 训练数据
data_collator=data_collator # 添加数据整理器
)
# 6. 开始训练
trainer.train()
model.save_pretrained("./qwen2-0.5b-finetuned")
tokenizer.save_pretrained("./qwen2-0.5b-finetuned") # 必须显式保存tokenizer
在window10下 conda 环境 python=3.10 运行结果如下是没有问题。
注意 to_hf_dataset().select(range(2)) 数据集可以小点调试。
关于alpaca-gpt4-data-zh数据集格式截图:
执行程序:
测试方法1:直接使用Transformers 执行测试
# -*- coding: utf-8 -*-
# file: 直接使用Transformers_test.py
# author: laich
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"./qwen2-0.5b-finetuned",
device_map="auto",
trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained("./qwen2-0.5b-finetuned", trust_remote_code=True)
inputs = tokenizer("Instruction: 保持健康的三个提示?\nInput: 用通俗语言\nOutput:", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
结果如下:
adapter_config.json 文件 “base_model_name_or_path”: “E:\soft\model\qwen\Qwen\Qwen2___5-0___5B-Instruct” 这里有对0.5B 模型的引用
测试方法2:通过Ollama测试
转换为Ollama格式
# 创建Modelfile
cat <<EOF > Modelfile
FROM ./qwen2-0.5b-finetuned
TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
"""
PARAMETER stop "<|im_end|>"
PARAMETER stop "<|im_start|>"
EOF
# 创建Ollama模型
ollama create qwen2-0.5b-finetuned -f Modelfile
测试:
# 启动服务
ollama serve &
ollama pull qwen2-0.5b-finetuned
# 交互测试
ollama run qwen2-0.5b-finetuned "Instruction: 写一首关于春天的诗\nInput: 七言绝句\nOutput:"
上述代码如果使用:huggingface 需要更换镜像源。
1. 安装依赖
pip install -U huggingface_hub
2. 设置环境变量
Linux
export HF_ENDPOINT=https://hf-mirror.com
Windows Powershell
$env:HF_ENDPOINT = "https://hf-mirror.com"