Metadata-Version: 2.4
Name: minicpmo-utils
Version: 1.0.7
Summary: Unified utilities package for MiniCPM-o: includes stepaudio2 and extensible utils.
Author: MiniCPM-o Utils Maintainers
License: Apache-2.0
Keywords: minicpmo,audio,tts,utils,token2wav
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24.0
Requires-Dist: pillow==10.4.0
Requires-Dist: librosa==0.9.0
Requires-Dist: decord==0.6.0; sys_platform != "darwin"
Requires-Dist: eva-decord; sys_platform == "darwin"
Requires-Dist: moviepy==2.1.2
Provides-Extra: tts
Requires-Dist: torch>=2.3.0; extra == "tts"
Requires-Dist: torchaudio>=2.3.0; extra == "tts"
Requires-Dist: transformers<4.53.0,>=4.51.0; extra == "tts"
Requires-Dist: onnxruntime<=1.21.0,>=1.18.0; extra == "tts"
Requires-Dist: onnx; extra == "tts"
Requires-Dist: hyperpyyaml; extra == "tts"
Requires-Dist: tqdm>=4.66.0; extra == "tts"
Requires-Dist: einops==0.8.1; extra == "tts"
Requires-Dist: scipy>=1.10.0; extra == "tts"
Requires-Dist: soundfile==0.12.1; extra == "tts"
Provides-Extra: all
Requires-Dist: minicpmo-utils[tts]; extra == "all"

# minicpmo-utils

MiniCPM-o 工具包，包含 Step-Audio2 Token2wav 等音频处理组件。

## 安装

要求 Python 3.10 或更新版本。Token2wav 推理需要支持 CUDA 的 PyTorch 和匹配的 torchaudio。

从源码安装公共依赖：

```bash
python -m pip install -e .
```

安装 TTS 依赖或全部依赖：

```bash
python -m pip install -e ".[tts]"
# 或
python -m pip install -e ".[all]"
```

构建并安装 wheel：

```bash
python -m pip install build
python -m build
python -m pip install "dist/minicpmo_utils-1.0.7-py3-none-any.whl[tts]"
```

## Token2wav

Token2wav 将 Step-Audio2 语音 token 转换为 24 kHz 单声道音频，支持整句合成和流式解码。

### 准备模型文件

权重需单独准备，模型目录包含以下文件：

| 文件 | 用途 |
|---|---|
| `speech_tokenizer_v2_25hz.onnx` | 参考音频的语音 token 提取 |
| `campplus.onnx` | 说话人特征提取 |
| `flow.yaml`、`flow.pt` | Flow Matching 配置与权重 |
| `config.yaml`、`hift.pt` | 流式 CosyVoice3 causal vocoder 配置与权重 |
| `hift_original.pt` | 整句合成使用的 HiFT 权重 |

配置与对应权重须匹配。流式 vocoder 使用 24 kHz、80 维 mel、480 samples/frame、`fmax=8000` 的配置。

### 初始化

`model_path` 指向包含上述文件的本地权重目录，请将示例路径替换为实际路径。

```python
from stepaudio2 import Token2wav

decoder = Token2wav(
    model_path="./models/token2wav",
    float16=False,
    n_timesteps=10,
)
```

`float16` 控制 FM 是否使用半精度；`n_timesteps` 设置 FM 推理步数，必须为正整数。

### 整句合成

`speech_tokens` 是上游模型生成的语音 token ID 列表，`prompt_wav` 是参考音频路径。
整句接口返回完整 WAV 文件的字节内容，可直接写入文件：

```python
from pathlib import Path

prompt_wav = "./prompt.wav"
wav_bytes = decoder(speech_tokens, prompt_wav=prompt_wav)
Path("output.wav").write_bytes(wav_bytes)
```

### 流式解码

每个新流先调用 `set_stream_cache()`。常规非末块传入 25 个待解码 token 和
3 个 lookahead token，共 28 个；只消费前 25 个，末尾 3 个保留到下一次调用。
结束时将剩余 token 以 `last_chunk=True` 传入，释放尾部音频。

以下示例将已有 token 序列分块解码并保存为 WAV：

```python
import wave

decoder.set_stream_cache(prompt_wav)
parts = []
offset = 0
while len(speech_tokens) - offset > 28:
    parts.append(decoder.stream(speech_tokens[offset:offset + 28]))
    offset += 25
parts.append(decoder.stream(speech_tokens[offset:], last_chunk=True))

with wave.open("output_stream.wav", "wb") as output:
    output.setnchannels(1)
    output.setsampwidth(2)
    output.setframerate(24000)
    output.writeframes(b"".join(parts))
```

`stream()` 默认返回不含 WAV 文件头的 little-endian int16 PCM bytes。
传入 `return_waveform=True` 时，返回形状为 `(1, N)` 的 NumPy float32 数组，
保留未经裁剪、未经 int16 量化的波形。

末块可以传入空列表以释放尚未输出的尾音。完成 final 后，开始下一句或切换参考音频时，
需重新调用 `set_stream_cache(prompt_wav)`。
