Blog

Research / September 22, 2026

Swarm the prompts GRPO throws away

An RL training set is only the prompts the model sometimes gets right. The hardest ones never make it in, because every rollout fails. We gave 223 such prompts the same extra budget four ways. A swarm of attempts that share programs rescued one in ten. So did plain resampling. Spending the samples mattered. How we structured them did not.

The short version. GRPO learns from the spread inside a group of rollouts, so a prompt where all eight fail teaches it nothing and gets dropped. Those are your hardest prompts, and they vanish from the training set. We took 223 of them and gave each one 24 more samples four ways. Every way rescued about one task in ten, and the differences sit inside the noise of re-running the same arm. The caveat is the model: a 4B model with thinking off barely passes a single sample test on these problems, so there was little for the swarm to share.

All-fail tasks rescued within 24 extra samples, with 95% intervals

Share of the 223 code_contests tasks where hosted Qwen3-4B failed all 8 base rollouts and the arm then found a program passing every hidden test. Same 24-sample budget per task per arm. Re-running the resample arm with two more seeds gave 9.0% and 10.8%, so a gap under 10.9 points is the eval re-running. Source: recipes/01-simulate/swarm-rescue/results.json.

All-fail tasks rescued within 24 extra samples, with 95% intervals
ItemValue95% interval
Resample, 24 independent tries7.2%4.1% to 10.3%
Solo, rewrite own best with the failing test6.7%3.3% to 10.1%
Ring swarm, plus two neighbours' best9.9%6.1% to 13.7%
Star swarm, plus the whole swarm's best9.9%6.1% to 13.7%

Where the training set comes from

A reinforcement learning run on a verifier does not train on prompts. It trains on groups: several rollouts of one prompt, scored pass or fail, with the passing ones pushed up relative to the failing ones [1]. If the whole group passes or the whole group fails, there is nothing to push, so the prompt contributes no gradient and dynamic sampling skips it [2]. The SDK's select(mode="rl") keeps the 20 to 80% band for the same reason.

That rule is right and it has a cost. The prompts that fail every time are the ones the model most needs, and they are exactly the ones the training set never contains. In our base pass, 223 of 275 tasks were in that pile.

A swarm is a different way to spend the same samples

Particle swarm optimization is a population search from 1995 [3]. Each particle keeps its own best position, looks at its neighbours' best, and moves toward a mix of the two. The part that transfers to language models is not the arithmetic. It is the social structure, and the one question the field studied for two decades: who sees whom.

We ran it in prose. A particle is one attempt at the problem. Its position is the program it wrote. Its fitness is how many of the visible tests that program passes. Each round, the model gets its own best program, the first visible test it failed with the expected and actual output, and one more thing that depends on the topology:

  • Solo sees nothing else. This is the swarm with the social term off.
  • Ring sees the best program of its two neighbours [4].
  • Star sees the best program in the whole swarm.

Eight particles, three rounds, 24 samples. Resampling gets 24 fresh independent tries. Every arm stops on a task the moment one program passes the hidden tests, which no arm ever sees.

Tasks rescued in each round, out of 223

Round 0 is 8 fresh samples for every arm. The swarms found most of their rescues in the rounds that read a failing test and a neighbour's program, as the design predicts. The two resample re-runs found 20 and 24, so the gap is inside the seed-to-seed spread.

Tasks rescued in each round, out of 223
ItemValue
Resample16
Solo15
Ring22
Star22

What happened

Feedback alone did nothing. Solo refinement matched resampling. Sharing added six rescues for either topology, and the two resample re-runs moved by more than that between seeds. On the tasks nobody rescued, the best program passes 8% of the visible tests on average. The fitness the swarm moves on was almost always zero, and a particle shown a neighbour's zero-fitness program has no direction to move in.

The training set did move. Across the six runs, 43 of the 223 dropped prompts got at least one program that passes every hidden test. The four arms alone wrote 112 distinct passing programs on 37 tasks into a file of bare rows: the problem in, the program out, no swarm context.

What this teaches about post-training

The training set is not fixed. Which prompts carry signal depends on how much you sample, and on this model it did not depend on how you condition the later samples. QuestA rescues the same prompts with partial reference solutions as hints [5]; the swarm tried to write its own hints and, at this fitness floor, could not. Model Swarms ran PSO over adapter weights [6], where fitness is a held-out score and always graded. A swarm needs a graded fitness. Pass or fail on a task the model cannot touch is not one.

The rescued rows carry a warning label. They were written with a neighbour's program in the prompt, so they are off-policy for the bare prompt and cannot go through the GRPO importance ratio as plain rollouts. They enter as privileged data: rejection-sampled SFT, or the on-policy distillation we compared last week. That training run is the next post, and it does not need the swarm to win first.

For researchers

SettingValue
Taskscode_contests test and valid splits [7], 275 problems after dropping interactive ones, median Codeforces rating 1900
Testsvisible = public + 8 generated; hidden = private + 32 generated; pass = whitespace-token match, floats within 1e-6, 6 s a test
Modelhosted Qwen3-4B, thinking off, temperature 1, 2,048 tokens, seed per sample; 7.8% of replies hit the cap
Base8 rollouts a task; all-fail = 0 of 8 pass every test; 223 of 275
Budget24 samples a task an arm: 8 particles x 3 rounds, or 24 independent draws
Fitnessshare of visible tests passed; a tie goes to the newer attempt
Rescueat least one program passing every visible and hidden test
Intervalwai.pass_at bootstrap over tasks; deltas vs resample by wai.compare_runs, paired, sign-flip p-value
Deltassolo -0.4 [-4.0, +2.7]; ring +2.7 [-1.3, +6.7]; star +2.7 [-0.9, +6.3] points
Noise floorresample at three seeds: 7.2, 9.0, 10.8%; run_std 1.8 points; band 10.9 (wai.eval_variance)
To resolvewai.holdout_size: 547 paired tasks for +5 points at a 7% base, 1,382 for +3
By ratingunder 1500: 10 / 13 / 15 of 70 (resample / ring / star); 1500 to 2199: 2 / 3 / 4 of 57; 2200 up: 4 / 6 / 3 of 96
Costabout 24,000 model calls, 25M tokens, 3.5 hours on one L40S

Run it

pip install whileai pyarrow
git clone https://github.com/whilehq/whileai-sdk
cd whileai-sdk/recipes/01-simulate/swarm-rescue
python run.py --dry-run          # three toy tasks, a fake model, no key
python run.py --limit 20         # twenty tasks on the hosted model
python run.py --noise-runs 2     # every task, four arms, the noise band

References

  1. Shao, Z., Wang, P., Zhu, Q., Xu, R., Song, J., Bi, X., Zhang, H., Zhang, M., Li, Y. K., Wu, Y. and Guo, D. (2024). DeepSeekMath: Pushing the limits of mathematical reasoning in open language models. arXiv:2402.03300.
  2. Yu, Q., et al. (2025). DAPO: An open-source LLM reinforcement learning system at scale. arXiv:2503.14476.
  3. Kennedy, J. and Eberhart, R. (1995). Particle swarm optimization. Proceedings of IEEE International Conference on Neural Networks, 1942 to 1948.
  4. Kennedy, J. and Mendes, R. (2002). Population structure and particle swarm performance. Proceedings of the IEEE Congress on Evolutionary Computation, 1671 to 1676.
  5. Li, J., et al. (2025). QuestA: Expanding reasoning capabilities of LLMs via question augmentation. arXiv:2507.13266.
  6. Feng, S., Wang, Z., Wang, Y., Ebrahimi, S., Palangi, H., Miculicich, L., Kulshrestha, A., Rauschmayr, N., Choi, Y., Tsvetkov, Y., Lee, C.-Y. and Pfister, T. (2024). Model Swarms: Collaborative search to adapt LLM experts via swarm intelligence. arXiv:2410.11163.
  7. Li, Y., et al. (2022). Competition-level code generation with AlphaCode. Science 378(6624), 1092 to 1097. arXiv:2203.07814.