import os
import torch
from datasets import load_dataset
from peft import LoraConfig
from transformers import AutoProcessor, AutoModelForVision2Seq, TrainingArguments
from trl import SFTTrainer
MODEL_ID = "HuggingFaceTB/SmolVLM-256M-Instruct"
JSONL_DATASET_PATH = "vlm_training_dataset.jsonl"
OUTPUT_DIR = "./smolvlm_finetuned"
BATCH_SIZE = 2
GRAD_ACCUM_STEPS = 4
NUM_EPOCHS = 3
dataset = load_dataset("json", data_files=JSONL_DATASET_PATH, split="train")
def format_conversations(example):
formatted_messages = []
for message in example["conversations"]:
role = "user" if message["from"] == "human" else "assistant"
formatted_messages.append({
"role": role,
"content": [{"type": "text", "text": message["value"]}]
})
return {"messages": formatted_messages, "images": [example["image"]]}
formatted_dataset = dataset.map(format_conversations)
split_dataset = formatted_dataset.train_test_split(test_size=0.1, seed=42)
train_dataset = split_dataset["train"]
eval_dataset = split_dataset["test"]
processor = AutoProcessor.from_pretrained(MODEL_ID)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = AutoModelForVision2Seq.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16,
device_map="auto"
)
training_args = TrainingArguments(
output_dir=OUTPUT_DIR,
num_train_epochs=NUM_EPOCHS,
per_device_train_batch_size=BATCH_SIZE,
gradient_accumulation_steps=GRAD_ACCUM_STEPS,
learning_rate=2e-4,
weight_decay=0.01,
logging_steps=10,
evaluation_strategy="steps",
eval_steps=50,
save_strategy="steps",
save_steps=100,
save_total_limit=2,
fp16=not torch.cuda.is_bf16_supported(),
bf16=torch.cuda.is_bf16_supported(),
remove_unused_columns=False,
report_to="none"
)
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
peft_config=lora_config,
processor=processor,
)
print("Starting SmolVLM Fine-tuning...")
trainer.train()
trainer.save_model(OUTPUT_DIR)
processor.save_pretrained(OUTPUT_DIR)
print(f"Training Complete! Finetuned weights successfully saved to: {OUTPUT_DIR}")