Datum helpers
A “datum” is one Whitney training example: right-shifted input/target tokens plus whatever loss-specific tensors yourloss_function needs. The completion’s
last token only ever appears as a target, never as an input, so input and
target_tokens are one token shorter than prompt_tokens + completion_tokens.
Advantage helpers
Building a forward payload
The build_loss contract
Most RL loops in the cookbooks are a single callable plugged into the same loop skeleton below:sample— the raw sampler result:{"sequences": [{"tokens", "logprobs", "stop_reason"}, ...], ...}.cycle— the zero-based cycle index.request— your original sample request object, needed forrequest["prompt"]["token_ids"](the sampler result alone carries no prompt tokens).ctx— a context object bundling a liveclient,run_id,sampler_id, andprovider, so your callable can issue further ordered operations before returning its payload — e.g. an extralogprobscall for a reference-policy KL term, or anothersamplecall for dynamic resampling.ctx.client.sampler_operation(ctx.run_id, ctx.sampler_id, kind, payload)is the same method the loop itself uses forsample. Any such call still advances the run’s orderedseq_id— it is a real, billed Whitney operation, not a side channel.
ctx.provider against the provider loss support
table before using a provider-specific loss name.
Ordered RL loop skeleton
cancel the run, poll until terminal, then close
the session. See SFT for the equivalent single-pass loop
without sampling, and Distillation for the two-run variant
where a frozen teacher run answers logprobs instead of training.
Provider loss support
GET /v1/training/capabilities does not return a loss-function list — it
cannot, because Whitney forwards loss_function straight through to the
provider. The table below is a caller-side hint that saves a wasted
allocation, not a live capability; call
require_advertised_loss before you build a
payload with a provider-specific loss name.
Scalar
loss_config keys Modal actually validates, per loss (an empty row
means that loss accepts no loss_config keys at all):
On Tinker Cloud, the equivalent clip range is set per-token on the datum
itself (
rl_datum(..., clip_low=, clip_high=)), not through loss_config.
