Skip to main content

Hyperparameters

Overview

When you post-train a model on Emissary, hyperparameters are the knobs that control how training runs — how fast the model learns, how long it trains, how much memory it uses, and how strongly it's regularized. Every job ships with defaults that reflect our recommended starting points, so you can train a solid model without touching any of them. This page is for when you do want to adjust: it explains each parameter, its range, and how to change it for common situations.

Emissary supports two post-training techniques, and they expose slightly different hyperparameters:

  • SFT (Supervised Fine-Tuning) — trains the model to imitate the input→output pairs in your dataset. Available for all fine-tunable task types.
  • GRPO (Group Relative Policy Optimization) — a reinforcement-learning technique that optimizes the model against a reward by comparing multiple sampled completions per prompt. Available for the text-generation task type only.

Both techniques fine-tune with LoRA adapters rather than updating the full model, so memory-related guidance below assumes LoRA.

You set these in the Hyperparameters (Advanced) section when creating a training job; every field is prefilled with the default and has an inline tooltip.


How to read this page

Each parameter lists the technique(s) it applies to, its type, its allowed range, and the default for each technique. A few conventions:

  • Range shows the lower and upper bounds. ≥ 1 means there is no fixed upper bound — use a value appropriate to your dataset and hardware.

  • Default columns show the value used by SFT and by GRPO. A dash (—) means the parameter isn't exposed for that technique.

  • Effective batch size appears throughout. It's the number of examples that contribute to one optimizer step:

    effective_batch_size = per_device_train_batch_size × gradient_accumulation_steps × num_gpus

Training duration & data

ParameterTypeRangeSFT defaultGRPO default
num_train_epochs — Number of Training Epochsint≥ 1515
downsample_size — Downsample Ratioint1–100100

num_train_epochs is how many full passes the model makes over your training data. Too few epochs and the model underfits (it hasn't learned enough); too many and it starts to overfit, memorizing the training set at the expense of generalization — a bigger risk on small datasets. Watch eval loss to find the sweet spot. GRPO defaults higher because each epoch makes smaller policy updates.

downsample_size (SFT) is the percentage of your dataset to actually train on, from 1 to 100. Leave it at 100 for real runs; drop it lower to train on a random subsample for fast experimentation or debugging without waiting for the full dataset.


Learning rate & schedule

ParameterTypeRangeSFT defaultGRPO default
learning_rate — Learning Ratefloat0–12e-45e-6
lr_scheduler_type — LR Scheduler Typestrsee valueslinearcosine
warmup_ratio — Warm-up Ratiofloat0–10.030.1

learning_rate is the single most impactful knob. It sets how big a step the optimizer takes on each update. Too high causes instability or divergence (loss spikes, NaNs); too low makes training crawl or stall. Typical ranges are 1e-4 to 5e-4 for LoRA and 1e-5 to 5e-5 for full fine-tuning. GRPO uses a much smaller rate (5e-6) because RL updates are noisier and need to be gentle to stay stable.

lr_scheduler_type controls how the learning rate changes over the run. Available values: linear, cosine, constant, constant_with_warmup, polynomial.

  • linear — decays linearly to 0.
  • cosine — decays smoothly along a cosine curve; often the best choice for LLM fine-tuning.
  • constant — holds the rate fixed.
  • constant_with_warmup — warms up, then holds constant.
  • polynomial — decays along a polynomial curve.

warmup_ratio is the fraction of total steps spent ramping the learning rate up from 0 to its target at the start of training. Warmup prevents large, destabilizing early updates. Typical values are 0.030.1; raise it if early training is unstable.


Optimizer & regularization

ParameterTypeRangeSFT defaultGRPO default
optim — Optimizerstrsee valuesadamw_torchpaged_adamw_8bit
weight_decay — Weight Decayfloat0–100.1
max_grad_norm — Max Gradient Normfloat0–100.30.1
adam_beta1 — Adam Beta 1float0–10.9
adam_beta2 — Adam Beta 2float0–10.99

optim selects the optimizer and, with it, the memory/precision trade-off. Available values: adamw_torch, paged_adamw_8bit, adamw_8bit, adamw_bnb_8bit, paged_adamw_32bit, adafactor.

  • adamw_torch — standard, high-precision; the safe default.
  • adamw_8bit / adamw_bnb_8bit — store optimizer state in 8-bit to cut memory significantly.
  • paged_* — page optimizer state to CPU to avoid out-of-memory errors on tight GPUs.
  • adafactor — lowest memory, at the cost of slower convergence.

weight_decay is L2 regularization that discourages large weights and curbs overfitting. Common values are 00.1 (0 disables it). With LoRA it applies to the adapter weights, not the frozen base model.

max_grad_norm caps the gradient norm: any update larger than this is rescaled down, which prevents exploding gradients. Lower values (0.31.0) make training more stable; 1.0 is the common default outside LoRA setups.

adam_beta1 / adam_beta2 (GRPO) are the Adam momentum terms — the decay rates for the running averages of the gradient and the squared gradient. adam_beta1 (0.9) rarely needs changing. adam_beta2 defaults to 0.99 here (below the library's usual 0.999) so the optimizer adapts faster to recent gradients, which helps stabilize LLM training.


Batch size & memory

ParameterTypeRangeSFT defaultGRPO default
per_device_train_batch_size — Training Batch Sizeint≥ 144
gradient_accumulation_steps — Gradient Accumulation Stepsint≥ 141
per_device_eval_batch_size — Evaluation Batch Sizeint≥ 14
eval_accumulation_steps — Evaluation Accumulation Stepsint≥ 150

per_device_train_batch_size is how many examples each GPU processes at once. Larger batches give smoother, more stable gradients but use more GPU memory — it's the first thing to reduce if you hit out-of-memory errors.

gradient_accumulation_steps lets you simulate a larger batch without the memory cost: the optimizer waits this many forward/backward passes before updating. Raising it increases the effective batch size while keeping per-step memory flat. To keep effective batch size constant while lowering memory, halve the batch size and double accumulation steps.

per_device_eval_batch_size (SFT) is the same idea for evaluation. It can usually be larger than the training batch size since no gradients or optimizer state are stored during eval.

eval_accumulation_steps (SFT) is how many prediction steps accumulate on the GPU before results move to CPU during evaluation. Higher is faster but uses more GPU memory; lower it to relieve memory pressure on large eval sets.


LoRA capacity

ParameterTypeAllowed valuesSFT defaultGRPO default
lora_rank — LoRA Rankint4, 8, 16, 32, 648

lora_rank sets the rank of the low-rank adapter matrices — effectively the adapter's capacity. Higher ranks add trainable parameters (more ability to fit complex behavior) but use more memory and can overfit on small datasets. Use 8–16 for most tasks; reach for 32–64 only when the task genuinely demands more representational capacity and you have the data to support it.


GRPO sampling

ParameterTypeRangeSFT defaultGRPO default
num_generations — Number of Generationsint≥ 14

num_generations (GRPO) is how many completions are sampled per prompt. GRPO computes each completion's advantage relative to the others for the same prompt, so this must be at least 2 — and it should evenly divide the effective batch size. More generations give a better reward comparison (lower-variance updates) but cost more memory and generation time per step.


Logging & checkpointing

ParameterTypeRangeSFT defaultGRPO default
logging_steps — Logging Stepsint≥ 1101
save_steps — Save Stepsint≥ 1250

logging_steps controls how often (in steps) training metrics like loss and learning rate are recorded. Lower values give finer-grained loss curves at the cost of more log volume.

save_steps (GRPO) controls how often a checkpoint is written, in steps. Lower values checkpoint more frequently — finer recovery and more points to evaluate — but use more storage. It applies only when the save strategy is step-based rather than epoch-based.


Recommendations

Start from the defaults and change one thing at a time, watching the eval loss (and your test-function metrics) after each run. The scenarios below are the most common reasons to adjust.

The model is overfitting

Symptom: training loss keeps falling but eval loss flattens or rises.

  • Lower num_train_epochs, or deploy an earlier checkpoint from before eval loss turned up.
  • Increase weight_decay (e.g. 0.010.1).
  • Lower lora_rank (e.g. 168) to reduce adapter capacity.
  • Enable dynamic_loss if the overfitting is driven by an imbalanced dataset (SFT).

The model is underfitting

Symptom: both training and eval loss stay high; outputs don't reflect your data.

  • Increase num_train_epochs.
  • Raise learning_rate within the LoRA range (1e-45e-4).
  • Increase lora_rank (816/32) to give the adapter more capacity.
  • Confirm downsample_size is 100 so you're training on the full dataset.

Training is unstable or diverging

Symptom: loss spikes, oscillates, or becomes NaN.

  • Lower learning_rate — the most common fix.
  • Tighten max_grad_norm (e.g. 1.00.3).
  • Increase warmup_ratio (e.g. 0.030.1) for a gentler start.
  • Use the cosine scheduler for smoother decay.
  • GRPO: keep adam_beta2 around 0.99 so the optimizer adapts to recent gradients.

Training is too slow / you want to iterate faster

  • Lower downsample_size to train on a representative subsample while experimenting (SFT).
  • Reduce num_train_epochs for quick signal.
  • Increase the effective batch size (larger batch or more accumulation) if memory allows.
  • GRPO: lower num_generations to cut generation cost per step.

Small dataset

  • Keep num_train_epochs modest and watch eval loss closely — overfitting comes fast.
  • Favor a lower lora_rank (48) and some weight_decay.
  • A slightly higher warmup_ratio can help stabilize the few steps you have.

Imbalanced dataset (SFT)

  • Enable dynamic_loss to reweight under-represented classes or tokens.

GRPO reward isn't improving

  • Increase num_generations for lower-variance advantage estimates (memory permitting).
  • Keep learning_rate small (around 5e-6); RL destabilizes easily at higher rates.
  • Give it more num_train_epochs — GRPO improvements accrue gradually.
tip

Change one hyperparameter per run and compare against the previous job. Tuning several at once makes it impossible to tell which change helped.