CoolFace
Modelpublic

fivetech/Harbour

sourceHugging Faceapache-2.0updated 3mo agoView on Hugging Face
0likes41downloads
train.py181 linesDownload Raw Back to root
1#!/usr/bin/env python32"""3Harbour Fine-tuning Script for qwen3.6:35b (Qwen3.6-35B-A3B MoE)4Uses LoRA with CPU training (121GB RAM available)5"""6 7import json8import torch9from pathlib import Path10from transformers import (11    AutoModelForCausalLM,12    AutoTokenizer,13    TrainingArguments,14    Trainer,15    DataCollatorForLanguageModeling,16)17from peft import LoraConfig, get_peft_model, TaskType18from datasets import Dataset19 20# Configuration21MODEL_NAME = "Qwen/Qwen3.6-35B-A3B"22TRAIN_FILE = Path("/home/fivetech/finetune/harbour_train.jsonl")23VAL_FILE = Path("/home/fivetech/finetune/harbour_val.jsonl")24OUTPUT_DIR = Path("/home/fivetech/finetune/output")25MAX_SEQ_LENGTH = 204826 27print("=" * 60)28print("Harbour Fine-tuning - qwen3.6:35b (MoE) with LoRA")29print("=" * 60)30 31# 1. Load tokenizer32print("\n1. Loading tokenizer...")33tokenizer = AutoTokenizer.from_pretrained(34    MODEL_NAME,35    trust_remote_code=True,36    padding_side="right",37)38if tokenizer.pad_token is None:39    tokenizer.pad_token = tokenizer.eos_token40 41# 2. Load dataset42print("2. Loading dataset...")43 44def load_jsonl(path):45    data = []46    with open(path) as f:47        for line in f:48            data.append(json.loads(line))49    return data50 51train_data = load_jsonl(TRAIN_FILE)52val_data = load_jsonl(VAL_FILE)53 54print(f"   Train: {len(train_data)} entries")55print(f"   Val: {len(val_data)} entries")56 57# 3. Format conversations for Qwen ChatML58print("3. Formatting conversations...")59 60def format_conversation(entry):61    """Convert messages to Qwen ChatML format."""62    messages = entry["messages"]63    text = tokenizer.apply_chat_template(64        messages,65        tokenize=False,66        add_generation_prompt=False,67    )68    return {"text": text}69 70train_dataset = Dataset.from_list([format_conversation(e) for e in train_data])71val_dataset = Dataset.from_list([format_conversation(e) for e in val_data])72 73# 4. Tokenize74print("4. Tokenizing...")75 76def tokenize_function(examples):77    return tokenizer(78        examples["text"],79        truncation=True,80        max_length=MAX_SEQ_LENGTH,81        padding=False,82    )83 84train_dataset = train_dataset.map(85    tokenize_function,86    batched=True,87    remove_columns=["text"],88    desc="Tokenizing train",89)90val_dataset = val_dataset.map(91    tokenize_function,92    batched=True,93    remove_columns=["text"],94    desc="Tokenizing val",95)96 97print(f"   Train tokens: {sum(len(x) for x in train_dataset['input_ids']):,}")98print(f"   Val tokens: {sum(len(x) for x in val_dataset['input_ids']):,}")99 100# 5. Load model (CPU with float32)101print("5. Loading model (CPU mode)...")102print("   This may take a few minutes...")103 104model = AutoModelForCausalLM.from_pretrained(105    MODEL_NAME,106    torch_dtype=torch.float32,107    device_map="cpu",108    trust_remote_code=True,109)110 111# 6. LoRA configuration112print("6. Configuring LoRA...")113lora_config = LoraConfig(114    task_type=TaskType.CAUSAL_LM,115    r=16,116    lora_alpha=32,117    lora_dropout=0.05,118    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],119    bias="none",120)121 122model = get_peft_model(model, lora_config)123model.print_trainable_parameters()124 125# 7. Training arguments126print("7. Setting up training...")127training_args = TrainingArguments(128    output_dir=str(OUTPUT_DIR),129    num_train_epochs=3,130    per_device_train_batch_size=1,131    gradient_accumulation_steps=16,132    learning_rate=1e-4,133    weight_decay=0.01,134    warmup_ratio=0.1,135    lr_scheduler_type="cosine",136    logging_steps=5,137    save_steps=50,138    save_total_limit=3,139    eval_strategy="steps",140    eval_steps=50,141    load_best_model_at_end=True,142    metric_for_best_model="eval_loss",143    bf16=False,144    fp16=False,145    dataloader_num_workers=1,146    report_to="none",147    remove_unused_columns=False,148    max_grad_norm=1.0,149)150 151# 8. Data collator152data_collator = DataCollatorForLanguageModeling(153    tokenizer=tokenizer,154    mlm=False,155)156 157# 9. Create trainer158print("8. Creating trainer...")159trainer = Trainer(160    model=model,161    args=training_args,162    train_dataset=train_dataset,163    eval_dataset=val_dataset,164    data_collator=data_collator,165)166 167# 10. Train168print("\n9. Starting training...")169print("=" * 60)170trainer.train()171 172# 11. Save173print("\n10. Saving model...")174trainer.save_model(str(OUTPUT_DIR / "final"))175tokenizer.save_pretrained(str(OUTPUT_DIR / "final"))176 177print("\n" + "=" * 60)178print("Training complete!")179print(f"Model saved to: {OUTPUT_DIR / 'final'}")180print("=" * 60)181