A really beautiful TUI app for local synthetic data generation <3 (we love finetunes)
| bin | ||
| src | ||
| .gitignore | ||
| Cargo.toml | ||
| Finetunify.png | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
Finetunify
A really beautiful TUI app for local synthetic data generation <3 (we love finetunes).
Current version: v0.1.0
Why Finetunify
- Generate train/eval/test splits fast with local Ollama models or OpenRouter
- Tool-calling friendly, JSON-first, and retry-safe
- Clean TUI workflow with previews, logs, and live progress
Requirements
- Rust + Cargo (for building from source or first npm install build)
- Ollama running locally (
ollama serve) for local generation - OpenRouter API key (optional) for cloud model distillation
- At least one local model (
ollama pull llama3) or an OpenRouter model
Installation
npm i -g finetunify
Run:
finetunify
Run from source
cargo run
Config & storage
- Config lives in:
~/.finetunify/finetunify.config.json - Outputs: default to
./output/(relative to the directory you launchfinetunifyfrom) - Checkpoints:
./output/.finetunify_checkpoint.json
Controls
Tabswitch focus (menu/content)Up/Downmove selectionEnterselect page / edit field / run actionSpacetoggle booleansRightopen selected menu itemLeftgo backaadd exampleddelete example:command palettegstart generationsstop generationrrefresh model listqquit
Prompt templating
The global prompt template supports:
{data_spec}{example}{split}{index}{total}
System prompts are split‑specific and editable in the UI.
Tool calling + format
Global tools jsonshould be a JSON array of tool definitions (passed to Ollama/api/chatastools).Global formatcan bejsonor a JSON schema object to constrain output.
Providers (Local + OpenRouter)
You can switch between local Ollama and OpenRouter in Global settings.
OpenRouter options:
OpenRouter API key(stored in config)OpenRouter concurrency(parallel requests)OpenRouter retries(HTTP retry attempts)
Model lists are fetched dynamically based on the selected provider.
Examples + retries
Global examplesaccepts one example per line. Each generated record is seeded with one example (rotating).Global json retriescontrols how many times to retry if the model returns malformed JSON.- The parser strips code fences, extracts the first JSON object/array, and removes trailing commas.
- Live preview updates every 5 generated items on the Generate page.
Command palette
Open with : and run quick commands like:
generatestoprefreshprovider ollama|openrouterset openrouter-key <key>page models|splits|global|examples|logs|generatemodel <name>examples add <text>/examples clear
Output format
Each output line is JSONL (when Wrap output is enabled) and includes:
id,split,model,system,userresponse.content(raw)response.content_json(parsed JSON, if any)response.tool_calls(if any)
If Wrap output is disabled, the raw model response (or tool calls) is written directly.
Troubleshooting
- No models listed: run
ollama listand ensureollama serveis running. - Generation stalls: the app waits for Ollama response; stop will take effect right after the current request completes.
- JSON invalid: increase
Global json retriesor tightenGlobal formatschema.
License
MIT
