code-llm-toolkit / train_sft.py
rndubs's picture
Upload train_sft.py
5748e4c verified
Raw
History Blame Contribute Delete
4.74 kB
"""
Stage 1 SFT Training Script: Fine-tune Qwen2.5-Coder-7B-Instruct for
Python code generation + tool-calling + RAG-aware generation.
Based on:
- Qwen2.5-Coder Technical Report (arxiv:2409.12186): coarse-to-fine SFT recipe
- ToolACE (arxiv:2409.00920): LoRA r=16, alpha=32, LR=1e-4, cosine, 3 epochs
- Gorilla (arxiv:2305.15334): retriever-aware training pattern
- TRL v1.2.0 SFTTrainer with ChatML messages format
Reference implementation: TRL SFT docs (https://huggingface.co/docs/trl/sft_trainer)
Dataset format: conversational ChatML with "messages" column
Usage:
# Launch via hf_jobs (recommended)
# Or run locally:
python train_sft.py
"""
import os
import torch
import trackio
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer
# ============================================================================
# Configuration — EDIT THESE FOR YOUR USE CASE
# ============================================================================
BASE_MODEL = "Qwen/Qwen2.5-Coder-7B-Instruct"
DATASET_REPO = "your-username/code-toolcall-sft-data" # From prepare_data.py
OUTPUT_DIR = "./qwen25-coder-7b-code-toolcall"
HUB_MODEL_ID = "your-username/qwen25-coder-7b-code-toolcall"
HF_TOKEN = os.environ.get("HF_TOKEN")
# Training hyperparameters (from ToolACE + Qwen2.5-Coder papers)
LEARNING_RATE = 1e-4 # LoRA LR (10x FFT rate)
NUM_EPOCHS = 2 # 2 epochs (Magicoder recipe)
BATCH_SIZE = 2 # Per-device batch size
GRAD_ACCUM = 8 # Effective batch = 2 * 8 = 16
MAX_SEQ_LENGTH = 8192 # 8K context for tool-calling
WARMUP_RATIO = 0.1
LORA_R = 32 # Rank (32-64 for code tasks)
LORA_ALPHA = 64 # Alpha = 2 * r
LORA_DROPOUT = 0.05
# ============================================================================
# Trackio Monitoring
# ============================================================================
trackio.init(name="code-toolcall-sft", project="code-llm-finetuning")
# ============================================================================
# Load Dataset
# ============================================================================
print(f"Loading dataset: {DATASET_REPO}")
dataset = load_dataset(DATASET_REPO, split="train")
print(f"Dataset size: {len(dataset)} examples")
split = dataset.train_test_split(test_size=0.02, seed=42)
train_dataset = split["train"]
eval_dataset = split["test"]
print(f"Train: {len(train_dataset)}, Eval: {len(eval_dataset)}")
# ============================================================================
# LoRA Configuration
# ============================================================================
peft_config = LoraConfig(
r=LORA_R,
lora_alpha=LORA_ALPHA,
lora_dropout=LORA_DROPOUT,
bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
)
# ============================================================================
# SFT Training Configuration
# ============================================================================
training_args = SFTConfig(
output_dir=OUTPUT_DIR,
hub_model_id=HUB_MODEL_ID,
push_to_hub=True,
hub_token=HF_TOKEN,
num_train_epochs=NUM_EPOCHS,
per_device_train_batch_size=BATCH_SIZE,
gradient_accumulation_steps=GRAD_ACCUM,
learning_rate=LEARNING_RATE,
lr_scheduler_type="cosine",
warmup_ratio=WARMUP_RATIO,
weight_decay=0.01,
max_grad_norm=1.0,
bf16=True,
gradient_checkpointing=True,
max_seq_length=MAX_SEQ_LENGTH,
assistant_only_loss=True, # Only train on assistant responses
packing=False,
logging_strategy="steps",
logging_steps=10,
logging_first_step=True,
disable_tqdm=True,
eval_strategy="steps",
eval_steps=200,
per_device_eval_batch_size=2,
save_strategy="steps",
save_steps=500,
save_total_limit=3,
load_best_model_at_end=True,
seed=42,
report_to="none",
)
# ============================================================================
# Train
# ============================================================================
print(f"Loading model: {BASE_MODEL}")
trainer = SFTTrainer(
model=BASE_MODEL,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
peft_config=peft_config,
)
print("Starting training...")
result = trainer.train()
print(f"Training complete! Loss: {result.training_loss:.4f}")
trainer.push_to_hub(commit_message="Final model after SFT training")
print(f"Model pushed to: https://huggingface.co/{HUB_MODEL_ID}")
trackio.log({"final_loss": result.training_loss})
trackio.finish()