humigencev2 / cli /train_lora_cli.py
lilbablo's picture
chore: initial public release of Humigence (CLI wizard + dual-GPU fine-tuning)
7275aef
#!/usr/bin/env python3
"""
Command-line interface for Humigence LoRA training
"""
import argparse
import sys
from pathlib import Path
# Add the humigence directory to Python path
humigence_dir = Path(__file__).parent.parent
sys.path.insert(0, str(humigence_dir))
from cli.train_lora_single import train_lora_single_gpu, main as train_main
def main():
"""Main CLI entry point for LoRA training."""
parser = argparse.ArgumentParser(
description="Humigence LoRA Training CLI",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Train Llama-3 with default settings
humigence train-lora --model meta-llama/Meta-Llama-3-8B-Instruct --output-dir ./out_lora
# Train Mistral with custom parameters
humigence train-lora --model mistralai/Mistral-7B-Instruct-v0.1 --output-dir ./out_mistral --max-steps 2000 --batch-size 2
# Train Phi-2 with custom LoRA settings
humigence train-lora --model microsoft/Phi-2 --output-dir ./out_phi --lora-r 32 --lora-alpha 64
# Use accelerate for better memory management
accelerate launch --num_processes=1 humigence train-lora --model meta-llama/Meta-Llama-3-8B-Instruct --output-dir ./out_lora
"""
)
# Required arguments
parser.add_argument("--model", type=str, required=True, help="Model name or path")
parser.add_argument("--output-dir", type=str, required=True, help="Output directory")
# Dataset arguments
parser.add_argument("--dataset", type=str, default="wikitext", help="Dataset name")
parser.add_argument("--dataset-config", type=str, default="wikitext-2-raw-v1", help="Dataset configuration")
# Training arguments
parser.add_argument("--max-steps", type=int, default=1000, help="Maximum training steps")
parser.add_argument("--batch-size", type=int, default=4, help="Per-device batch size")
parser.add_argument("--grad-accum", type=int, default=4, help="Gradient accumulation steps")
parser.add_argument("--learning-rate", type=float, default=2e-4, help="Learning rate")
parser.add_argument("--block-size", type=int, default=512, help="Block size for text grouping")
# LoRA arguments
parser.add_argument("--lora-r", type=int, default=16, help="LoRA rank")
parser.add_argument("--lora-alpha", type=int, default=32, help="LoRA alpha")
parser.add_argument("--lora-dropout", type=float, default=0.05, help="LoRA dropout")
# Other arguments
parser.add_argument("--warmup-steps", type=int, default=100, help="Number of warmup steps")
parser.add_argument("--logging-steps", type=int, default=10, help="Logging frequency")
parser.add_argument("--save-steps", type=int, default=200, help="Save frequency")
parser.add_argument("--eval-steps", type=int, default=200, help="Evaluation frequency")
parser.add_argument("--save-total-limit", type=int, default=2, help="Maximum number of checkpoints to keep")
args = parser.parse_args()
# Create output directory
Path(args.output_dir).mkdir(parents=True, exist_ok=True)
# Run training
result = train_lora_single_gpu(
model_name=args.model,
dataset_name=args.dataset,
dataset_config=args.dataset_config,
output_dir=args.output_dir,
max_steps=args.max_steps,
batch_size=args.batch_size,
grad_accum=args.grad_accum,
learning_rate=args.learning_rate,
block_size=args.block_size,
lora_r=args.lora_r,
lora_alpha=args.lora_alpha,
lora_dropout=args.lora_dropout,
warmup_steps=args.warmup_steps,
logging_steps=args.logging_steps,
save_steps=args.save_steps,
eval_steps=args.eval_steps,
save_total_limit=args.save_total_limit,
)
# Exit with appropriate code
if result["status"] == "success":
print("✅ Training completed successfully!")
sys.exit(0)
else:
print(f"❌ Training failed: {result.get('error', 'Unknown error')}")
sys.exit(1)
if __name__ == "__main__":
main()