OPBDH

Supervised fine-tuning

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.

base + chat models LoRA · QLoRA · Full OpenAI + Anthropic import 1–N GPUs
Gatherfiles or interactive examples
Curateedit and group with tags
Configurechoose a named recipe
Inspectreview sizing and cost
Launchsync artifacts home

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.

Base versus chat: a string input trains a plain prompt/completion pair. A message-list input is rendered with the selected tokenizer’s chat template, so you provide roles and content while the model supplies its own control tokens.

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.

Tags

Tags stay on the examples, not in a separate index, so the dataset remains portable and readable. After loading data, the console can:

  • bulk add or remove a tag, optionally within an existing group;
  • rename a tag everywhere;
  • edit one example’s tags;
  • clear tags; and
  • choose the groups included in a recipe.

Several selected tags use match-any semantics. Selecting no tags trains on every example, including untagged ones. Repeat --tag for the same behavior outside the console:

opbdh ft --recipe support-only --tag support --tag escalation --dry-run

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.

TechniqueUse it forStarting defaults
LoRADefault adapter training with a full-precision base model.2e-4 LR, rank 16, alpha 32, dropout .05
QLoRAAdapter training with a 4-bit NF4 base-model load and a lower memory floor.2e-4 LR, rank 16, alpha 32, dropout .05
FullUpdate 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.

Same safety rails: fine-tunes use OPBDH’s regular provider selection, billable-compute confirmation, spend guard, continuous artifact sync, and pod cleanup.

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.