How it works
From dataset to deployed adapter
One form, with a cost estimate and a checkpoint you control before every run.
- 1
Dataset
Pick a validated dataset, or upload one inline without leaving the form.
- 2
Base model
Any self-hosted platform LLM, or your own from the Model Registry.
- 3
Configure
Start from a template or paste your own training parameters.
- 4
Train
LoRA or QLoRA on 1, 2 or 4 GPUs. You see the cost estimate first.
- 5
Evaluate
Perplexity and exact-match on a held-out split.
- 6
Deploy
Attach the adapter to a running instance — no restart.
What you get
Your data, your base, your recipe
Defaults that work, and every knob you need when they do not.
LoRA and QLoRA
Adapters, not full weights. QLoRA is chosen automatically when the base would not fit the selected GPU in bf16, so a large base never fails after the meter starts.
Bring your own base model
Register a Hugging Face repo or weights already on your shared filesystem once, and it appears next to the platform catalogue. Repos are resolved and pinned to a commit so every run is reproducible.
Config templates
Save a recipe at submit with one click and load it next time. Every account starts with Fast iteration, Balanced and Quality templates you can edit or delete.
Custom parameters, honestly
Paste training JSON for anything the form does not show. Every accepted key demonstrably takes effect; an unsupported key is rejected by name instead of being silently ignored.
Multi-GPU by count
Choose 1, 2 or 4 GPUs. Extra GPUs buy wall-clock time — the effective batch and learning rate mean the same thing at any count, so a template behaves identically.
Pay per minute
A cost range is shown before launch and the meter runs only while training or evaluating. If your balance runs out the job pauses on a checkpoint; failed validation is never charged.
Training parameters
Paste any supported parameter — and be told when one is not
The form covers the common knobs. For the rest, paste JSON. Unknown keys are rejected by name rather than silently dropped, so what you set is what trains.
- LoRA: rank, alpha, dropout, target modules, bias, rsLoRA, modules to save
- Schedule: learning rate, epochs, warmup steps or ratio, scheduler type, optimizer
- Batch: micro batch size, gradient accumulation steps, max sequence length, packing
- Regularisation: weight decay, max grad norm, NEFTune noise
- Evaluation: held-out split size, eval cap, perplexity threshold
# pasted into the wizard — merged over the template you loaded
{
"lora": { "r": 16, "alpha": 32, "dropout": 0.05, "use_rslora": true },
"training": {
"learning_rate": 0.0002,
"num_epochs": 3,
"micro_batch_size": 4,
"gradient_accumulation_steps": 4,
"max_seq_length": 4096,
"warmup_ratio": 0.03,
"lr_scheduler_type": "cosine"
}
}
# a typo does not vanish — it is rejected by name:
# config.training.warmup_step is not a supported parameterServe it
Deploy without a restart
A finished adapter lands in your registry. Attach it to a LoRA-enabled inference instance at runtime — many adapters share one base model in GPU memory — and call it by alias.
from openai import OpenAI
client = OpenAI(base_url="https://api.ecohash.com/v1", api_key="YOUR_KEY")
# the adapter's alias from /fine-tuned-models — same API as every other model
response = client.chat.completions.create(
model="ft10:1",
messages=[
{"role": "system", "content": "You are a billing support agent."},
{"role": "user", "content": "Why was I charged twice?"},
],
)
print(response.choices[0].message.content)At a glance
The essentials
- Methods
- LoRA · QLoRA
- GPUs
- 1 · 2 · 4 (data-parallel)
- Base models
- Platform LLMs + your own
- Billing
- Per GPU-minute
- Evaluation
- Perplexity · exact match
- Model alias
- ft10:1
- Trainer
- Non-root, job-scoped credential
- Dataset storage
- Not billed