Metadata-Version: 2.3
Name: fasr-service-realtime
Version: 0.5.8
Summary: FastAPI realtime service plugin for fasr
Author: osc
Author-email: osc <790990241@qq.com>
Requires-Dist: fasr>=0.5.8
Requires-Dist: fastapi>=0.115.4
Requires-Dist: onnxruntime>=1.18.0
Requires-Dist: python-multipart>=0.0.20
Requires-Dist: speechgate-rs>=0.1.0
Requires-Dist: transformers>=4.47.0
Requires-Dist: uvicorn>=0.32.0
Requires-Dist: typer>=0.16.0
Requires-Dist: rich>=13.9.4
Requires-Python: >=3.10, <3.13
Description-Content-Type: text/markdown

# fasr-service-realtime

英文文档地址: [README_EN.md](README_EN.md)

fasr 的 FastAPI realtime 服务插件。

当前 realtime service 只保留 `realtime.fastapi.2pass`。它要求配置
`vad_model`，并且 `[service.asr_model]` 和 `[service.stream_asr_model]`
至少配置一个；`enhancement_model` 是可选的，配置时必须支持 streaming。
另外 service 内置了一个 QwenASR 风格的能量门控 `speech_gate`，默认在
`enhancement_model` 之前执行；如果没有配置 `enhancement_model`，它也会直接作用在
VAD/ASR 之前。它只把被判定为非保留窗口的音频置零，不删除 sample，因此不会影响
时间戳。`[service.enhancement_model]` 里的 `enhancement_strength` 只在配置了 enhancement model 时用于
把增强结果和门控后的原音做 wet/dry mixing。

## 注册入口

服务 entry point：

- `realtime.fastapi.2pass`

router entry point：

- `realtime.fastapi.2pass`

## CLI

```bash
fasr-service-realtime init --cfg realtime.cfg
fasr-service-realtime init \
  --cfg realtime.cfg \
  --vad fsmn_online \
  --asr paraformer \
  --stream-asr paraformer_online \
  --speech-gate energy
fasr-service-realtime init \
  --cfg realtime.cfg \
  --vad fsmn_online \
  --asr paraformer \
  --stream-asr paraformer_online \
  --punc ct_transformer

# init 默认会在每个参数上方写入 # 注释，方便理解参数作用；
# 如需生成纯配置文件，可以加 --no-comments。
fasr-service-realtime init --cfg realtime.cfg --no-comments

fasr-service-realtime serve --cfg realtime.cfg

fasr-service-realtime serve \
  --vad fsmn_online \
  --asr paraformer \
  --stream-asr paraformer_online \
  --host 0.0.0.0 \
  --port 8000

# 需要额外降噪时再加 --enhance
fasr-service-realtime serve \
  --vad fsmn_online \
  --asr paraformer \
  --stream-asr paraformer_online \
  --enhance rnnoise \
  --enhancement-strength 0.8
```

## 最小配置

```toml
[service]
@services = "realtime.fastapi.2pass"
host = "0.0.0.0"
port = 8000
debug_logging = false
cache_dir = null

[service.speech_gate]
@realtime_speech_gates = "energy"
speech_gate_before_enhancement = true

# 语音门控：ASR/降噪前的内置前处理，只衰减/静音，不删除采样点。
enabled = true

# 被判定为非语音的采样保留多少音量。升高会保留更多环境声、减少突兀静音；
# 降低会更彻底静音，0.0 表示完全静音。
attenuation = 0.0

# RMS 基础阈值。升高会更强地过滤低音量噪声，但可能切掉轻声说话；
# 降低会保留更轻的语音，但也更容易放过底噪。
base_thresh = 0.012

# 自适应噪声底之上的阈值倍率。升高会在嘈杂环境下更严格；
# 降低会更灵敏，适合轻声，但背景声更容易通过。
threshold_ratio = 2.0

[service.vad_model]
@vad_models = "fsmn_online"

[service.asr_model]
@asr_models = "paraformer"

[service.stream_asr_model]
@asr_models = "qwen3asr"
size = "large"
language = "Chinese"
hotwords = ["开锁", "转人工", "转人工服务"]
```

如需降噪，再额外添加：

```toml
[service.enhancement_model]
@enhancement_models = "deepfilternet"
enhancement_strength = 1.0
```

## 2Pass 配置说明

`realtime.fastapi.2pass` 可以用流式模型输出中间结果，用离线模型输出最终结果：

- `[service.asr_model]` 是可选的最终识别模型，配置后必须支持 batch `transcribe`
- `[service.stream_asr_model]` 是可选的中间结果模型，配置后必须支持 streaming `push_chunk`
- `[service.punc_model]` 是可选的最终标点恢复模型，只作用于 completed 最终文本
- `[service.asr_model]` 和 `[service.stream_asr_model]` 至少配置一个，服务不会隐式复用其中一个模型充当另一个角色
- 如果只配置 batch-only 的 `[service.asr_model]`，服务只在语音结束后返回最终结果，不返回中间结果
- 如果只配置 `[service.stream_asr_model]`，服务返回流式中间结果，并在模型输出 `is_last=True` 时返回 completed
- 如果 ASR 插件支持 `hotwords`，配置段中的热词是全站默认热词；`session.update` 中的热词会与它合并。对于 `qwen3asr`，合并后的热词会按官方 context 通道传给模型，但配置面只保留 `hotwords`

```toml
[service]
@services = "realtime.fastapi.2pass"
host = "0.0.0.0"
port = 8000
debug_logging = false
cache_dir = null

[service.speech_gate]
@realtime_speech_gates = "energy"
speech_gate_before_enhancement = true

# 语音门控：ASR/降噪前的内置前处理，只衰减/静音，不删除采样点。
enabled = true

# 被判定为非语音的采样保留多少音量。升高会保留更多环境声、减少突兀静音；
# 降低会更彻底静音，0.0 表示完全静音。
attenuation = 0.0

# RMS 基础阈值。升高会更强地过滤低音量噪声，但可能切掉轻声说话；
# 降低会保留更轻的语音，但也更容易放过底噪。
base_thresh = 0.012

# 自适应噪声底之上的阈值倍率。升高会在嘈杂环境下更严格；
# 降低会更灵敏，适合轻声，但背景声更容易通过。
threshold_ratio = 2.0

[service.vad_model]
@vad_models = "fsmn_online"

[service.asr_model]
@asr_models = "paraformer"

[service.stream_asr_model]
@asr_models = "paraformer_online"

[service.punc_model]
@punc_models = "ct_transformer"
```

如需降噪，再额外添加：

```toml
[service.enhancement_model]
@enhancement_models = "rnnoise"
enhancement_strength = 1.0
```

`speech_gate` 是 service 内置前置处理，不是 enhancement 插件。当前内置 `energy`。
默认 `energy` 只使用 10ms 窗口的 RMS 与自适应能量门限判断是否放行，参数更少、
更容易调。为了避免二值 gate 在真实人声里
产生“点点点”的硬切伪影，默认会填平 80ms 以内的语音中间短静音洞，并在边界做
5ms 淡入淡出。被过滤的片段只会衰减/静音，不会删除采样点，因此不会让后续时间戳
整体漂移。

扁平的 `serve --vad/--asr/--stream-asr/...` 只适合快速启动；
`--asr` 和 `--stream-asr` 至少填一个，`--enhance` 可选。
如果配置了 `--enhance` 且想降低降噪激进程度，可以额外传
`--enhancement-strength 0.7` 这类值。
如果需要模型专属参数，请改用配置文件。

`init` 默认等价于
`--vad silero --asr paraformer --stream-asr paraformer_online`，默认不写
`[service.enhancement_model]`，也默认不写 `[service.speech_gate]`。如果需要生成带
降噪模型默认参数的配置，可以显式传 `--enhance deepfilternet` 或
`--enhance rnnoise`；如果需要生成 speech gate 配置，可以显式传
`--speech-gate energy`。

如果需要一份仅最终结果或仅流式结果的配置，可以通过参数选择：

```bash
fasr-service-realtime init --cfg realtime-final.cfg --stream-asr none
fasr-service-realtime init --cfg realtime-stream.cfg --asr none
```

## Realtime API 文档

- 英文：[REALTIME_API.md](REALTIME_API.md)
- 中文：[REALTIME_API_ZH.md](REALTIME_API_ZH.md)

## Demo

启动后打开 `GET /demo`，可以直接做两类联调：

- realtime 页支持麦克风、屏幕共享和本地音频文件三种输入源；本地文件会按 chunk
  节奏推到 WebSocket，完整走 realtime 识别链路
- 页面可直接调 `enhancement_strength`、`threshold`、
  `silence_duration_ms`、`prefix_padding_ms` 和完整的 `speech_gate` 参数；
  每个可调参数旁边都有 `?` 说明按钮
- 降噪体验页支持上传文件测试 `/enhance`。如果没有配置 `enhancement_model`，
  接口仍会返回 WAV：有 `speech_gate` 时返回门控后的音频；两者都没有时返回原音并
  在服务端输出 warning。

## Client 示例

- Python client: [client.py](client.py)

调用 `/enhance`：

```bash
python services/fasr-service-realtime/client.py enhance input.wav output.wav \
  --server http://127.0.0.1:8000 \
  --enhancement-strength 0.8
```

如果省略 `output.wav`，客户端会优先使用服务端 `Content-Disposition` 返回的文件名：

```bash
python services/fasr-service-realtime/client.py enhance input.wav \
  --server http://127.0.0.1:8000
```
