|
|
|
|
|
""" |
|
|
Humigence CLI - Main entry point for all Humigence commands |
|
|
""" |
|
|
|
|
|
import typer |
|
|
from typing import Optional |
|
|
from rich.console import Console |
|
|
from rich.panel import Panel |
|
|
from pathlib import Path |
|
|
import sys |
|
|
|
|
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent)) |
|
|
|
|
|
from training.train_wikitext import run_training |
|
|
|
|
|
app = typer.Typer( |
|
|
name="humigence", |
|
|
help="Your AI. Your pipeline. Zero code.", |
|
|
add_completion=False, |
|
|
rich_markup_mode="rich" |
|
|
) |
|
|
|
|
|
console = Console() |
|
|
|
|
|
|
|
|
@app.command() |
|
|
def train_wikitext( |
|
|
model: str = typer.Option( |
|
|
..., |
|
|
"--model", |
|
|
"-m", |
|
|
help="Path or Hugging Face model name (e.g., 'gpt2' or 'microsoft/DialoGPT-small')" |
|
|
), |
|
|
output_dir: str = typer.Option( |
|
|
..., |
|
|
"--output-dir", |
|
|
"-o", |
|
|
help="Directory where checkpoints will be saved" |
|
|
), |
|
|
epochs: int = typer.Option( |
|
|
1, |
|
|
"--epochs", |
|
|
"-e", |
|
|
help="Number of training epochs" |
|
|
), |
|
|
batch_size: int = typer.Option( |
|
|
2, |
|
|
"--batch-size", |
|
|
"-b", |
|
|
help="Per-device batch size" |
|
|
), |
|
|
learning_rate: float = typer.Option( |
|
|
5e-5, |
|
|
"--learning-rate", |
|
|
"-lr", |
|
|
help="Learning rate for training" |
|
|
), |
|
|
dataset: str = typer.Option( |
|
|
"wikitext", |
|
|
"--dataset", |
|
|
help="Dataset name (default: wikitext)" |
|
|
), |
|
|
dataset_config: str = typer.Option( |
|
|
"wikitext-2-raw-v1", |
|
|
"--dataset-config", |
|
|
help="Dataset configuration (default: wikitext-2-raw-v1)" |
|
|
), |
|
|
max_steps: Optional[int] = typer.Option( |
|
|
None, |
|
|
"--max-steps", |
|
|
help="Maximum training steps (overrides epochs if set)" |
|
|
), |
|
|
block_size: int = typer.Option( |
|
|
1024, |
|
|
"--block-size", |
|
|
help="Maximum sequence length" |
|
|
), |
|
|
grad_accum: int = typer.Option( |
|
|
4, |
|
|
"--grad-accum", |
|
|
help="Gradient accumulation steps" |
|
|
), |
|
|
warmup_steps: int = typer.Option( |
|
|
100, |
|
|
"--warmup-steps", |
|
|
help="Number of warmup steps" |
|
|
), |
|
|
logging_steps: int = typer.Option( |
|
|
10, |
|
|
"--logging-steps", |
|
|
help="Logging frequency in steps" |
|
|
), |
|
|
save_steps: int = typer.Option( |
|
|
200, |
|
|
"--save-steps", |
|
|
help="Model saving frequency in steps" |
|
|
), |
|
|
eval_steps: int = typer.Option( |
|
|
200, |
|
|
"--eval-steps", |
|
|
help="Evaluation frequency in steps" |
|
|
), |
|
|
lora_r: int = typer.Option( |
|
|
8, |
|
|
"--lora-r", |
|
|
help="LoRA rank" |
|
|
), |
|
|
lora_alpha: int = typer.Option( |
|
|
32, |
|
|
"--lora-alpha", |
|
|
help="LoRA alpha parameter" |
|
|
), |
|
|
lora_dropout: float = typer.Option( |
|
|
0.05, |
|
|
"--lora-dropout", |
|
|
help="LoRA dropout rate" |
|
|
), |
|
|
): |
|
|
""" |
|
|
Train a model on Wikitext dataset using LoRA fine-tuning. |
|
|
|
|
|
This command fine-tunes a language model on the Wikitext dataset using LoRA (Low-Rank Adaptation) |
|
|
for efficient parameter updates. The training runs on a single GPU by default. |
|
|
|
|
|
Examples: |
|
|
# Basic training with GPT-2 |
|
|
humigence train-wikitext --model gpt2 --output-dir ./out |
|
|
|
|
|
# Training with custom parameters |
|
|
humigence train-wikitext --model microsoft/DialoGPT-small --output-dir ./out --epochs 2 --batch-size 4 --learning-rate 1e-4 |
|
|
|
|
|
# Training with specific steps instead of epochs |
|
|
humigence train-wikitext --model gpt2 --output-dir ./out --max-steps 1000 --batch-size 2 |
|
|
""" |
|
|
|
|
|
|
|
|
config_panel = Panel( |
|
|
f"""[bold blue]Training Configuration[/bold blue] |
|
|
|
|
|
[cyan]Model:[/cyan] {model} |
|
|
[cyan]Output Directory:[/cyan] {output_dir} |
|
|
[cyan]Epochs:[/cyan] {epochs} |
|
|
[cyan]Batch Size:[/cyan] {batch_size} |
|
|
[cyan]Learning Rate:[/cyan] {learning_rate} |
|
|
[cyan]Dataset:[/cyan] {dataset}/{dataset_config} |
|
|
[cyan]Max Steps:[/cyan] {max_steps if max_steps else 'Auto-calculated'} |
|
|
[cyan]Block Size:[/cyan] {block_size} |
|
|
[cyan]Gradient Accumulation:[/cyan] {grad_accum} |
|
|
[cyan]LoRA Rank:[/cyan] {lora_r} |
|
|
[cyan]LoRA Alpha:[/cyan] {lora_alpha} |
|
|
[cyan]LoRA Dropout:[/cyan] {lora_dropout}""", |
|
|
title="π Starting Wikitext Training", |
|
|
border_style="green" |
|
|
) |
|
|
|
|
|
console.print(config_panel) |
|
|
|
|
|
|
|
|
Path(output_dir).mkdir(parents=True, exist_ok=True) |
|
|
|
|
|
|
|
|
try: |
|
|
result = run_training( |
|
|
model=model, |
|
|
output_dir=output_dir, |
|
|
epochs=epochs, |
|
|
batch_size=batch_size, |
|
|
learning_rate=learning_rate, |
|
|
dataset=dataset, |
|
|
dataset_config=dataset_config, |
|
|
max_steps=max_steps, |
|
|
block_size=block_size, |
|
|
grad_accum=grad_accum, |
|
|
warmup_steps=warmup_steps, |
|
|
logging_steps=logging_steps, |
|
|
save_steps=save_steps, |
|
|
eval_steps=eval_steps, |
|
|
lora_r=lora_r, |
|
|
lora_alpha=lora_alpha, |
|
|
lora_dropout=lora_dropout, |
|
|
) |
|
|
|
|
|
if result["status"] == "success": |
|
|
console.print(Panel( |
|
|
f"""[bold green]β
Training Completed Successfully![/bold green] |
|
|
|
|
|
[cyan]Output Directory:[/cyan] {result['output_dir']} |
|
|
[cyan]Model Path:[/cyan] {result['model_path']} |
|
|
|
|
|
[bold blue]Final Metrics:[/bold blue] |
|
|
[cyan]Train Loss:[/cyan] {result['metrics'].get('train_loss', 'N/A')} |
|
|
[cyan]Eval Loss:[/cyan] {result['metrics'].get('eval_loss', 'N/A')} |
|
|
[cyan]Total Steps:[/cyan] {result['metrics'].get('total_steps', 'N/A')} |
|
|
[cyan]Epochs:[/cyan] {result['metrics'].get('epochs', 'N/A')} |
|
|
[cyan]Train Runtime:[/cyan] {result['metrics'].get('train_runtime', 'N/A')}s |
|
|
[cyan]Samples/Second:[/cyan] {result['metrics'].get('train_samples_per_second', 'N/A')}""", |
|
|
title="π Training Results", |
|
|
border_style="green" |
|
|
)) |
|
|
raise typer.Exit(0) |
|
|
else: |
|
|
console.print(Panel( |
|
|
f"""[bold red]β Training Failed[/bold red] |
|
|
|
|
|
[red]Error:[/red] {result.get('error', 'Unknown error')} |
|
|
[cyan]Output Directory:[/cyan] {result.get('output_dir', 'N/A')}""", |
|
|
title="π₯ Training Error", |
|
|
border_style="red" |
|
|
)) |
|
|
raise typer.Exit(1) |
|
|
|
|
|
except Exception as e: |
|
|
console.print(Panel( |
|
|
f"""[bold red]β Unexpected Error[/bold red] |
|
|
|
|
|
[red]Error:[/red] {str(e)}""", |
|
|
title="π₯ Unexpected Error", |
|
|
border_style="red" |
|
|
)) |
|
|
raise typer.Exit(1) |
|
|
|
|
|
|
|
|
@app.command() |
|
|
def version(): |
|
|
"""Show version information.""" |
|
|
console.print("[bold blue]Humigence v1.0.0[/bold blue]") |
|
|
console.print("[dim]Your AI. Your pipeline. Zero code.[/dim]") |
|
|
|
|
|
|
|
|
@app.callback() |
|
|
def main( |
|
|
version: bool = typer.Option( |
|
|
False, |
|
|
"--version", |
|
|
"-v", |
|
|
help="Show version and exit" |
|
|
) |
|
|
): |
|
|
""" |
|
|
Humigence - Your AI. Your pipeline. Zero code. |
|
|
|
|
|
A complete MLOps suite built for makers, teams, and enterprises. |
|
|
""" |
|
|
if version: |
|
|
console.print("[bold blue]Humigence v1.0.0[/bold blue]") |
|
|
console.print("[dim]Your AI. Your pipeline. Zero code.[/dim]") |
|
|
raise typer.Exit(0) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
app() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|