Train your own embedding model
Beat the baseline & ship·30 min

Beat the baseline: recall@5

0 / 1
# grade this stage (from your course directory)
npx theinference test --stage beat-the-baseline --watch

The moment of truth. Train the encoder with your chapter-5 loop, then compute recall@5 on the same frozen eval set — and report it next to the baseline. A correct trainer crushes the baseline; a broken objective (no temperature, sign-flipped gradient, one-directional loss) doesn't separate and lands near the baseline.

What to build

Your task

Train, then measure recall@5

Make your_program.sh recall train from the frozen init, embed the eval set with the trained encoder and with the untrained baseline, and print both recalls as JSON:

your_program.sh recall
$ ./your_program.sh recall
{"recall":0.96,"baselineRecall":0.44}
How it's graded

Process mode: stdout must be JSON matching fixtures/expected.json within atol 1e-4, rtol 1e-3. The trained recall sits far above the baseline — that gap is the proof your contrastive trainer learned meaning, not just word overlap. Because everything is seeded and single-thread, both numbers are reproducible to the reference's frozen values.

If your trained recall is near the baseline

The usual culprits: the one-directional loss where symmetric was expected, a missing temperature scale (cosines never sharpen), or an L2-norm-backward sign error that lets the loss fall but not separate the embeddings. Re-run gradCheck and confirm the loss actually dropped below ln(B) in chapter 5.