将 huggingface 仓库的 FlagAlpha/Llama2-Chinese-7b-Chat 模型下载到本地并做训练
一、下载模型到本地并训练
要将 Hugging Face 仓库中的 FlagAlpha/Llama2-Chinese-7b-Chat
模型下载到本地,并从本地路径加载和训练该模型,可以按照以下步骤进行操作:
1. 环境准备
安装必要的软件包
首先,确保你已经安装了所需的 Python 包,包括 transformers
、accelerate
、datasets
和 huggingface_hub
。你可以使用 pip
来安装这些包:
pip install transformers accelerate datasets huggingface_hub
确保硬件要求
Llama2-7B 模型非常大,训练和推理需要强大的硬件支持,通常需要多块高性能 GPU(例如 NVIDIA A100)。确保你的计算环境满足以下要求:
- GPU:推荐至少一块具有 40GB 显存的 GPU。
- 内存:至少 64GB 的系统内存。
- 存储:至少 100GB 的可用磁盘空间。
2. 获取 Hugging Face 访问权限
注册并获取访问令牌
- 前往 Hugging Face 网站并注册一个账户(如果尚未注册)。
- 登录后,进入账户设置,找到 Access Tokens 页面。
- 生成一个新的访问令牌,并复制保存该令牌。
登录 Hugging Face
在终端中运行以下命令并输入你的访问令牌以登录 Hugging Face:
huggingface-cli login
3. 下载模型到本地
创建本地存储目录
选择一个目录来存储下载的模型,例如 ./models/Llama2-Chinese-7b-Chat
:
mkdir -p ./models/Llama2-Chinese-7b-Chat
使用 transformers
下载模型
以下是一个 Python 脚本示例,用于下载模型和分词器到本地目录:
# pip install --upgrade transformers bitsandbytes accelerate peft
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import os
# 定义模型名称和本地路径
model_name = "FlagAlpha/Llama2-Chinese-7b-Chat"
local_model_path = "./models/Llama2-Chinese-7b-Chat"
# 创建本地存储目录(如果不存在)
os.makedirs(local_model_path, exist_ok=True)
# 配置 BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_8bit=True, # 启用 8-bit 量化
llm_int8_threshold=6.0, # 可选参数,根据需要调整
llm_int8_has_fp16_weight=False # 可选参数,根据需要调整
)
# 下载并加载分词器,确保传递 trust_remote_code=True 以支持自定义代码
print("正在下载分词器...")
tokenizer = AutoTokenizer.from_pretrained(
model_name,
trust_remote_code=True
)
# 下载并加载模型,确保传递 trust_remote_code=True 以支持自定义代码
print("正在下载模型...")
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True # 如果模型使用了自定义代码
)
# 显式保存模型和分词器到本地路径
print("正在保存模型和分词器到本地路径...")
model.save_pretrained(local_model_path)
tokenizer.save_pretrained(local_model_path)
print(f"模型和分词器已成功保存到 {local_model_path}")
将上述脚本保存为 download_and_save_model.py
,然后在终端中运行:
预期输出应包含:
- config.json:模型配置文件。
- pytorch_model.bin 或 model.safetensors:模型权重文件。
- 分词器相关文件,如 tokenizer.json、vocab.txt、merges.txt 等。
- 如果所有这些文件都存在,您可以继续加载模型和分词器。
注意:
device_map="auto"
会自动将模型分配到可用的 GPU 上。如果只有 CPU 可用,可以设置为device_map=None
并使用torch_dtype=torch.float32
。load_in_8bit=True
需要安装bitsandbytes
库,可以通过pip install bitsandbytes
安装。如果不支持,可以去掉此参数,但会占用更多显存。
手动下载(可选)
如果你希望手动下载模型文件,可以使用 huggingface_hub
:
from huggingface_hub import hf_hub_download
model_name = "FlagAlpha/Llama2-Chinese-7b-Chat"
local_model_path = "./models/Llama2-Chinese-7b-Chat"
# 下载模型文件
model_files = hf_hub_download(repo_id=model_name, repo_type="model", local_dir=local_model_path, allow_patterns=["*.bin", "*.json"])
# 下载分词器文件
tokenizer_files = hf_hub_download(repo_id=model_name, repo_type="model", local_dir=local_model_path, allow_patterns=["*.json", "*.tokenizer.json", "*.vocab"])
4. 从本地加载模型
一旦模型和分词器下载到本地目录,可以通过指定本地路径来加载它们:
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, GenerationConfig
import torch
# 定义本地模型路径
MODEL_PATH = "./models/Llama2-Chinese-7b-Chat"
# 配置 BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_8bit=True, # 启用 8-bit 量化
llm_int8_threshold=6.0,
llm_int8_has_fp16_weight=False
)
# 从本地路径加载分词器
print("正在加载分词器...")
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
trust_remote_code=True,
local_files_only=True # 强制仅从本地加载
)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "left"
# 从本地路径加载模型
print("正在加载模型...")
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH,
device_map="auto",
quantization_config=bnb_config,
trust_remote_code=True, # 如果模型使用了自定义代码
local_files_only=True # 强制仅从本地加载
)
# 配置生成参数
generation_config = GenerationConfig(
do_sample=True, # 启用采样
temperature=0.9,
top_p=0.6,
max_new_tokens=50 # 根据需要调整
)
# 示例文本生成
prompt = "你好,Llama2!"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
# 生成文本
with torch.no_grad():
outputs = model.generate(**inputs, generation_config=generation_config)
# 解码并打印生成的文本
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
5. 准备训练数据
使用 datasets
库加载和准备你的训练数据。例如,假设你有一个自定义数据集:
from datasets import load_dataset
# 加载自定义数据集
# 这里假设你有一个名为 "my_dataset" 的数据集
dataset = load_dataset("path_to_your_dataset")
# 预处理数据(例如,分词)
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
注意:确保你的数据集格式与模型输入要求一致。
6. 配置训练参数
使用 transformers
的 TrainingArguments
和 Trainer
进行训练。以下是一个示例:
from transformers import Trainer, TrainingArguments
training_args = TrainingArguments(
output_dir="./results", # 输出目录
per_device_train_batch_size=2, # 训练批次大小
per_device_eval_batch_size=2, # 验证批次大小
num_train_epochs=3, # 训练轮数
save_steps=10_000, # 每 10,000 步保存一次模型
save_total_limit=2, # 最多保存 2 个检查点
fp16=True, # 使用半精度训练
logging_steps=500, # 日志记录间隔
evaluation_strategy="steps", # 评估策略
eval_steps=1_000, # 评估间隔
load_best_model_at_end=True, # 在训练结束时加载最佳模型
metric_for_best_model="accuracy", # 评估指标
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
)
注意:
- 根据你的硬件资源调整
per_device_train_batch_size
和per_device_eval_batch_size
。 - 确保你的数据集包含
train
和validation
分支,或者根据需要调整。
7. 开始训练
运行以下命令启动训练:
trainer.train()
8. 保存训练后的模型
训练完成后,可以将模型和分词器保存到指定目录:
trainer.save_model("./trained_model")
tokenizer.save_pretrained("./trained_model")
完整示例代码
以下是一个完整的 Python 脚本,整合了上述步骤:
from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments
from datasets import load_dataset
import torch
# 定义模型名称和本地路径
model_name = "FlagAlpha/Llama2-Chinese-7b-Chat"
local_model_path = "./models/Llama2-Chinese-7b-Chat"
# 下载并缓存模型和分词器
tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=local_model_path)
model = AutoModelForCausalLM.from_pretrained(
model_name,
cache_dir=local_model_path,
device_map="auto",
load_in_8bit=True # 如果显存不足,可以启用 8-bit 精度
)
# 如果已经下载到本地,使用本地路径加载
# tokenizer = AutoTokenizer.from_pretrained(local_model_path)
# model = AutoModelForCausalLM.from_pretrained(
# local_model_path,
# device_map="auto",
# load_in_8bit=True
# )
# 加载训练数据
dataset = load_dataset("path_to_your_dataset")
# 定义预处理函数
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True)
# 预处理数据
tokenized_datasets = dataset.map(tokenize_function, batched=True)
# 定义训练参数
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
num_train_epochs=3,
save_steps=10_000,
save_total_limit=2,
fp16=True,
logging_steps=500,
evaluation_strategy="steps",
eval_steps=1_000,
load_best_model_at_end=True,
metric_for_best_model="accuracy",
)
# 初始化 Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
)
# 开始训练
trainer.train()
# 保存模型
trainer.save_model("./trained_model")
tokenizer.save_pretrained("./trained_model")
9. 进一步优化和注意事项
使用 accelerate
优化训练
accelerate
可以帮助你更高效地利用多 GPU 或分布式训练资源。确保在开始训练前配置 accelerate
:
accelerate config
按照提示选择适合你的硬件设置。然后,在训练脚本中使用 accelerate launch
来启动训练:
accelerate launch train_script.py
管理显存
如果在训练过程中遇到显存不足的问题,可以尝试以下方法:
- 减小
per_device_train_batch_size
。 - 使用梯度累积(
gradient_accumulation_steps
)。 - 启用 8-bit 精度(
load_in_8bit=True
)。 - 使用混合精度训练(
fp16=True
)。
监控训练过程
使用 TensorBoard
或其他监控工具来跟踪训练过程中的损失、准确率等指标:
pip install tensorboard
tensorboard --logdir=./results
然后在浏览器中访问 http://localhost:6006
查看训练日志。
保存和加载最佳模型
通过 Trainer
的 load_best_model_at_end=True
参数,可以在训练结束时自动加载表现最好的模型。如果需要手动保存和加载模型,可以使用以下代码:
# 保存最佳模型
trainer.save_model("./best_model")
tokenizer.save_pretrained("./best_model")
# 从最佳模型加载
best_model = AutoModelForCausalLM.from_pretrained("./best_model")
best_tokenizer = AutoTokenizer.from_pretrained("./best_model")
总结
通过以上步骤,你可以将 Hugging Face 上的 FlagAlpha/Llama2-Chinese-7b-Chat
模型下载到本地,并使用 transformers
和 Trainer
进行训练。请确保你的硬件资源充足,并根据实际需求调整训练参数和配置。如果在操作过程中遇到问题,可以参考 Hugging Face 的官方文档或在社区中寻求帮助。
二、通过lora 来减少参数,优化资源不足的问题
在上边的示例中,通过lora 来减少参数,优化资源不足的问题,请改进上边的训练方法。
好的,使用 LoRA(Low-Rank Adaptation)可以显著减少训练过程中需要调整的参数数量,从而优化资源不足的问题。以下是在之前示例的基础上,集成 LoRA 的改进方法。
1. 环境准备
安装必要的软件包
除了之前提到的包外,还需要安装 peft
(Parameter-Efficient Fine-Tuning)库,它支持 LoRA 等参数高效微调方法。
pip install transformers accelerate datasets huggingface_hub peft
注意:确保 peft
版本兼容 transformers
。如果遇到版本冲突,可以参考 PEFT 的官方文档 进行调整。
2. 下载并加载模型
与之前步骤类似,但在加载模型后,我们将应用 LoRA 到模型中。
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import get_peft_config, get_peft_model, LoraConfig, TaskType
# 定义模型名称和本地路径
model_name = "FlagAlpha/Llama2-Chinese-7b-Chat"
local_model_path = "./models/Llama2-Chinese-7b-Chat"
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(local_model_path)
# 加载模型
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
device_map="auto",
load_in_8bit=True # 使用 8-bit 精度,减少显存占用
)
# 配置 LoRA
lora_config = LoraConfig(
r=8, # 低秩分解的秩
lora_alpha=32, # LoRA 的缩放系数
target_modules=["q_proj", "v_proj"], # 要应用 LoRA 的模块名称,根据模型架构调整
lora_dropout=0.1,
bias="none",
task_type=TaskType.CAUSAL_LM
)
# 应用 LoRA 到模型
model = get_peft_model(model, lora_config)
# 打印 LoRA 模型信息
print(model)
说明:
target_modules
:指定哪些模块应用 LoRA。对于 LLaMA 模型,通常选择查询(q_proj
)和值(v_proj
)投影层。请根据具体模型架构调整。r
和lora_alpha
:这些参数控制 LoRA 的低秩分解维度和缩放系数,可以根据资源情况进行调整。
3. 准备训练数据
与之前相同,使用 datasets
库加载和预处理训练数据。
from datasets import load_dataset
# 加载自定义数据集
dataset = load_dataset("path_to_your_dataset")
# 定义预处理函数
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True, max_length=512)
# 预处理数据
tokenized_datasets = dataset.map(tokenize_function, batched=True)
注意:根据你的数据集结构,调整 examples["text"]
部分。
4. 配置训练参数
使用 transformers
的 TrainingArguments
和 Trainer
进行训练,同时配置 peft
相关参数。
from transformers import Trainer, TrainingArguments
from peft import PeftModel
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
num_train_epochs=3,
save_steps=10_000,
save_total_limit=2,
fp16=True,
logging_steps=500,
evaluation_strategy="steps",
eval_steps=1_000,
load_best_model_at_end=True,
metric_for_best_model="accuracy",
optim="adamw_torch", # 使用 AdamW 优化器
lr_scheduler_type="linear",
learning_rate=5e-5, # 根据需要调整学习率
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
tokenizer=tokenizer,
)
说明:
- 优化器和学习率:根据 LoRA 的特性,通常需要较小的学习率,如
5e-5
。你可以根据训练效果调整。 - 梯度累积:如果显存仍然不足,可以通过设置
gradient_accumulation_steps
来累积梯度,例如gradient_accumulation_steps=4
。
5. 开始训练
运行训练过程。
trainer.train()
6. 保存训练后的模型
训练完成后,保存包含 LoRA 权重的模型和分词器。
# 保存 LoRA 模型
model.save_pretrained("./trained_model")
# 保存分词器
tokenizer.save_pretrained("./trained_model")
7. 使用训练后的模型
加载训练后的 LoRA 模型进行推理时,需要使用 peft
来加载 LoRA 权重。
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("./trained_model")
# 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained(
"FlagAlpha/Llama2-Chinese-7b-Chat",
device_map="auto",
load_in_8bit=True
)
# 加载 LoRA 权重
model = PeftModel.from_pretrained(base_model, "./trained_model")
# 进行推理
prompt = "你好,Llama2!"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
8. 完整示例代码
以下是整合 LoRA 的完整 Python 脚本:
from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments
from transformers import BitsAndBytesConfig
from datasets import load_dataset
from peft import get_peft_model, LoraConfig, TaskType
import os
# 定义模型名称和本地路径
model_name = "FlagAlpha/Llama2-Chinese-7b-Chat"
local_model_path = "./models/Llama2-Chinese-7b-Chat"
# 创建本地存储目录(如果不存在)
os.makedirs(local_model_path, exist_ok=True)
# 配置 BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_8bit=True, # 启用 8-bit 量化
llm_int8_threshold=6.0,
llm_int8_has_fp16_weight=False
)
# 下载并加载分词器,确保传递 trust_remote_code=True
print("正在下载分词器...")
tokenizer = AutoTokenizer.from_pretrained(
model_name,
trust_remote_code=True
)
# 下载并加载模型,确保传递 trust_remote_code=True
print("正在下载模型...")
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True
)
# 显式保存模型和分词器到本地路径
print("正在保存模型和分词器到本地路径...")
model.save_pretrained(local_model_path)
tokenizer.save_pretrained(local_model_path)
print(f"模型和分词器已成功保存到 {local_model_path}")
# 从本地路径加载分词器
print("正在从本地路径加载分词器...")
tokenizer = AutoTokenizer.from_pretrained(
local_model_path,
trust_remote_code=True,
local_files_only=True # 强制仅从本地加载
)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "left"
# 从本地路径加载模型
print("正在从本地路径加载模型...")
model = AutoModelForCausalLM.from_pretrained(
local_model_path,
device_map="auto",
quantization_config=bnb_config,
trust_remote_code=True,
local_files_only=True
)
# 配置 LoRA
print("正在配置 LoRA...")
lora_config = LoraConfig(
r=8,
lora_alpha=32,
target_modules=["q_proj", "v_proj"], # 根据模型架构调整
lora_dropout=0.1,
bias="none",
task_type=TaskType.CAUSAL_LM
)
# 应用 LoRA 到模型
model = get_peft_model(model, lora_config)
# 加载训练数据(替换为您的数据集路径)
print("正在加载训练数据...")
dataset = load_dataset("path_to_your_dataset")
# 定义预处理函数
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True, max_length=512)
# 预处理数据
print("正在预处理数据...")
tokenized_datasets = dataset.map(tokenize_function, batched=True)
# 定义训练参数
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
num_train_epochs=3,
save_steps=10_000,
save_total_limit=2,
fp16=True,
logging_steps=500,
evaluation_strategy="steps",
eval_steps=1_000,
load_best_model_at_end=True,
metric_for_best_model="accuracy",
optim="adamw_torch",
lr_scheduler_type="linear",
learning_rate=5e-5,
gradient_accumulation_steps=4 # 根据需要调整
)
# 初始化 Trainer
print("正在初始化 Trainer...")
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
tokenizer=tokenizer,
)
# 开始训练
print("开始训练...")
trainer.train()
# 保存 LoRA 模型和分词器
print("正在保存 LoRA 模型和分词器...")
model.save_pretrained("./trained_model")
tokenizer.save_pretrained("./trained_model")
print("模型微调和保存完成。")
将上述代码保存为 fine_tune_with_lora.py
,然后在终端中运行:
9. 进一步优化和注意事项
使用 accelerate
优化训练
accelerate
可以帮助更高效地利用多 GPU 或分布式训练资源。
accelerate config
按照提示选择适合你的硬件设置。然后,使用 accelerate launch
启动训练:
accelerate launch train_script.py
管理显存
如果在训练过程中仍然遇到显存不足的问题,可以尝试以下方法:
- 减小
per_device_train_batch_size
:例如,从2
调整为1
。 - 增加
gradient_accumulation_steps
:例如,设置为4
,以在多个小批次上累积梯度。 - 调整 LoRA 参数:减少
r
的值,例如从8
调整为4
,以进一步减少参数数量。 - 使用更低的
max_length
:如果你的输入序列较长,可以尝试减小max_length
。
监控训练过程
使用 TensorBoard
或其他监控工具来跟踪训练过程中的损失、准确率等指标:
pip install tensorboard
tensorboard --logdir=./results
然后在浏览器中访问 http://localhost:6006
查看训练日志。
保存和加载最佳模型
通过 Trainer
的 load_best_model_at_end=True
参数,可以在训练结束时自动加载表现最好的模型。如果需要手动保存和加载模型,可以使用以下代码:
# 保存最佳模型
trainer.save_model("./best_model")
tokenizer.save_pretrained("./best_model")
# 从最佳模型加载
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("./best_model")
# 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained(
"FlagAlpha/Llama2-Chinese-7b-Chat",
device_map="auto",
load_in_8bit=True
)
# 加载 LoRA 权重
model = PeftModel.from_pretrained(base_model, "./best_model")
10. 参考资源
通过以上步骤,你可以有效地使用 LoRA 进行参数高效的微调,减少显存和计算资源的消耗。如果在操作过程中遇到问题,可以参考相关文档或在社区中寻求帮助。
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)