aboutsummaryrefslogtreecommitdiff
path: root/working/meeting-transcription-service/2026-09-19-work-handoff.org
diff options
context:
space:
mode:
Diffstat (limited to 'working/meeting-transcription-service/2026-09-19-work-handoff.org')
-rw-r--r--working/meeting-transcription-service/2026-09-19-work-handoff.org44
1 files changed, 44 insertions, 0 deletions
diff --git a/working/meeting-transcription-service/2026-09-19-work-handoff.org b/working/meeting-transcription-service/2026-09-19-work-handoff.org
new file mode 100644
index 0000000..d4da1d9
--- /dev/null
+++ b/working/meeting-transcription-service/2026-09-19-work-handoff.org
@@ -0,0 +1,44 @@
+#+TITLE: Handoff from work: the meeting transcription service needs an install home
+#+AUTHOR: Craig Jennings
+
+* What this is
+A self-hosted meeting transcription service (whisper.cpp plus pyannote speaker diarization) that runs on
+ratio, with velox as the offline fallback. It has been running on both machines since 2026-09-17. The code
+arrives as meeting-transcription-service.tar.gz alongside this note. I picked archsetup as its home because
+it is machine setup: a worker, two systemd user units, a Python venv and a model file. The client script and
+its Emacs backend entry are handled separately.
+
+* How it works
+- A job queue under ~/.local/state/meeting-transcribe/ with incoming/, work/, done/ and failed/. A systemd
+ user path unit (meeting-transcribe.path) starts a oneshot worker (meeting-transcribe.service) when a job
+ lands in incoming/.
+- The worker (src/transcribe-worker) converts audio to 16 kHz mono, runs whisper-cli at word level, runs
+ pyannote (speaker-diarization-community-1) through src/diarize.py with the job's speaker count, and
+ merges the two by timestamp with src/merge_transcript.py. One job at a time, behind a lock.
+- A finished job leaves done/<id>.txt. A failed job leaves failed/<id>.log. Nothing half-written reaches done/.
+- No network listener. Tailscale ssh is the transport and the login, systemd is the daemon, the
+ filesystem is the queue.
+
+* What the install has to provide, per machine
+- ~/.local/share/pyannote-diarize/.venv :: Python 3.12, torch (CPU build), pyannote.audio 4.0.7. About
+ 1.3 GB. Built with uv.
+- ~/.local/share/whisper-models/ggml-large-v3-turbo-q5_0.bin :: the whisper model; ratio's and velox's
+ copies have the same checksum. whisper-cpp itself must be installed (it was already on velox).
+- The src/ scripts placed where the units expect them, and the two user units enabled.
+- Linger on, so the path unit runs without a login session.
+- One-time, online, by hand: a Hugging Face token and acceptance of the pyannote model terms, so the
+ diarization model can be cached. After that neither machine needs Hugging Face. The token is a
+ credential: it must not be written into this repo, which is publicly cloneable.
+
+* State today
+- Installed by hand on ratio and velox; both verified. No NVIDIA GPU and no ROCm on ratio, so it is CPU only.
+- make check in the bundle runs pytest (129 tests; whisper, pyannote, ssh and scp are faked at the process
+ boundary), pyright and shellcheck. All green on 2026-09-19.
+- Known rough edge: when two local runs overlap, the second finds the lock held, the worker returns
+ silently, and the client says "finished without producing a transcript". Rerunning fixes it, but the
+ message should say the lock was held.
+
+* What I'm asking archsetup for
+Take ownership of the service side: the worker, diarize.py, merge_transcript.py, the two units, and an
+install step that builds the venv, fetches the model and enables the units on both daily drivers. Keep
+anything work-specific out of the repo; the code bundle has none (scanned before sending).