Research notesModel training · 05 November 2026

LiTiL / Research / soup du jour

Soup du Jour

Train the same model three times. Average the weights. Here’s how model soup took our clause classifier from 77.8% to 92.2%.

the chef is inEqual parts. Stir well.
Three checkpoints walk into a soup potSeeds 3407, 101, and 202 each contribute one third of their learned weight changes to a steaming pot labeled model soup. A ladle stirs the combined adapter. This is a schematic of weight averaging, not a plot of predictions.3407SEED⅓101SEED⅓202SEED⅓MODEL SOUPnow serving: rank 384
LiTiL Research · 5 minute readExplore the results

We're cooking, and today we made model soup. We trained three versions of a model, and averaged its weights into one. It bumped it's accuracy from 77.8% to 92.2%. This is our recipe.

01 / The recipe

First, what is model soup?

Everyone’s me-ma had a soup. The recipe was nothing: chicken, carrots, salt, a bay leaf she fished out later. What made it hers was knowing how much of each to throw in. Post-training a model is the same job, except me-ma doesn’t have to deal with PyTorch.

Model soup is what you get when you train the same model a few times and blend the weights.

No new training run, no new data. Just take the versions you already made, blend them, and taste. That’s it. It’s an old ML trick from the paper “Model Soups” by Wortsman et al. (ICML 2022).

Naturally you’re asking: why doesn’t this just produce garbage? Because every version started from the same pretrained base. Fine-tuning only nudges the weights, and all the nudges land in the same valley of the loss landscape. Average three points in one valley and you’re still in the valley, closer to the middle, which is where the good ingredients are. Our ingredients: three runs of one recipe, identical except for the random seed.

One bad apple can ruin the bunch

We fine-tuned Qwen3-1.7B to find the right passage in a contract and answer fixed-choice questions about it. Before training, we set five checks the model had to pass. No moving the goalposts after kickoff. The first run passed four.

On one check, it scored 0.612. The bar was 0.80. It missed by 0.19, which means into the garbage it goes. So we ran the identical recipe twice more and changed nothing but the seed. The next one came back at 0.878, and the next one after that came back at 0.952. Same recipe, same data, same GPU. Winner winner chicken dinner.

Figure 01

Same recipe, different seeds

One training recipe. Three runs. One equal-weight soup.

Ranking AUCHigher is better
0.40.50.60.70.80.91.0Seed 34070.612Seed 1010.878Seed 2020.952Three-seed soup0.878
Previous model 0.894Required AUC 0.80Axis: 0.4–1.0
Three-seed soup0.878 AUC · 95% CI 0.766–0.963
51 held-out questions, including four positive cases. Whiskers are 95% confidence intervals from 2,000 stratified row-bootstrap draws; they describe uncertainty from the test rows, not variation across training seeds.
View the data
Seed comparison: recorded evaluation results
ModelAUC95% CI low95% CI highMAE accuracy (%)
Seed 34070.6120.4150.78780.8
Seed 1010.8780.6761.00085.3
Seed 2020.9520.8831.00084.4
Three-seed soup0.8780.7660.96384.5
Download CSV

02 / A better model

The soup became our new model.

Equal parts of each seed, including the one we threw in the garbage. A third, a third, a third.

The soup scored 0.878 on fiduciary duty and 84.5% on material-adverse-effect questions. It passed all five checks, so it became the new model. It also came out better calibrated than any of its ingredients: expected calibration error of 0.0087, against 0.014 for the run we threw in the garbage.

Did it keep the good stuff?

On held out tests, the soup put a correct passage in first place for 92.2% of 320 contract–clause pairs. The previous model hit 77.8%. False flags per contract fell from 49.8 to 12.2.

Figure 02

What reaches the reviewer

Clause retrieval across 30 held-out contracts.

Correct passage found (%)Higher is better ↗
0%25%50%75%100%Previous model77.8%Seed 340793.4%Seed 10190.9%Seed 20291.3%Three-seed soup92.2%
Three-seed soup92.2% top-1 hit rate
Top-k is the share of 320 contract–clause pairs containing an answer for which a correct passage appears in the first k suggestions. The test covers 30 contracts, 33 clause types, and 48,642 passage–questions.
View the data
Clause retrieval and observed operating points
ModelTop 1 (%)Top 3 (%)Answers found (%)False flags / contractCutoff
Previous model77.895.994.449.80.5000
Seed 340793.498.193.813.70.4800
Seed 10190.998.492.514.30.4628
Seed 20291.398.193.416.40.4089
Three-seed soup92.298.192.512.20.5079
Download CSV

03 / Check the temperature

We over-seasoned it.

Before evaluating the soup, we got fancy. We refit its calibration temperatures on 2,000 training examples. The model had already seen those, so they looked easy. Calibrate a model on easy questions and it gets cocky on everything else. Expected calibration error came in at 0.0296. Our limit was 0.03. It passed by 0.0004, which is the eval version of making your flight because the flight was also late.

Then we threw out the refit and used the soup’s own blended temperatures, computed from the same saved predictions. ECE: 0.0087. Three times better, for doing less.

Calibrating on training rows is asking the cook whether dinner was good. Recalibrate a soup on held-out data, or leave it alone.

Figure 03

Calibration, before and after

The same soup, with two different temperature settings.

Expected calibration error · ECELower is better ↘
Soup: reconstructed offlineOriginal blended temperatures
0.000.010.020.03Seed 34070.0145Seed 1010.0128Seed 2020.0111Three-seed soup0.0087
Maximum allowed ECE 0.030Outlined bar = offline reconstruction
Three-seed soup0.0087 ECE · reconstructed offline
10,899 public test questions from trained task types; 15 equal-width confidence bins. The two soup values use the same trained model. The blended-temperature value was reconstructed offline from saved predictions. ECE measures calibration, not the rate of legal errors.
View the data
Calibration error and evaluation method
Model / settingECEEvaluation method
Seed 34070.0145Direct evaluation
Seed 1010.0128Direct evaluation
Seed 2020.0111Direct evaluation
Soup: blended temperatures0.0087Reconstructed offline
Soup: training-row refit0.0296Direct evaluation
Download CSV

04 / Ready to serve

The batch we kept.

We tried several other combinations, including blends of specialist models and a newer training recipe.

The previous model put a correct contract passage first 77.8% of the time. Our three-run soup raised that to 92.2%, passed all five checks, and became our new model.

Kitchen notes
  • Model: Qwen3-1.7B, rank-128 LoRA adapter, small decision head.
  • Data: public CUAD, MAUD and ContractNLI tasks, plus our own generated contract tasks. Charts use the legal4 run series.
  • Checks: written down before every training run.
Methods & reading
  • AUC: ranking quality with no cutoff. Intervals from 2,000 stratified bootstrap draws.
  • Clause retrieval: top-1 on 320 answer-bearing contract–clause pairs, 30 contracts, 33 clause types.
  • Calibration: expected calibration error, 15 bins, 10,899 public test questions.
  • Earlier blends: from our October experiment records.
Model soups · Wortsman et al., 2022