# Dictation's speech-to-text server, as a Quadlet. # # Quadlet rather than a hand-written unit wrapping `podman run`: systemd # generates the unit from this at boot, so there is one description of the # container rather than a unit and a command line drifting apart. # # Upstream's own Vulkan image, not one built here. whisper.cpp publishes it, it # already contains whisper-server, and it is maintained by the people who write # the thing -- a Containerfile in this repository would be a compile step on # every machine and a build to keep working, in exchange for nothing. # # Vulkan rather than ROCm, which is the reason this tag and not another. ROCm's # runtime is seven gigabytes and serves AMD alone; Vulkan compute runs on AMD, # Intel and NVIDIA through whatever Mesa driver a machine already has. These # machines are a mix of all three, and this image works on every one of them. # # Deliberately no [Install] section. whisper-server loads the model when it # starts and holds it, so a container started at login costs half a gigabyte of # memory in every session where nobody dictates. panama-dictate starts it on the # first press of the key, and it stays up for the rest of the session. [Unit] Description=Panama dictation speech-to-text server Documentation=https://github.com/ggml-org/whisper.cpp [Container] Image=ghcr.io/ggml-org/whisper.cpp:main-vulkan # The image's own entrypoint is a shell; the server is what is wanted. Entrypoint=/app/build/bin/whisper-server Exec=--host 0.0.0.0 --port 8791 --model /models/ggml-small.bin --inference-path /inference # The whole directory rather than a renderD node: the number differs between # machines, and this file is meant to be identical on all of them. AddDevice=/dev/dri # The model is host state -- fetched once, kept across image updates, and shared # with nothing else. Read-only because the server never writes to it, and :z # relabels for SELinux, which is enforcing on Fedora. Volume=%h/.local/share/panama/whisper:/models:ro,z # Loopback only. This transcribes whatever it is sent, with no authentication, # and has no business being reachable from the network. PublishPort=127.0.0.1:8791:8791 NoNewPrivileges=true [Service] # Loading the model takes a few seconds on a cold start; systemd should wait for # it rather than give up, and should bring the server back if it dies mid-session. TimeoutStartSec=180 Restart=on-failure RestartSec=3