forked from microsoft/agent-lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunsloth_helper.py
More file actions
92 lines (74 loc) · 3.19 KB
/
Copy pathunsloth_helper.py
File metadata and controls
92 lines (74 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Copyright (c) Microsoft. All rights reserved.
"""Helper module for Unsloth training with LoRA.
This module provides utilities for training language models using the Unsloth library,
which optimizes training performance with 4-bit quantization and LoRA (Low-Rank Adaptation).
The training function should be run in a separate process to ensure GPU memory is properly freed.
"""
from datasets import Dataset as HuggingFaceDataset # type: ignore
from rich.console import Console
console = Console()
def unsloth_training(model_path: str, sft_dataset: HuggingFaceDataset, next_model_path: str):
"""Train a Unsloth model on a SFT dataset.
This is recommended to be run in a separate process to avoid GPU memory issues.
Args:
model_path: The path to the model to train. Must be a local path.
sft_dataset: The SFT dataset to train on.
next_model_path: The path to save the trained model.
"""
from unsloth import FastLanguageModel
# The two imports must come in this order to make unsloth patch work.
if True:
# The SFTTrainer is actually patched by unsloth.
from trl import SFTConfig, SFTTrainer # type: ignore
model, tokenizer = FastLanguageModel.from_pretrained( # type: ignore
model_name=model_path,
max_seq_length=4096, # Choose any for long context!
load_in_4bit=True, # 4 bit quantization to reduce memory
)
# Config the model to use LoRA
model = FastLanguageModel.get_peft_model( # type: ignore
model, # type: ignore
r=32,
target_modules=[
"q_proj",
"k_proj",
"v_proj",
"o_proj",
"gate_proj",
"up_proj",
"down_proj",
],
lora_alpha=32,
lora_dropout=0, # Supports any, but = 0 is optimized
bias="none", # Supports any, but = "none" is optimized
use_gradient_checkpointing="unsloth", # True or "unsloth" for very long context
random_state=3407,
use_rslora=False, # Rank stabilized LoRA
loftq_config=None, # And LoftQ
)
sft_config = SFTConfig(
per_device_train_batch_size=2,
gradient_accumulation_steps=4, # Use GA to mimic batch size!
warmup_steps=5,
max_steps=60, # Maximum number of steps to train for
# num_train_epochs = 1, # Set this for 1 full training run
learning_rate=2e-4, # Reduce to 2e-5 for long training runs
logging_steps=1,
optim="adamw_8bit",
weight_decay=0.01,
lr_scheduler_type="linear",
seed=3407,
report_to="none", # Use this for W&B etc
)
trainer = SFTTrainer(
model=model, # type: ignore
tokenizer=tokenizer, # type: ignore
train_dataset=sft_dataset,
args=sft_config,
)
trainer_stats = trainer.train() # type: ignore
console.print(f"[bold red][Algo][/bold red] Trainer stats: {trainer_stats}")
# Save in 16-bit for vLLM inference later
model.save_pretrained_merged(next_model_path, tokenizer, save_method="merged_16bit") # type: ignore
# All unsloth memory should be freed now.
# But this won't happen unless you run unsloth_training in a separate process!