llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
引言
随着大规模语言模型(LLMs)如 LLaMA、GPT 等的兴起,许多研究者和开发者希望能够在自己定制的数据集上微调(fine-tuning)这些模型,以适应特定任务。然而,由于这些模型庞大的参数量,传统的微调方法需要大量的计算资源和内存。
LoRA(Low-Rank Adaptation) 是一种高效的微调技术,通过引入低秩矩阵的方式,在不修改原始模型权重的情况下高效地进行模型调整。这使得模型微调更加高效,并且能够在显存较小的设备上进行训练。
在本文中,我们将通过 llama-factory 库进行 SFT(Supervised Fine-Tuning),并结合 LoRA 技术在自定义数据集上进行训练与部署。我们将详细介绍 LoRA 在大模型微调中的应用,展示代码示例,并深入讲解每个步骤的原理。
1. 准备工作:环境设置与库安装
1.1 安装 llama-factory 和必要的依赖
首先,我们需要安装 llama-factory
库,它是一个用于大模型微调的框架。还需要安装相关的依赖库,如 transformers
、torch
和 datasets
。
pip install llama-factory transformers torch datasets accelerate
llama-factory
提供了易于使用的 API 来实现大规模模型的训练与部署,接下来我们将使用该库进行 LoRA 微调。
1.2 配置 GPU 环境
由于大模型微调需要大量的计算资源,建议使用支持 CUDA 的 GPU。如果没有足够的显存,可以使用 mixed precision training 或 LoRA 来节省显存并提高训练速度。
pip install torch torchvision torchaudio
确保安装的 torch
版本支持 GPU 加速,可以通过以下命令确认:
python -c "import torch; print(torch.cuda.is_available())"
如果返回 True
,则表示你的环境已正确配置 GPU。
2. 数据准备:自定义数据集
2.1 数据集格式
在进行微调前,我们需要准备一个自定义数据集。假设你想用一个包含问答对(QA)的数据集进行训练,数据集的格式通常为 CSV、JSON 或其他常见的文本格式。这里我们使用 datasets
库来加载数据集,假设数据集包含 question
和 answer
两个字段。
例如,你的数据集(data.csv
)可能是这样的:
question | answer |
---|---|
What is AI? | AI is the simulation of human intelligence processes by machines. |
What is machine learning? | Machine learning is a subset of AI that involves training algorithms on data. |
2.2 加载数据集
使用 datasets
库加载自定义数据集,并进行简单的预处理。
from datasets import load_dataset
# 加载 CSV 数据集
dataset = load_dataset("csv", data_files={"train": "data.csv"})
# 查看数据集
print(dataset["train"][0])
2.3 数据预处理与Tokenization
在训练前,我们需要将文本数据转换为模型可接受的格式(例如,将文本转换为token ID)。transformers
库提供了许多预训练模型的tokenizer,我们可以根据所选模型的类型进行相应的tokenization。
from transformers import LlamaTokenizer
# 加载 LLaMA 的 tokenizer
tokenizer = LlamaTokenizer.from_pretrained("facebook/llama-7b")
# Tokenize 数据集
def tokenize_function(examples):
return tokenizer(examples["question"], examples["answer"], padding="max_length", truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
# 查看预处理后的数据集
print(tokenized_datasets["train"][0])
3. LoRA 微调:训练与优化
3.1 什么是 LoRA
LoRA(Low-Rank Adaptation)是一种通过引入低秩矩阵来调整预训练模型的技术。与传统的微调方法不同,LoRA 只学习一小部分参数,而不修改原始模型的权重。这使得 LoRA 在节省计算资源和显存的同时,仍然能够有效地进行微调。
3.2 LoRA 微调设置
在 llama-factory
中,我们可以轻松地实现 LoRA 微调。通过设置 LoRA
参数,我们可以指定在特定层中应用低秩矩阵的方式。以下是如何配置 LoRA 微调的代码示例:
from llama_factory import LlamaForCausalLM, LlamaTokenizer
from llama_factory import Trainer, TrainingArguments
# 加载预训练模型和 tokenizer
model = LlamaForCausalLM.from_pretrained("facebook/llama-7b")
tokenizer = LlamaTokenizer.from_pretrained("facebook/llama-7b")
# 设置 LoRA 微调的超参数
lora_config = {
"r": 8, # 低秩矩阵的秩
"alpha": 16, # LoRA的缩放因子
"dropout": 0.1 # Dropout rate
}
# 在模型中启用 LoRA
model.enable_lora(lora_config)
# 设置训练参数
training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
learning_rate=5e-5,
per_device_train_batch_size=4,
num_train_epochs=3,
logging_dir="./logs",
save_strategy="epoch"
)
# 使用 llama-factory 的 Trainer 进行训练
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
tokenizer=tokenizer,
)
trainer.train()
3.3 LoRA 微调的优势
- 显存节省:LoRA 不会修改原始模型的权重,而是通过低秩矩阵在特定层中引入调整,因此显存占用大幅减少。
- 计算效率:LoRA 只需要训练少量的参数,因此训练过程更高效,尤其适用于显存和计算资源有限的设备。
- 性能保证:尽管训练的是较少的参数,但通过 LoRA 微调,大模型仍能实现良好的性能。
4. 部署:将微调模型部署到生产环境
4.1 保存微调后的模型
训练完成后,我们需要将微调后的模型保存到本地或云端,以便后续加载和推理。
# 保存微调后的模型
model.save_pretrained("./fine_tuned_llama_lora")
tokenizer.save_pretrained("./fine_tuned_llama_lora")
4.2 加载和推理
在部署环境中,我们可以轻松加载微调后的模型,并使用它进行推理。
# 加载微调后的模型
model = LlamaForCausalLM.from_pretrained("./fine_tuned_llama_lora")
tokenizer = LlamaTokenizer.from_pretrained("./fine_tuned_llama_lora")
# 进行推理
input_text = "What is deep learning?"
inputs = tokenizer(input_text, return_tensors="pt")
outputs = model.generate(inputs["input_ids"], max_length=50)
# 解码生成的文本
output_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(output_text)
4.3 部署到 Web 服务
如果你希望将微调后的模型部署为一个在线 API,可以使用 FastAPI 或 Flask 等轻量级框架来提供服务。例如,使用 FastAPI
:
from fastapi import FastAPI
from pydantic import BaseModel
# FastAPI 应用
app = FastAPI()
class Query(BaseModel):
text: str
@app.post("/generate")
def generate(query: Query):
inputs = tokenizer(query.text, return_tensors="pt")
outputs = model.generate(inputs["input_ids"], max_length=50)
output_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
return {"generated_text": output_text}
# 运行服务
# uvicorn app:app --reload
通过此方法,你可以将训练好的模型部署为在线服务,供其他应用进行调用。
5. 总结
在本教程中,我们介绍了如何使用 llama-factory 框架进行大模型的微调,特别是结合 LoRA 技术来高效地微调 LLaMA 模型。在自定义数据集上进行 LoRA 微调可以显著降低显存占用,并提高训练效率。我们还展示了如何保存和部署微调后的模型,以便在生产环境中进行推理。
通过掌握 LoRA 微调技术,你可以在有限的计算资源下充分利用大规模预训练模型,同时保持高效的训练与推理性能。如果你有更高的需求,可以进一步调整 LoRA 配置和训练参数,以获得更好的效果。