mirror of https://github.com/razor-ai/soup.git
98 lines
2.5 KiB
Python
98 lines
2.5 KiB
Python
"""soup init — interactive project setup wizard."""
|
|
|
|
from pathlib import Path
|
|
|
|
import typer
|
|
from rich.console import Console
|
|
from rich.panel import Panel
|
|
from rich.prompt import Prompt
|
|
|
|
from soup_cli.config.schema import TEMPLATES
|
|
|
|
console = Console()
|
|
|
|
|
|
def init(
|
|
template: str = typer.Option(
|
|
None,
|
|
"--template",
|
|
"-t",
|
|
help="Use a template: chat, code, medical",
|
|
),
|
|
output: str = typer.Option(
|
|
"soup.yaml",
|
|
"--output",
|
|
"-o",
|
|
help="Output config file path",
|
|
),
|
|
):
|
|
"""Create a new soup.yaml config interactively or from a template."""
|
|
output_path = Path(output)
|
|
|
|
if output_path.exists():
|
|
overwrite = typer.confirm(f"{output_path} already exists. Overwrite?")
|
|
if not overwrite:
|
|
raise typer.Exit()
|
|
|
|
if template:
|
|
if template not in TEMPLATES:
|
|
console.print(f"[red]Unknown template: {template}[/]")
|
|
console.print(f"Available: {', '.join(TEMPLATES.keys())}")
|
|
raise typer.Exit(1)
|
|
config_text = TEMPLATES[template]
|
|
console.print(f"[green]Using template:[/] {template}")
|
|
else:
|
|
config_text = _interactive_wizard()
|
|
|
|
output_path.write_text(config_text, encoding="utf-8")
|
|
console.print(
|
|
Panel(
|
|
f"[bold green]Config saved to {output_path}[/]\n\n"
|
|
f"Next step: [bold]soup train --config {output_path}[/]",
|
|
title="Ready!",
|
|
)
|
|
)
|
|
|
|
|
|
def _interactive_wizard() -> str:
|
|
"""Walk user through config creation."""
|
|
console.print(Panel("[bold]Soup Config Wizard[/]", subtitle="Let's set up your training"))
|
|
|
|
base_model = Prompt.ask(
|
|
"Base model",
|
|
default="meta-llama/Llama-3.1-8B-Instruct",
|
|
)
|
|
task = Prompt.ask("Task", choices=["sft", "dpo"], default="sft")
|
|
data_path = Prompt.ask("Training data path", default="./data/train.jsonl")
|
|
data_format = Prompt.ask(
|
|
"Data format", choices=["alpaca", "sharegpt", "chatml"], default="alpaca",
|
|
)
|
|
epochs = Prompt.ask("Epochs", default="3")
|
|
use_qlora = Prompt.ask("Use QLoRA (4-bit)?", choices=["yes", "no"], default="yes")
|
|
|
|
quantization = "4bit" if use_qlora == "yes" else "none"
|
|
|
|
return f"""# Soup training config
|
|
# Docs: https://github.com/MakazhanAlpamys/Soup
|
|
|
|
base: {base_model}
|
|
task: {task}
|
|
|
|
data:
|
|
train: {data_path}
|
|
format: {data_format}
|
|
val_split: 0.1
|
|
|
|
training:
|
|
epochs: {epochs}
|
|
lr: 2e-5
|
|
batch_size: auto
|
|
lora:
|
|
r: 64
|
|
alpha: 16
|
|
target_modules: auto
|
|
quantization: {quantization}
|
|
|
|
output: ./output
|
|
"""
|