Skip to content

[Feature] Version-checked held-out evaluation for online RL #1479

Description

@jszzr

Checklist

  • This feature maintains backward compatibility with the current APIs in
    areal/api/.

Background

Online RL mode currently cannot evaluate a fixed held-out dataset during
training:

  • PPOTrainer rejects any valid_dataset when agent.mode="online";
  • an online run has no train dataset from which to initialize a DataController,
    so a remote validation dataset cannot connect;
  • eval_rollout is unconditionally skipped in online mode;
  • _evaluate_fn() discards wait() results, so rejected eval trajectories can
    silently reduce the metric denominator.

This leaves an online agent experiment with only on-policy training reward. That
is not enough to distinguish genuine policy improvement from changing task mix,
reward drift, producer behavior, or stale/mixed inference weights.

A second correctness issue appears once evaluation is enabled. The controller's
current version is control-plane intent, while each generated token's
trajectory["versions"] is data-plane evidence. Partial Data Proxy version
updates, retries, or an update racing queued tasks can make those disagree. A
held-out reward should not be attributed to checkpoint v unless every
loss-bearing token proves it was generated by v.

Potential Solution

  1. Allow an actual validation dataset in online mode and let it lazily create a
    DataController when the train side has none.
    Require V2 actor/rollout controllers and a non-empty validation dataloader;
    fail before training side effects otherwise.

  2. Create an eval controller only when online validation data exists. Reuse the
    main inference servers, but keep Router, Data Proxy, Gateway, sessions, and
    waiter state independent.

  3. Use pull-owned direct-export eval sessions from fix(v2): separate callback and pull trajectory delivery #1476 so evaluation
    trajectories cannot enter the external online callback FIFO.

  4. At submit(is_eval=True), snapshot the controller's current policy version
    into the resolved workflow.

  5. Before recording reward, require:

    for every token where loss_mask == 1:
        trajectory.versions[token] == submit.expected_policy_version
    

    Missing, empty, mixed, or stale provenance fails closed. Do not substitute
    the controller's later/current version for missing token evidence.

  6. If any online evaluation workflow returns None, fail the complete
    evaluation round rather than publishing a metric over a selected subset.

  7. Log policy_version with each accepted held-out reward to make checkpoint
    attribution explicit.

  8. Offload remote RTensor provenance fetches from the workflow event loop and
    clear both accepted and rejected evaluation shards after their final
    consumer, so repeated evaluation does not grow Data Proxy storage or local
    fetch caches.

The online path without validation remains unchanged. Training trajectories keep
their existing off-policy behavior because strict equality is enabled only for
is_eval=True submissions.

Additional Information

Proposed validation is CPU-testable. The affected Linux test matrix covers the
trainer, controller, Data Proxy, version propagation, InfBridge token stamping,
Gateway, and online stack.

Explicit non-goals for the first PR:

  • promotion, rollback, or checkpoint selection policy;
  • changing evaluator cadence or claiming eval_before_train is a true version-0
    baseline (the current PPO loop first evaluates after an update);
  • export replay/ack semantics;
  • supporting online proxy mode in SPMD/Ray configurations that are already
    unsupported.

Related work:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions