Metadata-Version: 2.4
Name: fasr
Version: 0.5.0.post0
Summary: FASR: Fast Automatic Speech Recognition Pipeline
Author-email: osc <790990241@qq.com>
Requires-Python: <3.13,>=3.10
Requires-Dist: aiohttp>=3.10.10
Requires-Dist: catalogue>=2.0.10
Requires-Dist: confection>=0.1.5
Requires-Dist: docarray==0.40
Requires-Dist: editdistance>=0.8.1
Requires-Dist: huggingface-hub>=0.27.0
Requires-Dist: joblib>=1.4.2
Requires-Dist: jsonargparse[signatures,urls]>=4.38
Requires-Dist: kaldifst>=1.7.14
Requires-Dist: loguru>=0.7.2
Requires-Dist: modelscope>=1.19.1
Requires-Dist: nest-asyncio>=1.6.0
Requires-Dist: numpy>=1.24
Requires-Dist: protobuf>=3.20.0
Requires-Dist: pydantic>=2.9.2
Requires-Dist: soundfile>=0.12.1
Requires-Dist: soxr>=0.5.0
Requires-Dist: wasabi>=1.1.3
Provides-Extra: benchmark
Requires-Dist: pyaudio>=0.2.14; extra == 'benchmark'
Provides-Extra: litdata
Requires-Dist: litdata>=0.2.46; extra == 'litdata'
Description-Content-Type: text/markdown

![fasr logo](assets/logo.png)

# fasr

`fasr` 是一个面向生产场景的 Python 语音推理框架，专注于将语音处理能力以可组合、可扩展的方式落地到工程系统中。

它围绕 `AudioPipeline` 构建，支持将 VAD、ASR、标点恢复、语种识别等能力按组件自由编排，适用于离线转写、批处理任务和在线服务等场景。

核心特点：
- 插件化模型生态：能力按模型插件解耦，安装即注册，按需组合。
- 工程化流水线：统一数据结构与组件接口，便于维护和扩展。
- 高性能推理：组件异步执行，充分利用多核 CPU / GPU 资源。
- 面向生产：支持批量、流式与服务化部署，便于接入业务系统。

## 组件介绍

- `loader`：音频加载组件，负责读取本地或远程音频并构建 `Audio` 对象。
- `detector`：端点检测组件（VAD），将音频切分为语音片段（`segments`）。
- `recognizer`：语音识别组件（ASR），对每个语音片段进行转写。
- `sentencizer`：标点恢复与句子切分组件（Punc），将识别结果整理为可读文本。
- `identifier`：语言识别组件（LID，可选），用于多语言场景下识别语种。
- `custom`：支持通过 `add_pipe()` 注入自定义组件，扩展前后处理逻辑。

## 快速开始

fasr 的模型能力通过模型插件提供，需要先安装对应的插件包：

```bash
pip install fasr-vad-marblenet fasr-asr-qwen3
```

```python
import fasr
from fasr import AudioPipeline

# 加载流水线（首次运行会自动下载模型权重）
asr = (
    AudioPipeline()
    .add_pipe("detector", model="marblenet")
    .add_pipe("recognizer", model="qwen3_0_6b")
)

# 单条识别
audio = asr("example.wav")
for channel in audio.channels:
    print(channel.text)

# 批次识别
audios = asr.run(["1.wav", "2.wav", "3.wav"])
for audio in audios:
    for channel in audio.channels:
        print(channel.text)

# 流式返回（大批量场景，逐条 yield）
for audio in asr.stream(["1.wav", "2.wav", "3.wav"]):
    for channel in audio.channels:
        print(channel.text)
```

## 模型插件

fasr 通过模型插件机制加载组件能力，按任务安装对应插件后可自由组合流水线：

| 任务 | 插件包 | 典型模型 |
|---|---|---|
| VAD | `fasr-vad-marblenet` / `fasr-vad-fsmn` / `fasr-vad-firered` | `marblenet` / `fsmn` / `firered` |
| ASR | `fasr-asr-qwen3` / `fasr-asr-paraformer` / `fasr-asr-firered` / `fasr-asr-fun` | `qwen3_0_6b` / `paraformer` / `firered_aed` / `fun_asr_nano` |
| Punc | `fasr-punc-ct-transformer` | `ct_transformer` |
| LID | `fasr-lid-firered` | `firered` |

## 如何编写模型插件

fasr 的插件机制基于 [`catalogue`](https://github.com/explosion/catalogue)
+ Python entry points，**安装即注册，按需惰性导入**。一个最小的 VAD 插件骨架如下：

1. 继承对应任务的基类并用 `registry` 装饰器注册：

```python
# my_fasr_vad/models/vad.py
from fasr.models.vad_model import VADModel
from fasr.config import registry


@registry.vad_models.register("my_vad")
class MyVADModel(VADModel):
    def load_checkpoint(self, checkpoint_dir=None): ...
    def detect(self, audios): ...
```

2. 在插件包的 `pyproject.toml` 中声明 entry point，**group 名必须用下划线**
   （对应 `catalogue` 的 namespace `("fasr", "vad_models")` → `fasr_vad_models`）：

```toml
[project.entry-points."fasr_vad_models"]
my_vad = "my_fasr_vad.models.vad:MyVADModel"
```

   每个任务对应一个固定的 group 名：

   | 任务 | entry point group |
   |---|---|
   | ASR | `fasr_asr_models` |
   | 流式 ASR | `fasr_stream_asr_models` |
   | VAD | `fasr_vad_models` |
   | 流式 VAD | `fasr_stream_vad_models` |
   | 标点 | `fasr_punc_models` |
   | 语种识别 | `fasr_lid_models` |

   > 注意：**不要**写成 `fasr.vad_models`（点号），`catalogue` 只按下划线
   > 命名查找 entry point，点号写法会导致 `registry.resolve(cfg)` 找不到模型。
   > 如果注册名本身带点（例如 `stream_fsmn.onnx`），请用引号包起来：
   > `"stream_fsmn.onnx" = "..."`。

3. `pip install -e .`（或 `uv pip install -e .`）安装插件后，配置文件里
   `@vad_models = "my_vad"` 就会被 `fasr.load(cfg)` 自动发现，无需手动 `import`。
   其它插件的重型依赖（如 `torch`、`vllm`）不会被一同拉起，只有真正被配置引用的插件
   才会被导入。
