Inspiration
I did not start from a dataset. I started from the people sitting around me.
My college takes students from every part of the country, and we arrive speaking different mother tongues into the same lecture hall, where everything is delivered in English. I watched classmates who had cleared the same entrance exam I had — who understood the subject perfectly well — fall behind because of the language it arrived in. They would ask me afterwards what the professor had said. Not what a word meant. What the sentence meant.
Then I saw the live interpretation used in parliament, where a speech reaches every member in their own language as it is being spoken, and the question became obvious: why does a lecture hall not have this?
But the obvious version of this idea makes education worse. Point an ordinary translator at a lecture and it renders eigenvalue as अभिलक्षणिक मान — correct, literary, and a word that appears in no textbook, no exam, and no job interview. The student now understands the sentence and cannot answer the question. The sentence got easier and the degree got harder.
So the design rule came before the code: translate the explanation, never the vocabulary.
What it does
ProfessorTranslate is live interpretation for a classroom.
A professor opens a lecture and speaks normally. Every student joins with a code, picks their own language, and — within about a second — reads and hears the lecture in it. One professor, many languages, simultaneously.
The technical terms stay in the language of instruction. In the subtitles they are highlighted; in the audio they are spoken by a second voice, in English, inside an otherwise Hindi sentence:
Professor: "So the eigenvalue of this matrix tells us how much the eigenvector is stretched."
Student: "तो इस matrix का eigenvalue बताता है कि eigenvector कितना stretch होता है।"
|__ Hindi voice __| |English| |__ Hindi __| |__ English __|
The student understands the sentence and still meets \( \lambda \) called by the name their exam will use.
Around that core: Wolfram-rendered diagrams of whatever the lecturer is describing (published only after the professor approves them), spoken descriptions of every diagram for students who cannot see the board, lectures archived as text rather than audio so they replay in any language or through a screen reader, and a glossary that builds itself from a PDF of last year's notes or a syllabus URL.
The prompt is the product
This is a prompting project more than it is a translation project. Four techniques carried it:
1. Constrain, do not instruct. My first attempt asked the model, emphatically and at length, to preserve technical vocabulary. It mostly complied. "Mostly" is a failing grade when the word it drops is the one on the exam. So the terms are now removed before the model ever sees the sentence — each replaced by a sentinel, ⟦0⟧, ⟦1⟧. The model translates only the connective tissue between the sentinels and carries each sentinel through to wherever the target grammar wants it; the real terms are spliced back afterwards.
in → "So the ⟦0⟧ of this ⟦1⟧ tells us how much the ⟦2⟧ is stretched."
out → "तो इस ⟦1⟧ का ⟦0⟧ बताता है कि ⟦2⟧ कितना stretch होता है।"
A prompt can be ignored. An absence cannot. The model cannot translate what it was never given. Measured at 0% term loss across 162 translations, where prompt-based instruction leaked.
2. Register steering beats accuracy tuning. The model's default Hindi was flawless and useless — bookish, Sanskritised, harder for a student than the English original. Real Indian classroom speech is code-mixed: "अब देखते हैं कि determinant zero हो तो क्या होता है". So the system prompt carries an explicit banned list (शून्य, ऊर्जा, प्रणाली, आवृत्ति…), a ban on transliterating English into Devanagari, and a ban on bookish discourse markers — plus a handful of worked few-shot examples that demonstrate the register instead of describing it. Everyday English loanwords are masked with the same sentinel machinery, so they survive in English without being marked up as technical terms.
3. Few-shot examples are code, and they need tests. One of my examples had two placeholders in the input and one in the output. The model learned, faithfully, to drop a term. Nothing about the prompt looked wrong. A register test suite that asserts against the output caught it, so the prompt is now covered by assertions the same way the code is.
4. The prompt is a latency budget. My careful, thorough, well-reasoned system prompt was 1560 characters. Cutting it to 353 dropped time-to-first-token from 1209 ms to 586 ms — half the wait, and no measurable loss of quality. In a live setting every token of instruction is paid for by a student waiting to hear the sentence.
How I built it
TypeScript throughout — React front end, Express + WebSocket server, npm workspaces sharing one set of types.
Inference runs on Featherless AI with Qwen3-30B-A3B, streamed token by token so the first translated words appear while the sentence is still generating. The masking pass also records where each term landed, which is the only moment the system knows with certainty which characters are term and which are explanation — that boundary drives both the subtitle highlighting and the two-voice audio.
Speech recognition and synthesis run in the browser via the Web Speech API, deliberately, so a lecturer can walk into a hall and use this without anyone having provisioned a key. Wolfram|Alpha renders diagrams; Firecrawl reads syllabus pages into the glossary. Deployed on Render.
Third-party resources acknowledged: Featherless AI (inference), Qwen3-30B-A3B (open-weights model, Alibaba), Wolfram|Alpha Simple API, Firecrawl, the browser Web Speech API, React, Vite, Express, Tailwind, and Render. All application logic — the masking pipeline, the segmenter, the glossary extraction, the run-splitting, the voice scheduling — is my own.
How AI contributed
Two distinct ways, and they should not be confused:
AI inside the product. The translation model is the engine, but the engineering is in what it is denied. The interesting artefact here is not a call to a translate endpoint; it is a masking pipeline that makes a class of failure structurally impossible rather than statistically unlikely.
AI as a collaborator while building. I used AI assistance heavily to write and refactor code, and just as heavily to argue with. It was most useful where I could check its work — and least useful exactly where I trusted it. Nearly every real bug below came from a plausible-sounding assumption that a measurement refuted.
Challenges I ran into
Every symptom pointed at the wrong cause. So I stopped guessing and built probes.
"There is a lot of repetition." A live test produced "transverse energy transverse energy transverse energy through and". The cause was event.resultIndex in the Web Speech API. It is documented as where new content begins, and universally read as "the first result you have not seen". It is neither: it is the first result that changed, and Chrome keeps pointing at a finalised result while it revises what follows. Nine regression assertions now replay that exact browser event sequence.
"It is skipping lines." Single-sentence tests passed perfectly while real lectures lost words. A sustained-speech probe measured 8.1% of words silently dropped: the segmenter was waiting for punctuation that conversational speech never provides. Now 222 words in, 222 out.
"The simulations are not live." Diagrams never rendered. The concurrency gate read inFlight >= limit - 1, which with three student languages is permanently true. A one-character bug no amount of staring at the diagram code would have found.
Two smaller ones: adjacent sentinels fused into "eigenvaluematrix" until term runs were forbidden from merging with their neighbours — and a bigger model is not always a better one. Two larger checkpoints returned empty strings where the 30B mixture-of-experts was both faster and correct.
Accomplishments that I'm proud of
That the central claim is measured, not asserted. Anyone can clone the repo and reproduce these:
| Term preservation | 0% loss over 162 translations — npm run test:reliability |
| First translated word on screen | ~600 ms — npm run test:latency |
| Words lost from continuous speech | 0 — 222 in, 222 out — npm run test:sustained |
| Automated checks | 100+ assertions across 8 suites |
And that accessibility is not a bolt-on: because lectures are archived as text rather than audio, a screen reader can read back a class delivered entirely by voice, and every generated diagram carries a spoken description in the student's own language.
What I learned
Constraining the model beat instructing it. Every hour spent making the prompt more emphatic was worth less than the ten minutes spent making the terminology unreachable. The best prompt engineering I did was deciding what to keep out of the prompt.
Fluency is not usefulness. A translation can be flawless and still fail a student, if it hands them words their examiner will not recognise.
A test that passes on one sentence tells you nothing about a lecture. Nearly every real bug lived in duration, concurrency, or fragmentation — none reachable by a single-shot test.
What's next for ProfessorTranslate
Stated honestly: this is a prototype, not a product. It runs, it is measured, and it has not yet faced a real class. A mistranslated sentence costs a student more than no translation would, so the next step is a supervised pilot in one real lecture — not more features.
Then: animated demonstrations instead of static plots; generated video for concepts a plot cannot carry; spoken definitions protected like terms; glossaries built from photographs of the board; more languages (each is a config entry plus a few examples to pin the register); and cloud speech recognition as an option for noisy halls and strong accents.
Known limit, stated plainly: a device with no Hindi voice installed produces silence. The app detects this and says so rather than failing quietly — open /check on any device to see.
Built With
- express.js
- featherless-ai
- firecrawl
- node.js
- prompt-engineering
- qwen
- react
- render
- speech-to-text
- tailwind
- text-to-speech
- typescript
- vite
- web-speech-api
- websockets
- wolfram-technologies
Log in or sign up for Devpost to join the conversation.