All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Word-level
speakerin combined transcripts now falls back to the enclosing segment's speaker when WhisperX's word-level diarization join doesn't intersect any pyannote span (typically a boundary-overlap gap on short, low-confidence trailing words). Previously such words were emitted withspeaker: nulldespite the segment carrying a confident label. The Pydantic contract is unchanged — word-levelspeakeris still nullable in principle — but in practice the field is now populated whenever the segment-level assignment is confident.
- Published JSON Schemas for the combined transcript and batch summary documents under
docs/schemas/(combined-transcript-v1.json,batch-summary-v1.json). They are generated from the Pydantic source-of-truth in serialization mode, attached as GitHub release assets, and kept in lockstep with the models by a CI drift check. Consumers without access to the Python package can now fetch the schema for a pinned AR version directly from the release tag and validate transcripts against it. Seedocs/service.mdfor the consumption pattern. make generate-schemasandmake check-schemasMakefile targets. The drift check now runs as part ofmake all-checksand as a dedicated CI job (Schema Drift Checkinci.yml).
- Refreshed the README banner image.
- Service mode now defaults
CUDA_DEVICE_ORDERtoPCI_BUS_IDat startup (matching the CLI, respecting an explicit override), soREFINERY_DEVICE=cuda:Nselects the GPU atnvidia-smiindex N rather than CUDA's default FASTEST_FIRST ordering. Previously a multi-GPU host could load models onto the wrong card. - WhisperX forced-alignment failures are now logged at debug level (with the detected language and device) before falling back to transcription-only segments, instead of being swallowed silently.
- Corrected the service-mode tmpfs example to
--mount type=tmpfs,dst=/scratch,tmpfs-mode=1777. A bare--tmpfs /scratchmounts root-owned, so the non-rootrefineryuser could not write scratch and every job failed withPermissionError. Applied the same fix indocs/deployment.md. - Added service-mode GPU-selection guidance, an end-to-end local-directory batch runbook, and troubleshooting entries (tmpfs permissions, wrong-GPU selection, batch-size cap) to
docs/service.md. - Added the project banner to the README.
- Upgraded vulnerable transitive and dev dependencies to patched versions:
aiohttp3.13.3 → 3.13.5,requests2.32.5 → 2.34.2,Pygments2.19.2 → 2.20.0, andpytest9.0.2 → 9.0.3. Closes 13 Dependabot alerts (10aiohttpplusrequests,Pygments,pytest). Thetorchandtransformersalerts remain deferred to v0.3.0, when WhisperX removal lifts thetorch==2.1.2/transformers<4.40pins.
- HTTP service mode: a long-lived FastAPI service (
audio-refinery-serviceentry point) exposingPOST /transcribe,GET /jobs/{id}, andGET /health. Accepts multi-job batches, processes them serially on a background worker, and writes one combined transcript per job plus one summary per batch. Models load once at container startup and stay resident across jobs. - Combined transcript schema (v1.0.0) and per-batch summary schema (v1.0.0) — service-mode output documents that envelope the existing per-stage results so consumers read a single document per job/batch.
- Bearer-token authentication via the
REFINERY_API_KEYSallowlist; request and job-lifecycle logs carry a non-reversible caller fingerprint. - URI-driven I/O for the service:
https://(presigned GET for input, presigned PUT for output/summary) andfile://for local-dev and shared-volume deployments. - Multi-stage Dockerfile (CUDA 12.1 runtime base, non-root
refineryuser) published aslunarcommand/audio-refineryon Docker Hub. audio-refinery serveCLI subcommand — a convenience wrapper around the service entry point.- Optional GPU thermal guard in service mode via
REFINERY_GPU_TEMP_LIMIT/REFINERY_GPU_TEMP_POLL_SECONDS, reusing the CLI's monitor. - Service configuration via environment variables:
REFINERY_API_KEYS,REFINERY_DEVICE,REFINERY_WHISPER_MODEL,REFINERY_COMPUTE_TYPE,REFINERY_DEFAULT_LANGUAGE,REFINERY_SENTIMENT_ENABLED,REFINERY_SCRATCH_DIR,REFINERY_INTERMEDIATE_DIR,REFINERY_MAX_BATCH_SIZE,REFINERY_MAX_QUEUE_SIZE,REFINERY_JOB_RETENTION_SECONDS,REFINERY_PORT, andREFINERY_LOG_FORMAT.
- Demucs scratch directory is now host-agnostic: it defaults to
tempfile.gettempdir()/audio-refinery-demucsand honorsREFINERY_SCRATCH_DIRin both CLI and service mode, replacing the hard-coded/mnt/fast_scratchpath. - CLI batch input now accepts any
*.wavfile; theaudio_filename prefix is optional and stripped from the derived content ID, replacing the previous requiredaudio_<id>.wavpattern. - Sentiment analysis treats segments with no transcribed speech (e.g. silent audio) as no-ops rather than failures.
- Added
fastapi,uvicorn[standard], andhttpxas main dependencies for service mode. - Documentation restructured into a two-path (CLI + service) layout: lowercase
docs/filenames, a slimmed README with a "choose your path" landing, and newdocs/cli.md,docs/service.md, anddocs/index.md.
- Scoped both GitHub Actions workflows (
ci.yml,release.yml) to least-privilege permissions. Workflow default is nowcontents: read; thegithub-releasejob retains an explicitcontents: writeoverride. Closes CodeQL workflow-permission alerts. - Upgraded vulnerable transitive dependencies:
idna3.11 → 3.15,Mako1.3.10 → 1.3.12,Pillow12.1.1 → 12.2.0,urllib32.6.3 → 2.7.0. Closes nine Dependabot alerts covering path-traversal, redirect-header forwarding, decompression-bomb, OOB-write, and integer-overflow CVEs.
- 18 Dependabot alerts remain open against
torchandtransformers(including one critical and several high severity). Both packages are pinned to WhisperX-compatible versions (torch==2.1.2,transformers>=4.30,<4.40) and cannot be upgraded without breaking the current ASR pipeline. These alerts close together when v0.3.0 lands and removes WhisperX from the critical path; see the universal alignment plan for the migration path.
- Suppressed live Slack webhook calls during the test run via an autouse
_no_slackfixture intests/conftest.py. Previously,notifier._send()loaded the developer's.envon every invocation and POSTed real messages whenever pipeline tests triggered end-of-batch notifications.
0.1.1 - 2026-03-06
combined_report.jsonnow includes four derived metrics:avg_time_per_file_seconds,avg_time_per_mb_seconds,processing_speed_ratio(real-time factor), andwords_per_audio_hour(transcription density)- Slack notifications now include detailed per-stage stats (processed / skipped / failed counts) and average processing time per file
make test-slackMakefile target for validating Slack webhook integration- Dockerfile and
.dockerignorefor containerized deployment - Sentiment output directory (
<base>/sentiment/) support in batch pipeline
- Centralized Demucs scratch directory resolution in CLI — RAM disk detection and fallback confirmation now happen in one place
- Worker status reporting and failure aggregation in
pipeline-parallelrefactored for improved accuracy python-dotenvimport in Slack notifier is now conditional — avoids import-time failure when the package is absent- DEPLOYMENT.md expanded: Hugging Face token setup, NVIDIA driver requirements, cloud instance guidelines, and Docker usage
- Combined report fields documented in README under the Parallel Pipeline section
- Narrowed exception handling in
gpu_utils.py,transcriber.py, andnotifier.pyto avoid masking unexpected errors - Typo in
SeparationErrordocstring
0.1.0 - 2026-03-01
- Initial release
separatecommand: GPU-accelerated vocal separation via Demucshtdemucsdiarizecommand: Speaker diarization via Pyannotespeaker-diarization-3.1transcribecommand: Transcription with word-level alignment via WhisperXlarge-v3sentimentcommand: Per-segment sentiment analysis viacardiffnlp/twitter-roberta-base-sentiment-latestpipelinecommand: Single-GPU batch processing through all four stagespipeline-parallelcommand: Multi-GPU batch processing with worker distribution- GPU pre-flight checks via
nvidia-smiwith active process detection - Thermal monitoring with configurable shutdown threshold (default 80°C)
- Slack webhook notifications for pipeline completion and thermal events
- Resume behavior for batch pipelines (skips already-completed files)
- Pydantic data models for all pipeline outputs with full provenance tracking
- Rich terminal output with progress spinners and result tables
- VRAM usage tracking and peak memory reporting per stage
- Scratch space management with automatic cleanup of intermediate files
- GPU performance-based ordering via
gpu_tflops.tomllookup table
- WhisperX model loading: pinned install to commit
741ab9a(v3.7.6) — thev3.1.1tag uses an older API (transcribe.py) that lacks thedevice_indexparameter required by the ctranslate2 backend make install-whisperxnow also installs WhisperX runtime deps (av,ctranslate2,faster-whisper,flatbuffers,nltk,onnxruntime) which were previously missing after a--no-depsinstalltransformerscapped at<4.40.0— versions 4.40+ usetorch.utils._pytree.register_pytree_node, an API introduced in PyTorch 2.2, which breaks with the pinned PyTorch 2.1.2make dev-setupnow reinstalls CUDA torch wheels (torch==2.1.2+cu121,torchaudio==2.1.2+cu121) as its final step —uv syncresolves torch from PyPI and installs the CPU-only build, silently breaking GPU inference