fix(scriberr): model caches on /tank; HF_TOKEN is a placeholder (no real credential)

HF_HOME, TORCH_HOME and NLTK_DATA now point under /app/whisperx-env (the
/tank bind mount). Before, ~6 GB of models sat in the container layer and
every recreate threw them away. The cache was copied across (98/2/78 files,
apparent sizes identical).

HF_TOKEN is now a placeholder. Measured: with an invalid token, cached gated
pyannote models still load (huggingface_hub falls back to the cache on the 401),
and public models still download (HTTP 200). Scriberr only checks that the token
is non-empty. Re-verified on GPU 3: pyannote community-1 and WhisperX+3.1
diarization both exit 0 from the /tank cache with no downloads.
This commit is contained in:
vh
2026-10-06 13:33:17 -07:00
parent eaa32d6249
commit ec888c3130
3 changed files with 23 additions and 12 deletions
+20 -9
View File
@@ -72,15 +72,26 @@ services:
# and takes out the Parakeet + Sortformer backends (WhisperX survives).
# `copy` trades a little disk and time for it actually working.
- UV_LINK_MODE=${SCRIBERR_UV_LINK_MODE:-copy}
# Hugging Face token for the GATED pyannote models (speaker-diarization-3.1,
# segmentation-3.0). Without it every diarized job dies at the diarize step:
# WhisperX with a 401 GatedRepoError AFTER the whole transcription has run, and
# Parakeet+pyannote with "HuggingFace token is required". So it looks as if
# nothing works. Scriberr's config and both adapters read HF_TOKEN
# (internal/config/config.go), and it reaches the uv subprocesses. Value: vault
# `fv-ml1/hf-token` (account lkraven, read role; access to the gated repos was
# checked 2026-10-06). It lives only in the host .env, never in git.
- HF_TOKEN=${HF_TOKEN:-}
# ── Model caches on /tank, not in the container layer (Prime, 2026-10-06) ──
# Before this they lived under /home/appuser, which is the container's writable
# layer, so EVERY recreate threw away ~6 GB (Whisper large-v3, pyannote, the
# alignment model, NLTK) and the next job had to download it all again.
# /app/whisperx-env is the persistent /tank/scriberr/whisperx-env bind mount.
- HF_HOME=/app/whisperx-env/hf-cache
- TORCH_HOME=/app/whisperx-env/torch-cache
- NLTK_DATA=/app/whisperx-env/nltk_data
# ⚠ HF_TOKEN is a PLACEHOLDER on purpose. No real credential lives here.
# pyannote's diarization models are gated: downloading them needs a token whose
# account accepted their terms. LOADING an already-downloaded copy does not.
# Measured 2026-10-06: with an invalid token, huggingface_hub's check gets a 401
# and falls back to the cached copy, both online and with HF_HUB_OFFLINE=1.
# Public repos (any faster-whisper size) still download with an invalid token
# (HTTP 200). The placeholder exists only because Scriberr refuses to start
# pyannote diarization when HF_TOKEN is EMPTY (pyannote_adapter.go checks that
# it is non-empty, never that it is valid).
# To add a NEW gated model: run its first download once with a real token
# (vault `fv-ml1/hf-token`) set for that one run, then put the placeholder back.
- HF_TOKEN=${HF_TOKEN:-hf_placeholder_models_cached_on_tank}
# ── Memory settings, measured while Scriberr shared GPU 1 (2026-09-30; it moved to
# GPU 3 at 1322 the same day, so the 5.5 GB budget no longer binds, but the values stand). Prime: Scriberr shared GPU 1 with
# intern-decision, which holds ~9.7 GB resting / 10.3 GB peak). ──────────