This release is a pre-release and may not be stable for production use.
🌊 FlexAligner
Robust Speech-Text Alignment from Signal to Symbol
A Neural-Based Forced Alignment Framework for "Wild" Real-World Data
面向真实非受控数据的深度学习强鲁棒性对齐工具
📖 Introduction
FlexAligner is a robust speech-text alignment framework built upon wav2vec 2.0. It is designed for real-world linguistic data, where audio signals and textual transcriptions may contain noise, hesitations, untranscribed events, or local mismatches.
FlexAligner decomposes forced alignment into two stages:
- Macro-Segmentation (CTC Chunking): Uses a CTC acoustic model to locate reliable transcript anchors and divide long-form audio into ordered chunks.
- Micro-Alignment (Local Alignment): Uses a constrained pronunciation graph and two-pass Viterbi decoding to estimate word and phone boundaries within each chunk.
🌟 Key Features
- 🛡️ Tolerance to Mismatch: Uncovered portions of the audio timeline are
represented explicitly as
NULLintervals instead of being silently forced into neighboring words or phones. - 🎯 Word and Phone Boundaries: Produces Praat TextGrid files with continuous
wordsandphonestiers while preserving the input word order. - 🔒 Local and Reproducible: Explicit model paths remain fully local. When model paths are omitted, the CLI validates the selected pinned language bundle in the Hugging Face cache and asks before downloading it. Language-specific OOV pronunciations are generated locally and always reported as CLI warnings.
- 📦 Python Package and CLI: Provides a typed Python API and a command-line interface for single-file alignment.
The 0.3.0a1 preview provides English and Mandarin CPU single-file
alignment, optional local OOV G2P language packs, jieba segmentation for
Mandarin, and an optional audio conversion frontend. GPU, batch processing, Web
services, and confidence calibration remain reserved interfaces.
🌏 简介
FlexAligner 是一个基于 wav2vec 2.0 的语音—文本对齐框架,面向真实语言材料中 常见的噪音、停顿、未转写声音事件以及音频与文本局部不一致等问题。
FlexAligner 将强制对齐分为两个阶段:
- 宏观切分(CTC Chunking): 使用 CTC 声学模型寻找可靠的文本锚点,并将长音频 划分为顺序一致的局部片段。
- 微观对齐(Local Alignment): 在每个片段内构建受约束的发音图,通过两遍 Viterbi 解码估计词和音素边界。
🌟 核心优势
- 🛡️ 容错设计: 对未被词或音素覆盖的时段使用明确的
NULL区间表示,避免将其 静默挤压到相邻标签中。 - 🎯 词与音素边界: 输出 Praat TextGrid,
words和phones两层连续覆盖完整 音频时间轴,同时保持输入词序。 - 🔒 本地与可复现: 显式模型路径始终只在本地使用。未指定模型路径时,CLI 会先 校验 Hugging Face 默认缓存中所选语言的固定模型;缓存缺失时必须获得用户确认才会 下载。不同语言的 OOV 发音均在本地生成,CLI 每次都会明确输出 warning。
- 📦 Python 包与 CLI: 提供带类型定义的 Python API 和单文件命令行接口。
0.3.0a1 预览版提供英语与普通话 CPU 单文件对齐、可选的本地 OOV G2P 语言包、
普通话 jieba 分词,以及可选音频转换前端。GPU、批处理、Web 服务和置信度校准仍为
预留接口。
🏗️ Architecture
graph TD
Input[Input: PCM16 WAV + Transcript] --> Lexicon[Local Pronunciation Lexicon];
Lexicon --> B[Stage 1: CTC Chunking];
B --> C{Reliable Ordered Chunks};
C --> D[Stage 2: Pronunciation Graph];
D --> E[Two-pass Viterbi Decoding];
E --> F[Words + Phones + NULL TextGrid];
🚀 Installation
The import-safe core package targets Python 3.10–3.14. The frozen inference extra pins Torch 2.3.1 and Transformers 4.41.2 and is installable on Python 3.10–3.12. Real-model release evidence currently covers only Linux x86_64 with Python 3.10.8; Python 3.13–3.14 are core-only.
Install the 0.3.0a1 preview with English local OOV G2P and the frozen
inference stack:
python -m pip install "flexaligner[inference,en]==0.3.0a1"
For a CPU-only Linux environment, install the frozen Torch build from its CPU index first:
python -m pip install torch==2.3.1 --index-url https://download.pytorch.org/whl/cpu
python -m pip install "flexaligner[inference,en]==0.3.0a1"
To work from a reviewed source checkout:
git clone https://github.com/USTCPhonetics/FlexAligner.git
cd FlexAligner
python -m pip install -e ".[inference]"
The minimal package does not contain the English G2P checkpoint and does not
install Mandarin segmentation/G2P or audio conversion dependencies. Add only
the incremental capabilities you need. For a source checkout, install the
English language pack before selecting [en]:
# English local OOV G2P: separately packaged checkpoint
python -m pip install -e packages/flexaligner-g2p-en
python -m pip install -e ".[inference,en]"
# Mandarin alignment: inference stack + jieba + pypinyin
python -m pip install -e ".[inference,zh]"
# Add explicit decoding, resampling and PCM16 WAV conversion
python -m pip install -e ".[inference,zh,audio]"
The package does not include acoustic-model weights. The CLI can retrieve the
selected pinned en or zh bundle into the standard Hugging Face cache after
explicit confirmation. A pronunciation dictionary is still required; local G2P
is used only for words missing from that dictionary.
基础包支持 Python 3.10–3.14。首个 alpha 的推理依赖固定为 Torch 2.3.1 和
Transformers 4.41.2,仅支持在 Python 3.10–3.12 上安装;真实模型发布验证目前仅覆盖
Linux x86_64 与 Python 3.10.8。Python 3.13–3.14 暂时只承诺基础包和接口可用。
wheel 不包含声学模型权重。最小安装也不包含英语 G2P checkpoint、jieba、
pypinyin 或 PyAV;英语本地 G2P 使用 [en] extra 和独立
flexaligner-g2p-en distribution,普通话能力使用 [zh] extra,转码与重采样使用
[audio] extra。CLI 可在用户明确确认后,把固定的 en 或 zh 模型下载到标准
Hugging Face 缓存。发音词典仍必须由用户提供;本地 G2P 只处理词典 OOV,已有词典
条目始终优先。
💻 Usage
1. Command Line Interface (CLI)
Align one English 16 kHz mono PCM16 WAV file. If both model options are omitted,
the CLI first checks the default Hugging Face cache. On a cache miss in an
interactive terminal, it asks for download consent, cache directory (press
Enter for the default), and source (the default is hf-mirror.com; choose
official for huggingface.co):
flexaligner align \
--audio recording.wav \
--text-file transcript.txt \
--lexicon english.dict \
--output recording.TextGrid \
--chunk-metadata recording.alignment.json \
--num-threads 1
To fetch models before alignment, including in automation, run:
flexaligner models fetch
flexaligner models fetch --yes --model-source mirror
flexaligner models fetch --yes --model-source official \
--model-cache-dir /data/huggingface/hub
flexaligner models fetch --language zh --yes --model-source official
The downloader pins release v0.2.0a1 to the immutable commit
f9ca09d445e5e8981e43eca6a2f5421526ddc59e, requests only the twelve files for
the selected language, disables implicit token use, and validates the built-in manifest
hash plus every file size and SHA-256. It never falls back from one endpoint to
another. A non-interactive cache miss fails with model_cache_miss unless
--yes explicitly authorizes downloading. An incomplete or hash-invalid cache
fails closed without --yes; explicit models fetch --yes force-downloads the
pinned files and accepts the repaired cache only after the complete 12-file
size and SHA-256 validation passes again.
To bypass cache resolution and all network behavior, provide both
--chunker-model and --aligner-model. Providing only one is an error.
The CLI defaults to --pronunciation-mode g2p. Explicit dictionary entries are
never replaced or written back. Each generated OOV pronunciation emits one
structured WARNING on stderr with the word, occurrence indices, phones, and
G2P engine version. Use --pronunciation-mode lexicon for strict dictionary-only
behavior; an OOV then fails before inference. English OOV generation requires
the [en] extra. Its separately packaged checkpoint performs no network access
and supports normalized ASCII English words only. If the extra is absent, only
an actual English OOV request fails with optional_dependency_missing.
Mandarin alignment uses --language zh. The [zh] extra segments unspaced text
with jieba; user-supplied whitespace remains a hard segmentation boundary.
The current Mandarin model uses sil and has no sph output category, so the
Mandarin Stage 2 graph never creates optional sph states:
flexaligner align \
--language zh \
--audio mandarin.wav \
--text-file mandarin.txt \
--lexicon mandarin.dict \
--output mandarin.TextGrid
The Mandarin G2P fallback uses local, tone-free initial/final phones compatible with the current model vocabulary. Polyphonic-word quality is not claimed; provide an explicit dictionary entry whenever pronunciation matters.
The optional [audio] extra provides explicit conversion and opt-in alignment
policies while the default remains strict PCM16 WAV:
flexaligner audio convert input.flac canonical.wav
flexaligner align ... --audio-policy auto-resample # WAV input only
flexaligner align ... --audio-policy multi-format # explicit PyAV decoding
未指定两项模型参数时,CLI 会先检查默认 Hugging Face 缓存。交互终端发现缓存缺失后,
依次询问是否下载、缓存目录(直接回车使用默认目录)和下载来源(默认使用国内可访问的
hf-mirror.com,也可选择 official)。非交互环境不会自行下载,必须提前执行
flexaligner models fetch --yes。显式同时提供 --chunker-model 和
--aligner-model 时,会完全绕过缓存与网络;只提供其中一项会报错。
残缺或 hash 不匹配的 cache 在普通命令下会关闭式失败;只有显式执行
flexaligner models fetch --yes 才会强制重新下载,且必须再次通过完整 12 文件的
size 与 SHA-256 校验后才能使用。
CLI 默认使用 --pronunciation-mode g2p。显式词典条目不会被覆盖或写回文件;每个由
G2P 生成的 OOV 发音都会在 stderr 输出一条结构化 WARNING,包含词、出现位置、音素
和引擎版本。需要严格词典模式时使用 --pronunciation-mode lexicon,此时 OOV 会在
推理前失败。英语 OOV 生成需要 [en] extra;checkpoint 位于独立的
flexaligner-g2p-en distribution,不联网,当前只接受规范化后的 ASCII 英语词。
未安装 [en] 时,只有真实发生英语 OOV G2P 请求才返回
optional_dependency_missing;完整词典对齐不受影响。
普通话使用 --language zh。[zh] extra 通过 jieba 对无空格文本分词,用户已有的
空格边界不会被跨越;本地 pypinyin G2P 只为词典 OOV 生成与当前模型兼容的无声调
initial/final,并输出结构化 warning。多音字质量不作保证,重要发音应写入用户词典。
当前普通话模型包含 sil、不包含 sph,因此普通话 Stage 2 不构建任何可选 sph
状态。若文本、词典或模型与 --language 明显不匹配,程序会在推理前返回
language_mismatch。
[audio] extra 提供显式 audio convert、auto-resample 和 multi-format 能力;
默认输入契约仍是严格的 16 kHz 单声道 PCM16 WAV,不会静默转换。
Literal transcript text may be passed with --text instead of --text-file.
--num-threads configures Torch's process-global CPU thread count for the
inference lifetime; it is not isolated to a single aligner instance.
Use the capability command to inspect the installed preview:
flexaligner capabilities
flexaligner capabilities --json
2. Python API
from pathlib import Path
from flexaligner import (
AlignmentRequest,
AlignmentOptions,
FlexAligner,
LocalModelBundle,
PronunciationMode,
TextGridOutput,
)
models = LocalModelBundle(
chunker_dir=Path("/local/models/en/chunker"),
aligner_dir=Path("/local/models/en/aligner"),
)
with FlexAligner(
models=models,
lexicon_path=Path("english.dict"),
) as aligner:
result = aligner.align(
AlignmentRequest(
audio_path=Path("recording.wav"),
transcript=Path("transcript.txt").read_text(encoding="utf-8"),
output=TextGridOutput(path=Path("recording.TextGrid")),
utterance_id="recording",
),
options=AlignmentOptions(pronunciation_mode=PronunciationMode.G2P),
)
print(result.output_sha256)
Input Requirements / 输入要求
-
Audio must be uncompressed 16 kHz mono PCM16 WAV unless an optional audio policy is explicitly selected.
-
The transcript and dictionary must be UTF-8 and match
--language. CLI G2P mode may fill dictionary OOVs with warnings; strict mode and the Python default require full coverage. -
Models must resolve to validated local directories before inference; the dictionary must be available locally.
-
Output paths use no-clobber semantics: an existing output file is not overwritten.
-
除非显式选择
[audio]提供的策略,音频必须是未压缩的 16 kHz 单声道 PCM16 WAV。 -
文本和词典必须为 UTF-8,并与
--language一致。CLI G2P 模式可在 warning 后填补 词典 OOV;严格模式和 Python API 默认模式仍要求词典完整覆盖。 -
推理开始前模型必须解析为已校验的本地目录;词典必须提前保存在本地。
-
输出采用不覆盖已有文件的策略;若目标文件已存在,程序不会将其覆盖。
-
--num-threads会设置 Torch 的进程全局 CPU 线程数,并非仅对单个 aligner 实例生效。
🗓️ Roadmap
- Core Alignment Engine: Two-stage CTC chunking and local alignment.
- English CPU Single-File Alignment: CLI, Python API, and validated TextGrid output.
- Continuous TextGrid Coverage:
wordsandphonestiers useNULLintervals to cover the complete timeline. - Mandarin Development Path: Current models,
jiebasegmentation, lexicon-first local G2P,sil-only Stage 2, and real-sample validation. - GPU and Batch Processing: Accelerated and high-throughput workflows.
- Optional Audio Frontend: Explicit PyAV decoding, resampling and canonical PCM16 WAV conversion in the development tree.
- Validated English Model Retrieval: Pinned cache lookup, confirmed download, mirror/official selection, and manifest/hash verification.
- Local English OOV G2P: Lexicon-first ARPAbet fallback with structured CLI warnings and strict vocabulary validation.
- PyPI Public Alpha:
flexaligner==0.2.0a1is published with validated model retrieval and local English OOV G2P.
👨💻 Authors & Affiliation
Yiming Wang (王一鸣) - University of Science and Technology of China (USTC)
Jiahong Yuan (袁家宏) - University of Science and Technology of China (USTC)
📜 Citation
If you use FlexAligner in your research, please cite:
@misc{flexaligner2026,
title = {FlexAligner: Robust Speech--Text Alignment via CTC Chunking and Local Cross-Entropy Alignment},
author = {Wang, Yiming and Yuan, Jiahong},
year = {2026},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/USTCPhonetics/FlexAligner}},
organization = {University of Science and Technology of China}
}
📄 License
FlexAligner is released under the MIT License. Please refer to the
repository's LICENSE file for the authoritative license and copyright notice.
The optional flexaligner-g2p-en distribution contains the checkpoint derived
from g2p-en 2.1.0 under Apache-2.0, together with its license and provenance
notice. The minimal MIT-licensed flexaligner wheel does not contain that asset.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flexaligner-0.3.0a1.tar.gz.
File metadata
- Download URL: flexaligner-0.3.0a1.tar.gz
- Upload date:
- Size: 72.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0a6eed5626e759d547eaebcdb456f381cbeb850ce3c1d69728e71de0dae331c
|
|
| MD5 |
db13b0077037d7ac765cce59d579924a
|
|
| BLAKE2b-256 |
2d57cf2243b3a538ded496c0819ed7e4390386e48c6548f3c3e11a708c8f90ea
|
Provenance
The following attestation bundles were made for flexaligner-0.3.0a1.tar.gz:
Publisher:
release.yml on USTCPhonetics/FlexAligner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flexaligner-0.3.0a1.tar.gz -
Subject digest:
c0a6eed5626e759d547eaebcdb456f381cbeb850ce3c1d69728e71de0dae331c - Sigstore transparency entry: 2579709743
- Sigstore integration time:
-
Permalink:
USTCPhonetics/FlexAligner@97da48f6bb55af6c978c4fc6e770580821ccc346 -
Branch / Tag:
refs/tags/v0.3.0a1 - Owner: https://github.com/USTCPhonetics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@97da48f6bb55af6c978c4fc6e770580821ccc346 -
Trigger Event:
push
-
Statement type:
File details
Details for the file flexaligner-0.3.0a1-py3-none-any.whl.
File metadata
- Download URL: flexaligner-0.3.0a1-py3-none-any.whl
- Upload date:
- Size: 83.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44131f3dc21a1656608a38665b309d4f54731da175759286393c7b0055946314
|
|
| MD5 |
441d6295bfc74fcd45388a2a1df98a1b
|
|
| BLAKE2b-256 |
b374f735dd95dfea6ea0de0afc945f40f1da9862d95399cd8fb26fa43f85577a
|
Provenance
The following attestation bundles were made for flexaligner-0.3.0a1-py3-none-any.whl:
Publisher:
release.yml on USTCPhonetics/FlexAligner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flexaligner-0.3.0a1-py3-none-any.whl -
Subject digest:
44131f3dc21a1656608a38665b309d4f54731da175759286393c7b0055946314 - Sigstore transparency entry: 2579709749
- Sigstore integration time:
-
Permalink:
USTCPhonetics/FlexAligner@97da48f6bb55af6c978c4fc6e770580821ccc346 -
Branch / Tag:
refs/tags/v0.3.0a1 - Owner: https://github.com/USTCPhonetics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@97da48f6bb55af6c978c4fc6e770580821ccc346 -
Trigger Event:
push
-
Statement type: