Mitosis Bench

A mosaic of 120 tissue tiles from MIDOG++ training slides, sorted by stain color: violet at the center, pink at the edges.

1 Intro and Background

Introducing my first, of many, reinforcement learning environment and benchmark made for Prime Intellects RL residency. I wanted to create a medical environment since I haven’t seen many out there. I figured pathology would be an interesting one, we get told quite often that models will cure diseases and make vaccines. Throwing compute so that we can hillclimb medicine is one of the best, if not the best, uses of reinforcement learning. A world in which doctors, scientists, and nurses are 100x more productive due to super intelligence is a world I see very soon, and in my opinion, a world that is much better than one with just more productive engineers.

Mitosis Bench. A pathology benchmark where an agent has to find every mitotic figure in a tumor image. Claude Opus 5.5 leads all models with 28.6% pass@1.

0%10%20%30%40%50%32.4%43.0%Gemini 4 Argon28.6%38.0%Claude Opus 5.516.8%41.0%GLM 5.3 Flash8.8%26.0%DeepSeek V4.1 Flash
pass@1 and pass@5 on the 100 benchmark tasks, 5 attempts per task.

What is a Mitotic figure? A mitotic figure is a cell caught in the act of dividing, visible under the microscope. Pathologists use mitotic figures as an indicator of how fast a tumor is growing.

(a) mitotic figures

Six mitotic figures from MIDOG++ training slides: dark, condensed chromosomes in dividing cells.

(b) look-alikes

Six look-alikes from MIDOG++ training slides: dark nuclei the experts labeled as not mitotic.
Mitotic figures (a) and look-alikes (b), cut from MIDOG++ training slides.

About the Dataset: The dataset is MIDOG++(https://www.nature.com/articles/s41597-023-02327-4) , which is an extension of the MIDOG (Mitosis Domain Generalization) challenges. I chose a mitosis dataset specifically because I anticipated that models would struggle with identifying really small figures and navigating data where the amount of look-alikes outnumber real figures. MIDOG++ has 503 tumor regions of 7 tumor types: breast carcinoma, lung carcinoma, lymphosarcoma, neuroendocrine tumor, cutaneous mast cell tumor, cutaneous melanoma, and (sub)cutaneous soft tissue sarcoma. This dataset combines both human and dog histological specimens and is labeled by expert consensus.

MIDOG++ by tumor type.
Tumor typeSpeciesRegionsMitotic figuresLook-alikesLook-alikes per figure
Breast carcinomaHuman1501,7212,7141.58
(Sub)cutaneous soft tissue sarcomaDog1001,2862,3751.85
LymphosarcomaDog553,9594,2571.08
Neuroendocrine tumorHuman556391,7612.76
Cutaneous mast cell tumorDog502,3271,3660.59
Cutaneous melanomaHuman491,1509250.80
Lung carcinomaDog448559511.11
All 7Human and dog50311,93714,3491.20

2 Task and Reward shape

When designing the input and output I gave the agent a 768 x 768 px tissue image, sometimes I gave it two side by side. The model would NEVER get told how many cells there are, it is evaluating it similarly to how a pathologist would in a real work environment. The agent would output its answer in the format of “ Answer: [[x,y], …] on a 0-1000 grid.

(a) input

A 768 by 768 pixel H&E field from a MIDOG++ training slide.

(b) expert labels

The same field with each expert-labeled mitotic figure ringed at the 30 pixel match radius and its center on the 0 to 1000 grid; a dashed ring marks a look-alike.
A training field. In (b), each mitotic figure is ringed at the 30 px match radius and labeled with its center on the 0–1000 grid; dashed rings mark look-alikes.

Reward: I used a binary reward, it would only get the reward if the answer matches exactly the right cells within 30 px (7.5 µm which is the MIDOG challenge’s radius) with no extra or missing cells. No partial credit since we don’t have a judge and I could see partial credit opening up some reward hacks for the models. I still recorded precision and recall accuracy so we could diagnose failure. The model gets no tools; all it can do is inspect the image (crop, zoom, enhance) with whatever its harness offers. Rather than using the entire dataset I selected only images where the experts agreed on all the labels and where there were more than three figures, this was my eval set. The benchmark has 100 tasks across 55 different microscope slides and 7 different tumor types, the images in the benchmark were randomly seeded from the eval set.

Every figure matchedreward 1One figure missedreward 0One extra pointreward 0
The binary reward: expert-labeled figure, its 30 px match radius, × the model’s point.
The benchmark at a glance.
BenchmarkValue
Tasks100
Microscope slides55
Tumor types7
Imageone 768 × 768 px field (97 tasks), or two side by side, 1536 × 768 px (3 tasks)
Mitotic figures per image3 to 7, mean 3.2
AnswerAnswer: [[x, y], …], each center on a 0–1000 grid
Reward1 if every figure is matched within 30 px and nothing is extra, else 0
Attempts per task5
Cutaneous mast cell tumor31
Lymphosarcoma27
(Sub)cutaneous soft tissue sarcoma13
Neuroendocrine tumor9
Lung carcinoma8
Breast carcinoma6
Cutaneous melanoma6
Benchmark tasks per tumor type. Each row starts with a tissue sample of that type from a training slide.

3 Running the Evals

All the models ran through a Pi harness on high reasoning effort. For each task the models had 5 attempts and I only allowed retries if there was an infrastructure failure. I ended up having to retry most of deepseeks attempts since I ran into a bit of an interesting issue during evaluation, 147 attempts failed with a “Downloaded image content cannot exceed 30MB failure”. After running some tests I found out that the reason behind this was that agents saved zoomed PNG crops and since the harness would resend every image on every turn the requests piled up. To fix this I added a small local relay that re-encoded non-JPEG images as JPEG. The encoding was deterministic so caching still works and the largest request dropped to 17.5 MB with zero rejections across all its runs. To prove that this didn’t affect the eval results I measured performance with/without the relay, I used Opus as the control group (since it never hit the limit) and its score moved only +0.9 points. Deepseek ended up rising from 6% to 8.8% because the cap failures disappeared. In order to make sure there was no cheating I scanned every single tool output for all attempts for answers, scoring text or ids and found nothing.

Pi agentin its sandboxLocal relayPNG → JPEG, quality 95Prime APIthe modelLargest request (MB of images)Without relay68.4 MBWith relay17.5 MBPrime's cap ≈ 23.6 MB
Where the relay sits, and the largest request with and without it.
pass@1 without and with the relay.
ModelWithout relay
pass@1, 3 attempts
With relay
pass@1, 5 attempts
ChangeImage-cap failures
without relay
Claude Opus 5.527.7%28.6%+0.90 of 300
GLM 5.3 Flash14.3%16.8%+2.514 of 300
DeepSeek V4.1 Flash6.0%8.8%+2.8147 of 300

4 Results

0%10%20%30%40%$0$50$100$150$200Cost of k attempts on each of the 100 tasks (USD)pass@k43.0%38.0%41.0%26.0%
pass@k against cost; each line’s points are k = 1 to 5 attempts per task, left to right. Gemini 4 Argon ($0.36 per attempt), Claude Opus 5.5 ($0.18 per attempt), GLM 5.3 Flash ($0.07 per attempt), DeepSeek V4.1 Flash ($0.15 per attempt).

Something interesting to note from the chart is that Opus stops very early, especially on tasks it fails. In 334 out of 500 of its attempts it lists too few points. Deepseek makes 68 model calls per attempt while Opus only makes 6! Another interesting thing is that of the 100 tasks, Opus never solves 62 of them but there are 19 tasks it solves every time. On the other hand, 38% of tasks GLM attempted had some attempts pass and others fail. By pass@5 GLM is basically caught up with Opus! The mixed result tasks are perfect for RL.

Gemini 4 Argon1623126839Claude Opus 5.5143334GLM 5.3 Flash8470209136DeepSeek V4.1 Flash44951741850100200300400500
How each of the 500 attempts per model ended: solved, right count but wrong cells, too few points, too many points, no answer.
010203040506070Gemini 4 Argon18.0Claude Opus 5.56.2GLM 5.3 Flash26.6DeepSeek V4.1 Flash68.0
Model calls per attempt, averaged over each model’s 500 attempts.
Gemini 4 Argon
20 always · 23 mixed · 57 never
Claude Opus 5.5
19 always · 19 mixed · 62 never
GLM 5.3 Flash
3 always · 38 mixed · 59 never
DeepSeek V4.1 Flash
2 always · 24 mixed · 74 never
Each model’s 100 tasks, one tile per task, shaded by attempts solved out of 5 (0 5). A task sits in the same spot in every grid.
Results on the 100 benchmark tasks. Gemini 4 Argon ran on October 19; the relay retried the 4.5% of its requests that Prime’s API failed with a timeout.
Modelpass@1pass@2pass@3pass@4pass@5Cost per attemptModel calls per attemptMinutes per attempt
Gemini 4 Argon32.4%37.9%40.4%42.0%43.0%$0.36418.05.6
Claude Opus 5.528.6%33.7%36.2%37.4%38.0%$0.1786.21.1
GLM 5.3 Flash16.8%25.6%31.7%36.6%41.0%$0.06526.66.2
DeepSeek V4.1 Flash8.8%14.3%18.8%22.6%26.0%$0.15568.022.1
pass@k by attempts for Qwen3.5-9B, Qwen3.5-122B-A10B, glm-5.3-high-throughput, deepseek-v4.1-flash and qwen3.6-27b, k from 1 to 8.
pass@k by attempts.
Heatmap of pass@k by Qwen model size, k from 1 to 8.
pass@k by Qwen model size.