In the past few years, frontier AI models have made significant progress in mathematical research. Every week, a new result is announced, from the disproof of the Jacobian conjecture [1] to a finite-time singularity for the Navier–Stokes equations [2].
Yet has any of this changed how mathematicians work? For many of them, not much. In our conversations, two reasons came up again and again:
- Models are not integrated into the tools mathematicians use.
- Models are seen as substitutes for mathematicians rather than as tools in their hands.
We were surprised by how little the tools they spend the most time on have changed. Overleaf, where most of them write up their papers, was founded in 2012, and writing in it today feels much as it did then.
"Undefined control sequence"
When we interviewed mathematicians, one of the most common annoyances we heard about in their day to day work is battling with LaTeX compilation errors. LaTeX is the bread and butter of mathematics publishing, and fluency in its long tail of packages takes years.
Until it is reached, writing is constantly interrupted by those errors, which makes it hard to think while writing. This forces many researchers to write on other surfaces, then spend time typing their work in LaTeX.
In other words: every missing brace, every package that clashes with another is a minute of annoyance sacrificed forever on the altar of an unforgiving compiler.
Just fix it
The most obvious solution is to ask a chatbot to fix errors. That works decently well, except:
- Switching to a different window breaks the writing flow (and wins you a lecture along the way).
- Copy-pasting the snippet often loses relevant context, especially when multiple files are involved.
What we were looking for was different: a model that can run fast directly in the surface researchers work in, and without interrupting their work. Crucially, it has to be able to suggest changes, so they can be reverted in a click (Sundial's editor supports this natively). It also has to be very cheap to run at scale, given it will run on every compilation error.
Breaking LaTeX on purpose
We chose Thinking Machines' Inkling-Small as a starting point because it is fast, open weight and built to be fine-tuned.
Our first attempt involved creating many synthetic examples by taking valid LaTeX documents and dropping errors in them (heartbreaking, I know). From the broken document and the compilation error statement, we could train the model to emit reverse patches as search-and-replace edit blocks.
We fine-tuned the model, then tried it on examples donated by our generous beta-testers. It turned out it didn't transfer well to real examples. The model was learning our perturbations but not real LaTeX errors users were getting.
Building TeXtinguisher
Our next attempt had to be more ambitious.
We scraped 272,000 questions from TeX.StackExchange and kept them when:
- Their snippet still fails today with a located error.
- The accepted answer's version compiles.
- The difference replays exactly as a patch.
This gave us the largest dataset of real LaTeX errors and their fixes to date: 3,978 pairs, against 88 in the largest one previously released [3].
One thing that surprised us in the data is that 42% of the candidate documents compile fine today. This is because LaTeX is evolving and some packages have been fixed since the question was asked. So we removed those from the dataset.
Another 5,700 questions passed the first test but failed the third, because the answer could not be replayed as a patch. We kept those too: a teacher model wrote a fix for each, and we used it wherever it compiled.
A fix, whoever wrote it, is scored three ways, all deterministic: does it compile, how many characters of content it deleted, and whether its PDF matches the accepted answer's.
1\documentclass[12pt]{article} 2\usepackage{siunitx} 3\begin{document} 4\si{300}{\nanogram\per\millilitre}5\end{document}
pdflatex
Undefined control sequence.
l.4 \si{300}{\nanogram
\per\millilitre}
fix: the diff between the question and the accepted answer
- \si{300}{\nanogram\per\millilitre}+ \SI{300}{\nano\gram\per\milli\litre}
1\documentclass{article} 2\usepackage[symbol=$\uparrow$]{footnotebackref} 3\usepackage[hidelinks]{hyperref}4 5\begin{document} 6 7This is a statement.\footnote{And it is supported by this footnote.} 8 9\end{document}
pdflatex
LaTeX Error: Option clash for package hyperref.
See the LaTeX manual or LaTeX Companion for explanation.
l.3
fix: the diff between the question and the accepted answer
- \usepackage[symbol=$\uparrow$]{footnotebackref}- \usepackage[hidelinks]{hyperref}+ \usepackage[hidelinks]{hyperref}+ \usepackage[symbol=$\uparrow$]{footnotebackref}
1\documentclass[12pt,a4paper,oneside]{article} 2 3\begin{document} 4 5\begin{center} 6 7M = < X,Y,S,ta, \delta int, \delta ext, \lambda >8 9\end{center} 10 11\end{document}
pdflatex
Missing $ inserted.
<inserted text>
$
l.7 M = < X,Y,S,ta, \delta
fix: the diff between the question and the accepted answer
- \begin{center}- M = < X,Y,S,ta, \delta int, \delta ext, \lambda >- \end{center}+ \[+ M = \langle X, Y, S, ta, \delta_{\mathrm{int}}, \delta_{\mathrm{ext}}, \lambda \rangle+ \]
1\documentclass{article} 2\usepackage{xcolor} 3\usepackage{pgfplots} 4\begin{document} 5 \begin{tikzpicture} 6 \begin{axis} 7 \foreach \foridx/\forcol in {1/black,2/red,3/green,4/blue,5/orange}{ 8 \addplot[\forcol]{x^\foridx}; 9 } 10 \end{axis}11 \end{tikzpicture} 12\end{document}
pdflatex
Undefined control sequence.
\pgfkeyscurrentkey ->\forcol
l.10 \end{axis}
fix: the diff between the question and the accepted answer
- \foreach \foridx/\forcol in {1/black,2/red,3/green,4/blue,5/orange}{- \addplot[\forcol]{x^\foridx};+ \pgfplotsforeachungrouped \foridx/\forcol in {1/black,2/red,3/green,4/blue,5/orange}{+ \expandafter\addplot\expandafter[\forcol]{x^\foridx};
The training run
After a few attempts, we landed on a three-step recipe.
First, we start with SFT on labeled real cases, then we add fixes written by the teacher model for the unlabeled cases.
When SFT stops showing gains, we start RL: for each broken document, the model proposes eight fixes, each scored with the same three checks, and the score is the reward. We used GRPO from the Tinker cookbook. This got us close to frontier model accuracy at a fraction of the latency.
We tried tweaking the reward function in many ways.
- The first one was only a compilation check. This led the model to sometimes not fix the issue, instead removing content until the document built.
- We tried a bonus for the smallest edit in the group, but it often rewarded small hacks that change the document.
- We tried having an LLM judge the fixes, but it would call most of the human fixes hacks.
In the end, what worked best was two checks: 1 point if the document compiles, 0.5 more if the compiled PDF matches the solution's (same number of pages, at least 98.5% word-sequence agreement), both shrinking as deleted content grows and reaching zero at 150 characters. A hard cutoff instead of the decay made no measurable difference.
After all this, our model still lacked something: multi-file understanding. Sometimes, errors depend on files different from the one that failed compilation. We thus reconstructed projects from GitHub, TeX.StackExchange and ArXiv where multiple files were involved. Adding those to the set and giving our model relevant context put it on par with Claude Fable 5.1 and GPT-5.5, and within six points of GPT-6 Astra at a fourteenth of its cost.
Another thing we tried is training the model in an agentic loop instead of fixing errors in one shot. It was much slower and only marginally better in our tests, so we kept a single shot.
Results
On 647 real single-file errors held out after all training, measured end to end from the same client, with the same 8,000-token budget for every model:
| model | fixes compile | seconds per fix (p50) | output tokens |
|---|---|---|---|
| Inkling-Small, fine-tuned (ours) | 85.2% | 0.95 | 162 |
| GPT-6 Astra | 90.9% | 1.30 | 208 |
| Claude Fable 5.1 | 82.4% | 5.72 | 812 |
| GPT-5.5 | 80.7% | 2.47 | 866 |
| Grok 4.6 | 80.7% | 7.90 | 5,110 |
| Claude Opus 5 | 79.8% | 4.01 | 936 |
| Gemini 3.8 Flash | 76.0% | 3.37 | 3,396 |
| Gemini 3.7 Flash | 69.7% | 2.42 | 1,079 |
| Claude Sonnet 5 | 54.3% | 2.42 | 919 |
| Inkling-Small, base | 47.9% | — | 4,231 |
| Claude Haiku 4.5 | 46.7% | 2.91 | 315 |
We serve a merged checkpoint under vLLM on a single 8×H200 node on Modal. At 64 concurrent requests that one node handles about 28,500 fixes an hour, which is roughly $1.30 per thousand. This is cheap enough to fire on every failed compile rather than only when the user asks.
Limitations
Most of the benchmark comes from Stack Exchange questions: short documents with one error each, where we index on whatever the accepted answer did. The multi-file projects from GitHub and arXiv are closer to real work, but there are fewer of them. To make sure our model writes good fixes rather than just making the error go away, we would have to gather higher-quality labeled examples from real projects with many files.
On a smaller set of errors where we could verify the human fix, our model more often makes the document compile by deleting some of the user's content than frontier models do. We're working on tightening the checks on the compiled PDF so the model can never hack its way to compilation.
What we learned
Three things we learned:
- Designing the right reward takes iterations. Every time we checked only that the document compiled, the model found a way to make it compile that no author would accept.
- Synthetic data needs careful calibration. Our synthetic examples taught the model our idea of an error instead of real errors.
- Frontier models catch up quickly. We had the most accurate model on this benchmark until GPT-6 Astra came out. The lasting value of fine-tuning is speed and cost, where ours is still 27% faster and 14 times cheaper.
The benchmark, the mining scripts, the RL environment and the evaluation harness are at github.com/sundial-org/textinguisher, and the benchmark is on Hugging Face. We're rolling out the model inside the Sundial editor over the next few days. When a compile fails, the fix is applied in under a second and the PDF rebuilt, so the user can keep working without being interrupted. We apply all fixes as suggestions, so they can be reverted by the user if needed.
References
[1] T. Tao, "A digestion of the Jacobian conjecture counterexample", July 2026. terrytao.wordpress.com/2026/07/21/a-digestion-of-the-jacobian-conjecture-counterexample/
[2] OpenAI, "On the Navier–Stokes Millennium Prize Problem", September 2026. openai.com/index/navier-stokes-solution
[3] "TeXFix-Bench: An Empirically Grounded Multi-Format Benchmark for LLM-Based Document Source Repair", arXiv:2608.07617, 2026. arxiv.org/abs/2608.07617