praisonai-train Package

Train agents or fine-tune LLMs without installing the full PraisonAI wrapper

Train agents or fine-tune LLMs without installing the full PraisonAI wrapper.

Diagram

praisonai-train

🤖 Agent

⚙️ praisonai-train agents

⭐ Grader / Human

✅ Improved Agent

🧪 trials.json

♻️ data from-trials

📋 Dataset

⚙️ praisonai-train llm
⚙️ Multi-GPU

✅ LoRA Model

🚀 export

HF / GGUF / Ollama

The praisonai-train PyPI package (import: praisonai_train) is Tier 2c — it sits on top of praisonaiagents and gives you the train CLI group and a standalone praisonai-train console script.

Prefer a UI? See Desktop → Training

The PraisonAI Desktop app wraps praisonai-train llm in a Train tab — live loss chart, log, and reconnect-safe progress.

Quick Start

  1. Agent Training

    Improve an agent iteratively — no ML dependencies required.

    python
    from praisonaiagents import Agent
    
    agent = Agent(instructions="You are a helpful assistant.")
    bash
    pip install praisonai-train
    
    praisonai-train agents --input "What is Python?"
  2. LLM Fine-tuning

    Add the [llm] extra to pull the modern Unsloth/torch stack (unsloth>=2025.9.1, trl>=0.18.2, transformers>=4.51.3, torch>=2.6.0). The trainer uses each model’s own chat template, so chat_template is optional.

    bash
    pip install "praisonai-train[llm]"

    Llama

    bash
    praisonai-train llm dataset.json \
        --model unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit

    Gemma

    bash
    praisonai-train llm dataset.json \
        --model unsloth/gemma-2-2b-it-bnb-4bit

    Qwen

    bash
    praisonai-train llm dataset.json \
        --model unsloth/Qwen2.5-0.5B-Instruct-bnb-4bit

    From a config file

    Preview a run before you spend GPU time — --dry-run prints the resolved config and exits without loading the trainer. The tuning flags override the file (file first, flags on top).

    bash
    # Preview the resolved config before spending GPU time
    praisonai-train llm -c config.yaml --lora-r 32 --epochs 2 --dry-run
    
    # Then run it — flags override the file
    praisonai-train llm -c config.yaml --lora-r 32 --epochs 2

    Send it to a remote GPU box

    No GPU on this machine? Add --remote-host and the run happens on another box over SSH — the same as a remote: block in YAML or the desktop “Run on” dropdown. Set up key auth once with ssh-copy-id gpubox.

    bash
    praisonai-train llm dataset.json \
        --model unsloth/gemma-2-2b-it-bnb-4bit \
        --remote-host gpubox

    The log streams while training; Ctrl-C stops the remote run. See Remote in one step.

  3. Serve a trained model

    Serve a fine-tuned GGUF over an OpenAI-compatible endpoint — Gemma-4 auto-fetches its MTP drafter for lossless fast inference.

    bash
    praisonai-train serve --gguf model.gguf

    See Serve & MTP Fast-Inference for the full walkthrough.


Beginner-safe defaults

A minimal fine-tuning config trains locally and pushes nowhere unless you opt in.

yaml
model_name: "unsloth/gemma-2-2b-it-bnb-4bit"
max_seq_length: 2048
dataset:
  - name: "yahma/alpaca-cleaned"
    num_samples: 20   # subset for a fast smoke test
bash
# Trains locally, saves LoRA to lora_model/, no push.
praisonai-train llm dataset.yaml

Four headline safety guarantees (PraisonAI #3279):

  • A minimal config trains locally — publishing to Hugging Face or Ollama is opt-in (set the flag and its target).
  • assistant_only_loss: auto never crashes on a stock Gemma / Qwen / Llama template — it now masks via Unsloth turn markers when the template lacks {% generation %}, and falls back to full-sequence SFT only when neither route is available.
  • Unknown / misnamed keys warn instead of crashing — a typo logs WARNING: ignoring unknown config key '...' and training continues.
  • Environment preflight — missing or out-of-date training deps are now caught before the first heavy import; the CLI prints one pip install -U ... line that fixes them all.
  • An unknown model_name warns, it doesn’t fail — the trainer prints one line pointing at praisonai-train models (with a “did you mean?” suggestion when there’s a close match) and continues, because unsloth also loads models it doesn’t map.

Just before training, the trainer prints a run-summary block confirming the resolved model, example count, loss mask, steps, and output dir — see Train → Run summary.


Supported dataset shapes

Point praisonai-train llm at any of these shapes and it formats rows for training automatically — no rename: block needed.

Diagram

messages
OpenAI / export_sft

Chat template

conversations
ShareGPT

instruction / input / output
Alpaca

Alpaca formatter

text
Raw text

Used as-is

ShapeExample rowHow the trainer handles it
Chat — conversations{"conversations":[{"role":"user",...},{"role":"assistant",...}]}Standardised (ShareGPT) and formatted with the chat template
Chat — messages{"messages":[{"role":"user",...},{"role":"assistant",...}]}Renamed to conversations automatically, then handled the same way
Alpaca{"instruction":"...","input":"...","output":"..."}Alpaca formatter
Raw text{"text":"..."}Trained on as-is

A dataset that already has a conversations column is left alone (no rename, no overwrite). Preference-tuning runs (method: dpo / orpo / kto / grpo) keep their own required columns unchanged.


When to Use praisonai-train vs praisonai train

Install the standalone package when you only need training; use the wrapper’s praisonai train when you already run the full stack.

Diagram

Already have the
full wrapper

Just agent training

Agent training +
LLM fine-tuning

Fine-tune on
multiple GPUs

Full stack +
fine-tuning deps

What do I need?

praisonai train …

pip install praisonai-train

pip install praisonai-train[llm]

torchrun –nproc_per_node=N …

pip install praisonai[train]

Both entry points expose the same commands: every praisonai train <sub> also runs as praisonai-train <sub>.


CLI Subcommands

Eleven subcommands cover dataset tooling, benchmarking, fine-tuning, model discovery, serving, export, and agent training.

SubcommandPurpose
praisonai-train generate [--config FILE]Synthesize an instruction dataset from a teacher LLM
praisonai-train validate DATASET [--out FILE]Quality-check / filter an instruction dataset
praisonai-train data from-trials REPORTExport passing trial attempts to a trainer-ready SFT dataset
praisonai-train benchmark -d DEPLOYMENT ...Rank deployments by generation speed
praisonai-train llm DATASETFine-tune an LLM via Unsloth (as of PR #4317, the wrapper route praisonai train llm also actually launches the trainer instead of falling through to a chat prompt)
praisonai-train models [SEARCH]List the models the trainer knows how to load — with --json / -n and * starting-point markers
`praisonai-train export {ollama\gguf\hf}`Publish an already-trained model without re-running training
praisonai-train agents [AGENT_FILE]Iteratively train an agent
praisonai-train serve --gguf FILE [--benchmark]Serve a fine-tuned GGUF over an OpenAI-compatible endpoint (auto-fetches the MTP drafter on Gemma-4)
praisonai-train listList training sessions
praisonai-train show SESSION_IDShow a session’s iterations and best score
praisonai-train apply SESSION_IDApply learned suggestions to an agent

See Train CLI for full flags.


Supported models

praisonai-train llm fine-tunes any Unsloth-supported model. The full list — ~246 repos on a recent unsloth release, including every 4-bit key and its 16-bit mirror — is discoverable from the CLI itself:

bash
praisonai-train models              # everything, capped at 40
praisonai-train models gemma        # filter by family
praisonai-train models 7b           # or by size
praisonai-train models --json       # machine-readable
praisonai-train models -n 0         # the full list

Rows marked * are the curated starting set — one current base per major family, sized to fit a single 24 GB GPU in 4-bit. Pick one of these if you haven’t chosen yet:

Model familyCurated --modelOptional chat_template
Llamaunsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bitllama-3.1 / llama-3
Qwenunsloth/Qwen2.5-7B-Instruct-bnb-4bitqwen-2.5 / qwen-3
Gemmaunsloth/gemma-2-9b-it-bnb-4bitgemma / gemma-2
Mistralunsloth/mistral-7b-instruct-v0.3-bnb-4bitmistral
Phiunsloth/Phi-3.5-mini-instruct-bnb-4bitphi-3
Qwen (small)unsloth/Qwen2.5-3B-Instruct-bnb-4bitqwen-2.5
Gemma (small)unsloth/gemma-2-2b-it-bnb-4bitgemma / gemma-2

The trainer uses each model’s own chat template, so chat_template is optional — set it only to override.


Common Patterns

Fine-tune a non-Llama base (Gemma / Qwen)

Point --model at any Gemma or Qwen base — the trainer uses each model’s own chat template automatically.

bash
pip install "praisonai-train[llm]"

# Gemma 2 (uses the model's own template automatically)
praisonai-train llm dataset.json \
    --model unsloth/gemma-2-2b-it-bnb-4bit

# Qwen 2.5
praisonai-train llm dataset.json \
    --model unsloth/Qwen2.5-0.5B-Instruct-bnb-4bit

Fine-tune on 2 GPUs with checkpointing

Launch under torchrun and add a handful of checkpoint keys — an interrupted run resumes from the latest. See Multi-GPU.

yaml
# config.yaml
model_name: "unsloth/gemma-2-2b-it-bnb-4bit"
max_seq_length: 2048
dataset:
  - name: "yahma/alpaca-cleaned"
save_strategy: "steps"
save_steps: 50
resume_from_checkpoint: true
bash
torchrun --nproc_per_node=2 -m praisonai_train.train.llm.trainer train --config config.yaml

Train, review, apply

Run a training session, inspect the iterations, then bake the best one into your agent.

bash
# --iterations N is a max — training stops early on a score >= 9.5 in LLM mode
praisonai-train agents --input "Explain AI" --human
praisonai-train list
praisonai-train show train-abc123 --iterations
praisonai-train apply train-abc123 --run "Explain AI"

Apply in Python

Apply a session’s suggestions to an agent directly.

python
from praisonaiagents import Agent
from praisonai_train.train.agents import apply_training

agent = Agent(instructions="You are a helpful assistant.")
apply_training(agent, session_id="train-abc123")

Train on any console

The same commands run identically on macOS, Linux, and Windows — no encoding configuration needed.

python
# Works identically on macOS/Linux/Windows — no encoding config needed
from praisonaiagents import Agent

agent = Agent(instructions="You are a helpful assistant.")
bash
# On a Windows cp1252 console, the summary renders as plain ASCII
# and the session is still persisted for later review.
praisonai-train agents --input "What is Python?"
praisonai-train show train-abc123

Force all iterations

Benchmarks, regression tests, and demos that need to observe the feedback loop across every iteration should pass --no-early-stop (CLI) or no_early_stop=True (Python) so the 9.5 threshold is bypassed.

bash
# CLI — always runs all 3 iterations
praisonai-train agents --input "What is Python?" --iterations 3 --no-early-stop
python
from praisonaiagents import Agent
from praisonai_train.train.agents import AgentTrainer, TrainingScenario

agent = Agent(instructions="You are a helpful assistant.")
trainer = AgentTrainer(agent=agent, iterations=3, no_early_stop=True)
trainer.scenarios.append(TrainingScenario(input_text="What is Python?"))
report = trainer.run()

Without this flag, --iterations behaves as a maximum in LLM-as-Judge mode — training stops as soon as any iteration scores ≥ 9.5.


Exporting an already-trained model

Publish a lora_model/ you trained earlier — no dataset, no re-training.

Diagram

✅ lora_model

🚀 praisonai-train export

Hugging Face

GGUF

Ollama

  1. Push to Hugging Face
    bash
    praisonai-train export hf --model-dir lora_model --hf me/my-model
  2. Export a GGUF

    Writes a local .gguf; add --hf to also push it to the Hub.

    bash
    praisonai-train export gguf --model-dir lora_model --hf me/my-model --quant q4_k_m
  3. Push to Ollama
    bash
    praisonai-train export ollama --model-dir lora_model --ollama me/my-model --quant q4_k_m
Export doesn't need a dataset

for_export() skips the training-only validation, so an export-only run needs no dataset: — and no config file at all.

Chat template is inferred

The base model (for chat-template selection) is read from <model-dir>/config.json:_name_or_path, falling back to the directory name. Override it with --base-model.

Quantization is validated up front

--quant accepts the same values as the LLM training path (q4_k_m, q5_k_m, q8_0, q4_0, q4_1, q5_0, q5_1, q3_k_m, q6_k, f16, bf16, q2_k). A typo fails fast, listing every valid choice.

Ollama needs a namespaced model + registered key

The model must be namespaced <username>/<name>, and your public key must be registered at https://ollama.com/settings/keys. An unauthorized push tells you exactly where to click and prints your local ~/.ollama/id_ed25519.pub.

Python API

Export-only, straight from a config dict — no dataset required.

python
from praisonai_train import TrainModel

trainer = TrainModel.for_export({
    "model_name": "unsloth/gemma-2-2b-it-bnb-4bit",
    "final_model_dir": "lora_model",
    "hf_model_name": "me/my-model",
    "quantization_method": "q4_k_m",
})
model, tokenizer = trainer.load_model()
trainer.model, trainer.hf_tokenizer = model, tokenizer
trainer.save_model_merged()            # merged HF push
# or  trainer.push_model_gguf()        # GGUF-to-HF push
# or  trainer.create_and_push_ollama_model()   # Ollama push

See praisonai train export for every flag and exit code.


Windows & non-UTF-8 Consoles

praisonai-train agents renders its summary table with emoji (✅ PASSED, ❌ NEEDS WORK, ★ best-iteration marker) when stdout supports UTF-8, and automatically falls back to ASCII (PASSED, NEEDS WORK, *) when it doesn’t. It detects the console’s encoding at runtime.

Diagram

UTF-8

cp1252 / ASCII

No

Yes

praisonai-train agents

stdout
encoding?

Rich table + emoji
PASSED tick / star marker

Rich table + ASCII labels
PASSED / * marker

Rich still
UnicodeEncodeError?

Plain-text summary
Key: value lines


Exit Codes

praisonai-train agents reports three distinct outcomes.

ExitMeaning
0Training completed and the report was persisted (praisonai-train list will show it). A warning is printed if only the console display failed to encode.
1Training itself failed — the run raised an exception (including encoding errors that hit before save_report) or arguments were invalid. No report is persisted.
130Interrupted by Ctrl-C.

Best Practices

Install the base package for agent training

pip install praisonai-train pulls praisonaiagents plus litellm (needed for LLM-as-Judge grading) — enough for agents, list, show, and apply. Add [llm] only when you need Unsloth fine-tuning.

Use the standalone script when you don't want the wrapper

The praisonai-train console script exposes the full train group without installing praisonai. Ideal for lightweight training-only environments.

Old imports keep working

Existing praisonai.train.*, praisonai.train_vision, and praisonai.upload_vision imports still resolve to the same module objects in praisonai_train. Nothing to migrate.

Let the tokenizer's native template win

For LLM fine-tuning, only set chat_template for models without one, or to force a specific one. Forcing llama-3.1 on Gemma/Qwen was the old default and silently corrupted training — the trainer now uses each model’s own template by default. See Train → Chat Template.

Update to the modern Unsloth stack

The [llm] extra now requires unsloth>=2025.9.1, trl>=0.18.2, transformers>=4.51.3, and torch>=2.6.0. If you had pinned trl<0.9.0, upgrade — the pre-0.9 TRL API is no longer supported. As of PraisonAI PR #4365, the trainer refuses to import a stale stack at all and tells you the exact pip install -U ... to run.

Fix a GPU out-of-memory run in order

When a fine-tuning run stops with “The GPU ran out of memory”, lower max_seq_length first (biggest lever), then enable use_gradient_checkpointing: unsloth, then halve per_device_train_batch_size while doubling gradient_accumulation_steps, and switch to a 4-bit base model only as a last resort. See Train → GPU out of memory for the full walkthrough.


Related