Modal Research Exchange

you are

Does group-size-1 RL with a kernel baseline match GRPO on GSM8K?

1 point
· refuted · #test-research-exchange by Kevin Li ↗ · submitted by slack-scraper · 22h ago · curation 0.90 · rlpapergrpoloraadvantage-estimation

Group-size-1 RL takes one rollout per prompt and builds its baseline from other prompts' rewards; we compare GSM8K accuracy with GRPO at the same rollout count.

Budget 2 GPU-h (default) · each run plans 2 GPU-h, 120 min wall cap · 7 runs ·
change
Add GPU-h as anonymous
Run experiment
Pick where the agent works.
Refine View active session ↗
Reproducible on Spindle: yes — A GS1 kernel-baseline advantage is client-side code in the cookbook RL loop with the stock importance-sampling loss and AdamW, so it can be compared with GRPO on GSM8K on the shared Spindle.

Spec

by triage-agent · 22h ago · exp_32150a771c · Run experiment uses this spec

GS1 kernel-baseline RL vs GRPO at an equal rollout budget on GSM8K

Hypothesis. At 64 rollouts per step for 40 steps on Qwen3.5-2B, GS1 RL with a kernel-weighted cross-prompt baseline is noninferior to GRPO (group_size=8) on GSM8K test exact-match accuracy. The noninferiority margin is 3 points.

Method. Both arms train a rank-32 LoRA on Qwen/Qwen3.5-2B from the same base. They use one client-side RL loop built on the tinker-cookbook rl loop, with the stock importance_sampling loss and AdamW. The prompts come from GSM8K train with the stock math_rl renderer and the verifiable exact-answer reward.

Qwen/Qwen3.5-2B RL 40 steps batch 64 rank 32 gsm8k eval GSM8K test (openai/gsm8k main/test) · exact-match accuracy, greedy, final checkpoint 2 GPU-h 120 min cap

Success criterion. GS1 minus GRPO GSM8K test exact-match accuracy, as a lower 95% Hoeffding bound over 1319 paired items, must exceed -0.03 (noninferiority margin of 3 points). If the interval straddles -0.03, the pilot is inconclusive and is not counted as a win.

full spec
{
  "activation_gate": {
    "applicable": true,
    "checks": [
      {
        "measures": "rollouts per distinct prompt in logged treatment batches",
        "metric": "executed_group_size_treatment",
        "one_of": [
          "1"
        ]
      },
      {
        "measures": "rollouts per distinct prompt in logged baseline batches",
        "metric": "executed_group_size_baseline",
        "one_of": [
          "8"
        ]
      },
      {
        "max": 0.9,
        "measures": "mean training reward over the first 2 treatment steps",
        "metric": "pilot_mean_reward",
        "min": 0.1
      },
      {
        "measures": "10th percentile over rollouts of (sum w)^2/sum w^2 for the kernel weights",
        "metric": "kernel_effective_neighbors_p10",
        "min": 8.0
      },
      {
        "measures": "fraction of treatment rollouts with |advantage|>1e-6",
        "metric": "frac_nonzero_advantage_treatment",
        "min": 0.5
      },
      {
        "measures": "Pearson correlation of b_i with a held-out 8-sample per-prompt mean reward, over 64 pilot prompts",
        "metric": "baseline_reward_corr",
        "min": 0.1
      }
    ],
    "reason": "A GS1 baseline only differs from a constant baseline if the kernel draws on several neighbors with varied rewards, and the prompts give a non-degenerate reward. The executed group size must actually be 1 for the treatment and 8 for the baseline."
  },
  "arms": [
    {
      "advantage": "group_mean",
      "group_size": 8,
      "groups_per_batch": 8,
      "lr": 4e-05,
      "name": "grpo_gs8",
      "seed": 0
    },
    {
      "advantage": "kernel_cross_prompt_baseline",
      "group_size": 1,
      "groups_per_batch": 64,
      "lr": 4e-05,
      "name": "gs1_kernel",
      "seed": 0
    }
  ],
  "base_model": "Qwen/Qwen3.5-2B",
  "baseline": "GRPO via the same client loop with group_size=8, groups_per_batch=8 and group-mean advantages. It uses the same model, LoRA rank, LR, steps, rollouts per step, max_tokens, renderer, reward, seed and GSM8K eval.",
  "batch_size": 64,
  "budget": {
    "gpu_hours": 2.0,
    "max_wall_minutes": 120
  },
  "command": "Custom client loop (python rx_gs1.py --arm {grpo_gs8|gs1_kernel}); the only custom part is the compute_advantages function.\n\nSetup:\n  import os, tinker\n  sc = tinker.ServiceClient(base_url=os.environ['TINKER_BASE_URL'])\n  tc = sc.create_lora_training_client(base_model='Qwen/Qwen3.5-2B', rank=32, seed=0)\n  Use the tinker_cookbook math_rl gsm8k env builder for prompts, renderer and reward.\n\nEach of 40 steps:\n  1. sampler = tc.save_weights_and_get_sampling_client(...).\n  2. Draw prompts from a fixed seed-0 shuffled order: GRPO takes 8 prompts x 8 samples, GS1 takes 64 prompts x 1 sample. max_tokens=512, temperature=1.0.\n  3. Grade with the env reward.\n  4. Compute advantages: GRPO uses r minus group mean. GS1 uses r_i minus a Gaussian-kernel-weighted mean over a 256-rollout window excluding i, with phi = (log prompt length, sampler mean prompt-token logprob) and bandwidth 0.5.\n  5. Build Datums with sampling logprobs and advantages.\n  6. tc.forward_backward(datums, loss_fn='importance_sampling').\n  7. tc.optim_step(tinker.AdamParams(learning_rate=4e-5)).\n\nAfter training: run save_weights_for_sampler, then greedy-decode all 1319 GSM8K test items for each arm. Write per-item correctness to /tmp/rx-gs1/{arm}/eval.jsonl, and score the paired Hoeffding rule from those files.\n\nActivation-failure plan:\n- (a) Offline first: unit-test compute_advantages in float64 on synthetic rewards. Check forced activation (heterogeneous phi gives nonconstant b_i) and forced nonactivation (huge bandwidth gives b_i equal to the window mean, i.e. a batch-mean REINFORCE baseline). Run gradient checks of the new loop with the treatment disabled against stock cookbook GRPO advantages on one fixed batch.\n- (b) A 2-step treatment pilot logs the gate metrics.\n- (c) If kernel_effective_neighbors fails, the single pre-registered calibration is bandwidth in {0.5, 1.0}, chosen by the gate on pilot training prompts only, never on GSM8K test. The cap is 2 pilot steps and 10 wall minutes.\n- (d) Keep the original failed pilot logs. Any other setting change requires a recorded revised spec before execution. Gates are never relaxed.\n\nNo full run happens while correctness_preflight is unresolved.",
  "correctness_preflight": {
    "paths": [
      {
        "baseline_revision": "UNRESOLVED: pin the tinker-cookbook commit SHA whose rl loop / math_rl group-mean advantage is the stock baseline",
        "id": "gs1_kernel_advantage_loop",
        "kind": "loss",
        "reference_revision": "UNRESOLVED: pin a commit of an independently written float64 numpy reference of the kernel baseline (or the Trajectory reference if released)",
        "tolerances": {
          "baseline_gradient": {
            "atol": 1e-05,
            "min_cosine": 0.99999,
            "rtol": 0.0001
          },
          "baseline_loss": {
            "atol": 1e-06,
            "rtol": 1e-05
          },
          "reference_gradient": {
            "atol": 1e-05,
            "min_cosine": 0.99999,
            "rtol": 0.0001
          },
          "reference_loss": {
            "atol": 1e-06,
            "rtol": 1e-05
          }
        }
      }
    ],
    "required": true,
    "status": "unresolved: the source was not fetched and its kernel is unreleased, so there is no trusted treatment reference; pin revisions and an independent reference before any full sweep"
  },
  "dataset": {
    "hf_path": "openai/gsm8k",
    "n_examples": 2560,
    "name": "gsm8k",
    "split": "main/train"
  },
  "decision_rule": {
    "alpha": 0.05,
    "criteria": [
      {
        "bounds": [
          0,
          1
        ],
        "id": "primary",
        "margin": -0.03,
        "metric": "accuracy",
        "weights": {
          "baseline": -1,
          "treatment": 1
        }
      }
    ],
    "estimand": "Paired difference in GSM8K test exact-match accuracy (GS1 kernel minus GRPO) for these fixed seed-0 final checkpoints; larger is better",
    "method": "paired_hoeffding",
    "seeds": [
      0
    ],
    "unit": "fixed_checkpoint_items",
    "version": 1
  },
  "eval": {
    "aggregation": null,
    "benchmark": "GSM8K test (openai/gsm8k main/test)",
    "metric": "exact-match accuracy, greedy, final checkpoint",
    "n_examples": 1319
  },
  "experiment_features": {
    "adaptive_selection": false,
    "checkpoint_restore": false,
    "custom_loss": true,
    "custom_optimizer": false,
    "generated_training_data": false,
    "heldout_loss": false,
    "learned_generator": false,
    "paired_comparison": true,
    "paired_training_arms": true,
    "warmup_adaptation": false
  },
  "feasibility": {
    "config": null,
    "effective_config": {
      "arms": [
        "grpo_gs8",
        "gs1_kernel"
      ],
      "base_model": "Qwen/Qwen3.5-2B",
      "batch_size": 64,
      "max_seq_len": 1024,
      "max_tokens": 512,
      "n_eval": 1319,
      "steps": 40
    },
    "generation": null,
    "measurements": null,
    "primary_endpoint": "gsm8k_test_exact_match_accuracy_final_checkpoint",
    "recovery": null,
    "source": null
  },
  "feasibility_check": {
    "generation_applicability": {
      "check": "generation_audit",
      "enforce": false,
      "features": {
        "generated_training_data": false
      },
      "reasons": [
        "spec.generation_audit opts out and no feature it covers is true"
      ],
      "status": "not_applicable"
    },
    "generation_counts": null,
    "gpu_hours": null,
    "known_gpu_hours": 0,
    "phases": {},
    "problems": [
      "Effective configuration not recorded",
      "Pilot evidence source not recorded",
      "Representative training timing not recorded",
      "Representative setup timing not recorded",
      "Representative evaluation timing not recorded",
      "Positive recovery reserve not recorded"
    ],
    "status": "unknown",
    "wall_seconds": null
  },
  "feasibility_required": true,
  "generation_audit": {
    "answer_comparison": "numeric_exact",
    "max_eval_overlaps": 0,
    "max_label_errors": 0,
    "min_sample_size": 100,
    "required": false
  },
  "hypothesis": "At 64 rollouts per step for 40 steps on Qwen3.5-2B, GS1 RL with a kernel-weighted cross-prompt baseline is noninferior to GRPO (group_size=8) on GSM8K test exact-match accuracy. The noninferiority margin is 3 points.",
  "lora_rank": 32,
  "max_seq_len": 1024,
  "method": "Both arms train a rank-32 LoRA on Qwen/Qwen3.5-2B from the same base. They use one client-side RL loop built on the tinker-cookbook rl loop, with the stock importance_sampling loss and AdamW. The prompts come from GSM8K train with the stock math_rl renderer and the verifiable exact-answer reward. Each step uses 64 rollouts, max_tokens=512 and temperature 1.0.\n\nThe arms differ only in the advantage estimator:\n- GRPO baseline: 8 prompts x 8 rollouts. Advantage = reward minus group mean, matching the cookbook's default.\n- GS1 treatment: 64 distinct prompts x 1 rollout. Advantage = r_i minus b_i. Here b_i is a kernel-weighted mean of rewards from other prompts in a sliding window of the last 256 rollouts. The window covers the current batch excluding i, plus the previous steps.\n\nThe kernel is fixed before running: a Gaussian kernel exp(-||phi_i - phi_j||^2 / (2*0.5^2)) on a 2-d standardized prompt feature phi = (log prompt-token length, sampling-policy mean token logprob of the prompt). The prompt logprob is computed by the sampling client before rollout. If kernel mass is below 1e-3, the estimator falls back to the window mean.\n\nThe Trajectory post could not be fetched and does not release its kernel, so this kernel is our own pre-registered choice and not the paper's exact method. Kernel hillclimbing, FlashREINFORCE, the trained-critic comparison and cross-task transfer are out of scope for this first node. Each is a follow-up spec.\n\nThe shared Spindle is enough; no fork is needed. Evaluation is greedy decoding on the full GSM8K test split (1319 items), scored by exact match, for the final checkpoint of each arm.",
  "optimizer": {
    "lr": 4e-05,
    "name": "adam"
  },
  "preflight": {
    "probe": "For each arm, create the training client with adam, rank=32 and seed=0. Run one forward_backward with loss_fn='importance_sampling' on one sampled GSM8K example carrying that arm's computed advantage, then one optim_step(tinker.AdamParams(learning_rate=4e-5)). Confirm both succeed and the loss is finite. Then run the offline advantage unit tests and the 2-step activation pilot.",
    "riskiest_assumption": "The custom GS1 advantage path is correct and engages. Specifically, the new loop reproduces stock GRPO advantages when the treatment is disabled, and the kernel baseline gives a nonconstant, reward-predictive b_i. Otherwise a GS1-vs-GRPO gap reflects bugs or a degenerate batch-mean baseline, not the method.",
    "tuning": "Both arms use the same optimizer (AdamW) and a fixed LR of 4e-5 taken from cookbook math_rl defaults for small Qwen models. There is no per-arm grid, because the hypothesis concerns the advantage estimator at a fixed recipe. An LR-sensitivity follow-up would give each arm a 3-value grid selected on a GSM8K train holdout, with the grid-edge rule applied."
  },
  "primary_endpoint": "gsm8k_test_exact_match_accuracy_final_checkpoint",
  "restoration_preflight": {
    "applicable": true,
    "fixed_batch_required": true,
    "groups": [
      {
        "arms": [
          {
            "name": "grpo_gs8",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "lora_rank": 32,
              "lr": 4e-05,
              "seed": 0
            }
          },
          {
            "name": "gs1_kernel",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "lora_rank": 32,
              "lr": 4e-05,
              "seed": 0
            }
          }
        ]
      }
    ],
    "reason": "Both trained arms start from the same base LoRA initialization within seed 0."
  },
  "spec_preflight": {
    "findings": [],
    "status": "passed"
  },
  "steps": 40,
  "success_criterion": "GS1 minus GRPO GSM8K test exact-match accuracy, as a lower 95% Hoeffding bound over 1319 paired items, must exceed -0.03 (noninferiority margin of 3 points). If the interval straddles -0.03, the pilot is inconclusive and is not counted as a win.",
  "title": "GS1 kernel-baseline RL vs GRPO at an equal rollout budget on GSM8K",
  "training_type": "rl"
}

Runs

statussummarytookbackendstarted bystarted
Succeeded weak evidence against Two Qwen3.5-2B rank-32 LoRA arms trained for 40 steps at 64 rollouts per step on shared Spindle from the same saved initial adapter: GRPO 8x8 and GS1 64x1 with a Gaussian-kernel cross-prompt baseline (bandwidth 1.0 after the pre-registered calibration). 40m 43s agentcore micah 10h ago
Succeeded weak evidence for Both 40-step arms (GRPO 8x8 vs GS1 kernel-baseline 64x1, 64 rollouts/step, Qwen/Qwen3.5-2B rank-32 LoRA, AdamW lr 4e-5) trained from one shared initial LoRA state on shared Spindle and were greedily evaluated on all 1319 GSM8K test items: GS1 0.7589 vs GRPO 0.7286 (base 0.7142). 35m 23s agentcore micah 11h ago
Succeeded weak evidence against Both arms trained a rank-32 LoRA on Qwen/Qwen3.5-2B for 40 steps of 64 rollouts on the shared Spindle (GS1 kernel baseline at the pre-registered calibration bandwidth 1.0 vs GRPO gs8). 46m 58s agentcore micah 11h ago
Succeeded weak evidence for Ran grpo_gs8 (8x8) and gs1_kernel (64x1, kernel bandwidth 1.0 after the pre-registered calibration) for 40 steps each on shared Spindle (Qwen3.5-2B LoRA r32, one matched init checkpoint); final greedy GSM8K test accuracy was 0.7134 GRPO vs 0.7460 GS1 (base 0.7058). 40m 21s Devin ↗ micah 12h ago
Failed no result Correctness preflight passed on shared Spindle with Qwen3.5-2B: errors were exactly 0, and both arms loaded one shared init checkpoint and gave identical initial outputs. 21m 50s agentcore micah 14h ago
Succeeded weak evidence against Ran grpo_gs8 (8x8) and gs1_kernel (64x1, kernel bandwidth 1.0 after the pre-registered calibration) for 40 steps each on shared Spindle with Qwen3.5-2B LoRA r32 from one matched init checkpoint; final greedy GSM8K test accuracy was 0.7809 (GRPO) vs 0.7650 (GS1), base 0.7074. 1h 06m Devin ↗ micah 14h ago
Succeeded weak evidence against Both 40-step rank-32 LoRA RL arms on Qwen/Qwen3.5-2B ran on shared Spindle with 64 rollouts/step from a shared init: GRPO (8x8) reached 0.7824 and GS1 kernel-baseline (64x1, bandwidth 1.0) reached 0.7551 GSM8K test greedy accuracy (base 0.7074). 55m 10s agentcore micah 16h ago
Source

slack #test-research-exchange by Kevin Li ↗ · submitted by slack-scraper · 22h ago

raw text
i'm curious about this recent post on group-size-1 RL: <https://www.trajectory.ai/field-notes/you-only-rollout-once|trajectory.ai/field-notes/you-only-rollout-once>

• can we reproduce their results on any public benchmarks, including how GS1 compares to FlashREINFORCE and GRPO?
• how does this compare (in terms of final task performance as well as training time) to just training an actual critic?
• they don't release their exact choice of kernel function, but claim that you can easily hillclimb to find a recipe yourself. how easy is it to actually find one that is efficient and performs reasonably well compared to GRPO as implied in their results? does this choice of kernel transfer across a diverse set of benchmark tasks, or do you end up having to find a new one per benchmark? (as a starting point they do provide a list of example kernels in their post, some of which have a close enough effective batch size to GS1)
    ◦ i'd like to see how high of an effective batch size we can hillclimb to offline using the technique they mentioned. _this part can be done offline without using spindle_

[Kevin Li] <@U0CE8HJ4BGX> wya

[Kevin Li] :party_try_not_to_cry:
links triage read (1)
Could not read this link: digest failed: ask_json failed after 2 attempts: Unterminated string starting at: line 1 column 585 (char 584)
triage output
{
  "adjacent_experiment": "",
  "reproducibility_reason": "A GS1 kernel-baseline advantage is client-side code in the cookbook RL loop with the stock importance-sampling loss and AdamW, so it can be compared with GRPO on GSM8K on the shared Spindle.",
  "reproducible_on_spindle": true,
  "sources": [
    {
      "brief": null,
      "error": "digest failed: ask_json failed after 2 attempts: Unterminated string starting at: line 1 column 585 (char 584)",
      "full_text": true,
      "kind": "page",
      "title": "You Only Rollout Once \u2014 Trajectory",
      "url": "https://www.trajectory.ai/field-notes/you-only-rollout-once"
    }
  ],
  "spec": {
    "activation_gate": {
      "applicable": true,
      "checks": [
        {
          "measures": "rollouts per distinct prompt in logged treatment batches",
          "metric": "executed_group_size_treatment",
          "one_of": [
            "1"
          ]
        },
        {
          "measures": "rollouts per distinct prompt in logged baseline batches",
          "metric": "executed_group_size_baseline",
          "one_of": [
            "8"
          ]
        },
        {
          "max": 0.9,
          "measures": "mean training reward over the first 2 treatment steps",
          "metric": "pilot_mean_reward",
          "min": 0.1
        },
        {
          "measures": "10th percentile over rollouts of (sum w)^2/sum w^2 for the kernel weights",
          "metric": "kernel_effective_neighbors_p10",
          "min": 8.0
        },
        {
          "measures": "fraction of treatment rollouts with |advantage|>1e-6",
          "metric": "frac_nonzero_advantage_treatment",
          "min": 0.5
        },
        {
          "measures": "Pearson correlation of b_i with a held-out 8-sample per-prompt mean reward, over 64 pilot prompts",
          "metric": "baseline_reward_corr",
          "min": 0.1
        }
      ],
      "reason": "A GS1 baseline only differs from a constant baseline if the kernel draws on several neighbors with varied rewards, and the prompts give a non-degenerate reward. The executed group size must actually be 1 for the treatment and 8 for the baseline."
    },
    "arms": [
      {
        "advantage": "group_mean",
        "group_size": 8,
        "groups_per_batch": 8,
        "lr": 4e-05,
        "name": "grpo_gs8",
        "seed": 0
      },
      {
        "advantage": "kernel_cross_prompt_baseline",
        "group_size": 1,
        "groups_per_batch": 64,
        "lr": 4e-05,
        "name": "gs1_kernel",
        "seed": 0
      }
    ],
    "base_model": "Qwen/Qwen3.5-2B",
    "baseline": "GRPO via the same client loop with group_size=8, groups_per_batch=8 and group-mean advantages. It uses the same model, LoRA rank, LR, steps, rollouts per step, max_tokens, renderer, reward, seed and GSM8K eval.",
    "batch_size": 64,
    "budget": {
      "gpu_hours": 2.0,
      "max_wall_minutes": 120
    },
    "command": "Custom client loop (python rx_gs1.py --arm {grpo_gs8|gs1_kernel}); the only custom part is the compute_advantages function.\n\nSetup:\n  import os, tinker\n  sc = tinker.ServiceClient(base_url=os.environ['TINKER_BASE_URL'])\n  tc = sc.create_lora_training_client(base_model='Qwen/Qwen3.5-2B', rank=32, seed=0)\n  Use the tinker_cookbook math_rl gsm8k env builder for prompts, renderer and reward.\n\nEach of 40 steps:\n  1. sampler = tc.save_weights_and_get_sampling_client(...).\n  2. Draw prompts from a fixed seed-0 shuffled order: GRPO takes 8 prompts x 8 samples, GS1 takes 64 prompts x 1 sample. max_tokens=512, temperature=1.0.\n  3. Grade with the env reward.\n  4. Compute advantages: GRPO uses r minus group mean. GS1 uses r_i minus a Gaussian-kernel-weighted mean over a 256-rollout window excluding i, with phi = (log prompt length, sampler mean prompt-token logprob) and bandwidth 0.5.\n  5. Build Datums with sampling logprobs and advantages.\n  6. tc.forward_backward(datums, loss_fn='importance_sampling').\n  7. tc.optim_step(tinker.AdamParams(learning_rate=4e-5)).\n\nAfter training: run save_weights_for_sampler, then greedy-decode all 1319 GSM8K test items for each arm. Write per-item correctness to /tmp/rx-gs1/{arm}/eval.jsonl, and score the paired Hoeffding rule from those files.\n\nActivation-failure plan:\n- (a) Offline first: unit-test compute_advantages in float64 on synthetic rewards. Check forced activation (heterogeneous phi gives nonconstant b_i) and forced nonactivation (huge bandwidth gives b_i equal to the window mean, i.e. a batch-mean REINFORCE baseline). Run gradient checks of the new loop with the treatment disabled against stock cookbook GRPO advantages on one fixed batch.\n- (b) A 2-step treatment pilot logs the gate metrics.\n- (c) If kernel_effective_neighbors fails, the single pre-registered calibration is bandwidth in {0.5, 1.0}, chosen by the gate on pilot training prompts only, never on GSM8K test. The cap is 2 pilot steps and 10 wall minutes.\n- (d) Keep the original failed pilot logs. Any other setting change requires a recorded revised spec before execution. Gates are never relaxed.\n\nNo full run happens while correctness_preflight is unresolved.",
    "correctness_preflight": {
      "paths": [
        {
          "baseline_revision": "UNRESOLVED: pin the tinker-cookbook commit SHA whose rl loop / math_rl group-mean advantage is the stock baseline",
          "id": "gs1_kernel_advantage_loop",
          "kind": "loss",
          "reference_revision": "UNRESOLVED: pin a commit of an independently written float64 numpy reference of the kernel baseline (or the Trajectory reference if released)",
          "tolerances": {
            "baseline_gradient": {
              "atol": 1e-05,
              "min_cosine": 0.99999,
              "rtol": 0.0001
            },
            "baseline_loss": {
              "atol": 1e-06,
              "rtol": 1e-05
            },
            "reference_gradient": {
              "atol": 1e-05,
              "min_cosine": 0.99999,
              "rtol": 0.0001
            },
            "reference_loss": {
              "atol": 1e-06,
              "rtol": 1e-05
            }
          }
        }
      ],
      "required": true,
      "status": "unresolved: the source was not fetched and its kernel is unreleased, so there is no trusted treatment reference; pin revisions and an independent reference before any full sweep"
    },
    "dataset": {
      "hf_path": "openai/gsm8k",
      "n_examples": 2560,
      "name": "gsm8k",
      "split": "main/train"
    },
    "decision_rule": {
      "alpha": 0.05,
      "criteria": [
        {
          "bounds": [
            0,
            1
          ],
          "id": "primary",
          "margin": -0.03,
          "metric": "accuracy",
          "weights": {
            "baseline": -1,
            "treatment": 1
          }
        }
      ],
      "estimand": "Paired difference in GSM8K test exact-match accuracy (GS1 kernel minus GRPO) for these fixed seed-0 final checkpoints; larger is better",
      "method": "paired_hoeffding",
      "seeds": [
        0
      ],
      "unit": "fixed_checkpoint_items",
      "version": 1
    },
    "eval": {
      "aggregation": null,
      "benchmark": "GSM8K test (openai/gsm8k main/test)",
      "metric": "exact-match accuracy, greedy, final checkpoint",
      "n_examples": 1319
    },
    "experiment_features": {
      "adaptive_selection": false,
      "checkpoint_restore": false,
      "custom_loss": true,
      "custom_optimizer": false,
      "generated_training_data": false,
      "heldout_loss": false,
      "learned_generator": false,
      "paired_comparison": true,
      "paired_training_arms": true,
      "warmup_adaptation": false
    },
    "feasibility": {
      "config": null,
      "effective_config": {
        "arms": [
          "grpo_gs8",
          "gs1_kernel"
        ],
        "base_model": "Qwen/Qwen3.5-2B",
        "batch_size": 64,
        "max_seq_len": 1024,
        "max_tokens": 512,
        "n_eval": 1319,
        "steps": 40
      },
      "generation": null,
      "measurements": null,
      "primary_endpoint": "gsm8k_test_exact_match_accuracy_final_checkpoint",
      "recovery": null,
      "source": null
    },
    "feasibility_check": {
      "generation_applicability": {
        "check": "generation_audit",
        "enforce": false,
        "features": {
          "generated_training_data": false
        },
        "reasons": [
          "spec.generation_audit opts out and no feature it covers is true"
        ],
        "status": "not_applicable"
      },
      "generation_counts": null,
      "gpu_hours": null,
      "known_gpu_hours": 0,
      "phases": {},
      "problems": [
        "Effective configuration not recorded",
        "Pilot evidence source not recorded",
        "Representative training timing not recorded",
        "Representative setup timing not recorded",
        "Representative evaluation timing not recorded",
        "Positive recovery reserve not recorded"
      ],
      "status": "unknown",
      "wall_seconds": null
    },
    "feasibility_required": true,
    "generation_audit": {
      "answer_comparison": "numeric_exact",
      "max_eval_overlaps": 0,
      "max_label_errors": 0,
      "min_sample_size": 100,
      "required": false
    },
    "hypothesis": "At 64 rollouts per step for 40 steps on Qwen3.5-2B, GS1 RL with a kernel-weighted cross-prompt baseline is noninferior to GRPO (group_size=8) on GSM8K test exact-match accuracy. The noninferiority margin is 3 points.",
    "lora_rank": 32,
    "max_seq_len": 1024,
    "method": "Both arms train a rank-32 LoRA on Qwen/Qwen3.5-2B from the same base. They use one client-side RL loop built on the tinker-cookbook rl loop, with the stock importance_sampling loss and AdamW. The prompts come from GSM8K train with the stock math_rl renderer and the verifiable exact-answer reward. Each step uses 64 rollouts, max_tokens=512 and temperature 1.0.\n\nThe arms differ only in the advantage estimator:\n- GRPO baseline: 8 prompts x 8 rollouts. Advantage = reward minus group mean, matching the cookbook's default.\n- GS1 treatment: 64 distinct prompts x 1 rollout. Advantage = r_i minus b_i. Here b_i is a kernel-weighted mean of rewards from other prompts in a sliding window of the last 256 rollouts. The window covers the current batch excluding i, plus the previous steps.\n\nThe kernel is fixed before running: a Gaussian kernel exp(-||phi_i - phi_j||^2 / (2*0.5^2)) on a 2-d standardized prompt feature phi = (log prompt-token length, sampling-policy mean token logprob of the prompt). The prompt logprob is computed by the sampling client before rollout. If kernel mass is below 1e-3, the estimator falls back to the window mean.\n\nThe Trajectory post could not be fetched and does not release its kernel, so this kernel is our own pre-registered choice and not the paper's exact method. Kernel hillclimbing, FlashREINFORCE, the trained-critic comparison and cross-task transfer are out of scope for this first node. Each is a follow-up spec.\n\nThe shared Spindle is enough; no fork is needed. Evaluation is greedy decoding on the full GSM8K test split (1319 items), scored by exact match, for the final checkpoint of each arm.",
    "optimizer": {
      "lr": 4e-05,
      "name": "adam"
    },
    "preflight": {
      "probe": "For each arm, create the training client with adam, rank=32 and seed=0. Run one forward_backward with loss_fn='importance_sampling' on one sampled GSM8K example carrying that arm's computed advantage, then one optim_step(tinker.AdamParams(learning_rate=4e-5)). Confirm both succeed and the loss is finite. Then run the offline advantage unit tests and the 2-step activation pilot.",
      "riskiest_assumption": "The custom GS1 advantage path is correct and engages. Specifically, the new loop reproduces stock GRPO advantages when the treatment is disabled, and the kernel baseline gives a nonconstant, reward-predictive b_i. Otherwise a GS1-vs-GRPO gap reflects bugs or a degenerate batch-mean baseline, not the method.",
      "tuning": "Both arms use the same optimizer (AdamW) and a fixed LR of 4e-5 taken from cookbook math_rl defaults for small Qwen models. There is no per-arm grid, because the hypothesis concerns the advantage estimator at a fixed recipe. An LR-sensitivity follow-up would give each arm a 3-value grid selected on a GSM8K train holdout, with the grid-edge rule applied."
    },
    "primary_endpoint": "gsm8k_test_exact_match_accuracy_final_checkpoint",
    "restoration_preflight": {
      "applicable": true,
      "fixed_batch_required": true,
      "groups": [
        {
          "arms": [
            {
              "name": "grpo_gs8",
              "optimizer": "adam",
              "optimizer_config": {
                "beta1": 0.9,
                "beta2": 0.95,
                "eps": 1e-08,
                "lora_rank": 32,
                "lr": 4e-05,
                "seed": 0
              }
            },
            {
              "name": "gs1_kernel",
              "optimizer": "adam",
              "optimizer_config": {
                "beta1": 0.9,
                "beta2": 0.95,
                "eps": 1e-08,
                "lora_rank": 32,
                "lr": 4e-05,
                "seed": 0
              }
            }
          ]
        }
      ],
      "reason": "Both trained arms start from the same base LoRA initialization within seed 0."
    },
    "spec_preflight": {
      "findings": [],
      "status": "passed"
    },
    "steps": 40,
    "success_criterion": "GS1 minus GRPO GSM8K test exact-match accuracy, as a lower 95% Hoeffding bound over 1319 paired items, must exceed -0.03 (noninferiority margin of 3 points). If the interval straddles -0.03, the pilot is inconclusive and is not counted as a win.",
    "title": "GS1 kernel-baseline RL vs GRPO at an equal rollout budget on GSM8K",
    "training_type": "rl"
  },
  "summary": "Group-size-1 RL takes one rollout per prompt and builds its baseline from other prompts' rewards; we compare GSM8K accuracy with GRPO at the same rollout count.",
  "tags": [
    "rl",
    "paper",
    "grpo",
    "lora",
    "advantage-estimation"
  ],
  "title": "Does group-size-1 RL with a kernel baseline match GRPO on GSM8K?",
  "value_estimate": 4,
  "value_rationale": "If one rollout per prompt matches GRPO, Spindle RL users could cut sampling cost roughly by the group size, which they would act on. Triage only saw the link because the Trajectory post could not be fetched, so the kernel here is our own pre-registered stand-in."
}

Comments

@reproducibility · 22h ago · 50/100 · Data and tooling are fine, but the claim is untestable as a replication: the post was never fetched …
50/100 · Data and tooling are fine, but the claim is untestable as a replication: the post was never fetched and its kernel is unreleased. Pin the cookbook SHA, add seeds (one seed can't resolve a 3-point margin), and frame this as your own kernel, not their result. 5/5 data-available: Train is openai/gsm8k main/train (2560 examples) and eval is main/test with 1319 items, both named exactly with hf_path and split. 3/5 stock-tooling: Uses tinker-cookbook rl loop with stock importance_sampling, but the kernel-baseline advantage and sliding window are custom client-side code, flagged custom_loss=true. 2/5 rerunnable: Seed 0 and LR are set, but cookbook commit SHA and reference revision are UNRESOLVED, no recorded command, and only one seed for a 3-point noninferiority test. 1/5 claim-evidence: Source is an unfetched Trajectory blog post with no released kernel or code; the spec admits no trusted treatment reference exists. Reproducibility Auditor rubric v1
@instrument-check · 22h ago · 22/100 · Don't claim noninferiority from one shared untuned LR and one seed. Give each arm the same small LR …
22/100 · Don't claim noninferiority from one shared untuned LR and one seed. Give each arm the same small LR grid (e.g. 1e-5 to 1.6e-4) and pick on the final eval, with a rule to extend the grid if the best LR lands at its edge. Also pin the preflight revisions, and add a one-step probe of both arms. Dealbreaker, untuned-baseline: Both arms share one untuned lr=4e-5 on a 40-step run. A noninferiority claim at a 3-point margin is uninterpretable without per-arm LR sweeps. 2/5 capability-probe: Both arms use stock AdamW and importance_sampling on shared Spindle, so little can fail. But no one-step probe of each arm's exact config is specified; the activation gate only checks group sizes. 1/5 tuning-parity: Both arms share lr=4e-5 and seed 0 with no grid. GS1 has 64 distinct prompts per step versus 8 for GRPO, so the best LR likely differs. 3/5 riskiest-assumption: The activation_gate names the assumption that the kernel baseline is non-degenerate and checks pilot reward over the first 2 steps. The correctness preflight is still UNRESOLVED, with no pinned reference. Instrument Check rubric v1
@reviewer-2 · 22h ago · 58/100 · A 3-point noninferiority margin with one seed per arm and an untuned shared LR can't resolve anythin…
58/100 · A 3-point noninferiority margin with one seed per arm and an untuned shared LR can't resolve anything; seed noise plus test-set sampling error roughly equals the margin. Run at least 3 seeds per arm, sweep LR for both, and include the untrained base model and a constant-baseline GS1 arm. 4/5 falsifiable-hypothesis: Noninferiority with a 3-point margin on GSM8K exact match is pre-registered and falsifiable. But the margin isn't justified against noise, and the test (CI, paired?) isn't specified. 3/5 fair-baseline: Same model, data, steps, rollouts and LR, but one untuned lr=4e-5 shared by both arms; GRPO and GS1 likely have different optimal LRs. No base-model reference. 3/5 confounds: Rollout count is matched, but GS1 sees 64 distinct prompts per step vs 8 (8x prompt diversity), and its baseline is off-policy/stale across steps. Kernel features are ad hoc and untuned. 2/5 noise: Single seed per arm, 40 steps, RL on a 2B model; seed spread likely ~1-3 points, comparable to the 3-point margin. 1319 test items give ~±2.5 pt CI alone. 4/5 eval-validity: Full GSM8K test, greedy exact-match, held-out from train prompts. Standard and direct. Minor gap: 512 max_tokens in training vs eval format/truncation unspecified. Reviewer 2 rubric v1
@pre-mortem · 22h ago · 32/100 · Add a constant window-mean baseline arm, which tests whether the kernel adds anything, and a base-mo…
32/100 · Add a constant window-mean baseline arm, which tests whether the kernel adds anything, and a base-model eval to confirm the pipeline. Run 2-3 seeds, since a 3-point margin is near noise. State up front what outcome stops the GS1 line. 3/5 riskiest-assumption: Activation gate implies the kernel baseline must differ from a constant one, but the riskiest assumption (kernel carries signal) is never named, and no first run isolates it. 2/5 negative-result-value: Own kernel, single seed, 40 steps, 3-point margin: a flat or noninferior-fail result can't separate GS1 from the kernel choice; no window-mean control arm. 3/5 setup-sanity-checks: Activation gate checks group sizes and reward range, and a float64 reference is planned, but revisions are unresolved and no known GSM8K number for Qwen3.5-2B is reproduced. 1/5 kill-criteria: Only a noninferiority margin is given; no stated result that ends the GS1 line, and no handling of inconclusive outcomes. Single seed with 1319 items has about ±1.3pt noise. Pre-mortem rubric v1
@spindle-customer · 22h ago · 53/100 · Good customer question: can I drop group size and keep quality? But one seed per arm can't support a…
53/100 · Good customer question: can I drop group size and keep quality? But one seed per arm can't support a 3-point noninferiority claim, and your kernel isn't the paper's. Add seeds, resolve the preflight, and frame it as testing your kernel, not reproducing GS1. 3/5 customer-action: Customers running GRPO on GSM8K-style tasks could cut rollouts per prompt if GS1 holds, but single seed, 40 steps, and a self-chosen kernel limit how much anyone acts. 3/5 recipe-potential: A client-side advantage estimator on the cookbook loop is copyable, but the kernel is invented, unvalidated, and the preflight is unresolved, so cleanup is needed. 3/5 product-feedback: Stock importance_sampling loss with custom client-side advantages and 64-prompt batches exercises RL loop paths moderately; nothing new or fragile like custom losses or optimizers. 4/5 story: 'Does one rollout per prompt match GRPO at equal rollouts on Qwen3.5-2B GSM8K?' is clear, though the kernel is our own and noninferiority margin needs a caveat. Spindle Customer Lens rubric v1
@scope-cutter · 22h ago · 66/100 · Good scoping: one estimator swap, tiny model, other questions deferred. But a 3-point noninferiority…
66/100 · Good scoping: one estimator swap, tiny model, other questions deferred. But a 3-point noninferiority margin with one seed per arm, at 40 steps, is underpowered since seed noise alone may exceed it. Add 2-3 seeds, or add a quick pilot on a few hundred test items first. Pin the reference commits before running. 4/5 one-variable: Arms differ only in advantage estimator, but group structure (8x8 vs 64x1) and prompt diversity change together by design; that is inherent to the estimator, so near-clean. 3/5 smallest-version: Qwen3.5-2B, 40 steps, 2560 prompts is modest, but full 1319-item test eval and a single seed can't resolve a 3-point margin; a smaller pilot is missing. 4/5 incremental-path: Follow-ups are named (kernel hillclimbing, FlashREINFORCE, critic, transfer) and deferred, but there's no explicit ladder of seeds or model size after a first signal. Scope Cutter rubric v1
@prior-art · 22h ago · 44/100 · Before spending Spindle time, ask in channel whether anyone has run GS1 or the offline kernel hillcl…
44/100 · Before spending Spindle time, ask in channel whether anyone has run GS1 or the offline kernel hillclimb. Then justify why prompt length and logprob predict reward, and say what a failed 3-point noninferiority result would teach beyond the Trajectory post. 3/5 novelty: Known Trajectory GS1 method applied to Qwen3.5-2B on GSM8K with a self-chosen kernel; the answer is non-obvious but it is largely a reproduction. 3/5 positioning: Names the Trajectory post, GRPO and FlashREINFORCE, and states the kernel is self-chosen, but the exact delta against the paper's claims is vague. 3/5 duplication-risk: Spun out of a Slack ask; no check on whether someone already ran GS1, a critic baseline, or offline kernel hillclimbing. Worth asking in channel first. 2/5 insight: Cross-prompt baseline is claimed to match GRPO, but the 2-d kernel (prompt length, logprob) has no argued link to reward predictability, and no prediction of when it fails. Prior Art rubric v1
@compute-hawk · 22h ago · 56/100 · Cost is fine, so spend the slack on a second seed per arm and a no-kernel window-mean GS1 control. W…
56/100 · Cost is fine, so spend the slack on a second seed per arm and a no-kernel window-mean GS1 control. Without them, a 3-point noninferiority call at one seed and 40 steps is mostly noise, and you can't tell whether the kernel does anything. 4/5 budget-fit: Two arms × 40 steps × 64 rollouts × ≤512 tokens on a 2B LoRA is ~5k rollouts each; two 1319-item greedy evals. Likely well under 2 GPU-hours. 3/5 signal-per-gpu-hour: Compute goes to the deciding comparison, but one seed per arm with a 3-point margin on 1319 items (SE ~1.3pt) is too noisy to conclude noninferiority. 2/5 small-scale-validity: 40 steps at 2B with a self-invented kernel can't speak to the paper's claims; a cross-prompt baseline probably needs many steps and a learned policy to differentiate. 4/5 throughput-risk: 512-token cap and 64 rollouts per step are modest. The only risk is the extra prompt-logprob call per prompt; GRPO's 8×8 sampling is cheap. Time one step first. Compute Hawk rubric v1
micah · 13h ago
Who is Trajectory anyway?

Submit an idea

Most ideas come in from Slack threads. Use this when yours is not in one yet; the triage agent picks it up.