Files
SIA/tools/qwq_train/train/qwq.py

135 lines
3.7 KiB
Python

#!/root/venvs/train/bin/python
"""
Fine-tuning for QwQ model
"""
# Unsloth should be imported before transformers to ensure all optimizations are applied.
from unsloth import FastLanguageModel, is_bfloat16_supported
from dataclasses import dataclass
from pathlib import Path
from transformers import AutoTokenizer, TrainingArguments
from trl import SFTTrainer
from typing import Optional, List
import argparse
import json
import os
from .dataset import Dataset
@dataclass
class Args:
def __init__(self, args: Optional[List[str]] = None):
parser = argparse.ArgumentParser(description='Train SIA model using QwQ')
parser.add_argument(
'--config',
type=Path,
default=Path('/root/sia/training/config.yaml'),
help='Path to config file'
)
parser.add_argument(
'--base-model',
type=str,
default='unsloth/QwQ-32B-bnb-4bit',
help='HuggingFace model ID for base model'
)
parser.add_argument(
'--output-dir',
type=Path,
required=True,
help='Directory to save the trained model'
)
parser.add_argument(
'--api-key',
type=str,
default=os.environ.get('SIA_HF_API_KEY'),
help='HuggingFace API key'
)
if args is None:
self.args = parser.parse_args()
else:
self.args = parser.parse_args(args)
@property
def config_path(self) -> Path:
return self.args.config
@property
def base_model(self) -> str:
return self.args.base_model
@property
def output_dir(self) -> Path:
return self.args.output_dir
@property
def api_key(self) -> str:
return self.args.api_key
def main():
args = Args()
dataset = Dataset(args.config_path)
dataset.validate()
with open('/root/sia/qwq_tokenizer_config.json', 'r') as f:
tokenizer_config = json.load(f)
tokenizer = AutoTokenizer.from_pretrained(
args.base_model,
**tokenizer_config,
)
model, _returned_tokenizer = FastLanguageModel.from_pretrained(
model_name = args.base_model,
gpu_memory_utilization = 0.5,
)
model = FastLanguageModel.get_peft_model(
model,
target_modules = [
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
], # Remove QKVO if out of memory
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,
)
training_args = TrainingArguments(
output_dir=str(args.output_dir) + "_train",
num_train_epochs=3,
per_device_train_batch_size=1,
gradient_accumulation_steps=16,
gradient_checkpointing=True,
learning_rate=2e-5,
lr_scheduler_type="cosine",
warmup_ratio=0.05,
weight_decay=0.01,
fp16=not is_bfloat16_supported(),
bf16=is_bfloat16_supported(),
logging_steps=10,
save_steps=200,
save_total_limit=3,
report_to="none",
optim="adamw_8bit",
)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
args=training_args,
train_dataset=dataset.to_transformers_dataset(tokenizer),
dataset_text_field="messages",
)
trainer.train()
model.save_pretrained_merged(
str(args.output_dir),
tokenizer=tokenizer,
save_method="merged_4bit_forced"
)
if __name__ == "__main__":
main()