> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fastino.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use https://docs.fastino.ai/llms.txt to discover and navigate pages. Use https://docs.fastino.ai/llms-full.txt when you need the complete documentation corpus. Use https://docs.fastino.ai/openapi.json as the source of truth for customer-facing routes. For GLiDE decision inference, call POST https://api.fastino.ai/v1/systemone with model fastino/GLiDE. Create managed config jobs with POST /v1/training/jobs using base_model. Both config and interactive jobs use /v1/training/jobs/{job_id} for their canonical REST lifecycle. For custom training loops, use the supported Tinker-compatible SDK client; its /v1/training/compat/tinker adapter is intentionally absent from OpenAPI and must not be called directly. Auto Train is private access and has no public route; direct interested users to sales@fastino.ai. Do not infer undocumented routes. Read API keys from FASTINO_API_KEY and never embed credentials in code, logs, or reports.

# Train with verifiable rewards

> Turn a deterministic grader into a learning signal for one interactive Fastino job.

Use a verifiable reward when code can check a response, such as a math answer,
test result, schema constraint, exact extraction, or tool outcome.

```text theme={null}
prompt -> sample a group -> grade -> center rewards -> build datums -> update
```

Sampling, forward/backward work, optimizer steps, and checkpoints all belong to
the same interactive Fastino job. Reward execution and application state remain
in your code.

## Before you start

Complete the [custom-loop Quickstart](/training/quickstart#custom-training-loop),
then confirm through capabilities
that your chosen model and training operations are enabled. The snippets below
focus on the user-owned reward flow; adapt datum construction to
`tinker==0.33.1` and your selected model.

<Note>
  This guide is not a standalone copy-and-paste trainer. Begin with a validated
  SDK workload whose renderer and datum construction match the selected model,
  then add the reward flow below.
</Note>

<Warning>
  Run generated code or tools only in an isolated, resource-limited
  environment. Fastino does not execute your reward function or manage its side
  effects.
</Warning>

## 1. Define a narrow grader

Separate parsing from scoring so malformed output is observable:

```python theme={null}
def get_reward(response: str, expected: str) -> float:
    actual = parse_answer(response)
    if actual is None:
        return 0.0
    return 1.0 if actual == expected else 0.0
```

Keep a frozen fixture set that includes correct, incorrect, malformed, and
equivalently formatted answers. Log parse failures separately from valid but
incorrect responses.

## 2. Snapshot the job for sampling

Create a sampler checkpoint from the current weights, then resolve it through
the SDK:

```python theme={null}
checkpoint = training_client.save_weights_for_sampler(
    f"rollout-{step:06d}"
).result()
sampling_client = service_client.create_sampling_client(
    model_path=checkpoint.path
)

sample_result = sampling_client.sample(
    prompt=model_input,
    num_samples=group_size,
    sampling_params=sampling_params,
).result()
```

This does not create another training run. The checkpoint and sampling work are
associated with the same interactive job.

## 3. Convert rewards to advantages

```python theme={null}
rewards = [
    get_reward(render_response(sequence.tokens), expected)
    for sequence in sample_result.sequences
]

mean_reward = sum(rewards) / len(rewards)
advantages = [reward - mean_reward for reward in rewards]

if all(advantage == 0.0 for advantage in advantages):
    continue
```

Track groups with no reward variance. They may indicate that the task is too
easy, too hard, or parsed incorrectly.

## 4. Build aligned datums

The prompt is context, so prompt positions normally receive zero advantage.
Completion positions receive the response's group-relative advantage. A datum
builder should fail before submission if model input, target, log-probability,
and advantage lengths differ:

```python theme={null}
if not (
    model_input.length
    == len(target_tokens)
    == len(padded_logprobs)
    == len(padded_advantages)
):
    raise ValueError("training datum arrays are not aligned")
```

Use the renderer and tokenizer associated with the selected `base_model`. Keep
the sampled tokens and log probabilities needed by the SDK operation you
selected from capabilities.

## 5. Update the interactive job

For an enabled importance-sampling workflow, the SDK call pattern is:

```python theme={null}
train_future = training_client.forward_backward(
    datums,
    loss_fn="importance_sampling",
)
train_result = train_future.result()

optim_future = training_client.optim_step(optimizer_params)
optim_result = optim_future.result()
```

Both operations mutate the existing interactive job. Resolve and record each
result before advancing the application step. Do not construct equivalent
adapter HTTP requests.

## 6. Save a recovery boundary

```python theme={null}
state = training_client.save_state(f"step-{step:06d}").result()
```

Persist the returned checkpoint identifier with:

* Canonical job ID from `training_client.get_info().model_data.model_id`
* Application step and dataset cursor
* Dataset and reward implementation revisions
* Base model and training configuration
* Evaluation metrics

This metadata lets a controller choose a checkpoint without guessing from its
name.

## Verify before scaling

* The grader distinguishes known correct and incorrect fixtures.
* Malformed responses do not crash the application loop.
* At least one sample group has reward variance.
* Datum arrays satisfy the installed SDK's expected shapes.
* Forward/backward and optimizer futures complete on the same job.
* A state checkpoint can be loaded with its client-owned resume metadata.
* Held-out evaluation remains separate from the training reward batch.

For the surrounding lifecycle, read
[Build a custom training loop](/training/training-loop).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.