Native Forced Aligner
Relevant source files
The following files were used as context for generating this wiki page:
The Native Forced Aligner is a high-performance, word-level timestamp generation system implemented entirely in MLX for Apple Silicon. It is a ground-up reimplementation of the Qwen3-ForcedAligner, designed to provide precise alignment between audio and transcript text without requiring PyTorch or external heavy dependencies in the core inference path.
The aligner functions by processing audio features and text prompts containing special timestamp tokens. It calculates the temporal boundaries for every word in the provided transcript, supporting 52 languages with specialized tokenization for CJK (Chinese, Japanese, Korean) scripts.
Sources: CLAUDE.md:16, mlx_qwen3_asr/forced_aligner.py:12-25
Architecture and Components
The system is structured into three primary layers: a high-level wrapper for user interaction, a native MLX backend for model execution, and a text processor for specialized linguistic handling and post-processing.
System Class Structure
The ForcedAligner acts as the entry point, lazily initializing the _MLXForcedAlignerBackend which manages the specific MLX model weights and tokenizer.
Sources: mlx_qwen3_asr/forced_aligner.py:313-352, mlx_qwen3_asr/forced_aligner.py:270-310
Data Flow and Alignment Logic
The alignment process transforms raw audio and a string of text into a sequence of AlignedWord objects.
Alignment Sequence
- Tokenization: The
ForcedAlignTextProcessorsplits text based on language rules. Japanese usesnagisa, Korean usessoynlpwith a custom dictionary, and other languages use a space/CJK-aware splitter. - Feature Extraction: Audio is converted to mel spectrograms and passed through the 24-layer transformer encoder to generate audio features.
- Logit Projection: The model projects hidden states through an
lm_headto predict token IDs. - Timestamp Extraction: Token IDs corresponding to
<timestamp>placeholders are extracted and converted to milliseconds.
Sources: mlx_qwen3_asr/forced_aligner.py:284-310, mlx_qwen3_asr/forced_aligner.py:157-167, CLAUDE.md:78-83
Longest Increasing Subsequence (LIS) Correction
A critical aspect of the aligner is the fix_timestamp utility. Raw model predictions can sometimes be non-monotonic (out of order). The aligner uses a Longest Increasing Subsequence (LIS) algorithm to identify "normal" timestamps and repair anomalies.
| Correction Step | Logic |
|---|---|
| Identification | Uses a Fenwick tree optimized $O(N \log N)$ algorithm to find the longest non-decreasing sequence of timestamps. |
| Anomaly Detection | Any timestamp not part of the LIS is flagged as an anomaly. |
| Linear Interpolation | If an anomaly is found between two valid timestamps, the values are interpolated linearly. |
| Boundary Handling | Anomalies at the start or end of the sequence are clamped to the nearest valid neighbor. |
Sources: mlx_qwen3_asr/forced_aligner.py:170-221, mlx_qwen3_asr/forced_aligner.py:223-263, tests/test_forced_aligner.py:108-115
Configuration and Usage
The aligner can be invoked via the CLI or the Python API. It defaults to the 0.6B parameter model for speed.
CLI Parameters
| Flag | Type | Description | Default |
|---|---|---|---|
--timestamps | Boolean | Enables word-level timestamps via the forced aligner. | False |
--forced-aligner | String | HF model ID or local path for the aligner model. | Qwen/Qwen3-ForcedAligner-0.6B |
--dtype | Choice | MLX data type: float16, float32, or bfloat16. | float16 |
Python API Example
from mlx_qwen3_asr.forced_aligner import ForcedAligner
import numpy as np
aligner = ForcedAligner()
audio = np.random.randn(16000) # 1s of audio
words = aligner.align(audio, "Hello world", "English")
# Accessing results
for word in words:
print(f"{word.text}: {word.start_time} - {word.end_time}")
Sources: mlx_qwen3_asr/cli.py:448-460, mlx_qwen3_asr/forced_aligner.py:313-325, scripts/eval_aligner_parity.py:176-184
Summary
The Native Forced Aligner provides a robust, Metal-optimized solution for generating word-level metadata. By utilizing MLX for local inference and incorporating specialized CJK tokenization and LIS-based timestamp correction, it ensures high precision alignment that remains consistent with reference PyTorch implementations while maximizing performance on Apple Silicon hardware.
Sources: CLAUDE.md:16, mlx_qwen3_asr/forced_aligner.py:12-15