File size: 1,899 Bytes
ef69abc | 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 | # /// script
# dependencies = ["trl>=0.12.0", "peft>=0.7.0", "trackio", "datasets"]
# ///
"""
Obsidian Bases SLM Training Script
Fine-tunes Qwen 3 0.6B to generate .base files from natural language.
"""
import os
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTTrainer, SFTConfig
import trackio
# Load dataset from Hub
dataset = load_dataset("ssdavid/obsidian-bases-query-v1", split="train")
# Format for SFT - convert to messages format
def format_example(example):
return {
"messages": [
{"role": "user", "content": example["instruction"]},
{"role": "assistant", "content": example["output"]}
]
}
dataset = dataset.map(format_example)
# Split for evaluation
dataset_split = dataset.train_test_split(test_size=0.1, seed=42)
# LoRA config for efficient fine-tuning
peft_config = LoraConfig(
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
bias="none",
task_type="CAUSAL_LM"
)
# Training config
training_args = SFTConfig(
output_dir="obsidian-bases-slm",
push_to_hub=True,
hub_model_id="ssdavid/obsidian-bases-slm",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
warmup_ratio=0.1,
logging_steps=10,
eval_strategy="steps",
eval_steps=50,
save_strategy="steps",
save_steps=100,
max_length=512,
report_to="trackio",
project="obsidian-bases-slm",
run_name="qwen3-0.6b-bases-v1",
)
# Create trainer
trainer = SFTTrainer(
model="Qwen/Qwen3-0.6B",
train_dataset=dataset_split["train"],
eval_dataset=dataset_split["test"],
peft_config=peft_config,
args=training_args,
)
# Train
trainer.train()
# Push to Hub
trainer.push_to_hub()
print("Training complete! Model pushed to ssdavid/obsidian-bases-slm")
|