2026.RA.Fairness-GRPO β€” LoRA adapters

These adapters did not achieve their objective. They are published as the artifact of a preregistered negative result, and should not be used as "a fairer negotiator" β€” measured against the untrained base model they are worse on welfare and more selfish in canonical bargaining games.

What these are

LoRA adapters (r=32, Ξ±=64, 87.3M trainable parameters) on Qwen/Qwen3-8B, trained with GRPO in six-party self-play negotiation against a smoothed logarithmic Nash-welfare reward. Two arms, each with a checkpoint ladder at steps {5, 10, 15, 20, 24}:

  • 2026.RA.Fairness-GRPO-lam0 β€” Ξ»=0, each seat paid its own normalized outcome.
  • 2026.RA.Fairness-GRPO-lam1 β€” Ξ»=1, every seat paid the table's mean outcome.

The reward is R_i(Ξ») = (1βˆ’Ξ»)Β·g(z_i) + λ·mean_j g(z_j) where z_i is party i's normalized surplus and g(z) = log z above a threshold Ξ΅ = 0.01, continuing linearly below it. It is text-blind: computed from the engine's scoring of the closed deal, never from generated text.

Measured performance (this is the part that matters)

Held-out evaluation on 24 games never trained on (48 instance clusters, 960 episodes per cell), trained minus untrained Qwen3-8B, 95% instance-cluster bootstrap:

endpoint Ξ»=0 step 24 Ξ»=1 step 24 direction
normalized Nash welfare βˆ’0.185 [βˆ’0.225, βˆ’0.145] βˆ’0.109 [βˆ’0.145, βˆ’0.070] worse
deal rate (baseline 0.817) βˆ’0.252 βˆ’0.149 worse
below-threshold agreements βˆ’0.087 [βˆ’0.127, βˆ’0.050] βˆ’0.079 [βˆ’0.124, βˆ’0.030] better
NNW among individually-rational deals +0.014 [βˆ’0.012, +0.040] βˆ’0.040 [βˆ’0.067, βˆ’0.015] Ξ»=1 worse
Gini among IR deals βˆ’0.008 [βˆ’0.025, +0.009] +0.023 [+0.010, +0.036] Ξ»=1 worse

Interpretation. The one thing training bought is a reduction in below-threshold agreements β€” deals a party signs that are worse for it than walking away. It bought that substantially by not agreeing at all: deal rate fell by 0.25 (Ξ»=0) and 0.15 (Ξ»=1). Overall welfare therefore fell. Splitting the fairness metrics into all episodes versus only-fully-individually-rational episodes separates the arms: Ξ»=0's welfare loss is a composition effect (fewer deals, not worse ones β€” every among-IR interval spans zero), whereas Ξ»=1 struck measurably less fair deals among the deals it did strike.

Out-of-distribution behaviour got worse. Seated in the classic ultimatum game, which the policy never saw in training, the untrained model proposes an accepted 60/40 split. Both trained arms propose 96.7/3.3, accepted 100% of the time β€” a move toward the self-interested subgame-perfect prediction and away from the fair split, consistent across every seed. Divide-the-dollar shifts the same way more weakly (max share 0.794 β†’ 0.844 / 0.894 against a 1/n reference of 0.333).

Guards. The trained policy is not exploitable β€” seated against five computable rational agents its own capture is unchanged (Ξ»=0 βˆ’0.001 [βˆ’0.036, +0.036]). A transcript audit found no degenerate strategy: the trained policy actually negotiates more (turns per episode 20.5 β†’ 25.1) and agrees less.

Training-time metrics (on the training bank, so not evidence of generalization): reward R_table +0.61 / +0.57, worst-off seat's g +2.86 / +3.33, log-prob drift from the frozen base +0.14 / +0.27 nats per token, 0 fabricated turns at any step.

Caveat that bounds every number above

The run is 24 GRPO steps per arm, 12% of the preregistered 200-step budget, because a step costs ~17 minutes in this environment (an episode is ~20 sequential co-stepping model calls). Over-training is already visible β€” welfare worsens between step 10 and step 24 β€” but nothing here rules out a different trajectory at full budget. Treat this as a well-instrumented short run.

Reproducing

python -m grpo.train --lam 0 --steps 24 --groups 4 --k 8 --micro-batch 6 --max-new-tokens 384 \
    --lr 5e-5 --checkpoint-steps 5 10 15 20 24 --bank instances_grpo_train_v1 \
    --out runs/lam0 --transcript-every 5 \
    --wandb-project rational_agents_fairness_grpo --wandb-group fairness-grpo-pilot

Evaluation fleet and analysis: python -m grpo.launch_eval --checkpoint "lam0_step24=runs/lam0/checkpoint-24" --out-dir sbatch_grpoeval --submit, then python -m grpo.analyze_eval --baseline "<baseline>_primary_s*" --trained "lam0_step24=<run>_primary_s*" --out eval.json.

Usage

from peft import PeftModel
from transformers import AutoModelForCausalLM
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-8B", dtype="bfloat16")
model = PeftModel.from_pretrained(base, "siddharthmb/2026.RA.Fairness-GRPO-lam0", subfolder="checkpoint-24")

Links

  • Dataset (training steps, eval contrasts, rollout transcripts): siddharthmb/2026.RA.Fairness-GRPO
  • Weights & Biases: project rational_agents_fairness_grpo, group fairness-grpo-pilot β€” Ξ»=0 iedvonxu, Ξ»=1 a6wqb6l8
  • Cluster artifacts: /nlp/scr/siddharth/ii_mats/rational_agents/fairness_grpo/ (adapters, step logs, 256 sampled rollout transcripts); evaluation run directories /nlp/scr/siddharth/ii_mats/rational_agents/grpoeval_*
  • Full write-up: research note 0023-fairness-grpo-pilot.md in the project repository, with the preregistration it was run against and the compliance table.
Downloads last month
-
Video Preview
loading

Model tree for siddharthmb/2026.RA.Fairness-GRPO-lam0

Finetuned
Qwen/Qwen3-8B
Adapter
(1979)
this model

Dataset used to train siddharthmb/2026.RA.Fairness-GRPO-lam0