OPBDH:FT
opbdh ft gathers examples, manages tags and training recipes, sizes a pod for the model and technique, then runs the job through OPBDH’s normal confirmation, spend guard, result sync, and cleanup lifecycle.
Install and start
pip install "opbdh[ft]"
opbdh ft
The optional extra only adds local TOML-writing support. The generated pod installs the GPU training stack—Transformers, TRL, Accelerate, Datasets, PEFT, and BitsAndBytes when QLoRA needs it.
The interactive console can point at existing files or directories, create examples with you, edit tags after loading, select or create a recipe, and preview the launch plan. Use flags instead when you want a repeatable, non-interactive command.
TOML format
Every normalized example has an input, an output, and optional tags. Keep one example per file for easy hand editing, or put many examples in one file.
Base model
input = "Translate hello to Italian"
output = "Ciao"
tags = ["translation", "short"]
Chat model
output = "Ciao! Come posso aiutarti?"
tags = ["italian"]
[[input]]
role = "system"
content = "Reply in Italian."
[[input]]
role = "user"
content = "Hello!"
Several examples in one file
[[examples]]
input = "2 + 2"
output = "4"
tags = ["math"]
[[examples]]
input = "3 + 5"
output = "8"
tags = ["math"]
For a chat example inside an [[examples]] file, add one [[examples.input]] table per message. Multiline TOML strings work for longer prose.
OPBDH also reads a single JSON object, a JSON array, an { "examples": [...] } wrapper, or JSONL with one object per line. A directory is loaded recursively, so one-file-per-example and many-examples-per-file layouts can coexist.
Import data
Convert common provider formats into editable OPBDH TOML without launching a pod:
opbdh ft:import training.jsonl --format openai
opbdh ft:import anthropic-a.jsonl anthropic-b.jsonl \
--format anthropic -o examples.toml
opbdh ft:import training.jsonl --tag imported --tag support
--format auto is the default. OpenAI messages rows and prompt/completion rows are supported. Anthropic message content blocks, a separate system field, and legacy Human:/Assistant: prompt/completion rows are normalized.
The output extension selects TOML, JSON, or JSONL; without --output, the destination is named after the source with .opbdh.toml appended. Pass files directly to opbdh ft --data ... when you want the console to import them into the managed dataset immediately.
Recipes
A named recipe stores the training decisions while the examples remain shared. Use separate recipes to compare techniques, parameter sets, tag slices, providers, or GPU counts without duplicating data.
| Technique | Use it for | Starting defaults |
|---|---|---|
| LoRA | Default adapter training with a full-precision base model. | 2e-4 LR, rank 16, alpha 32, dropout .05 |
| QLoRA | Adapter training with a 4-bit NF4 base-model load and a lower memory floor. | 2e-4 LR, rank 16, alpha 32, dropout .05 |
| Full | Update every model weight when the model and optimizer state fit. | 2e-5 LR |
All techniques begin at three epochs, a 2,048-token maximum length, batch size 1 per GPU, eight gradient-accumulation steps, packing off, and seed 42. Treat these as useful starting points, not universal optima.
The console can switch, create, clone, rename, reset, and delete recipes. A new recipe retains the current model and infrastructure choices but starts from all examples; clone a recipe when you want a controlled variation of every current setting.
opbdh ft --recipe qlora-default --method qlora --dry-run
opbdh ft --recipe full-2gpu --method full --gpu-count 2 \
--learning-rate 1e-5
Launch
The interactive path is simply opbdh ft. A fully specified run can be launched from flags:
opbdh ft \
--data ./examples \
--model Qwen/Qwen3-8B \
--model-type chat \
--recipe lora-4gpu \
--method lora \
--gpu-count 4 \
--max-spend 10
Use --dry-run to normalize the selected rows, generate and verify the runner, size the pod, and print the plan without renting anything. A real run asks for confirmation unless --yes is present.
Core overrides include --epochs, --learning-rate, --max-length, --batch-size, --gradient-accumulation, --lora-r, --lora-alpha, --lora-dropout, --packing, --seed, --vram-gb, --provider, --max-dollars-per-hour, and --max-spend.
Multi-GPU
Set --gpu-count in a recipe or choose the count in the console. OPBDH requests one pod with that many GPUs, prices the whole pod, and launches TRL through Accelerate.
opbdh ft --recipe lora-4gpu --method lora --gpu-count 4
The default strategy is data parallel: each GPU receives a model replica and processes a different slice of the batch. This improves throughput and increases the effective batch size, but every GPU still needs enough memory for one replica. Automatic sizing therefore does not divide the model’s memory requirement by the GPU count.
The chosen model, technique, maximum sequence length, batch size, and GPU count feed the resource estimate. OPBDH then asks the selected provider for the cheapest available pod that satisfies the resulting VRAM, RAM, disk, price, and count constraints.
Project state
Fine-tuning state lives beneath the project where it was created. Run opbdh ft from that directory—or one of its children—to reopen the same dataset and recipes.
.opbdh/
├── finetune.json # named recipes + dataset metadata
└── finetune/
├── data.toml # editable normalized examples
├── jobs/<recipe>/ # runner + selected rows
└── results/<recipe>/<run-id>/
# model/adapter, metrics, logs
Each recipe gets its own generated jobs and result history. Launching another technique against the same data does not overwrite a previous recipe’s artifacts.
Ready. Install opbdh[ft], run opbdh ft, and either point the console at your examples or create the first one there. Start with --dry-run whenever you want to inspect the generated job and pod plan without spending anything.