Advanced Guide

Configure and Extend PRM-as-a-Judge

Detailed reference for adapting PRM-as-a-Judge to your data, compute resources, evaluation goals, and choice of Process Reward Model (PRM).

If this is your first run, complete the Quick Start before changing the defaults described here.

高级指南

PRM-as-a-Judge 进阶配置

详细介绍如何根据数据形式、计算资源、评测目标和过程奖励模型(Process Reward Model,PRM)的选择调整 PRM-as-a-Judge。

如果尚未完成首次评测,请先按照快速开始运行默认流程,再调整本页介绍的配置。

Input: Manifest Format

The default input is a JSONL manifest. Each line describes one rollout case. Paths may be absolute or relative to the manifest file.

Single View

{"case_id":"case_001","task_name":"put_can","task":"put the can into the basket","video":"videos/case_001.mp4"}

Main View with a Single-Arm Robot Wrist View

{"case_id":"case_002","task_name":"put_can","task":"put the can into the basket","video":"high.mp4","wrist_video":"wrist.mp4"}

Main View with Bimanual Robot Wrist Views

{"case_id":"case_003","task_name":"put_can","task":"put the can into the basket","video":"high.mp4","left_wrist_video":"left.mp4","right_wrist_video":"right.mp4"}

With a Goal Image, Outcome Label, and Benchmark Name

goal_image shows the desired final state; label records a known success or failure outcome; benchmark identifies the source benchmark or dataset; and model identifies the policy or model that generated the rollout.

{"case_id":"case_004","task_name":"arrange_flowers","task":"arrange the flowers in the vase","video":"h.mp4","wrist_video":"w.mp4","goal_image":"goal.png","label":"success","benchmark":"RoboTwin","model":"pi0"}
Field Requirement Description
case_id ● Required Stable case identifier. The loader raises an error if it is missing.
task ● Required Natural-language task description used for evaluation and passed to the selected PRM model when applicable. instruction and task_prompt are accepted aliases.
video ● Required Main-view rollout video path. It may be a third-person, overhead, or other view that clearly shows the operation process.
wrist_video ○ Optional Wrist-camera path for a single-arm robot. If the selected Judge Model supports multi-view input, it automatically uses the main-view and wrist-view videos together. Do not combine it with the bimanual wrist fields.
left_wrist_video / right_wrist_video ○ Optional pair Left- and right-wrist camera paths for a bimanual robot. If the selected Judge Model supports multi-view input, it automatically uses the main-view, left-wrist, and right-wrist videos together. The two fields must be provided together and cannot be combined with wrist_video.
task_name ○ Optional Short task name used for grouping, filtering, and output directories. If omitted, the program automatically uses the task text as the task name.
goal_image ○ Optional Image of the desired final state. You can use the final frame of a successful demonstration or another image that clearly shows the goal state.
label ○ Optional Known outcome of the rollout: success or failure. By default, a single progress threshold separates successful and failed cases, but the same threshold may not be suitable for every rollout. When reliable Benchmark labels are available, set --success-source label to use the labels for SR and to assign successful and failed rollouts to SQS and FNS, respectively.
benchmark ○ Optional Dataset or benchmark name copied into reports.
model ○ Optional Name of the policy model that generated the rollout.
progress / progress_path ○ Optional Imports a progress curve generated by an external PRM. Put the progress values directly in progress, or use progress_path to point to a JSON file containing them. Use with --prm recorded; the toolkit then performs curve postprocessing, metric calculation, and report generation without running a PRM model.

Output: Evaluation Results

Outputs are written to eval/results/run_YYMMDD_HHMMSS/ by default.

File Use it for
run_params.json Resolved CLI options and runtime settings for reproducibility.
run_summary.json Total, successful, failed, and aggregated metric counts for the run.
per_case.jsonl Raw and processed progress curves plus metrics for each rollout.
benchmark/model/task/case/result_summary.json Per-case result file under the case output directory.
summary.csv Metrics aggregated by benchmark, policy model, and task, including case counts and metrics such as MaxP, SR, and PPL, for comparing task and model performance.
leaderboard.csv Model-level summary for comparing policies.
report.md Markdown run overview listing total cases, cases evaluated without runtime errors, and errors, with references to detailed CSV and JSONL outputs.
discovery_manifest.json Resolved input paths, runtime choices, and reproducibility metadata.
visualizations/curve_metrics.csv Per-case curve metric details. Each row includes case and task information, PRM evaluation method, policy model, curve length, and progress metrics such as MaxP, SR, and PPL for filtering and downstream analysis.
visualizations/report.html Local interactive HTML report generated when --visualize or VISUALIZE=1 is enabled. Open it in a browser to review rollout videos, progress curves, live frame metrics, milestones, and sortable model-level, model-by-task, and per-case metric tables.
visualizations/visualization_report.md Visualization artifact index and plot-generation status.
visualizations/case_plots.csv Per-case curve plot index. Each row maps a case, task, PRM evaluation method, and policy model to its PNG file path.
visualizations/cases/*.png Static progress-curve plot for each case, comparing raw and postprocessed curves and showing the success threshold and key curve positions; generated when matplotlib is installed.

Generate visualizations after a run has finished:

prm-judge visualize --run-root eval/results/run_YYMMDD_HHMMSS

For reliable MP4 playback and seeking, use the built-in Range-aware server:

prm-judge serve \
  --run-root eval/results/run_YYMMDD_HHMMSS \
  --host 127.0.0.1 \
  --port 8000

Open http://127.0.0.1:8000/report.html. For a remote server, keep the report service on loopback and create a tunnel from your workstation:

ssh -L 8000:127.0.0.1:8000 user@server

After the run completes, the final performance report presents a Model Leaderboard that summarizes the core metrics for every evaluated model. You can also use the interactive trajectory explorer to filter and inspect individual cases, including their rollout videos, progress curves, live-frame values, and per-case metrics.

Default Settings

The table below lists the main defaults in eval/run_eval.sh. Keep these settings for the first run. After confirming that the evaluation pipeline works, adjust them for video length, GPU memory, and evaluation goals.

Setting Default When to adjust
PRM evaluation method PRM=dopamine You need RoboMeter, want to import a progress curve from an external PRM, or want to integrate a custom PRM.
Dopamine mode EVAL_MODE=incremental The default incremental mode compares adjacent sampled frames. Use forward to anchor progress estimates to the initial state; use backward when a reliable goal image is available and progress should be evaluated relative to the goal.
Success threshold --success-threshold 0.99 Without a reliable label, success is determined by whether MaxP reaches the default threshold of 0.99. Because the MaxP distribution may vary across tasks, adjust the threshold when necessary.
Frame sampling interval FRAME_INTERVAL=72 Decrease it for denser progress curves on short videos or fast actions; increase it to speed up inference on long videos.
Inference batch size BATCH_SIZE=10 Decrease it when GPU memory is insufficient; increase it when memory is available and higher throughput is needed.
GPU selection GPUS=0 Change the index to use another GPU, or provide multiple indices such as GPUS=0,1 to shard cases across GPUs.
Outlier handling OUTLIER_METHOD=local_median Set it to none when you need to preserve the raw PRM output.
Curve smoothing SMOOTHING=weighted_window
Weights: [0.1, 0.2, 0.4, 0.2, 0.1]
Set it to none to preserve an unsmoothed curve, or change the window weights to adjust smoothing strength.

PRM Evaluation Methods

The toolkit supports several progress-evaluation methods. dopamine uses the Robo-Dopamine model and is the default; robometer uses the RoboMeter model; recorded reads precomputed curves without loading a model; and a custom adapter can integrate your own PRM. Once a progress curve is available, all methods share the same postprocessing and metric pipeline.

Use case Recommended method Why
Fine-grained process changes or routine batch evaluation dopamine (Robo-Dopamine) with EVAL_MODE=incremental Compares adjacent sampled states, making it suitable for capturing local, fine-grained progress and regression.
Long-horizon, repetitive, or context-dependent actions robometer (RoboMeter) Uses temporal context from video sequences, making it suitable when adjacent states alone cannot distinguish sustained progress, repeated actions, or back-and-forth motion.
Debugging metrics without loading a model recorded (precomputed curves) Uses progress or progress_path from the manifest.
Integrating another PRM Custom adapter Return absolute progress in [0, 1], or configure normalization before metrics. See Custom PRM for the adapter steps.

Run with RoboMeter

RoboMeter is a sequence-style PRM model. The runner can start a local RoboMeter HTTP server, wait for /health, evaluate cases, and shut the server down after the run.

PRM=robometer \
MANIFEST=/path/to/cases.jsonl \
bash eval/run_eval.sh

Reuse an already running server when you want to manage the model process yourself:

PRM=robometer \
MANIFEST=/path/to/cases.jsonl \
ROBOMETER_SERVER_URL=http://localhost:8000 \
ROBOMETER_AUTO_START=0 \
bash eval/run_eval.sh
When PRM=robometer, eval/run_eval.sh uses ROBOMETER_PYTHON for both the runner and the auto-started server so video dependencies such as decord or opencv-python are available. If you call prm-judge directly, run it from an environment that can decode your videos.

Dopamine Modes

Robo-Dopamine is a pair-style PRM. It constructs a progress curve by scoring sampled states with one of three comparison modes.

Mode What is compared How progress is interpreted When to use
incremental (default) Previous sampled state as before, current sampled state as after. The model score is treated as a local progress change and accumulated over time. Default mode for local step-wise change analysis. Consider a larger FRAME_INTERVAL if adjacent samples are too similar.
forward Start frame as before, current sampled state as after. The model score is treated as the current absolute progress estimate. Use it when start-to-current change is easier to judge than distance to the goal image.
backward Goal image as before, current sampled state as after. The model score is converted to progress with progress = 1 + score. Use it when a goal image or goal placeholder is available and goal-relative scoring is preferred.

Examples:

EVAL_MODE=incremental MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh
EVAL_MODE=forward MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh
EVAL_MODE=backward MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

Video Views and Goal Images

Every case must provide video as its main view. Wrist views and goal_image are optional: wrist videos add details about grasps, contacts, and occluded areas, while a goal image describes the desired final state.

Video fields

  • video: required main-view video path, such as a third-person, fixed-camera, or overhead view.
  • wrist_video: wrist-view video for a single-arm robot. Do not combine it with the bimanual wrist fields.
  • left_wrist_video and right_wrist_video: left- and right-wrist videos for a bimanual robot. Provide both fields together.

How Robo-Dopamine uses views

Views provided in the manifest Robo-Dopamine behavior
video only Reuses the main view for all camera inputs required by the model, which is suitable for quick tests.
video + wrist_video Uses video as the main view and reuses the single-arm wrist video for both wrist inputs.
video + left_wrist_video + right_wrist_video Maps the main, left-wrist, and right-wrist videos to their corresponding model inputs.

Selecting a RoboMeter view

RoboMeter evaluates one video view at a time and uses video by default. To evaluate a wrist view, set ROBOMETER_VIEW to wrist_video, left_wrist_video, or right_wrist_video. The selected field must exist in the case; otherwise, that case reports an error.

PRM=robometer \
ROBOMETER_VIEW=left_wrist_video \
MANIFEST=cases.jsonl \
bash eval/run_eval.sh

How goal images are used

goal_image is a visual reference for the completed task state. Robo-Dopamine uses it as REFERENCE END to help locate the current state along the path from task start to completion; in backward mode, the goal image is also compared directly with the current sampled state.

  • When a reliable success-state image is available, set goal_image in the manifest; for example, use the final frame of a successful demonstration.
  • If no goal image is available, omit the field. PRM-as-a-Judge automatically uses eval/examples/blank.png as a placeholder.
  • Do not use the final frame of the rollout being evaluated unless that rollout is known to have succeeded; otherwise, a failure state may be treated as the task goal.

Multi-GPU

The default uses one GPU to keep the command predictable. On larger batches, set GPUS or pass --gpus to shard cases across local devices.

GPUS=0,1,2,3 MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

Each worker loads one PRM instance on its assigned GPU, processes its shard, and the runner merges shard outputs at the end. This is simple local data parallelism and is usually enough for evaluation batches.

You can also ask the runner to choose GPUs automatically. In the current implementation, GPUS=auto queries nvidia-smi, selects devices whose used memory is below 1024 MiB, and falls back to GPU 0 if no such device is found.

GPUS=auto MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

For RoboMeter multi-GPU runs, each shard uses ROBOMETER_SERVER_PORT + shard_index for an auto-started server, so choose a free base port when running several evaluations on the same machine.

Progress Curve Standard

The metric stack consumes normalized absolute progress curves. Every PRM adapter should eventually produce:

progress[t] in [0, 1]
PRM output Convert before metrics
Absolute progress in [0, 1] Use directly, then clip small numerical overflow.
Absolute progress in [0, 100] Divide by 100 with --normalize 0_100.
Step-wise delta progress Use --source-type delta, accumulate over time, then clip to [0, 1].
Uncalibrated reward or similarity Add adapter-specific calibration before metric computation.

Do not force the curve to be monotonic. Regressions and oscillations are meaningful signals used by drawdown, recovery, stagnation, and regret metrics. Results should store both progress_raw and progress_processed.

Progress Curve Processing

After the PRM produces a raw progress curve, the toolkit applies the following steps:

  1. Normalize the PRM output to absolute progress in [0, 1].
  2. Clip values to [0, 1].
  3. Replace isolated local outliers with the local median. The default threshold is 0.35.
  4. Smooth with a weighted temporal window.
p'_t = 0.1*p_{t-2} + 0.2*p_{t-1} + 0.4*p_t + 0.2*p_{t+1} + 0.1*p_{t+2}

The default outlier handling and smoothing reduce isolated erroneous spikes and short-term fluctuations. They do not force progress to increase continuously, so genuine regressions remain visible. For example, when a rollout is clearly advancing overall but adjacent-frame scores fluctuate, these steps produce a more stable representation of the trend.

Disable postprocessing when you are debugging raw PRM behavior:

prm-judge eval --manifest cases.jsonl --outlier-method none --smoothing none

Change the smoothing weights from the CLI:

prm-judge eval --manifest cases.jsonl --smoothing-weights 0.05,0.15,0.6,0.15,0.05

The weight list should have odd length, non-negative values, and a positive sum. It is normalized automatically. For deeper customization, edit eval/prm_judge/curves.py, especially parse_smoothing_weights, weighted_smooth, and PostprocessConfig.smoothing_weights.

Evaluation Metrics

By default, metrics and evaluation reports use the progress curve after outlier handling and smoothing. The raw curve is retained in the outputs mainly for inspecting the PRM's direct predictions and troubleshooting.

means higher is better; means lower is better.

In the formulas below, p_0 = 0, p_1, ..., p_T is the processed normalized progress curve, θ is the success threshold, δ = 0.005 is the default stagnation threshold, and 1[·] is the indicator function.

Metric Scope Formula Interpretation
MaxP ↑ All rollouts
Highest progress reached. A higher value means the rollout came closer to completing the task.
M25 ↑, M50 ↑, M75 ↑ All rollouts
Whether a rollout reached the 25%, 50%, and 75% progress milestones; aggregates report the proportion of rollouts reaching each milestone.
SR ↑ All rollouts
default label source
Whether a rollout reached the success threshold, which defaults to 0.99; aggregates report the success rate.
PPL ↑ All rollouts
Measures path efficiency while making progress. Higher values indicate that useful progress is more concentrated.
CRA ↓ All rollouts
Measures cumulative loss caused by regressions. Lower is better; compare rollouts that reached similar progress.
Stag ↓ All rollouts
Fraction of steps with almost no progress change. Lower values indicate less stagnation.
RBS ↑ All rollouts
Measures recovery after the largest progress regression. Higher values indicate more complete recovery.
FNS ↑ Failed rollouts
Measures how close a failed rollout came to success by combining its highest progress and milestone completion.
SQS ↑ Successful rollouts
Measures execution quality among successful rollouts, rewarding efficient, low-regret, and low-stagnation behavior.
Some diagnostics are conditional. For example, CRA is most informative when comparing rollouts that both achieved similar progress. A completely stagnant curve may have low regret but still be a poor rollout. By default, success grouping uses MaxP >= --success-threshold. Use --success-source label only when benchmark labels should define success and failure.

Custom PRM

The toolkit separates two responsibilities: a PRM adapter produces a progress curve, and the metric stack computes diagnostics from the standardized curve. This common interface supports both built-in and custom Judge Models.

In this developer section, backend means the implementation registered under --prm. It may call a PRM model or, like recorded, read a precomputed progress curve.

Minimal integration steps

  1. Create a new adapter file under eval/prm_judge/prm/ and subclass BasePRMAdapter.
  2. Implement predict(case, output_dir) so it reads the manifest case, runs your PRM, and returns a ProgressTrace.
  3. Register the backend name in eval/prm_judge/cli.py: add it to the --prm choices and create the adapter in build_adapter.
  4. Make sure the returned progress is absolute [0, 1], or run with the matching --normalize and --source-type options.
  5. Evaluate with prm-judge eval --prm your_backend --manifest cases.jsonl.

Adapter checklist

  • Read EvalCase fields such as videos, task text, goal image, and metadata.
  • Run your PRM and return a progress sequence aligned to sampled frames or video time.
  • Decide whether the output is absolute progress, step-wise deltas, or another score.
  • Decide whether the scale is [0, 1], [0, 100], or uncalibrated.
  • Prefer returning absolute progress in [0, 1]. If not, pass the matching --normalize and --source-type options for the whole run.
from prm_judge.prm.base import BasePRMAdapter
from prm_judge.schema import EvalCase, ProgressTrace

class MyAdapter(BasePRMAdapter):
    def predict(self, case: EvalCase, output_dir):
        scores = run_my_model(case.videos, case.task, case.goal_image)
        return ProgressTrace(
            case_id=case.case_id,
            progress=scores,
            source_scale="0_1",
            source_type="absolute",
        )

Existing adapters under eval/prm_judge/prm/ can be used as templates. recorded.py is the smallest example, while robometer.py shows how to wrap an external model service. Document the model's output scale, semantics, required views, goal-image behavior, and runtime requirements next to your adapter.

RoboMeter as an example

RoboMeter is integrated as a sequence-style backend through an HTTP adapter. It reads outputs_progress.progress_pred as an absolute progress curve in [0, 1]. Because it reasons over a longer sequence, it is a useful comparison point for repeated-motion cases where local pairwise judging is not enough.

When you reuse an existing RoboMeter server, PRM-as-a-Judge checks /model_info and requires the server model path to match PRM_PATH. This helps avoid accidentally evaluating with an old checkpoint. The adapter uploads frame arrays as .npy multipart files, which keeps long-video requests manageable.

Command Reference

Batch evaluate many videos without moving files

MANIFEST=/data/my_rollouts/cases.jsonl \
PRM_PATH=/models/Robo-Dopamine-GRM-8B-Pro \
OUTPUT_ROOT=eval/results/my_rollouts \
bash eval/run_eval.sh

Use all four local GPUs

GPUS=0,1,2,3 MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

Run a denser curve for short manipulation tasks

FRAME_INTERVAL=36 MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

Use benchmark labels for success grouping

prm-judge eval --manifest cases.jsonl --success-source label --visualize

Check a manifest before spending GPU time

prm-judge eval --manifest cases.jsonl --prm recorded --dry-run --limit 10

Compare raw and processed progress

prm-judge eval --manifest cases.jsonl --outlier-method none --smoothing none --visualize
prm-judge eval --manifest cases.jsonl --visualize

FAQ

1. What is goal_image used for?

goal_image is an optional parameter specific to Robo-Dopamine. It provides an explicit visual reference for the completed task state, helping the model understand what success should look like, reduce goal ambiguity, and improve progress-judgment accuracy. Robo-Dopamine uses it as REFERENCE END; in backward mode, the goal image is also compared directly with the current sampled state. Other Judge Model adapters do not necessarily use this field.

In practice, set goal_image in the manifest when a reliable success-state reference is available, preferably the final frame of a manually verified successful demonstration or a separately captured target state. If no reliable goal image is available, omit the field; the Robo-Dopamine adapter will use eval/examples/blank.png as a placeholder, although the evaluation will not benefit from an explicit goal reference. Do not use the final frame of the rollout being evaluated unless that rollout is known to have succeeded, because a failure state could otherwise be treated as the task goal and reduce judgment accuracy.

2. How does Robo-Dopamine estimate progress, and when should I use another PRM as the judge?

Robo-Dopamine is a pair-wise Judge Model. Depending on EVAL_MODE, it compares two sampled images or states—for example, adjacent samples, the initial state and the current state, or the current state and a goal reference—to estimate relative progress. These pair-wise judgments are then linked into a progress curve.

This local comparison works well for many robot manipulation tasks. However, it can be ambiguous for repeated or oscillatory motions and tasks that depend strongly on temporal context. Two images alone may not reveal whether the robot is making sustained progress, repeating an action cycle, or simply moving back and forth. For these tasks, consider a sequence-style PRM that evaluates a longer video sequence, such as RoboMeter, or use it as a comparison.

输入:Manifest 格式

默认输入为 JSONL manifest 文件,每一行描述一个执行案例。路径可以是绝对路径,也可以是相对于 manifest 文件的相对路径。

单视角

{"case_id":"case_001","task_name":"put_can","task":"put the can into the basket","video":"videos/case_001.mp4"}

主视角加单臂机器人腕部视角

{"case_id":"case_002","task_name":"put_can","task":"put the can into the basket","video":"high.mp4","wrist_video":"wrist.mp4"}

主视角加双臂机器人左右腕视角

{"case_id":"case_003","task_name":"put_can","task":"put the can into the basket","video":"high.mp4","left_wrist_video":"left.mp4","right_wrist_video":"right.mp4"}

带目标图像、结果标签和 Benchmark 名称

goal_image 表示任务期望的最终状态;label 记录已知的成功或失败结果; benchmark 表示案例所属的 Benchmark 或数据集;model 表示生成该轨迹的策略或模型。

{"case_id":"case_004","task_name":"arrange_flowers","task":"arrange the flowers in the vase","video":"h.mp4","wrist_video":"w.mp4","goal_image":"goal.png","label":"success","benchmark":"RoboTwin","model":"pi0"}
字段 要求 说明
case_id ● 必需 稳定的案例标识符。缺失时加载器会报错。
task ● 必需 用于评测的自然语言任务描述;采用模型评测时,它会传递给所选 PRM 模型。instructiontask_prompt 也可作为别名使用。
video ● 必需 主视角执行视频路径,可以为第三人称、俯视视角或其他能清晰展示操作过程的视角。
wrist_video ○ 可选 单臂机器人的腕部相机路径。如果所选 Judge Model 支持多视角输入,会自动同时使用主视角和腕部视角视频。不能与双臂机器人的左右腕字段同时使用。
left_wrist_video / right_wrist_video ○ 可选但必须成对 双臂机器人的左腕和右腕相机路径。如果所选 Judge Model 支持多视角输入,会自动同时使用主视角、左腕和右腕视频。两个字段必须同时提供,并且不能与 wrist_video 同时使用。
task_name ○ 可选 用于分组、筛选和输出目录的简短任务名称。省略时,程序会自动使用 task 的文本作为任务名称。
goal_image ○ 可选 任务期望最终状态的图像。可以使用成功演示轨迹的最后一帧,或其他能够清楚展示目标状态的图片。
label ○ 可选 轨迹的已知结果:success(成功)或 failure(失败)。默认使用统一的进度阈值区分成功和失败案例,但该阈值不一定适用于所有轨迹。若 Benchmark 提供可靠标签,可设置 --success-source label,使用标签计算 SR,并分别划分用于计算 SQS 和 FNS 的成功与失败轨迹。
benchmark ○ 可选 复制到报告中的数据集或 benchmark 名称。
model ○ 可选 生成该执行轨迹的策略模型名称。
progress / progress_path ○ 可选 用于导入外部 PRM 已生成的进度曲线。progress 直接填写进度值数组,progress_path 指向保存该数组的 JSON 文件。配合 --prm recorded 使用;导入后,本工具只执行曲线后处理、指标计算和报告生成,不再运行 PRM 模型。

输出:评测结果

默认情况下,输出会写入 eval/results/run_YYMMDD_HHMMSS/

文件 用途
run_params.json 记录已解析的 CLI 选项和运行时设置,用于可复现性。
run_summary.json 记录本次运行的总数、成功数、失败数和聚合指标计数。
per_case.jsonl 每个执行案例的原始和处理后进度曲线以及指标。
benchmark/model/task/case/result_summary.json 案例输出目录下的单案例结果文件。
summary.csv 按 Benchmark、策略模型和任务分组的指标汇总表,包含案例数以及 MaxP、SR、PPL 等聚合指标,用于比较不同任务和模型的表现。
leaderboard.csv 用于比较策略的模型级汇总。
report.md Markdown 格式的运行概览,列出案例总数、正常完成评测的案例数和错误数,并指向详细的 CSV 和 JSONL 结果文件。
discovery_manifest.json 已解析的输入路径、运行时选择和可复现性元数据。
visualizations/curve_metrics.csv 单案例曲线指标明细表。每行包含案例与任务信息、PRM 评测方式、策略模型、曲线点数,以及 MaxP、SR、PPL 等进度曲线指标,便于筛选和二次分析。
visualizations/report.html 启用 --visualizeVISUALIZE=1 时生成的本地交互式 HTML 报告。在浏览器中打开后,可以查看执行视频、进度曲线、实时帧指标、里程碑,以及可排序的模型级、模型-任务级和单案例指标表。
visualizations/visualization_report.md 记录可视化产物索引和单案例图生成状态。
visualizations/case_plots.csv 单案例曲线图索引。每行记录案例、任务、PRM 评测方式、策略模型及其对应 PNG 文件路径,便于程序批量查找或引用曲线图。
visualizations/cases/*.png 每个案例的静态进度曲线图,对比原始曲线与后处理曲线,并显示成功阈值和关键曲线位置;安装 matplotlib 后生成。

在一次运行完成后生成可视化结果:

prm-judge visualize --run-root eval/results/run_YYMMDD_HHMMSS

为了可靠播放和拖动 MP4,请使用内置的 Range-aware 报告服务:

prm-judge serve \
  --run-root eval/results/run_YYMMDD_HHMMSS \
  --host 127.0.0.1 \
  --port 8000

打开 http://127.0.0.1:8000/report.html。如果评估在远端服务器上运行,请保持服务只绑定 loopback,并从本机建立 SSH tunnel:

ssh -L 8000:127.0.0.1:8000 user@server

评测完成后,最终性能报告会生成 Model Leaderboard,汇总展示每个被评测模型的核心指标;还可以通过交互式轨迹查看器筛选并逐条查看每个案例(case)的执行视频、进度曲线、实时帧数值和单案例指标。

默认设置

下表列出 eval/run_eval.sh 的主要默认配置。首次运行建议先保持默认值;确认评测流程正常后,再根据视频长度、GPU 显存和评测目标进行调整。

设置 默认值 何时调整
PRM 评测方式 PRM=dopamine 需要使用 RoboMeter、导入外部 PRM 进度曲线或接入自定义 PRM 时。
Dopamine 模式 EVAL_MODE=incremental 默认使用 incremental 比较相邻采样帧。需要以起始状态为锚点观察累计进展时改为 forward;有可靠的目标图像、希望根据当前状态与目标的差距评估进度时改为 backward
成功阈值 --success-threshold 0.99 没有可靠的 label 时,程序根据 MaxP 是否达到默认阈值 0.99 判断成功。不同任务的 MaxP 分布可能不同,可根据实际情况调整该阈值。
帧采样间隔 FRAME_INTERVAL=72 短视频或快速动作需要更密集的进度曲线时调小;长视频需要加快推理时调大。
推理批大小 BATCH_SIZE=10 GPU 显存不足时调小;显存充足并希望提高吞吐时调大。
GPU 选择 GPUS=0 使用其他 GPU 时修改编号;填写多个编号(如 GPUS=0,1)可将案例分片到多张 GPU。
异常值处理 OUTLIER_METHOD=local_median 需要保留原始 PRM 输出时设为 none
曲线平滑 SMOOTHING=weighted_window
权重:[0.1, 0.2, 0.4, 0.2, 0.1]
需要保留未平滑曲线时设为 none;需要改变平滑强度时调整窗口权重。

PRM 评测方式

该工具包支持多种进度评测方式:dopamine 使用 Robo-Dopamine 模型并作为默认选择; robometer 使用 RoboMeter 模型;recorded 不加载模型,直接读取预计算曲线;自定义适配器则可以接入你自己的 PRM。获得进度曲线后,所有方式共享相同的后处理和指标流水线。

使用场景 推荐评测方式 原因
细粒度过程变化或常规批量评测 dopamine(Robo-Dopamine)配合 EVAL_MODE=incremental 比较相邻采样状态,适合捕捉局部、细粒度的进展与回退。
长时、重复或依赖上下文的动作 robometer(RoboMeter) 利用视频序列中的时间上下文,适合仅凭相邻状态难以区分持续进展、重复动作或往返运动的轨迹。
不加载模型调试指标 recorded(预计算曲线) 使用 manifest 中的 progressprogress_path
接入其他 PRM 自定义适配器 返回 [0, 1] 中的绝对进度,或在计算指标前配置归一化。适配器步骤见 自定义 PRM

使用 RoboMeter 运行

RoboMeter 是序列式 PRM 模型。运行器可以启动本地 RoboMeter HTTP 服务器,等待 /health,评估案例,并在运行结束后关闭服务器。

PRM=robometer \
MANIFEST=/path/to/cases.jsonl \
bash eval/run_eval.sh

当你希望自行管理模型进程时,可以复用已经运行的服务器:

PRM=robometer \
MANIFEST=/path/to/cases.jsonl \
ROBOMETER_SERVER_URL=http://localhost:8000 \
ROBOMETER_AUTO_START=0 \
bash eval/run_eval.sh
PRM=robometer 时,eval/run_eval.sh 会同时为运行器和自动启动的服务器使用 ROBOMETER_PYTHON,确保可用 decordopencv-python 等视频依赖。如果直接调用 prm-judge,请在能够解码你的视频的环境中运行。

Dopamine 模式

Robo-Dopamine 是成对比较式 PRM。它通过三种比较模式之一对采样状态打分,构建进度曲线。

模式 比较对象 进度解释方式 适用场景
incremental(默认) 将上一采样状态作为 before,当前采样状态作为 after 模型分数被视为局部进度变化,并随时间累积。 默认模式,用于局部逐步变化分析。如果相邻采样点过于相似,可考虑更大的 FRAME_INTERVAL
forward 将起始帧作为 before,当前采样状态作为 after 模型分数被视为当前绝对进度估计。 当从起点到当前状态的变化比到目标图像的距离更容易判断时使用。
backward 将目标图像作为 before,当前采样状态作为 after 模型分数会用 progress = 1 + score 转换为进度。 适用于可提供目标图像或目标占位图,并且希望使用目标相对评分的情况。

示例:

EVAL_MODE=incremental MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh
EVAL_MODE=forward MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh
EVAL_MODE=backward MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

视频视角与目标图像

每个案例必须提供 video 作为主视角。腕部视角和 goal_image 均为可选:腕部视频可以补充抓取、接触和遮挡区域的细节;目标图像用于说明任务期望达到的最终状态。

视频字段

  • video:必需的主视角视频路径,可以使用第三人称、固定相机或俯视视角。
  • wrist_video:单臂机器人的腕部视角视频,不能与双臂机器人的左右腕字段同时使用。
  • left_wrist_videoright_wrist_video:双臂机器人的左腕和右腕视角视频,必须成对提供。

Robo-Dopamine 如何使用视角

Manifest 中提供的视角 Robo-Dopamine 的处理方式
video 将主视角复用于模型需要的全部相机输入,适合快速测试。
video + wrist_video 使用 video 作为主视角,将单臂腕部视频复用于两个腕部输入。
video + left_wrist_video + right_wrist_video 将主视角、左腕和右腕视频分别映射到对应的模型输入。

选择 RoboMeter 视角

RoboMeter 每次评估一个视频视角,默认使用 video。如需评估腕部视角,可以通过 ROBOMETER_VIEW 指定 wrist_videoleft_wrist_videoright_wrist_video。所选字段必须存在,否则该案例会报错。

PRM=robometer \
ROBOMETER_VIEW=left_wrist_video \
MANIFEST=cases.jsonl \
bash eval/run_eval.sh

目标图像的作用

goal_image 是任务完成状态的视觉参考。Robo-Dopamine 将其作为 REFERENCE END,用于帮助模型判断当前状态在任务开始到完成过程中的位置;在 backward 模式中,目标图像还会直接与当前采样状态比较。

  • 有可靠的成功状态图像时,可以在 manifest 中填写 goal_image,例如使用成功演示轨迹的最后一帧。
  • 如果没有目标图像,可以省略该字段;PRM-as-a-Judge 会自动使用 eval/examples/blank.png 作为占位图。
  • 不建议直接使用待评测轨迹的最后一帧,除非已经确认该轨迹成功,否则可能把失败状态误当成任务目标。

Multi-GPU

默认使用一个 GPU,以保持命令可预测。在更大的批次上,可以设置 GPUS 或传入 --gpus,将案例分片到本地设备。

GPUS=0,1,2,3 MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

每个 worker 会在分配到的 GPU 上加载一个 PRM 实例,处理自己的分片,运行器最后合并分片输出。这是简单的本地数据并行,通常足以处理评估批次。

也可以让运行器自动选择 GPUs。在当前实现中,GPUS=auto 会查询 nvidia-smi,选择已用显存低于 1024 MiB 的设备;如果没有找到这样的设备,则回退到 GPU 0。

GPUS=auto MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

对于 RoboMeter multi-GPU runs,每个分片会使用 ROBOMETER_SERVER_PORT + shard_index 作为自动启动服务器的端口。因此,当同一台机器上运行多个评估时,请选择空闲的基础端口。

进度曲线规范

指标栈消费归一化绝对进度曲线。每个 PRM 适配器最终都应产生:

progress[t] in [0, 1]
PRM 输出 计算指标前的转换方式
[0, 1] 中的绝对进度 直接使用,然后裁剪小的数值溢出。
[0, 100] 中的绝对进度 使用 --normalize 0_100 除以 100。
逐步增量进度 使用 --source-type delta,随时间累积,然后裁剪到 [0, 1]
未校准的奖励或相似度 在指标计算前添加适配器专用校准。

不要强制曲线单调。回退和振荡是有意义的信号,会被回撤、恢复、停滞和 regret 指标使用。结果应同时存储 progress_rawprogress_processed

进度曲线处理

PRM 生成原始进度曲线后,工具会依次执行以下处理:

  1. 将 PRM 输出归一化为 [0, 1] 中的绝对进度。
  2. 将数值裁剪到 [0, 1]
  3. 用局部中位数替换孤立的局部异常值。默认阈值为 0.35
  4. 使用加权时间窗口进行平滑。
p'_t = 0.1*p_{t-2} + 0.2*p_{t-1} + 0.4*p_t + 0.2*p_{t+1} + 0.1*p_{t+2}

默认的异常值处理和平滑用于减少单个异常点和短时间内的频繁波动,但不会强制进度曲线持续上升,因此真实的任务退步仍会保留。例如,当视频中的任务整体在持续推进,但模型对相邻采样帧的评分时高时低时,这些处理可以让曲线更稳定地反映整体趋势。

当你在调试原始 PRM 行为时,可以禁用后处理:

prm-judge eval --manifest cases.jsonl --outlier-method none --smoothing none

从 CLI 修改平滑权重:

prm-judge eval --manifest cases.jsonl --smoothing-weights 0.05,0.15,0.6,0.15,0.05

权重列表应为奇数长度、非负,并且总和为正。它会被自动归一化。如果需要更深度的自定义,请编辑 eval/prm_judge/curves.py,尤其是 parse_smoothing_weightsweighted_smoothPostprocessConfig.smoothing_weights

评测指标

默认情况下,指标计算和评测报告都使用经过异常值处理与平滑的进度曲线。原始曲线会保留在结果中,主要用于检查 PRM 的直接输出和排查问题。

表示数值越高越好, 表示数值越低越好。

以下公式中,p_0 = 0, p_1, ..., p_T 表示处理后的归一化进度曲线, θ 表示成功阈值,δ = 0.005 表示默认停滞阈值, 1[·] 表示指示函数。

指标 适用范围 公式 说明
MaxP ↑ 全部轨迹
轨迹达到的最高进度。数值越高,表示执行过程越接近完成任务。
M25 ↑M50 ↑M75 ↑ 全部轨迹
是否达到 25%、50% 和 75% 的进度里程碑;汇总时表示达到相应里程碑的轨迹比例。
SR ↑ 全部轨迹
默认 使用标签
是否达到成功阈值,默认阈值为 0.99;汇总时表示成功率。
PPL ↑ 全部轨迹
衡量轨迹在取得进展时的路径效率,数值越高表示有效进展越集中。
CRA ↓ 全部轨迹
衡量进度回退带来的累计损失,数值越低越好;应在达到相近进度的轨迹之间比较。
Stag ↓ 全部轨迹
近乎没有进度变化的步骤比例,数值越低表示停滞越少。
RBS ↑ 全部轨迹
衡量轨迹在最大进度回退后的恢复程度,数值越高表示恢复越充分。
FNS ↑ 失败轨迹
衡量失败轨迹距离成功有多近,综合最高进度和里程碑完成情况。
SQS ↑ 成功轨迹
衡量成功轨迹的执行质量,奖励高效、低回退和低停滞的过程。
有些诊断是有条件的。例如,CRA 在比较达成相似进度的执行案例时最有信息量。完全停滞的曲线可能 regret 很低,但仍然是差的执行过程。 默认情况下,成功分组使用 MaxP >= --success-threshold 只有当基准标签应定义 success 和 failure 时,才使用 --success-source label

自定义 PRM

工具包将两个职责分离:PRM 适配器生成进度曲线,指标栈基于标准化曲线计算诊断结果。通过这一统一接口,可以使用内置或自定义的 Judge Model。

在本开发章节中,后端是指注册到 --prm 下的实现。它既可以调用 PRM 模型,也可以像 recorded 一样直接读取预计算进度曲线。

最小集成步骤

  1. eval/prm_judge/prm/ 下创建新的适配器文件,并继承 BasePRMAdapter
  2. 实现 predict(case, output_dir),让它读取 manifest 案例、运行你的 PRM,并返回 ProgressTrace
  3. eval/prm_judge/cli.py 中注册后端名称:将其加入 --prm 选项列表,并在 build_adapter 中创建适配器。
  4. 确保返回的进度是绝对 [0, 1],或者使用匹配的 --normalize--source-type 选项运行。
  5. 使用 prm-judge eval --prm your_backend --manifest cases.jsonl 进行评估。

适配器检查清单

  • 读取 EvalCase 字段,例如视频、任务文本、目标图像和元数据。
  • 运行你的 PRM,并返回与采样帧或视频时间对齐的进度序列。
  • 判断输出是绝对进度、逐步增量,还是其他分数。
  • 判断尺度是 [0, 1][0, 100],还是未校准。
  • 优先返回 [0, 1] 中的绝对进度。如果不是,请为整次运行传入匹配的 --normalize--source-type 选项。
from prm_judge.prm.base import BasePRMAdapter
from prm_judge.schema import EvalCase, ProgressTrace

class MyAdapter(BasePRMAdapter):
    def predict(self, case: EvalCase, output_dir):
        scores = run_my_model(case.videos, case.task, case.goal_image)
        return ProgressTrace(
            case_id=case.case_id,
            progress=scores,
            source_scale="0_1",
            source_type="absolute",
        )

eval/prm_judge/prm/ 下的现有适配器可以作为模板。 recorded.py 是最小示例,robometer.py 展示了如何包装外部模型服务。请在你的适配器旁边记录模型的输出尺度、语义、必需视角、目标图像行为和运行时要求。

以 RoboMeter 为例

RoboMeter 通过 HTTP 适配器集成为序列式后端。它将 outputs_progress.progress_pred 读取为 [0, 1] 中的绝对进度曲线。由于它会基于更长的序列进行推理,因此对于局部成对评判不够充分的重复动作案例,它是一个有用的比较对象。

当复用已有 RoboMeter 服务器时,PRM-as-a-Judge 会检查 /model_info,并要求服务器模型路径与 PRM_PATH 匹配。这有助于避免误用旧 checkpoint 进行评估。适配器会以 .npy multipart files 上传帧数组,从而让长视频请求更易处理。

常用命令

不移动文件,批量评估大量视频

MANIFEST=/data/my_rollouts/cases.jsonl \
PRM_PATH=/models/Robo-Dopamine-GRM-8B-Pro \
OUTPUT_ROOT=eval/results/my_rollouts \
bash eval/run_eval.sh

使用全部四个本地 GPUs

GPUS=0,1,2,3 MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

为短操作任务运行更密集的曲线

FRAME_INTERVAL=36 MANIFEST=cases.jsonl PRM_PATH=/path/to/prm bash eval/run_eval.sh

使用 benchmark labels 进行成功分组

prm-judge eval --manifest cases.jsonl --success-source label --visualize

花费 GPU 时间前检查 manifest

prm-judge eval --manifest cases.jsonl --prm recorded --dry-run --limit 10

比较原始进度和处理后进度

prm-judge eval --manifest cases.jsonl --outlier-method none --smoothing none --visualize
prm-judge eval --manifest cases.jsonl --visualize

常见问题(FAQ)

1. 目标图像(goal_image)的作用是什么?

goal_imageRobo-Dopamine 专用的可选参数。它为模型提供明确的任务完成状态视觉参考,帮助模型理解“成功状态应该是什么样”,减少目标歧义,并提升进度判断的准确性。 Robo-Dopamine 会将其作为 REFERENCE END;在 backward 模式中,目标图像还会直接与当前采样状态进行比较。其他 Judge Model 适配器不一定使用该字段。

在实际使用中,如果有可靠的成功状态参考,建议在 manifest 中填写 goal_image,优先选择经过人工确认的成功演示轨迹最后一帧,或单独拍摄的标准目标状态。如果没有可靠的目标图像,可以省略该字段;Robo-Dopamine 适配器会使用 eval/examples/blank.png 作为占位图,但此时无法获得明确目标参考带来的判断增益。不要直接使用待评测轨迹的最后一帧,除非已经确认该轨迹成功,否则模型可能把失败状态误当成任务目标,反而降低判断准确性。

2. Robo-Dopamine 如何判断进度,何时应使用其他 PRM 作为 Judge?

Robo-Dopamine 是一种成对比较式(pair-wise)Judge Model。它会根据 EVAL_MODE 比较两张采样图像或状态,例如相邻采样点、初始状态与当前状态,或当前状态与目标参考,得到相对进度判断,再将连续的成对判断连接成进度曲线。

这种局部比较适合许多机器人操作任务。但是,对于往复运动、周期性动作或强依赖时间上下文的任务,成对比较可能产生歧义。两张图像可能无法区分机器人是在持续取得进展、重复一个动作周期,还是仅仅来回移动。对于这类任务,可以使用能够分析更长视频序列的序列式(sequence-style)PRM,例如 RoboMeter,或将其评测结果作为对照。