Train
Model training and fine-tuning
The train command group covers LLM fine-tuning and iterative agent training.
Usage
praisonai train {generate|validate|benchmark|dedup|from-trials|llm|models|agents|export|serve|list|show|apply|checkpoints|infer|remote}Requirements
Pick the install that matches what you want to train.
| Command | Gets you | When to use |
|---|---|---|
pip install praisonai-train | Agent training via agents/list/show/apply, no CUDA/Unsloth; litellm included for LLM-as-Judge grading | Fastest way to try LLM-as-Judge / human-feedback agent training |
pip install "praisonai-train[llm]" | Above + Unsloth/torch stack for llm, and the praisonai wrapper (pulled in transitively) | Fine-tuning a base model |
pip install praisonai | Full stack: praisonai train ... routes through the code tier | Standard PraisonAI install |
pip install "praisonai[train]" | Now equivalent to praisonai + praisonai-train[llm] | Full stack plus fine-tuning deps |
praisonai train generate
Synthesize an instruction dataset from a teacher LLM.
praisonai train generate [OPTIONS]Options
| Option | Short | Description | Default |
|---|---|---|---|
--config | -c | YAML config file (all keys below can live here) | – |
--output | -o | Output JSONL file (required) | – |
--recipe | -r | Recipe name (e.g. tamil) or an inline dict | tamil |
--deployment | -d | Teacher model / Azure deployment name (required) | – |
--num | -n | Number of examples to generate (required) | – |
--concurrency | – | Parallel teacher requests | 32 |
--start-offset | – | Prompt-index offset for disjoint parallel workers | 0 |
--snapshot-every | – | Copy the output to snapshots/{stem}_{n}.jsonl every N rows | – |
YAML-only keys
These have no CLI flag — set them in --config.
| Key | Type | Default | Description |
|---|---|---|---|
endpoint | str | env AZURE_OPENAI_ENDPOINT / OPENAI_BASE_URL | Chat completions endpoint |
api_key | str | env AZURE_OPENAI_KEY / OPENAI_API_KEY | Bearer / Azure api-key |
azure | bool | auto | Force Azure vs OpenAI routing |
api_version | str | 2024-10-21 | Azure only |
max_completion_tokens | int | 2048 | Teacher max_completion_tokens |
request_timeout | int | 120 | Per-request HTTP timeout (seconds) |
dedup_from | list | [] | JSONL paths whose instruction values are excluded |
stop_file | path | ~/.praisonai_train_stop | Touch this file to halt immediately |
snapshot_dir | path | snapshots | Directory for --snapshot-every snapshots |
Examples
# One-command dataset
praisonai train generate -r tamil -d gpt-4o -n 1000 -o data/tamil.jsonl
# Drive everything from YAML
praisonai train generate --config generate.yaml
# Disjoint parallel slice (offset past the first worker)
praisonai train generate -r tamil -d gpt-4o -n 5000 --start-offset 5000 -o data/b.jsonlSee Dataset Tooling for recipes, dedup, snapshots, and the generate_dataset() Python API.
praisonai train validate
Quality-check and filter an instruction dataset (dedup, boilerplate/refusal, script purity, diversity).
praisonai train validate [OPTIONS] DATASETOptions
| Option | Short | Description | Default |
|---|---|---|---|
dataset (positional) | – | JSONL dataset to validate (or input: in config) | – |
--config | -c | YAML config for thresholds | – |
--out | -o | Write filtered (kept) rows to this JSONL | – |
--no-near-dup | – | Skip the O(n²) near-dup pass on very large datasets | false |
YAML-only keys
| Key | Type | Default | Description |
|---|---|---|---|
near_dup | bool | true | Enable near-duplicate detection |
near_dup_jaccard | float | 0.7 | 4-gram Jaccard threshold (≈ Self-Instruct ROUGE-L 0.7) |
min_output_chars | int | 20 | Below this, output is dropped as too_short |
script_range | [int, int] | [2944, 3071] (Tamil block) | Unicode range that defines the target script |
script_drop | float | 0.5 | Drop rows below this script purity |
script_flag | float | 0.7 | Flag (but keep) rows between script_drop and this |
Examples
# Validate and write the clean rows
praisonai train validate data/tamil.jsonl --out data/clean.jsonl
# Drive thresholds from YAML
praisonai train validate --config validate.yaml
# Skip the O(n^2) near-dup pass on a large dataset
praisonai train validate data/big.jsonl --no-near-dup --out data/clean.jsonlThe command prints an in / kept / drops / flags / metrics report to stdout. Malformed JSONL lines are skipped with a warning — the run still succeeds on the remaining rows.
See Dataset Tooling for the full check list and the score() / filter_rows() Python API.
from-trials --qc reuses this QC filter but auto-disables the Tamil script check for English agent trajectories — pass qc_cfg={"script_range": [...]} to opt back in for another language.
praisonai train benchmark
Measure and rank generation speed across LLM deployments.
praisonai train benchmark [OPTIONS]Options
| Option | Short | Description | Default |
|---|---|---|---|
--config | -c | YAML config file | – |
--deployment | -d | Deployment/model to benchmark (repeatable; required via flag or config) | – |
--n | -n | Requests per deployment | 24 |
--concurrency | – | In-flight requests per deployment | 8 |
--api-version | – | Azure OpenAI api-version | "2024-10-21" |
--max-tokens | – | max_completion_tokens per request | 2048 |
--recipe | -r | Recipe supplying the default prompt | "tamil" |
--json-mode / --no-json-mode | – | Send the response_format JSON hint; disable for endpoints without JSON mode | True |
--output | -o | Write ranked results as JSON | – |
YAML-only keys
| Key | Type | Description |
|---|---|---|
endpoint | str | Shared endpoint for every target (falls back to AZURE_OPENAI_ / OPENAI_) |
api_key | str | Shared API key |
azure | bool | true for Azure OpenAI, false for OpenAI-compatible |
prompt | dict | Explicit {system, user} prompt sent on every request |
request_timeout | int | Per-request timeout in seconds (default 180) |
Examples
# Compare two deployments from the environment credentials
praisonai train benchmark -d gpt-4o -d gpt-4o-mini --n 24 --concurrency 8 -o bench.json
# Drive everything from YAML
praisonai train benchmark --config benchmark.yaml
# OpenAI-compatible endpoint without JSON mode
praisonai train benchmark -d llama-3.1-70b --no-json-modeThe command prints each target as it finishes, then a table ranked by rows/min. n < 1 or concurrency < 1 raises ValueError; if every request fails the CLI exits 1.
See Speed Benchmark for the benchmark_deployments() Python API and cross-endpoint benchmarking.
praisonai train dedup
Merge many JSONL files into one deduped file with a single shared exact + MinHash/LSH index — catching the cross-file near-duplicates that per-file validate always misses.
praisonai train dedup FILES... --out MERGED.jsonl \
[--method minhash|sliding] \
[--threshold 0.7] \
[--exact-only]Options
| Option | Type | Default | Description |
|---|---|---|---|
FILES... (positional) | list[Path] | — | One or more JSONL files to merge and dedup across. Glob expansion happens in the shell (batch_*.jsonl). |
--out | Path | required | Path to write the merged, deduplicated JSONL. |
--method | str | minhash | Near-dup engine — minhash (scalable MinHash + LSH) or sliding (bounded look-back window). |
--threshold | float | 0.7 | Jaccard threshold above which two rows are treated as near-duplicates. |
--exact-only | flag | false | Skip near-dup detection — only sha1 exact matches are removed. Fastest mode. |
--config | Path | — | YAML supplying the same keys (near_dup_method, near_dup_window, minhash_perm, ngram_n, minhash_seed, near_dup_jaccard) for reproducible runs. |
Examples
# Merge parallel-generation batches, remove exact + near-duplicates
praisonai train dedup batch_*.jsonl --out data/merged.jsonl
# Exact-only, fastest path (no near-dup pass)
praisonai train dedup a.jsonl b.jsonl c.jsonl --out merged.jsonl --exact-onlyDrive it from YAML for a reproducible config:
# dedup.yaml
inputs: [batch_1.jsonl, batch_2.jsonl, batch_3.jsonl]
out: data/merged.jsonl
near_dup_method: minhash
near_dup_jaccard: 0.75
minhash_perm: 128
ngram_n: 4
minhash_seed: 1praisonai train dedup --config dedup.yamlThe command prints a in / kept / removed stats block on completion and exits non-zero only on IO errors. The write is atomic — an --out that aliases an input is never truncated before its rows are read.
The global_dedup(), near_dedup(), and MinHashLSH Python API behind this command.
praisonai train data from-trials
Export the passing attempts from a scored trials report into a trainer-ready SFT dataset (plus a provenance sidecar) — the “keep what verified, then fine-tune on it” step of the trials loop.
praisonai train data from-trials REPORT [OPTIONS]Options
| Flag | Short | Type | Default | Description | |
|---|---|---|---|---|---|
REPORT (positional) | — | path | required | Serialised trials-report JSON | |
--out | -o | path | {report_stem}.jsonl | Output JSONL | |
--all | — | flag | false | Include failed / unscored attempts (only_passed=False) | |
--include-saturated | — | flag | false | Include all-pass / zero-pass cases (frontier_only=False) | |
--format | — | messages \ | alpaca | messages | messages = ShareGPT {"conversations": [...]}; alpaca = {instruction, input, output} |
--qc | — | flag | false | Run emitted rows through the same QC filter as validate |
Examples
# Basic: keep passing, tool-free, frontier attempts as ShareGPT rows
praisonai-train data from-trials trials.json -o data/train.jsonl
# Small report: include failed/unscored attempts and saturated cases
praisonai-train data from-trials trials.json --all --include-saturated -o data/train.jsonl
# Alpaca instead of ShareGPT
praisonai-train data from-trials trials.json --format alpaca -o data/train.jsonl
# Run the exported rows through the same QC filter as validate
praisonai-train data from-trials trials.json --qc -o data/train.jsonlEvery run also writes {out}.jsonl.meta.json — a provenance sidecar mapping each emitted row to its source case, attempt, and score.
The selection discipline, export_trials() Python API, provenance sidecar, and the rejection-sampling caveat.
praisonai train llm
Fine-tune an LLM using Unsloth.
praisonai train llm [OPTIONS] [DATASET]Pass a dataset path, or --config a file that names one — one of the two is required.
Options
| Option | Short | Description | Default | |||||
|---|---|---|---|---|---|---|---|---|
--model | -m | Base model to fine-tune — Llama, Gemma, Qwen, Mistral, and Phi bases are validated | – | |||||
--config | -c | Training config YAML. The flags below override it. See Config keys for LLM fine-tuning for every key a config file may set. | – | |||||
--dry-run | – | Print the resolved config as YAML (including the settled remote: block, with credentials redacted) and exit, without training. Bad remote settings are caught here too. Does not load the runner. | false | |||||
--method | – | Training method — `sft \ | cpt \ | dpo \ | orpo \ | kto \ | grpo (method`) | – |
--max-seq-length | – | Sequence length (max_seq_length) | – | |||||
--epochs | – | Epochs (num_train_epochs). Ignored if --max-steps is set. | – | |||||
--max-steps | – | Stop after this many steps (max_steps) | – | |||||
--learning-rate | – | Learning rate (learning_rate) | – | |||||
--batch-size | – | Per-device batch size (per_device_train_batch_size) | – | |||||
--grad-accum | – | Gradient accumulation steps (gradient_accumulation_steps) | – | |||||
--lora-r | – | LoRA rank (lora_r) | – | |||||
--lora-alpha | – | LoRA alpha (lora_alpha) | – | |||||
--output-dir | – | Where checkpoints go (output_dir) | – | |||||
--chat-template | – | Chat template name (chat_template) | – | |||||
--remote-host | – | SSH alias to train on, as in ~/.ssh/config (remote.host). Omit to train locally. | – | |||||
--remote-python | – | Interpreter on the remote host (remote.python) | python3 | |||||
--remote-workdir | – | Directory on the remote host to work in (remote.workdir) | ~/.praisonai-train | |||||
--remote-gpus | – | How many GPUs the remote run expects to find (remote.gpus) | 1 | |||||
--verbose | -v | Verbose output | false |
Precedence
The resolved config is built in three layers — each layer overrides the one above.
| Order | Source | Sets |
|---|---|---|
| 1 | Bare defaults (from TrainModel) | Baseline values |
| 2 | --config config.yaml | Your saved config |
| 3 | Tuning flags on the command line | The keys you override |
An untouched config key survives when a different key is overridden by a flag.
Preview a run with --dry-run
--dry-run prints the resolved config as YAML you can paste back into a file, then a comment listing which keys came from flags — and exits without training.
praisonai-train llm -c config.yaml --lora-r 32 --epochs 2 --dry-runlora_r: 32
max_seq_length: 2048
model_name: unsloth/gemma-2-2b-it-bnb-4bit
num_train_epochs: 2.0
# 2 value(s) came from flags: lora_r, num_train_epochsWhen --remote-host (or --remote-python, --remote-workdir, --remote-gpus) is on the command line, the settled remote: block appears in the printed YAML with credentials redacted — the host, interpreter, workdir, and GPU count the run would actually use:
praisonai-train llm -c config.yaml --remote-host gpubox --dry-runlora_r: 32
model_name: unsloth/gemma-2-2b-it-bnb-4bit
remote:
gpus: 1
host: gpubox
python: python3
workdir: ~/.praisonai-trainA bad remote: block is caught here too: a malformed block exits 1 with Bad remote settings at --dry-run, not after dispatch.
--dry-run does not load the training runner, so it works even without the [llm] extra installed.
Supported models
The trainer uses each model’s own chat template, so chat_template is optional — set it only to override.
| Model family | Example --model | Optional chat_template |
|---|---|---|
| Llama | unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit | llama-3.1 / llama-3 |
| Gemma | unsloth/gemma-2-2b-it-bnb-4bit | gemma / gemma-2 |
| Qwen | unsloth/Qwen2.5-0.5B-Instruct-bnb-4bit | qwen-2.5 / qwen-3 |
| Mistral | unsloth/mistral-7b-instruct-v0.3-bnb-4bit | mistral |
| Phi | unsloth/Phi-3-mini-4k-instruct-bnb-4bit | phi-3 |
Types, defaults, and the fail-fast ValueError when no template is available.
Examples
# Fine-tune with a dataset
praisonai train llm dataset.json
# Fine-tune with a specific base model
praisonai train llm --model llama-3.1 dataset.json
# Fine-tune Gemma or Qwen with their native templates (no config needed)
praisonai train llm dataset.json --model unsloth/gemma-2-2b-it-bnb-4bit
praisonai train llm dataset.json --model unsloth/Qwen2.5-0.5B-Instruct-bnb-4bit
# Override tuning knobs straight from the CLI
praisonai-train llm data.jsonl --lora-r 32 --epochs 2
# Start from a config file, override one key
praisonai-train llm -c config.yaml --max-seq-length 4096
# Preview the resolved config without training
praisonai-train llm -c config.yaml --dry-runWhere config.yaml comes from
The CLI writes ./config.yaml from your flags plus resolved defaults in the invocation directory, then hands that single file to the trainer.
- Materialise the config
praisonai train llmresolves the config (file first, flags on top) and writes it to./config.yamlin the directory you ran from — the only path the legacy dispatcher and its trainer subprocess read. - Back up any existing config.yaml
If a
config.yamlwas already there and its contents differ from what’s about to be written, the previous contents are saved to./config.yaml.bakand the run continues:text NOTE: config.yaml already existed; the previous contents were saved to config.yaml.bak. - No-op writes leave no .bak
Re-running the same command produces no
.bakfile — an identical write is detected and skipped. A first run in an empty directory also writes no.bak.
Config keys for LLM fine-tuning
Drive fine-tuning from config.yaml (all keys optional and backward compatible).
| Key | Type | Default | Description | |
|---|---|---|---|---|
method | str | "sft" | Training method — sft, dpo, orpo, or kto. Case-insensitive. See Preference Training. | |
model | str | — | Alias for model_name (parity with --model). If both are set, model_name wins. | |
method | str | "sft" | Training method. One of sft, cpt, dpo, orpo, kto, grpo. cpt is continued pretraining on a raw-text corpus — see Continued Pretraining; grpo is scored by reward functions — see Reward Functions & GRPO. | |
embedding_learning_rate | float | learning_rate / 10 | Only used when method: cpt. Rate for embed_tokens / lm_head when they are in modules_to_save. | |
chat_template | str | None (model’s own) | Force a specific Unsloth chat template — e.g. "llama-3.1", "gemma", "qwen-2.5". Required when the base model’s tokenizer has no built-in template, else the trainer raises ValueError. | |
assistant_only_loss | `”auto” \ | bool` | "auto" | Mask prompts out of the loss (SFT). "auto" masks whenever a route is available — TRL’s {% generation %} or Unsloth’s turn markers; true forces on (errors only when neither route is available); false forces off. train_on_responses_only is accepted as an alias. |
beta | float | trainer default | Preference-loss temperature for dpo / orpo / kto. | |
max_prompt_length | int | max_seq_length // 2 | Prompt truncation length for dpo / orpo / kto. | |
desirable_weight | float | trainer default | kto only — weight on thumbs-up examples. | |
undesirable_weight | float | trainer default | kto only — weight on thumbs-down examples. | |
dataset[].num_samples | int | — | Train on the first N rows of the split. Positive integer — validated on load. | |
train | bool | true | Set false to skip training and publishing. | |
huggingface_save | bool | false | Push merged LoRA to Hugging Face. Requires hf_model_name. | |
huggingface_save_gguf | bool | false | Push GGUF quantizations to Hugging Face. Requires hf_model_name. | |
ollama_save | bool | false | Push to Ollama. Requires ollama_model. |
Unsloth surface keys
Model access, PEFT selectors, quant, and vLLM rollouts — all optional and additive. See Unsloth Surface for the full walkthrough.
| Key | Type | Default | Area | Description | |
|---|---|---|---|---|---|
hf_token | str | — | model access | HF token. Downloads gated bases and authenticates publishing. Overridden by HF_TOKEN. | |
trust_remote_code | bool | — | model access | Required for custom-code models. | |
revision | str | — | model access | Pin a HF branch, tag, or SHA for reproducibility. | |
finetune_last_n_layers | int | — | PEFT | Tune only the last N transformer blocks. | |
layers_to_transform | `int \ | list[int]` | — | PEFT | Explicit layer indices to adapt. |
layers_pattern | str | — | PEFT | Pattern selecting which layers to adapt. | |
target_parameters | list[str] | — | PEFT | Selectors — required to LoRA MoE experts. | |
init_lora_weights | `str \ | bool` | — | PEFT | LoRA init scheme ("gaussian", "pissa", "olora"). |
merged_save_dir | str | — | quant | Merge the adapter into this local folder — no Hub needed. | |
imatrix_file | str | — | quant | Precomputed importance matrix for imatrix quants. Auto-fetched when unset. | |
fast_inference | bool | false | vLLM | Turn on vLLM rollouts for GRPO. | |
gpu_memory_utilization | float | — | vLLM | vLLM GPU memory fraction. Only sent when fast_inference is on. | |
max_lora_rank | int | — | vLLM | Max LoRA rank vLLM allocates for. Only sent when fast_inference is on. |
See Train → Config.yaml example for the full file.
Publishing
Publishing defaults off — set the flag and its matching target to push a fine-tuned model.
| To publish to | Set flag | And target |
|---|---|---|
| Hugging Face (merged) | huggingface_save: true | hf_model_name |
| Hugging Face (GGUF) | huggingface_save_gguf: true | hf_model_name |
| Ollama | ollama_save: true | ollama_model |
Enabling a flag without its target fails fast on load:
ValueError: hf_model_name is required when huggingface_save or huggingface_save_gguf is enabled.
ValueError: ollama_model is required when ollama_save is enabled.Preflight validation
Before any model or GPU load, the trainer fails fast with a single friendly line for the five most common misconfigurations: stale/missing training deps (checked first, before any heavy import), no CUDA GPU, missing Hugging Face credentials, low disk (< 10 GB free), and an invalid quantization_method. The GPU check is skipped when train: false, so publish-only / export-only runs succeed on CPU.
See Train → Preflight validation for the full check table, fix guidance, and the 35 valid quantization values.
Exit codes
The llm (and the praisonai_train.train.llm.trainer module) entrypoint prints a clean one-line error instead of a traceback for expected failures.
| Exit | Meaning |
|---|---|
0 | Training (or export) completed successfully. |
1 | Expected, actionable failure — printed as a single ERROR: <message> line to stderr with no Python traceback. Covers preflight failures, config errors, HF/Ollama publish errors, and ollama create/push failures. As of PR #4317, a non-zero SystemExit from the router (e.g. missing training deps) also propagates through the train_llm Typer command, so $? sees the failure. Clean exits still return 0. |
130 | Interrupted by Ctrl-C — printed as Interrupted. to stderr. |
| other | An unexpected exception — the full Python traceback is printed (a real bug; please file it). |
Missing-deps behaviour
On a bare pip install praisonai-train, llm prints one of two messages: LLM fine-tuning dependencies not installed with pip install "praisonai-train[llm]" when praisonai-code is absent, or `Failed to load LLM fine-tuning runner:
when praisonai-code` is present but a downstream import (torch/unsloth) failed. See Train for the full flow.
Errors you may see
The most common error after pip install --no-deps or on a hand-built conda env is a stale training stack. The trainer version-checks six packages (torch, transformers, unsloth, trl, peft, bitsandbytes) before any heavy import and prints one actionable block:
Training dependencies are missing or too old.
Missing: unsloth
torch 2.5.1 is older than the required 2.6.0
Install with: pip install -U "unsloth>=2025.9.1" "torch>=2.6.0"Run the printed pip install -U ... command — it upgrades every listed package at once. A dev / rc suffix on a matching release satisfies the floor (2.6.0rc1 counts as 2.6.0). See Train → Runtime version-floor enforcement.
Multi-GPU launch
Fine-tune across every GPU on the machine with torchrun — --nproc_per_node is the number of GPUs.
torchrun --nproc_per_node=2 -m praisonai_train.train.llm.trainer train --config config.yamlThe trainer detects the distributed launch, loads the full model per rank, and lets only rank 0 save and publish. See Multi-GPU for the full walkthrough.
Remote in one step
Send this one run to a remote GPU box with --remote-host — the same as a remote: block in config.yaml or the desktop “Run on” dropdown. Precedence is flag > YAML > default; with no host settled, the command trains locally as before.
praisonai-train llm dataset.json --model unsloth/gemma-2-2b-it-bnb-4bit --remote-host gpuboxThe dispatcher ships the config (stripping the remote: block so the far side does not dispatch again), streams the log, and forwards Ctrl-C to the remote run. Credentials in the block (password, token, identity_file, …) are refused up front. See Remote in one step.
Resume
Set resume_from_checkpoint: true in config.yaml, then re-run the same command — the trainer picks the latest checkpoint in output_dir.
# config.yaml
save_strategy: "steps"
save_steps: 50
resume_from_checkpoint: truepraisonai-train llm config.yamlSee Checkpointing for save_total_limit, best-checkpoint, and early-stopping keys.
Environment variables
torchrun sets the distributed variables; you set only your Hugging Face token.
| Variable | Set by | Purpose |
|---|---|---|
LOCAL_RANK | torchrun | This process’s GPU index on the node. |
WORLD_SIZE | torchrun | Total number of processes / GPUs. |
RANK | torchrun | Global process rank (0 = main process). |
UNSLOTH_USE_NEW_MODEL | trainer | Set to 1 under DDP before unsloth imports (DDP-safe checkpointing). |
HF_TOKEN | you | Needed only when publishing to Hugging Face. |
praisonai train models
List every model praisonai train llm knows how to load — the same catalog model_name is validated against.
praisonai train models [SEARCH] [OPTIONS]Options
| Option | Short | Description | Default |
|---|---|---|---|
search (positional) | — | Case-insensitive substring filter, e.g. gemma, qwen, 7b. | — |
--json | -j | Emit the (filtered) list as a JSON array. | false |
--limit | -n | Max rows to show. 0 shows the full catalog. | 40 |
Examples
# Everything unsloth maps (~246 repos on a recent unsloth release)
praisonai train models
# Just the Gemma family
praisonai train models gemma
# JSON for scripts
praisonai train models --json
# The full list, un-truncated
praisonai train models -n 0Each row is prefixed with * if it’s part of the small curated starting set, or a space otherwise:
* unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit
unsloth/Meta-Llama-3.1-8B-Instruct
...The trailing line explains the marker (* = a good starting point.) and, when the output was truncated, prints {shown} of {total}; -n 0 for all.
How the catalog is built
The command reads unsloth.models.mapper at runtime — both the 4-bit repo keys and their 16-bit mirror values — rather than shipping a vendored copy that would go stale between releases.
When unsloth isn’t installed (the CLI is importable without the training extra), the command falls back to a 7-entry curated list of one current base per family, sized for a single 24 GB GPU in 4-bit. See Supported models.
Exit codes
| Exit | Meaning |
|---|---|
0 | Rows printed, or JSON emitted. |
1 | The filter matched nothing — prints Nothing matches '<search>' with the remediation Try a family name (gemma, qwen, llama) or a size (7b). |
praisonai train export
Publish an already-trained model to Hugging Face, GGUF, or Ollama without re-running training.
praisonai train export {ollama|gguf|hf} --model-dir DIR [--hf REPO] [--ollama NAME] [--quant Q] [--base-model NAME] [--config FILE] [--push|--no-push]Point it at a lora_model/ you trained earlier — no dataset, no re-training. The hf target pushes a merged model to the Hub; gguf writes a local .gguf (and additionally pushes to the Hub when --hf is set); ollama creates and pushes an Ollama model (add --no-push to keep it local).
Options
| Option | Short | Type | Default | Description | ||
|---|---|---|---|---|---|---|
target (positional) | — | ollama \ | gguf \ | hf | required | Export destination. Case-insensitive. An unknown target exits 1 with Use one of: ollama, gguf, hf. |
--model-dir | -d | path | required | Directory of the already-trained model (e.g. lora_model). Must be an existing directory, else exits 1. | ||
--hf | — | str | — | Hugging Face repo id, e.g. me/mymodel. Required for hf; optional for gguf (adds a Hub push on top of the local .gguf). | ||
--ollama | — | str | — | Ollama model name, e.g. me/mymodel. Required for ollama. | ||
--quant | — | str | — | Quantization method for gguf/ollama. One of 35 values — 24 standard plus 11 imatrix; see Export → Valid quant values. An invalid value fails fast, listing every valid choice. | ||
--base-model | — | str | inferred | Base model id for chat-template selection. Auto-inferred from <model-dir>/config.json:_name_or_path, falling back to the directory name. | ||
--config | -c | path | — | Optional config.yaml for extra export knobs (e.g. dtype, load_in_4bit). Must parse to a YAML mapping — a top-level list/scalar exits 1 with Config file must be a YAML mapping. | ||
--mtp-draft | — | flag | false | Also download the stock MTP drafter (Gemma-4 only) for fast inference. A failure here only warns; the export still succeeds. | ||
--push / --no-push | — | bool | push | ollama target: push to ollama.com after ollama create. --no-push keeps the model local. Overrides ollama_push in --config. Ignored for hf/gguf. |
Examples
# Push a merged model to Hugging Face
praisonai-train export hf --model-dir lora_model --hf me/my-model
# Write a local GGUF (and push it to HF when --hf is given)
praisonai-train export gguf --model-dir lora_model --quant q4_k_m
praisonai-train export gguf --model-dir lora_model --hf me/my-model --quant q4_k_m
# Push to Ollama (default)
praisonai-train export ollama --model-dir lora_model --ollama me/my-model --quant q4_k_m
# Keep local only — never upload
praisonai-train export ollama --model-dir lora_model --ollama my-model --quant q4_k_m --no-pushExit codes
| Exit | Meaning |
|---|---|
0 | Success — prints Exported model to <target>. |
1 | Invalid target, missing --model-dir, missing destination for the chosen target, config not a YAML mapping, or any ValueError / RuntimeError / CalledProcessError raised during load or push. Errors print as a single clean line (ERROR: <msg>) — no traceback. |
The TrainModel.for_export() Python API and behaviour notes behind this command.
See praisonai train llm for the full training path that produces the model you export here.
praisonai train agents
Train agents through iterative feedback loops.
praisonai train agents [OPTIONS] [AGENT_FILE]Options
| Option | Short | Description | Default |
|---|---|---|---|
--iterations | -n | Maximum training iterations. In LLM mode, stops early when a score reaches 9.5 (use --no-early-stop to force all). | 3 |
--no-early-stop | – | Run all --iterations even when a score reaches 9.5. | false |
--human | -h | Use human feedback instead of LLM grading | false |
--scenarios | -s | Path to scenarios JSON file | – |
--input | -i | Single input text for training | – |
--expected | -e | Expected output for the input | – |
--output | -o | Output directory for training data | – |
--model | -m | LLM model for grading | gpt-4o-mini |
--verbose / --quiet | -v / -q | Show detailed progress. When --verbose, the orchestrator prints its own post-persist summary; a display-only encoding failure there is logged as a warning and does not affect the exit code. | --verbose |
--dry-run | – | Show what would happen without running | false |
--storage-backend | – | Storage backend: file, sqlite, or redis://url | file |
--storage-path | – | Path for storage backend | – |
Early Stop (LLM mode)
--iterations N is a maximum, not an exact count. In LLM-as-Judge mode, training stops early as soon as any iteration scores ≥ 9.5 — easy factual prompts often finish in one iteration.
When training stops early, an INFO line is logged even in --quiet mode:
INFO ...orchestrator: Early stop after iteration 1/3 (score 10.0 >= 9.5 threshold). Use no_early_stop=True to run all iterations.Reaching 9.5 on the final iteration counts as a full run — Stopped Early stays absent from the summary.
Human-in-the-loop mode (--human) does not use the 9.5 threshold — the user decides when to stop.
Examples
# Simple training with single input
praisonai train agents --input "What is Python?"
# Training with expected output
praisonai train agents --input "What is 2+2?" --expected "4"
# Training with scenarios file
praisonai train agents --scenarios scenarios.json
# Human feedback mode
praisonai train agents --input "Explain AI" --human
# More iterations
praisonai train agents --input "Hello" --iterations 5
# Force all iterations even if a score hits 9.5
praisonai-train agents --input "What is Python?" --iterations 3 --no-early-stop
# See the early-stop INFO line in the console
praisonai-train agents --input "Capital of Italy?" --iterations 3 --verbose
# With agent file
praisonai train agents my_agent.yaml --scenarios scenarios.jsonSummary Rows
When training completes, the summary table always shows Total Iterations, Average / Min / Max Score, Improvement, and Status. Two extra rows appear only when the run was truncated:
| Row | When it appears | Value |
|---|---|---|
Requested Iterations | requested > completed | The value passed via --iterations |
Stopped Early | metadata.early_stopped == True | Yes (score X.X >= 9.5; use --no-early-stop to run all) |
The session JSON persists both signals as metadata.target_iterations (int) and metadata.early_stopped (bool), so tools reading persisted sessions can distinguish “user asked for 3, got 1 due to 9.5” from “user asked for 1, got 1”.
Storage Backend Options
Store training data in different backends.
# SQLite backend (recommended for production)
praisonai train agents --input "Hello" --storage-backend sqlite --storage-path ~/.praisonai/train.db
# Redis backend (for distributed systems)
praisonai train agents --input "Hello" --storage-backend redis://localhost:6379
# File backend (default)
praisonai train agents --input "Hello" --storage-backend file --storage-path ~/.praisonai/trainExit Codes
| Exit | Meaning |
|---|---|
0 | Training completed and the session was persisted. On non-UTF-8 consoles a warning may be printed if the summary display failed to encode. |
1 | Training failed. This includes both runtime exceptions and encoding errors that occur before the report is saved. |
130 | Interrupted by Ctrl-C. |
praisonai train serve
Serve a fine-tuned GGUF over an OpenAI-compatible endpoint — auto-fetching the MTP drafter for lossless fast inference on Gemma-4.
praisonai train serve [OPTIONS]Options
| Option | Short | Description | Default |
|---|---|---|---|
--model-dir | -d | Directory of the trained model (target GGUF auto-detected; drafter files skipped) | – |
--gguf | – | Explicit path to the target GGUF to serve | – |
--config | -c | Optional config.yaml for base-model / MTP knobs | – |
--base-model | – | Base model id used to select the MTP drafter | – |
--mtp-draft / --no-mtp-draft | – | Use the stock MTP drafter (auto: on when the family supports it) | --mtp-draft |
--spec-draft-n-max | – | Max tokens the MTP drafter proposes per step | 2 |
--port | – | Port for llama-server | 8080 |
--ngl | – | Number of layers to offload to GPU | 99 |
--benchmark | – | Run a one-shot speed benchmark instead of serving | false |
How MTP is auto-detected
The base model name (from --base-model, --config, or the model directory’s config.json) drives drafter selection. A Gemma-4 target fetches its matching stock drafter from the Hub; any other family falls back to plain serving with a clear message.
Examples
# Serve a single GGUF on the default OpenAI endpoint (:8080)
praisonai train serve --gguf model.gguf
# Serve from a model directory (target GGUF auto-detected)
praisonai train serve --model-dir lora_model
# One-shot benchmark: tokens/sec + MTP draft acceptance, then exit
praisonai train serve --gguf gemma4-e4b.gguf --benchmarkpraisonai train checkpoints
List the checkpoints a training run saved — answers “what did it save?” without an ls.
praisonai train checkpoints [OPTIONS]Options
| Option | Short | Description | Default |
|---|---|---|---|
--model-dir | -d | Directory the run wrote to (its output_dir) | outputs |
--json | -j | Emit a JSON array instead of the human listing | false |
Examples
# List saved checkpoints, newest step first
praisonai train checkpoints -d outputs
# Machine-readable output for scripts
praisonai train checkpoints -d outputs --jsonMatches checkpoint-<n> exactly (a checkpoint-final directory is skipped), sorts numerically newest-first, and reports each checkpoint’s size on disk. An empty or missing directory exits 1 with a remediation. JSON entries are {"step": int, "path": str, "bytes": int}.
See List Checkpoints for the full workflow and jq patterns.
praisonai train infer
Run a single generation against a model you just trained — answers “did it work?”.
praisonai train infer -d lora_model "Summarise this release."Options
| Option | Short | Description | Default |
|---|---|---|---|
prompt (positional) | – | What to send the model | required |
--model-dir | -d | Path to a trained adapter or model (must exist) | lora_model |
--max-new-tokens | – | Maximum new tokens to generate | 256 |
--temperature | – | Sampling temperature | 0.7 |
--max-seq-length | – | Context length used when loading the model | 2048 |
--load-in-4bit / --no-load-in-4bit | – | Load the model in 4-bit quantisation | true |
Examples
# Simplest one-liner — reply streams to stdout
praisonai train infer -d lora_model "Summarise this release."
# Longer, more focused output
praisonai train infer -d lora_model "Write release notes." \
--max-new-tokens 512 --temperature 0.3Output streams via TextStreamer(skip_prompt=True), so the prompt is not echoed and the first token arrives early. Without the Unsloth / Transformers stack it exits 1 with pip install "praisonai-train[llm]".
See Infer (one-shot inference) for the full walkthrough and the infer vs serve vs benchmark decision guide.
praisonai train list
List all training sessions.
praisonai train list [OPTIONS]Options
| Option | Short | Description | Default |
|---|---|---|---|
--limit | -n | Max sessions to show | 20 |
--json | -j | Output as JSON | false |
--storage-backend | – | Storage backend: file, sqlite, or redis://url | file |
--storage-path | – | Path for storage backend (file dir or sqlite db path) | – |
Examples
# List recent sessions
praisonai train list
# Show more sessions as JSON
praisonai train list --limit 50 --json
# List sessions from a SQLite backend
praisonai train list --storage-backend sqlite --storage-path ~/.praisonai/train.db
# List sessions from Redis
praisonai train list --storage-backend redis://localhost:6379
# List sessions from a custom file directory
praisonai train list --storage-backend file --storage-path ~/.praisonai/trainEach row shows the session ID, iteration count, size, and last-modified time.
praisonai train show
Show details of a training session, including its iterations and best score.
praisonai train show [OPTIONS] SESSION_IDOptions
| Option | Short | Description | Default |
|---|---|---|---|
--iterations | -i | Show detailed iteration info | false |
--json | -j | Output as JSON | false |
--storage-backend | – | Storage backend: file, sqlite, or redis://url | file |
--storage-path | – | Path for storage backend (file dir or sqlite db path) | – |
Examples
# Show session summary
praisonai train show train-abc123
# Show with detailed iterations
praisonai train show train-abc123 --iterations
# Output as JSON
praisonai train show train-abc123 --json
# Session stored in a SQLite database
praisonai train show train-abc123 \
--storage-backend sqlite --storage-path ~/.praisonai/train.db
# Session stored in Redis
praisonai train show train-abc123 --storage-backend redis://localhost:6379
# Session stored in a custom file directory
praisonai train show train-abc123 \
--storage-backend file --storage-path ~/.praisonai/trainThe summary highlights the best iteration (★) with its score and feedback.
praisonai train apply
Apply learned suggestions from a session to an agent via hooks. Uses the best-scoring iteration by default.
praisonai train apply [OPTIONS] SESSION_IDOptions
| Option | Short | Description | Default |
|---|---|---|---|
--agent | -a | Path to agent YAML file | – |
--iteration | -n | Specific iteration number | best score |
--run | -r | Run agent with this prompt after applying | – |
--json | -j | Output as JSON | false |
--storage-backend | – | Storage backend: file, sqlite, or redis://url | file |
--storage-path | – | Path for storage backend (file dir or sqlite db path) | – |
Examples
# Apply best iteration to default agent
praisonai train apply train-abc123
# Apply a specific iteration
praisonai train apply train-abc123 --iteration 2
# Apply to an agent from a YAML file
praisonai train apply train-abc123 --agent my_agent.yaml
# Apply and run immediately
praisonai train apply train-abc123 --run "Hello, how are you?"
# Apply a session stored in SQLite
praisonai train apply train-abc123 \
--storage-backend sqlite --storage-path ~/.praisonai/train.db
# Apply a session stored in Redis, then run
praisonai train apply train-abc123 \
--storage-backend redis://localhost:6379 \
--run "Hello, how are you?"
# Apply a session written to a custom file dir
praisonai train apply train-abc123 \
--storage-backend file --storage-path ~/.praisonai/trainStandalone script
Install praisonai-train on its own to get a praisonai-train console script that exposes the same subcommands directly.
pip install praisonai-train
praisonai-train agents --input "What is Python?"
praisonai-train data from-trials trials.json -o data/train.jsonl
praisonai-train list
praisonai-train show train-abc123 --iterations
praisonai-train apply train-abc123 --iteration 2 --run "Hello, how are you?"
praisonai-train export hf --model-dir lora_model --hf me/my-modelEvery praisonai train <sub> example above runs as-is with the praisonai-train <sub> prefix.
See Also
- Train – Training overview and fine-tuning setup
- Export a trained model – Publish a trained model without re-training
- Unsloth Surface – Gated models, PEFT selectors, offline merge, and vLLM rollouts
- Train → Preflight validation – Fast, friendly config checks before any GPU load
- Serve & MTP Fast-Inference – Serve a GGUF over OpenAI HTTP with MTP speculative decoding
- Dataset Tooling – Generate and quality-check instruction datasets
- praisonai-train Package – Standalone package guide
- Multi-GPU Training – Fine-tune across multiple GPUs with torchrun
- Remote Training – Ship a run to a GPU box over SSH with the
remotegroup - Remote in one step – Send a run to a remote GPU box with
--remote-host,remote:YAML, or the desktop dropdown - Checkpointing – Save, resume, and keep the best checkpoint
- Eval – Evaluation and testing
- Storage Backends – Pluggable storage backends