Skip to main content

Semantic text search over audio files without full transcription

Project description

๐Ÿ”Š EchoVector

Semantic text search over audio files โ€” without full transcription.

CI Coverage Python License


What is EchoVector?

EchoVector indexes audio files by generating semantic embeddings directly from audio waveforms, then lets you search them with natural language text queries โ€” all without transcribing a single word.

Traditional approach (slow & expensive)

Audio โ†’ Full Transcription โ†’ Text Embeddings โ†’ Text Search

EchoVector approach (fast & efficient)

Audio โ†’ Audio Chunks โ†’ Audio Embeddings โ”€โ”
                                          โ”œโ”€โ–บ ANN Search โ†’ Results
Text Query โ†’ Text Embedding โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Features

  • ๐ŸŽต Multi-format support โ€” MP3, WAV, FLAC, M4A
  • ๐Ÿง  Direct audio embeddings โ€” No transcription needed
  • ๐Ÿ” Semantic search โ€” Query with natural language
  • โšก FAISS-powered โ€” Approximate nearest neighbor search
  • ๐Ÿ”Œ Pluggable backends โ€” CLAP, Whisper, wav2vec2, HuBERT, AST
  • ๐Ÿงช Offline smoke backend โ€” local backend for CI/Kaggle tests without model downloads
  • ๐Ÿ“Š Rich CLI โ€” Progress bars, colors, benchmarking mode
  • ๐ŸŒ REST API โ€” Optional FastAPI server
  • ๐Ÿ“ฆ Production-ready โ€” Typed, tested, documented

Quick Start

Installation

pip install echovector

Or with uv:

uv add echovector

CLI Usage

# One-time indexing: split audio into timestamped chunks and embed each chunk
echovector index ./meetings

# Fast repeated search: embed only the text query and search the saved FAISS index
echovector search "discussion about transformers"

# Search with options
echovector search "pricing strategy" --top-k 10

# View index statistics
echovector stats

For a no-download smoke test, use the deterministic local backend:

echovector index ./meetings --backend local --store-dir ./ev-index
echovector search "high alarm tone" --backend local --store-dir ./ev-index
echovector stats --backend local --store-dir ./ev-index

The search command does not reopen or scan the audio files. All expensive audio processing happens during index; search loads the saved vector index, embeds the short text query, and returns the nearest timestamped chunks.

Python API

from echovector import EchoVector

ev = EchoVector()

# Index audio files
ev.index("./meetings")

# Search with natural language
results = ev.search("conversation about CUDA kernels")

for r in results:
    print(
        f"{r.filepath} "
        f"[{r.timestamp_range.start:.1f}s - {r.timestamp_range.end:.1f}s] "
        f"score={r.score:.4f}"
    )

Testing on Kaggle

Kaggle is useful for GPU-backed CLAP tests, but first check the runtime Python version:

import sys
print(sys.version)

EchoVector currently declares Python >=3.12. If the Kaggle image is older, install and test in a Python 3.12-capable environment instead, or relax the project requirement only after validating the test suite on that Python version.

Notebook smoke test without internet/model downloads

Upload this repository as a Kaggle dataset, attach it to a notebook, then run:

%cd /kaggle/input/<your-echo-vector-dataset>
!pip install -e . --no-deps
!pip install numpy soundfile librosa faiss-cpu typer rich pydantic
!python -m pytest tests/ -q

Create a tiny audio corpus and test the real CLI/index path:

import os
import numpy as np
import soundfile as sf

audio_dir = "/kaggle/working/ev-audio"
index_dir = "/kaggle/working/ev-index"
os.makedirs(audio_dir, exist_ok=True)

sr = 16000
t = np.linspace(0, 1.0, sr, endpoint=False)
sf.write(f"{audio_dir}/high_tone.wav", 0.25 * np.sin(2 * np.pi * 880 * t), sr)
sf.write(f"{audio_dir}/low_tone.wav", 0.25 * np.sin(2 * np.pi * 110 * t), sr)
!echovector index /kaggle/working/ev-audio --backend local --store-dir /kaggle/working/ev-index --reset
!echovector search "high alarm tone" --backend local --store-dir /kaggle/working/ev-index --top-k 2
!echovector stats --backend local --store-dir /kaggle/working/ev-index

This validates packaging, audio loading, FAISS persistence, metadata storage, and the CLI without depending on Hugging Face downloads.

CLAP semantic test

For actual semantic text-to-audio search, enable internet in the notebook settings and use a GPU runtime if available:

!pip install transformers torch faiss-cpu librosa soundfile
!echovector index /kaggle/input/<audio-dataset> --backend clap --device cuda --store-dir /kaggle/working/clap-index --recursive --reset
!echovector search "people discussing pricing strategy" --backend clap --device cuda --store-dir /kaggle/working/clap-index --top-k 10

If GPU is unavailable, replace --device cuda with --device cpu; it will be slower. Keep indexes under /kaggle/working so they are writable during the notebook session.

Architecture

echovector/
โ”œโ”€โ”€ audio/        # Audio loading, chunking, streaming, metadata
โ”œโ”€โ”€ embeddings/   # Pluggable embedding backends (CLAP, Whisper, etc.)
โ”œโ”€โ”€ indexing/     # Vector index backends (FAISS, with pluggable design)
โ”œโ”€โ”€ search/       # Search engine, filtering, result hydration
โ”œโ”€โ”€ cli/          # Typer-based CLI with Rich output
โ”œโ”€โ”€ api/          # Optional FastAPI server
โ”œโ”€โ”€ evaluation/   # Metrics (recall@k, throughput)
โ”œโ”€โ”€ benchmarks/   # Reproducible benchmark harness
โ””โ”€โ”€ utils/        # Config, logging, helpers

Supported Embedding Backends

Backend Text+Audio Aligned Notes
CLAP (default) โœ… Best for textโ†’audio search
Whisper Encoder โŒ Audio-only embeddings
wav2vec2 โŒ Audio-only, good for speech
HuBERT โŒ Audio-only, self-supervised
Audio Spectrogram Transformer โŒ Audio-only, classification-focused

Development

# Clone and install
git clone https://github.com/echovector/echovector.git
cd echovector
uv sync --all-extras

# Run checks
make lint
make typecheck
make test
make coverage

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

echo_vector-0.1.1.tar.gz (20.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

echo_vector-0.1.1-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

File details

Details for the file echo_vector-0.1.1.tar.gz.

File metadata

  • Download URL: echo_vector-0.1.1.tar.gz
  • Upload date:
  • Size: 20.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for echo_vector-0.1.1.tar.gz
Algorithm Hash digest
SHA256 dbc2d571864e7745652418565e66c82cfe6404e37e42631c7fb90f0ef31ac32a
MD5 4b82e3c5e655ee23cf247090148403fb
BLAKE2b-256 03f182a70a80913656be9607dba10c4eeeb56d4b4aba3a651e3c7198c6cf612a

See more details on using hashes here.

Provenance

The following attestation bundles were made for echo_vector-0.1.1.tar.gz:

Publisher: workflow.yml on ahron-maslin/echo_vector

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file echo_vector-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: echo_vector-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 34.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for echo_vector-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0ce4d14bb4b5ee0113890d90ab7ed84e5072f8729e125fe9b0e2d08538ec3eff
MD5 f7c80dee422fd9c4312f77308200818c
BLAKE2b-256 d211bbb872a8edfb0518046d09cc987b7d59d5dc95235437052bdfab4f63d2f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for echo_vector-0.1.1-py3-none-any.whl:

Publisher: workflow.yml on ahron-maslin/echo_vector

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page