Metadata-Version: 2.4
Name: kaldi-native-fbank-buffer
Version: 1.22.3
Home-page: https://github.com/csukuangfj/kaldi-native-fbank
Author: Fangjun Kuang
Author-email: csukuangfj@gmail.com
License: Apache-2.0
Classifier: Programming Language :: C++
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.8.0
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: requires-python

# kaldi-native-fbank

`kaldi-native-fbank` 是一个不依赖外部数值计算库、与 Kaldi 数学实现兼容的在线
FBank 特征提取器。

项目已在 Linux、macOS、Windows 和 Android 上使用，并支持 x86、x86_64、ARM
及 aarch64。

## C++ 使用方式

以下项目使用 `kaldi-native-fbank` 为实时语音识别计算特征：

- [sherpa-ncnn](https://github.com/k2-fsa/sherpa-ncnn)，可参考其中的
  [features.h](https://github.com/k2-fsa/sherpa-ncnn/blob/master/sherpa-ncnn/csrc/features.h)
- [sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx)

本仓库使用 CMake 构建。默认配置会同时构建 C++ core、Python 扩展和测试：

```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build --output-on-failure
```

## Python 安装

可以从 PyPI 安装：

```bash
python3 -m pip install kaldi-native-fbank-buffer
```

也可以构建并安装当前源码：

```bash
git clone https://github.com/csukuangfj/kaldi-native-fbank
cd kaldi-native-fbank
python3 -m pip install .
```

安装后可检查版本和模块位置：

```bash
python3 -c "import kaldi_native_fbank as knf; print(knf.__version__, knf.__file__)"
```

PyPI distribution 名称为 `kaldi-native-fbank-buffer`，Python import 名称继续使用
`kaldi_native_fbank`，以兼容原有调用代码。

## 高性能 Python Buffer API

`OnlineFbank.accept_waveform_and_get_frames()` 在一次 native 调用中接收 PCM 并返回
本次新产生的所有帧。它避免 Python Sequence 逐元素转换、逐帧 `get_frame()` 和
`numpy.vstack()`。

```python
import numpy as np
import kaldi_native_fbank as knf

sample_rate = 16000
opts = knf.FbankOptions()
opts.frame_opts.dither = 0
opts.frame_opts.snip_edges = False
opts.mel_opts.num_bins = 80

stream = knf.OnlineFbank(opts)
waveform = np.zeros(sample_rate, dtype=np.int16)

outputs = []
chunk_samples = sample_rate // 10
for offset in range(0, waveform.size, chunk_samples):
    features = stream.accept_waveform_and_get_frames(
        sample_rate,
        waveform[offset : offset + chunk_samples],
    )
    outputs.append(features)

# 空 buffer 的 final 调用会 flush 尾部帧。
outputs.append(
    stream.accept_waveform_and_get_frames(
        sample_rate,
        waveform[:0],
        is_final=True,
    )
)
```

输入要求：

- 实现 Python buffer protocol 的一维、C-contiguous 数据；
- dtype 必须是 native-endian `numpy.float32` 或 `numpy.int16`；
- 非连续 view、二维数据及其他 dtype 会直接报错，不会静默复制或转换；
- `int16` 按整数原值转换为 `float32`，不会除以 32768。这与旧接口接收
  `int16_array.tolist()` 的数值语义一致。

返回值始终是拥有独立内存、C-contiguous 的二维 `numpy.float32` 数组，shape 为
`[num_new_frames, stream.dim]`。没有新帧时 shape 为 `[0, stream.dim]`。

耗时的 int16 转换、FBank 计算和帧物化均释放 Python GIL。不同
`OnlineFbank` 实例可以由不同 Python 线程真正并行处理；同一实例内部串行保护，
调用方仍应按音频顺序提交 chunk。

`is_final=True` 后不再接受非空输入。可以使用 `stream.reset()` 清空 native 在线
状态、frame cursor 和 final 状态，然后复用相同配置。已经返回的批量 NumPy 数组
拥有自己的内存，不受后续调用、`reset()` 或 stream 析构影响。

## 旧 Python API 兼容性

原有 list API 保持可用：

```python
stream = knf.OnlineFbank(opts)
stream.accept_waveform(sample_rate, waveform.astype(np.float32).tolist())
stream.input_finished()
frames = [stream.get_frame(i) for i in range(stream.num_frames_ready)]
```

`OnlineMfcc`、`OnlineWhisperFbank` 和 `OnlineRawAudioSamples` 的现有接口没有改变。

## 正确性与性能验证

高性能接口测试覆盖 int16/float32、不同 chunk 大小、整段输入、空输入、final
flush、短尾、`snip_edges`、reset、非法 buffer、多 session 和多线程生命周期：

```bash
python3 kaldi-native-fbank/python/tests/test_online_fbank_buffer.py
```

32 路并发 benchmark 会保存逐轮 JSONL，而不只输出汇总表：

```bash
python3 benchmarks/online_fbank_buffer_benchmark.py \
  --api buffer \
  --dtype int16 \
  --sessions 32 \
  --seconds 60 \
  --chunk-ms 100 \
  --workers 1 2 4 8 16 \
  --warmups 1 \
  --runs 3 \
  --output benchmarks/results/local.jsonl
```

脚本记录 Git revision、编译参数、CPU、Python/pybind11 版本、每轮 makespan、帧数、
吞吐率和 RSS。仓库中的 `benchmarks/results/` 保存了本次优化的原始测量结果。

## 许可证

本项目使用 [Apache License 2.0](LICENSE)。
