This is a submission for the Hacktoberfest Challenge: Ghost in the Machine
What I Built
Ofrenda is a small tool that turns a spoken or typed memory of someone you love into a candlelit remembrance page: their favourite foods, their songs, the things they used to say, and the stories you want to keep.
You give it a voice recording or a text file. A local speech model transcribes it, a local open-weight model pulls out the details, and a single self-contained HTML page comes out. No account, no upload, no API key.
DÃa de los Muertos is about keeping people present by telling their stories. I wanted a tool that makes that easy without handing those stories to anyone else's server.
Demo
- Code: https://github.com/ShaikhAtifa/Ofrenda-ghost_in_laptop
- The demo uses
sample_story.txt, a fictional story, so no real family recording is published.
To try it:
pip install -r requirements.txt
ollama pull gemma4:e2b
python ofrenda.py sample_story.txt --name "Abuela Lupe" --model gemma4:e2b
Then open ofrenda.html in a browser. python ofrenda.py --demo renders a sample page without any model.
Why Open Mattered Here
A recording of a grandmother telling stories is about as private as data gets. It carries her voice, her words and her family's names. With a closed cloud service, using a tool like this means uploading all of that to a server I do not control, under terms I will probably never read.
Because the whole pipeline is open, none of that happens:
- The data stays on the laptop. Whisper and Gemma both run locally. After the models are downloaded, it works with the Wi-Fi off.
- It costs nothing per use. There is no per-minute transcription bill and no token bill, which matters for something a family might run again every November.
-
I can change it. The extraction rules live in one prompt. I can make the model stricter, ask for different sections, or swap in another model with a single
--modelflag.
The trade-off is real: a small local model is less capable than a large hosted one, and on a CPU it is slower. For this job I decided privacy mattered more than speed.
How It Works
-
Transcribe.
faster-whisper(thesmallmodel, int8, on the CPU) turns audio into text. Text files skip this step. - Extract. Gemma, running through Ollama, receives the transcript and a strict prompt: use only what was said, never invent names, dates or events, and answer as JSON with a short dedication, foods, songs, sayings and stories.
- Render. The JSON is HTML-escaped and poured into one static page with a flickering candle and marigold colours. I escape everything because the text comes from a model.
The transcript is saved next to the output, so anyone can check the page against what was actually said.
Known Limits
- A small model can still get details wrong. That is why the prompt forbids invention and why the transcript is saved beside the page. A family should always read the two side by side.
- Speech recognition varies. Whisper handles Spanish and many other languages, but accents, background noise and mixed-language speech can cause mistakes.
- It is slower on a CPU. A GPU makes it much faster, but I wanted it to run on an ordinary laptop.
- Long recordings are cut to the first 6,000 words.
My Run
- Model: gemma4:e2b
- Time to produce the page: 40 seconds
What I Would Do Next
- Let the page include a photo and print cleanly as an ofrenda card.
- Better handling of mixed Spanish and English recordings.
- A check mode that shows which sentence in the transcript each detail came from, so a family can trust the result more.
Prize Categories
Best Use of Gemma: Gemma, through Ollama, does the extraction and writes the dedication, running entirely on a local machine.
Please only use recordings with the speaker's consent. DÃa de los Muertos is a living tradition, and I built this to honour it, not to decorate it.
Top comments (0)