TL;DR: A year ago we concluded that no open-source large language model (LLM) could match Claude for parsing German grammar. So instead of waiting for a general-purpose model to get good enough, we trained a small, specialized one. The satzklar model is a German dependency parser that matches treebank state-of-the-art (it attaches 97.7% of words to the right head on the German-HDT treebank), runs in milliseconds on a plain CPU (an ordinary computer processor), and now powers the grammar analysis behind every sentence on satzklar.net. We've open-sourced it on Hugging Face.
The right tool for one job
Large language models are astonishing generalists. But when we benchmarked them for one narrow, unglamorous task (reading a German sentence and working out which word depends on which), the generalists showed their seams: word-dropping, inconsistent structure, and answers that changed from run to run. Great for prose, risky for a grammar tool where a learner is counting on the tree to be right.
Dependency parsing is a solved-enough problem in academic natural-language processing that you don't need a frontier model for it. You need a model that does exactly this and nothing else. So we built one.
What we trained
The satzklar model is a Dozat-Manning biaffine dependency parser, the workhorse architecture of modern treebank parsing, on top of gbert-base, a German BERT encoder. Given a sentence, it predicts, for every word, its syntactic head and the relation that connects them (subject, object, modifier, and so on). That dependency tree is the backbone we build satzklar's colour-coded component trees on.
We fine-tuned it on the union of two German treebanks, German-HDT and German-GSD, which together hold roughly 167,000 annotated sentences of gold-standard syntax.
How well does it parse?
On held-out test data, scored the standard way (UAS = how often the head is right; LAS = head and label right):
| Test set | Sentences | UAS | LAS |
|---|---|---|---|
| German-HDT | 18,459 | 97.72 | 96.71 |
| German-GSD | 977 | 89.39 | 84.33 |
The HDT numbers sit right on the published biaffine results for that treebank (~97.97 / 96.97); GSD is at the ceiling reported for that smaller, noisier corpus. In other words: for the task it's built for, this compact model is as good as the literature, and dramatically more reliable than prompting a general LLM to do the same thing.
But does it hold up on real learners?
Treebank scores are one thing; your sentences are another. Learner German isn't news German, so we ran a proper, pre-registered evaluation on real, anonymised sentences from satzklar.net, with thresholds and sample frozen before we looked at the results, so we couldn't move the goalposts.
Small, fast, and deterministic
Because it does one thing, the model is tiny by today's standards (~110 million parameters) and quantises cleanly to 8-bit. In production it parses a sentence in milliseconds on four CPU threads, with no graphics card, no per-token billing, and the same input always giving the same tree. That last part matters more than it sounds: a grammar tutor should never contradict itself between page loads.
Swapping our LLM parse calls for this model made satzklar's analysis both faster and cheaper, while the linguistic quality went up, not down.
Open on Hugging Face
We've published the base HDT∪GSD model (weights, an evaluation card with all the numbers above, and usage notes) under a permissive CC BY-SA 4.0 licence:
It's a clean, self-contained German dependency parser you can drop into your own pipeline. (Part-of-speech and morphology come from a separate component in our stack; the published model is head-and-relation only, which is exactly what most parsing pipelines want.)
Why this matters
The lesson isn't "LLMs are bad." It's that a lot of production "AI" is really a handful of well-defined sub-tasks wearing a trench coat. Identify the one that's actually a classic natural-language processing problem, train a specialist, and you often get something faster, cheaper, more accurate, and reproducible, while saving the frontier model for the parts that genuinely need it (translation, explanation, story generation, which satzklar still does with Claude).
A year ago we said an open model would eventually beat the generalists at German parsing. It turned out the fastest way to get there was to train it ourselves.
Try satzklar to see the parser at work on any German sentence, or grab the model from Hugging Face and put it in your own project.