File size: 4,069 Bytes
7275aef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/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()