The short version
Your question goes to a small set of AI services running on a server in my dev lab — not to a commercial AI provider. One service writes the answer using my actual career documents as source material. A second service reads that answer aloud in a clone of my voice. The page plays the audio the moment the first sliver of it exists and rolls the transcript out in time with it, like live captions on a video call.
Step by step
- You ask. The browser sends your question straight to my home lab over HTTPS. Nothing is stored, and each question starts a fresh conversation.
- The answer gets written. A chat service running Qwen3-4B-Instruct (a compact open-weight model, quantized so it fits on a small GPU) drafts the reply. Before it does, my career material — resume, role history, project notes — is pasted into the prompt, so it answers from documents rather than from memory. That is retrieval-augmented generation, done the plain way: a folder of files, injected verbatim.
- The answer gets spoken. The finished text is handed to a text-to-speech service running Qwen3-TTS (
Qwen3-TTS-12Hz-1.7B-Base). It clones my voice from one short reference recording of me talking — no per-voice training step — and synthesizes the reply sentence by sentence.
- You hear it immediately. Rather than waiting for the whole clip, the service streams raw audio out as each sentence finishes. The page schedules each piece back-to-back with the Web Audio API, so playback starts on the first chunk instead of the last one.
- The captions follow the voice. The text is deliberately held back until audio actually starts, then revealed at the pace of the speech, so reading and listening stay together.
What’s underneath
- Both models run on
llama.cpp, which is what makes a 6 GB consumer graphics card enough for a chat model and a voice model at the same time.
- The models never unload. Loading a model cold takes ten to fifteen seconds — unacceptable if you are waiting on a phone call. Both services build their model once at startup and keep it resident, so the only cost per question is the thinking itself.
- One container, one port. The chat service and the voice service are independent, fronted by a single web server that routes by URL path (
/llm/ and /tts/).
- The page is static. This site is plain HTML on GitHub Pages — no backend, no build step, no secrets. All the intelligence lives behind the API it calls.
Why build it this way
It is a working answer to a question I get asked a lot: what can you actually run yourself, on hardware you already own, without renting a model by the token? Self-hosted open models on a used GPU turn out to be well past the toy stage — good enough to hold a short conversation about my own resume and sound like me doing it.
Fair warning: the voice is synthetic and the words are generated by a language model reading my career documents. It gets things right most of the time, and confidently wrong some of the time. For anything that matters, ask the real me.