CoolFace
Modelpublic

fivetech/Harbour

sourceHugging Faceapache-2.0updated 3mo agoView on Hugging Face
0likes41downloads
train_unsloth.py172 linesDownload Raw Back to root
1#!/usr/bin/env python32"""3Harbour Fine-tuning Script for Qwen3.6-35B-A3B (MoE)4Uses Unsloth + LoRA with GGUF quantized model5Optimized for CPU with 121GB RAM6"""7 8import json9import torch10from pathlib import Path11from datasets import Dataset12from unsloth import FastLanguageModel13from trl import SFTTrainer14from transformers import TrainingArguments15 16# Configuration17MODEL_NAME = "unsloth/Qwen3.6-35B-A3B-GGUF"18MODEL_FILE = "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf"19TRAIN_FILE = Path("/home/fivetech/finetune/harbour_train.jsonl")20VAL_FILE = Path("/home/fivetech/finetune/harbour_val.jsonl")21OUTPUT_DIR = Path("/home/fivetech/finetune/output")22MAX_SEQ_LENGTH = 204823 24print("=" * 60)25print("Harbour Fine-tuning - Qwen3.6-35B-A3B (MoE) with Unsloth + LoRA")26print("=" * 60)27 28# 1. Load model from GGUF29print("\n1. Loading model from GGUF (Q4_K_M)...")30model, tokenizer = FastLanguageModel.from_pretrained(31    model_name=MODEL_NAME,32    gguf_file=MODEL_FILE,33    max_seq_length=MAX_SEQ_LENGTH,34    load_in_4bit=True,35    dtype=None,36)37 38# 2. LoRA configuration39print("2. Configuring LoRA...")40model = FastLanguageModel.get_peft_model(41    model,42    r=16,43    lora_alpha=32,44    lora_dropout=0.05,45    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",46                     "gate_proj", "up_proj", "down_proj"],47    bias="none",48    use_gradient_checkpointing="unsloth",49    random_state=42,50)51 52# 3. Load dataset53print("3. Loading dataset...")54 55def load_jsonl(path):56    data = []57    with open(path) as f:58        for line in f:59            data.append(json.loads(line))60    return data61 62train_data = load_jsonl(TRAIN_FILE)63val_data = load_jsonl(VAL_FILE)64 65print(f"   Train: {len(train_data)} entries")66print(f"   Val: {len(val_data)} entries")67 68# 4. Format conversations69print("4. Formatting conversations...")70 71def format_conversation(entry):72    messages = entry["messages"]73    text = tokenizer.apply_chat_template(74        messages,75        tokenize=False,76        add_generation_prompt=False,77    )78    return {"text": text}79 80train_dataset = Dataset.from_list([format_conversation(e) for e in train_data])81val_dataset = Dataset.from_list([format_conversation(e) for e in val_data])82 83# 5. Tokenize84print("5. Tokenizing...")85 86def tokenize_function(examples):87    return tokenizer(88        examples["text"],89        truncation=True,90        max_length=MAX_SEQ_LENGTH,91        padding=False,92    )93 94train_dataset = train_dataset.map(95    tokenize_function,96    batched=True,97    remove_columns=["text"],98    desc="Tokenizing train",99)100val_dataset = val_dataset.map(101    tokenize_function,102    batched=True,103    remove_columns=["text"],104    desc="Tokenizing val",105)106 107print(f"   Train tokens: {sum(len(x) for x in train_dataset['input_ids']):,}")108print(f"   Val tokens: {sum(len(x) for x in val_dataset['input_ids']):,}")109 110# 6. Training arguments111print("6. Setting up training...")112training_args = TrainingArguments(113    output_dir=str(OUTPUT_DIR),114    num_train_epochs=3,115    per_device_train_batch_size=1,116    gradient_accumulation_steps=16,117    learning_rate=1e-4,118    weight_decay=0.01,119    warmup_ratio=0.1,120    lr_scheduler_type="cosine",121    logging_steps=5,122    save_steps=50,123    save_total_limit=3,124    eval_strategy="steps",125    eval_steps=50,126    load_best_model_at_end=True,127    metric_for_best_model="eval_loss",128    bf16=False,129    fp16=False,130    dataloader_num_workers=1,131    report_to="none",132    remove_unused_columns=False,133    max_grad_norm=1.0,134    optim="adamw_8bit",135)136 137# 7. Create trainer138print("7. Creating trainer...")139trainer = SFTTrainer(140    model=model,141    tokenizer=tokenizer,142    args=training_args,143    train_dataset=train_dataset,144    eval_dataset=val_dataset,145    max_seq_length=MAX_SEQ_LENGTH,146    dataset_text_field="text",147)148 149# 8. Train150print("\n8. Starting training...")151print("=" * 60)152trainer.train()153 154# 9. Save LoRA adapter155print("\n9. Saving LoRA adapter...")156trainer.save_model(str(OUTPUT_DIR / "final"))157tokenizer.save_pretrained(str(OUTPUT_DIR / "final"))158 159# 10. Export to GGUF (optional)160print("\n10. Exporting to GGUF...")161model.save_pretrained_gguf(162    str(OUTPUT_DIR / "gguf"),163    tokenizer,164    quantization_method="q4_k_m",165)166 167print("\n" + "=" * 60)168print("Training complete!")169print(f"LoRA adapter saved to: {OUTPUT_DIR / 'final'}")170print(f"GGUF model saved to: {OUTPUT_DIR / 'gguf'}")171print("=" * 60)172