h
1.安装微调库
#1安装微调库 (2024/6/16修改-官方库变动,原视频中这段代码修改,现在只需要安装最新官方库和依赖)
%%capture
!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
!pip install --no-deps xformers "trl<0.9.0" peft accelerate bitsandbytes
#----------------------------------------------------------------------------------
#import torch
#major_version, minor_version = torch.cuda.get_device_capability()
# 由于Colab有torch 2.2.1,会破坏软件包,要单独安装
#!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
#if major_version >= 8:
# 新GPU,如Ampere、Hopper GPU(RTX 30xx、RTX 40xx、A100、H100、L40)。
# !pip install --no-deps packaging ninja einops flash-attn xformers trl peft accelerate bitsandbytes
#else:
# 较旧的GPU(V100、Tesla T4、RTX 20xx)
!pip install --no-deps peft accelerate bitsandbytes
!pip install xformers==0.0.25 #最新的0.0.26不兼容
#pass
-
!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
:- 这个命令安装
unsloth
库的一个特定版本,其中包含了为 Colab 环境定制的依赖项。 colab-new
是unsloth
的一个安装选项,包含了适合在 Colab 中使用的最新设置和依赖项。git+https://github.com/unslothai/unsloth.git
表示直接从 GitHub 仓库获取最新代码并进行安装。
- 这个命令安装
-
!pip install --no-deps xformers "trl<0.9.0" peft accelerate bitsandbytes"
:- 这个命令安装多个特定的包,并且使用
--no-deps
选项,这意味着它们不会自动安装依赖项。这样做可能是为了避免与其他包版本冲突或确保特定版本的依赖被使用。 xformers
: 这是一个用于优化 Transformer 模型计算的库。trl<0.9.0
: 这个包可能是指用于训练语言模型的库,安装的版本低于 0.9.0。peft
: 可能是 "Parameter-Efficient Fine-Tuning" 的缩写,用于高效地微调模型的库。accelerate
: 这个库通常用于简化分布式训练和部署机器学习模型的流程。bitsandbytes
: 一个用于优化 GPU 内存使用的库,特别是在处理大型模型时。
- 这个命令安装多个特定的包,并且使用
这些命令共同作用,确保在 Colab 环境中安装和使用的所有包都是经过特定配置和优化的,适合进行深度学习和大规模语言模型的训练或推理。
2.加载模型
#2加载模型
from unsloth import FastLanguageModel
import torch
max_seq_length = 2048
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/llama-3-8b-bnb-4bit",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)
FastLanguageModel
是 unsloth
库中的一个类,用于加载和处理大型语言模型。
max_seq_length
: 定义了模型可以处理的最大序列长度,这里设置为 2048。这意味着模型可以处理长度最多为 2048 个标记的输入文本。dtype
: 指定模型的参数类型,这里设置为None
,表示使用默认设置。load_in_4bit
: 设置为True
,表示使用 4-bit 精度来加载模型参数。这种精度缩减可以显著降低模型的内存占用,同时在推理时提供更快的计算速度,虽然可能会损失一些精度。
-
model_name
: 指定了要加载的预训练模型的名称,这里是unsloth/llama-3-8b-bnb-4bit
,一个具有 8 亿参数的模型,使用了 4-bit 的权重表示。FastLanguageModel.from_pretrained
: 这是一个类方法,用于从给定的模型名称加载预训练模型及其对应的分词器(tokenizer
)。分词器用于将文本转换为模型可以处理的输入形式。
-
这个过程的目的是将模型和分词器加载到内存中,以便进行文本生成、理解等自然语言处理任务。使用 4-bit 量化模型能够有效降低计算资源需求,使得在资源有限的环境中也能高效运行大规模模型
-
3 微调前测试
-
#3微调前测试 alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request. ### Instruction: {} ### Input: {} ### Response: {}""" FastLanguageModel.for_inference(model) inputs = tokenizer( [ alpaca_prompt.format( "请用中文回答", # instruction "海绵宝宝的书法是不是叫做海绵体?", # input "", # output ) ], return_tensors = "pt").to("cuda") from transformers import TextStreamer text_streamer = TextStreamer(tokenizer) _ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128)
#4准备微调数据集 EOS_TOKEN = tokenizer.eos_token # 必须添加 EOS_TOKEN def formatting_prompts_func(examples): instructions = examples["instruction"] inputs = examples["input"] outputs = examples["output"] texts = [] for instruction, input, output in zip(instructions, inputs, outputs): # 必须添加EOS_TOKEN,否则无限生成 text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN texts.append(text) return { "text" : texts, } pass from datasets import load_dataset dataset = load_dataset("kigner/ruozhiba-llama3-tt", split = "train") dataset = dataset.map(formatting_prompts_func, batched = True,)
#5设置训练参数
from trl import SFTTrainer
from transformers import TrainingArguments
model = FastLanguageModel.get_peft_model(
model,
r = 16, # 建议 8, 16, 32, 64, 128
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",],
lora_alpha = 16,
lora_dropout = 0,
bias = "none",
use_gradient_checkpointing = "unsloth", # 检查点,长上下文度
random_state = 3407,
use_rslora = False,
loftq_config = None,
)
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = max_seq_length,
dataset_num_proc = 2,
packing = False, # 可以让短序列的训练速度提高5倍。
args = TrainingArguments(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
warmup_steps = 5,
max_steps = 60, # 微调步数
learning_rate = 2e-4, # 学习率
fp16 = not torch.cuda.is_bf16_supported(),
bf16 = torch.cuda.is_bf16_supported(),
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
output_dir = "outputs",
),
)
#6开始训练
trainer_stats = trainer.train()
#7测试微调后的模型
FastLanguageModel.for_inference(model)
inputs = tokenizer(
[
alpaca_prompt.format(
"只用中文回答问题", # instruction
"火烧赤壁 曹操为何不拨打110求救?", # input
"", # output
)
], return_tensors = "pt").to("cuda")
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128)
#8保存LoRA模型
model.save_pretrained("lora_model") # Local saving
tokenizer.save_pretrained("lora_model")#(2024/06/16修改,官方库变化)
# model.push_to_hub("your_name/lora_model", token = "...") # 在线保存到hugging face,需要token
#9合并模型并量化成4位gguf保存 (目前colab有空间限制,可能会转换失败)
model.save_pretrained_gguf("model", tokenizer, quantization_method = "q4_k_m")
#model.save_pretrained_merged("outputs", tokenizer, save_method = "merged_16bit",) #合并模型,保存为16位hf
#model.push_to_hub_gguf("hf/model", tokenizer, quantization_method = "q4_k_m", token = "") #合并4位gguf,上传到hugging face(需要账号token)
#10挂载google drive
from google.colab import drive
drive.mount('/content/drive')
#11复制模型到google drive
import shutil
source_file = '/content/model-unsloth.Q4_K_M.gguf'
destination_dir = '/content/drive/MyDrive/Llama3'
destination_file = f'{destination_dir}/model-unsloth.Q4_K_M.gguf'
shutil.copy(source_file, destination_file)