Metadata-Version: 2.4
Name: fasr-asr-qwen3
Version: 0.5.1
Summary: Qwen3 ASR model for fasr
Author-email: fasr <790990241@qq.com>
Requires-Python: <3.13,>=3.10
Description-Content-Type: text/markdown
Requires-Dist: fasr
Requires-Dist: transformers==4.57.6
Requires-Dist: nagisa==0.2.11
Requires-Dist: soynlp==0.0.493
Requires-Dist: accelerate==1.12.0
Requires-Dist: vllm==0.14.0
Requires-Dist: librosa
Requires-Dist: soundfile

# fasr-asr-qwen3

内置 Qwen3-ASR 推理（Transformers / vLLM）的语音识别模型插件，为 fasr 提供无时间戳 ASR 能力。

## 安装

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

## 注册模型

| 注册名 | 类 | 默认 checkpoint | 说明 |
|---|---|---|---|
| `qwen3_0_6b` | `Qwen3_06BForASR` | `Qwen/Qwen3-ASR-0.6B` | 离线 ASR，当前不返回时间戳 |
| `qwen3_1_7b` | `Qwen3_17BForASR` | `Qwen/Qwen3-ASR-1.7B` | 离线 ASR，当前不返回时间戳 |
| `stream_qwen3_0_6b` | `Qwen3_06BForStreamASR` | `Qwen/Qwen3-ASR-0.6B` | 流式 ASR（vLLM 后端），每 `chunk_size_ms` 重新解码一次 |
| `stream_qwen3_1_7b` | `Qwen3_17BForStreamASR` | `Qwen/Qwen3-ASR-1.7B` | 流式 ASR（vLLM 后端），每 `chunk_size_ms` 重新解码一次 |

## 使用方式

```python
from fasr import AudioPipeline

pipeline = (
    AudioPipeline()
    .add_pipe("detector", model="fsmn")
    .add_pipe("recognizer", model="qwen3_1.7b")  # 或 qwen3_0.6b
    .add_pipe("sentencizer", model="ct_transformer")
)
```

### 单独使用模型

模型实例化时会自动执行 `download_checkpoint()` + `load_checkpoint()`：

```python
from fasr.config import registry

model = registry.asr_models.get("qwen3_1.7b")(gpu_memory_utilization=0.6)
# or model.load_checkpoint("/path/to/custom/qwen3")
```

## 运行期 / 会话参数

| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| `checkpoint` | `str \| None` | 子类各自默认 | 远程 repo_id；非空时实例化会自动下载到 `cache_dir` |
| `cache_dir` | `str \| Path \| None` | `None` | 缓存目录，`None` 使用 `fasr.utils.get_cache_dir()` |
| `endpoint` | `Literal["modelscope", "huggingface", "hf-mirror"]` | `"modelscope"` | 下载端点 |
| `max_new_tokens` | `int` | `4096` | 最大生成 token 数 |
| `max_inference_batch_size` | `int` | `-1` | vLLM 推理批次上限，`-1` 不限制 |
| `gpu_memory_utilization` | `float` | `0.8` | vLLM 可占用的 GPU 显存比例，`(0, 1]` |
| `max_model_len` | `int \| None` | `None` | vLLM `max_model_len`；`None` 回退为 `max_new_tokens * 2` |

## 流式使用（StreamASR）

`stream_qwen3_*` 实现了 `ASRModel.push_chunk`，接在流式 VAD 之后即可：

```python
from fasr.config import registry

model = registry.stream_asr_models.get("stream_qwen3_0_6b")(
    chunk_size_ms=2000,
    language="zh",          # 可选：强制语种
)
for chunk in audio_chunk_stream:
    span = model.push_chunk(chunk)
    if span is not None:
        print(span.text, flush=True)
```

> 注意：Qwen3-ASR 流式本质是“累计音频重解码”，每个 chunk 返回的是
> 当前累计结果（`AudioSpan.raw_text`）。后续 chunk 可能会改写前文，
> 所以上层消费应采用“覆盖显示最新文本”，而不是拼接增量 delta。

## 输出说明

- 当前模型不返回词级/字级时间戳。
- 离线模式把整段识别文本写入 `span.raw_text`（`span.text` 即可访问）；
  流式模式每个 chunk 都返回当前累计文本（`AudioSpan(raw_text=...)`），
  最后一个 chunk 的返回带 `is_last=True`。
