Download docs/ARCHITECTURE.md from vertox-ai/speech-text-data-aligners: direct link, hf CLI and curl.
- Browser
- Download file 7.33 kB
-
https://huggingface.co/vertox-ai/speech-text-data-aligners/resolve/main/docs/ARCHITECTURE.md
- Command line
-
hf download hf://vertox-ai/speech-text-data-aligners/docs/ARCHITECTURE.md
-
curl -L -o ARCHITECTURE.md https://huggingface.co/vertox-ai/speech-text-data-aligners/resolve/main/docs/ARCHITECTURE.md
Architecture
Speech-Text Data Aligners is a library-first forced-alignment framework. The core contract accepts WAV audio plus a known, authoritative transcript and returns backend-neutral timed words. The CLI is only a composition and presentation layer.
The mandatory design rules are defined in the modular architecture contract and the aligner engineering contract.
Layers and Dependency Direction
CLI --------------------> Application --------------------> Core
| ^
+----------> Data -------------+
+----------> Benchmarking -----+
+----------> Runtime ----------+
CLI -- lazy composition --> Concrete Backends
| |
+------------> Core
+------------> Runtime
In compact form:
CLI -> Application -> Core
-> Data
-> Benchmarking
-> Runtime
Concrete Backends -> Core / Runtime
The enforced consequences are:
- Core does not import application, data, benchmarking, CLI, or concrete backends.
- Data and benchmarking do not depend on concrete backends.
- Application services receive an
AlignmentBackendprotocol instance; they do not branch on NeMo, MFA, or WhisperX names. - Concrete backend packages do not import one another.
- The registry stores lazy dotted factories so unavailable optional runtimes do not break backend-neutral imports or sibling backends.
- The CLI delegates annotation and benchmarking to reusable Python services.
Current Package Tree
src/speech_text_data_aligners/
|-- __init__.py public backend-neutral facade
|-- application/
| |-- annotate.py annotation orchestration and publication policy
| `-- benchmark.py identical-request benchmark orchestration
|-- backends/
| |-- registry.py immutable lazy backend composition
| |-- nemo/
| | |-- backend.py neutral adapter
| | |-- config.py typed configuration
| | |-- manifest.py reference JSONL and output-manifest parsing
| | |-- runner.py isolated NFA execution
| | `-- ctm.py word CTM parsing and mapping
| |-- mfa/
| | |-- backend.py neutral adapter
| | |-- config.py typed configuration
| | |-- corpus.py temporary WAV/LAB corpus
| | |-- runner.py isolated MFA execution
| | `-- textgrid.py word-tier parsing and mapping
| `-- whisperx/
| |-- backend.py neutral adapter
| |-- config.py typed configuration
| |-- segments.py full-WAV authoritative segments
| |-- provider.py isolated-worker transport
| |-- worker.py lazy heavyweight native runtime
| `-- parser.py native word-dictionary parsing and mapping
|-- benchmarking/
| |-- metrics.py sparse-gold and pairwise metrics
| `-- reports.py JSON/CSV/Markdown report rendering
|-- cli/
| |-- main.py command dispatch
| |-- annotate.py annotation argument adapter
| `-- benchmark.py benchmark argument adapter
|-- core/
| |-- models.py immutable neutral values and provenance
| |-- protocols.py injected backend contracts
| |-- errors.py project exception taxonomy
| |-- normalization.py lexical plans and monotonic reconciliation
| |-- validation.py result and publication-path invariants
| `-- extraction.py six first/last output fields
|-- data/
| |-- audio.py WAV resolution and lightweight probing
| `-- metadata.py preserving, atomic CSV I/O
`-- runtime/
|-- process.py shell-free injected subprocess boundary
|-- artifacts.py temporary and retained artifact lifecycle
`-- receipts.py hashes and run provenance
Package-marker __init__.py files not shown above are deliberately empty. The root
__init__.py is the tested public facade.
Backend Isolation and Native Containment
PARENT PROCESS
Python caller or CLI
|
v
backend-neutral application API
|
v
AlignmentBackend protocol
|
v
concrete adapter (NeMo | MFA | WhisperX)
|
| injected process/provider boundary
v
+------------------------------------------------------+
| ISOLATED NATIVE RUNTIME |
| NeMo NFA process | MFA process | WhisperX worker |
| Heavy optional dependencies and model lifecycle |
+------------------------------------------------------+
|
| native files / native dictionaries
v
adapter-local builder, parser, and reconciliation
|
| only neutral records cross this point
v
AlignmentResult | AlignmentFailure | diagnostics | provenance
NeMo manifests, output manifests, and CTM rows remain inside
backends.nemo. MFA corpus labels and TextGrid objects remain inside
backends.mfa. WhisperX segment payloads and native result dictionaries remain
inside backends.whisperx. NeMo CTM, MFA TextGrid, and WhisperX native dictionaries
never escape their adapters; callers receive only backend-neutral models.
The parent process does not import heavyweight NeMo, MFA, WhisperX, Torch, or Torchaudio packages. NeMo and MFA run through the shared shell-free process boundary. WhisperX runs in a dedicated worker that imports its heavy stack only after invocation.
Transcript-to-Result Data Flow
authoritative transcript
|
v
backend-specific reference representation
|
v
native timed words
|
v
shared monotonic reconciliation
|
v
shared validation
|
v
AlignmentResult
The authoritative en_transcript remains unchanged throughout. A backend may
normalize or expand text only through a reversible plan that retains ownership of
original lexical words. Shared reconciliation requires complete monotonic coverage,
and shared validation rejects non-finite, negative, reversed, overlapping, incomplete,
or out-of-audio timestamps. It never clamps, interpolates, or invents a timestamp.
Reuse and Composition
The root facade exposes reusable annotation and benchmark services. Applications may
inject any object satisfying AlignmentBackend, including a lightweight test or
custom backend. The default registry is a convenience for the CLI, not a dependency of
the application layer.
Benchmarking consumes the same neutral results as annotation. Native parsing, transcript mapping, CSV I/O, metric calculation, report rendering, and process execution each have one owning layer, so adding another adapter does not require changes to established backend-neutral behavior.
Architecture is enforced by deterministic AST tests and Import Linter contracts. The accepted audit and complete dependency evidence are recorded in the Stage 5 final acceptance report.