Instructions to use lamplitlabs/licht-german-tutor with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers.js
How to use lamplitlabs/licht-german-tutor with Transformers.js:
// npm i @huggingface/transformers import { pipeline } from '@huggingface/transformers'; // Allocate pipeline const pipe = await pipeline('text-generation', 'lamplitlabs/licht-german-tutor');
licht-german-tutor
A small German tutor that runs in your browser. It explains grammar and vocabulary, corrects your sentences, drills forms, plays one side of an everyday conversation and helps you prepare for the telc and Goethe exams, at levels A2 to B2. It answers in the language you write in, German or English. The model (3 billion parameters, fine-tuned from SmolLM3-3B) runs on your own device with transformers.js on WebGPU: nothing you type leaves your computer.
Try it: huggingface.co/spaces/lamplitlabs/licht-german-tutor opens the tutor in your browser (Chrome or Edge with WebGPU; the weights download once, 2.2 GB or 3.7 GB, then stay in the browser cache). How each release was measured is on ai.lamplitlabs.com.
The current release is v16 (2026-09-12), available as tag v16 and on main; the previous release is tag
v13. What changed is under Versions.
What it does
- Explains: the difference between
seitandvor, whenals,wennandwannare used, how adjective endings, cases, the Perfekt and word order work, with short bilingual examples. - Corrects: shows the corrected sentence first, then names the changed word and the rule in one or two lines.
- Drills: gender and plural of nouns, irregular verb forms, numbers, ordinals, dates, prices, clock times, contractions, verb-preposition pairs, false friends.
- Role-plays: asked to practise a situation (bakery, doctor's appointment, ticket counter, barber, landlord and others), it plays the other person in one short German line and a question, using only the facts you set.
- Prepares for exams: exam-format writing and speaking tasks, Sprachbausteine, model letters, and a session plan for a stated level.
Examples
Real answers from this release's automated check run (greedy decoding, the system prompt shown below, and the
rule note from grounding.json attached where its cue words matched):
Learner: Can you correct this sentence? 'Weil ich bin krank, bleibe ich zu Hause.'
Tutor: Weil ich krank bin, bleibe ich zu Hause.
Fix: word order: 'bin' moves back (after 'ich krank').
Reason: After 'weil' the verb goes to the end of the clause.
Learner: Heißt es der, die oder das Verlust? Und wie lautet der Plural?
Tutor: der Verlust (maskulin). Plural: die Verluste (-e).
Englisch: loss.
Beispiel: Der Verlust seiner Mutter war für ihn sehr schwer.
Learner: Wie sagt man die Uhrzeit 10:30 auf Deutsch (formell und umgangssprachlich)?
Tutor: zehn Uhr dreißig
Alltag: halb elf.
Regel: formell mit Uhr; halb nennt die kommende Stunde.
In a role-play the learner sets the scene (asking a neighbour to water the plants; four fixed facts: the neighbour is away Monday to Wednesday, the key is handed over on Friday, the post goes in the hallway, watering twice a week), pastes the dialogue so far and asks for the neighbour's next line. After the learner's "Oh ja, bitte. Wo sollen Sie die Post hinlegen?" the tutor answers:
Tutor (as the neighbour): Legen Sie das in den Flur, dort ist genug Platz. Haben Sie schon den Schlüssel?
Use it in your own app
import { pipeline } from "@huggingface/transformers";
const tutor = await pipeline("text-generation", "lamplitlabs/licht-german-tutor", {
dtype: "q8", // 3.7 GB; or "q4" (2.2 GB) on machines with less memory
device: "webgpu",
revision: "v16", // pin the release; omit to follow main
});
const messages = [
{ role: "system", content: SYSTEM_PROMPT }, // the tutor prompt below
{ role: "user", content: "Was ist der Unterschied zwischen 'seit' und 'vor'?" },
];
const out = await tutor(messages, { max_new_tokens: 500, do_sample: false });
console.log(out[0].generated_text.at(-1).content);
In Node.js, drop the device option. The model was trained under this system prompt and answers best with
it:
You are a patient, precise German tutor for learners from A1 to C1. Reply in the language the learner writes in (usually English) and keep German examples in German, with translations. Adapt depth to the learner's level when it is given. Be compact: state the meaning or rule in a few sentences, give two or three short example sentences, always mark gender and plural for nouns, and when correcting show the corrected sentence first, then explain briefly. Plain text with light Markdown, no emojis, and never mention being an AI model.
The last clause suppresses boilerplate disclaimers, not honesty: asked directly whether it is a person, the
model says it is a computer program (checked on this release in German and English). The prompt is also stored
in export_manifest.json under system_prompt, so an application can read it instead of copying it.
Two data files ship with the model and make it markedly more reliable when your application uses them:
grounding.json- short rule notes (numbers, dates, prices, clock times, contractions, cases after prepositions, and so on), each with cue words. When a cue word appears in the learner's message, append the note to the prompt as a second system message. The Space does this, and the evaluation numbers below were measured with it.lexicon.json- 3,800 nouns with gender and plural and 164 irregular verbs, verified against a Wiktionary-derived table. Use it to check the forms the model cites and to mark disagreements to the learner.
Keep generation_config.json (no_repeat_ngram_size: 24 stops list loops without changing normal answers),
and prefer greedy decoding - that is what was evaluated; sampling was not.
This repository holds the browser export only (ONNX, 8-bit and 4-bit). The merged PyTorch checkpoint
(safetensors, bf16) is kept by the maintainers and available on request through the Community tab; if it is
published it will appear under student/ in a later revision.
Model details
| Base model | HuggingFaceTB/SmolLM3-3B (Apache-2.0): 3B parameters, 36 layers, hidden size 2048, vocabulary 128,256 |
| Fine-tuning | LoRA (r 64, alpha 128, dropout 0.05), completion-only loss, 3 epochs, effective batch 16, cosine schedule, sequences up to 2,432 tokens; adapters merged before export |
| Files | ONNX opset 18. onnx/model_quantized.onnx (block-wise 8-bit, dtype: "q8", 3.7 GB in two external-data chunks) and onnx/model_q4.onnx (dtype: "q4", 2.2 GB, also two chunks); tokenizer and chat template; generation_config.json; grounding.json and lexicon.json; export_manifest.json (export record, including the system prompt) and verify_report.json |
| Runtime | transformers.js on WebGPU (browser) or Node.js; exported with onnxruntime 1.29 and transformers 4.57 |
| Languages | German and English; the answer follows the language the learner writes in |
| Licence | Apache-2.0, inherited from the base model (see Provenance and licences) |
| Release | v16, 2026-09-12 (tag v16); previous release v13, 2026-09-09 (tag v13) |
Intended use and scope
Learning German: grammar and vocabulary explanations, gender and plural of nouns, irregular verb forms, numbers, ordinals, dates, prices and clock times, contractions, verb-preposition pairs, false friends, sentence correction with a short explanation, formal and informal letters, exam-format questions, short dialogue practice and session planning for a stated level.
Out of scope: anything other than learning German; legal, medical or safety advice; use as the only source for exam preparation. It is a 3B model: it makes the mistakes listed under Known weak spots and should run with the lexicon check when learners cannot judge the answer themselves.
How it was trained
The training set has 8,090 rows (416 more for validation), all produced by the same pipeline. Answers are between 7 and 667 words (median 91; in the model's tokenizer median 173 tokens, 95th percentile 559, longest 1,327); every answer over 300 words was shortened at paragraph boundaries before training so that letters, dialogues and plans end inside a browser's token budget. Six kinds of rows:
- Teacher answers to learner questions (about 4,000 rows). Questions from about fifty categories - word meaning, gender and plural, translation in both directions, gap fills, exam formats (writing, speaking, Sprachbausteine, grading, planning), idioms, register, learning strategy - answered by a large language model acting as the teacher under the system prompt above; refusals and cut-off answers were dropped. About 4,100 of these questions carried a verified rule note in the prompt, so the model learns to answer with a reference in front of it.
- Rule drills with computed answers (about 1,400 rows). Numbers, ordinals, dates, prices, clock times, contractions and verb prepositions come from deterministic rule engines, so the answer is correct by construction.
- Lexicon drills (about 2,200 rows). Gender, plural and irregular verb forms taken from the verified
lexicon that ships as
lexicon.json. - Corrections (210 rows). One rule for each classic learner error (perfect-tense auxiliary, adjective endings, verb position, case after prepositions, and others), with verified bilingual rule sentences and a line that names the changed word.
- Role-play turns (340 rows). Seventeen everyday situations - the bakery, a doctor's appointment by phone, the station ticket counter, the barber shop, the caretaker and the laundry room, and others - turned into short in-character replies with a question, where the facts of the situation are fixed. Eight further situations are kept out of training and used only for evaluation.
- Grammar rule cards (359 rows). Thirty bilingual cards - Perfekt, adjective endings, cases, word order,
als/wenn/wann,dass/oband the other topics learners ask about - in explain, contrast, check and examples form; every rule sentence is copied from a verified reference block, and where that block is in the prompt the answer opens by quoting it word for word.
Some questions of kind 1 were based on a privately held language-course export (vocabulary lists, lesson notes). That material is not redistributed; the model saw the teacher's answers about it, not the material.
How it was evaluated
Before a version is released it answers 151 fixed scenarios through the exported 8-bit graph in transformers.js - the runtime learners use - with greedy decoding, up to 700 new tokens, offline. Eight checks must pass; v16 passes all eight.
| Check | What it looks at | Must reach | v16 | v13 |
|---|---|---|---|---|
| no_loop | no repeated-phrase runaway | 1.00 | 1.000 | 1.000 |
| not_truncated | the answer ends before the token budget | 0.97 | 0.987 | 0.972 |
| no_ai_talk | never presents itself as an AI or a model | 1.00 | 1.000 | 1.000 |
| language_follows | answers in the learner's language | 0.90 | 0.987 | 0.993 |
| facts | rule facts match the engines (numbers, dates, cases, forms) | 0.85 | 0.932 | 0.880 |
| shape | the requested form (list, letter, dialogue, table) is delivered | 0.80 | 1.000 | 0.939 |
| lexicon | every cited gender, plural and verb form is in the verified lexicon | 0.95 | 0.993 | 0.972 |
| export | files, manifest, sizes, ONNX against PyTorch agreement | 1.00 | 1.000 | 1.000 |
v13 was measured on the 143 scenarios of its day; the eight role-play scenarios were added afterwards. Other
rates on the v16 run: no_emoji 1.000, markdown_sane 0.993, length_budget 0.934; scenarios passing every check
at once 0.854 (129 of 151; v13 106 of 143). Agreement of the ONNX graphs with the PyTorch model (teacher-forced,
16 tokens, three prompts): fp32 1.000, q8 1.000, q4 0.854. The run used the grounding.json and
lexicon.json in this repository.
Per category, the share of scenarios passing every check, and the facts rate where the category has fact
checks:
| Category | n | facts | all checks |
|---|---|---|---|
| adjective-declension | 6 | 1.000 | 1.000 |
| clock | 8 | 1.000 | 1.000 |
| dates | 6 | 1.000 | 1.000 |
| exam-facts | 12 | 1.000 | 1.000 |
| grammar-explain | 6 | - | 1.000 |
| irregular-verbs | 10 | 1.000 | 1.000 |
| ordinals | 4 | 1.000 | 1.000 |
| roleplay | 8 | 1.000 | 1.000 |
| verb-prepositions | 8 | 1.000 | 1.000 |
| vocab-list | 8 | 1.000 | 1.000 |
| preposition-case | 8 | 1.000 | 0.875 |
| false-friends | 6 | 0.833 | 0.833 |
| gender-plural | 12 | 0.833 | 0.833 |
| prices | 6 | 0.833 | 0.833 |
| contractions | 4 | 0.750 | 0.750 |
| dialogue | 4 | - | 0.750 |
| letter-formal | 4 | 1.000 | 0.750 |
| numbers | 8 | 0.875 | 0.750 |
| correction | 12 | 0.750 | 0.667 |
| letter-informal | 3 | 1.000 | 0.667 |
| translation | 8 | - | 0.125 |
Separately, five large language models act as judges: each scores the same 41 held-out answers of every version from 1 to 5 and flags severe errors. This score compares versions with each other and is not a release condition. v16 reads 3.56 (accuracy 3.16, helpfulness 3.30, German 3.96, format 3.82; v13 3.29), with eight answers flagged severe by all five judges (v13 six; the two unreleased versions in between, ten each).
Known weak spots
- Translation. Asked to translate, the model translates and then explains: seven of eight translation scenarios run over the length budget (none is cut off). Ask for the translation alone when that is all you want.
- Correction. Three of twelve correction scenarios do not lead with the corrected sentence, and one answers
in the other language; the rule it gives can be a neighbouring rule or an invented one (
hätte gern wissenwas left standing with a made-up justification in the check run). - Gender and plural in running text. Drills pass the lexicon check at 0.993, but inside longer vocabulary
lists and model letters the model still states a wrong article or plural, or a non-word (
die Fahrrad,den nächtlichen Bellen,Medikamentenpflicht) - this is what the judges flag most. Check cited nouns againstlexicon.json. - Grammar explanations without a rule note. With a note from
grounding.jsonin the prompt the model quotes it correctly; without one it can invent an analysis (a separable-verb rule, Präteritum examples taught as Plusquamperfekt). Keep the grounding file in the prompt. - Long forms. One English-prompted B2 formal letter and one B2 dialogue still hit the 700-token cap, and one
informal letter runs over the budget. Raise
max_new_tokensfor long letters. - Numbers and prices. Writing a large number or price out in words fails in about one of eight cases (
438became "vierhundertachtundvierzig"); one of four contraction scenarios misses a form. - False friends (
Ambulanzglossed without "outpatient department") and exam facts (telc B1 points, Goethe B2 Lesen parts) are answered from general knowledge and are sometimes wrong. - The model has no knowledge of current events, can be confidently wrong, and has not been evaluated for anything outside German learning. It was evaluated with greedy decoding only.
Versions
- v16 (2026-09-12, tag
v16, current). v13's recipe and data plus three additions: the role-play turns (asked for a role-play, the tutor answers as the barber, baker or landlord in one short German line and a question), the grammar rule cards (rule sentences copied from verified reference blocks and quoted word for word when the block is in the prompt), and the 300-word length budget on training answers so that long answers end inside the browser's token limit. Against v13: facts 0.932 (0.880), lexicon 0.993 (0.972), shape 1.000 (0.939), not_truncated 0.987 (0.972), judges 3.56 (3.29). Two intermediate versions were trained and measured between v13 and v16 and not released, because each fell short of one of the release conditions. - v13 (2026-09-09, tag
v13). The first release on the Hub (public since 2026-09-10): the verified lexicon and the rule engines as training targets, and a rebuilt correction family - one rule for every classic learner error, verified bilingual rule sentences, a line naming the changed word (facts 0.880, correction 10 of 12).
Provenance and licences
- Base model: HuggingFaceTB/SmolLM3-3B, Apache-2.0. These weights are a derivative work released under the same licence, with attribution.
- Lexicon:
lexicon.jsonis derived from gambolputty/german-nouns (Wiktionary-derived, CC BY-SA 4.0, commit8386d23). The file carriessource,licenceandattributionfields; share-alike applies to that file, not to the weights. - Teacher answers: the training answers of kind 1 are synthetic - written by a large language model acting as teacher, then filtered by the rule engines and the lexicon before training.
- Course-based questions: a privately held course export was the basis of some questions; it is not redistributed.
- The training dataset is not published.
About
The model was built with licht, a toolkit for training, checking and serving small tutors in the browser (data build, LoRA fine-tune, ONNX export, the 151-scenario release check, the browser UI); one A100 trains, exports and checks a version in a few hours. The toolkit's source is not yet published. Questions and requests, including for the PyTorch checkpoint, go to this repository's Community tab.
Citation
@misc{licht-german-tutor,
title = {licht-german-tutor: a German tutor that runs in the browser},
author = {Lamplit Labs},
year = {2026},
note = {release v16},
url = {https://huggingface.co/lamplitlabs/licht-german-tutor}
}
- Downloads last month
- 333
Model tree for lamplitlabs/licht-german-tutor
Base model
HuggingFaceTB/SmolLM3-3B-Base