---
language: ja
license: apache-2.0
library_name: onnx
---
# karin v1 — 日本語母音検出 ONNX モデル
日本語音声からフレーム単位(20ms)で母音ラベルを推定する軽量 ONNX モデルです。\
VOICEROID / AivisSpeech 等のリップシンク非対応 TTS にリップシンクを後付けする用途を想定しています。\
ブラウザ完結(onnxruntime-web)で動作する 11.25 MB の fp16 モデルです。
## 仕様
本モデルの入出力・サイズ等の主要仕様は以下のとおりです。
| 項目 | 値 |
| --- | --- |
| 入力 | `wav` — `[batch, samples]` float32, 16 kHz mono, 値域 [-1, 1] |
| 出力 | `logits` — `[1, T, 8]` float32(T = samples // 320 + 1) |
| クラス | `a i u e o N cons pau`(後述) |
| フレーム長 | 20 ms(hop 320 サンプル @ 16 kHz) |
| パラメータ数 | 4.51M |
| ファイルサイズ | 11.25 MB(fp16) |
- メル特徴量抽出と CMVN(発話単位正規化)は ONNX グラフ内部にあります。\
ブラウザ側で特徴量計算は不要で、生の 16 kHz mono 波形をそのまま入力できます。
- 入出力テンソルは float32 です(fp16 は重みのみ)。
- 1 発話ずつ入力します(出力は常に batch=1)。
## クラス
出力 logits の 8 クラスは以下のとおりです。
| Index | ラベル | 説明 |
| --- | --- | --- |
| 0 | `a` | 母音 /a/ |
| 1 | `i` | 母音 /i/ |
| 2 | `u` | 母音 /u/ |
| 3 | `e` | 母音 /e/ |
| 4 | `o` | 母音 /o/ |
| 5 | `N` | 撥音 /N/ |
| 6 | `cons` | 子音(促音 cl 含む) |
| 7 | `pau` | 無音・休止 |
リップシンク用途では `cons` を直後の母音ランへ吸収する後処理が推奨されます。\
口の動きから子音は視覚上ほぼ識別できず、母音境界を連結することで母音間の遷移が滑らかになります。
## 使い方
Python(onnxruntime)と JavaScript(onnxruntime-web)での最小推論例を示します。
### Python(onnxruntime)
```python
import numpy as np
import onnxruntime as ort
import librosa
LABELS = ["a", "i", "u", "e", "o", "N", "cons", "pau"]
session = ort.InferenceSession("karin_vowel_v1_fp16.onnx")
wav, _ = librosa.load("input.wav", sr=16000, mono=True)
logits = session.run(None, {"wav": wav[None, :].astype(np.float32)})[0]
frames = logits[0].argmax(axis=-1) # (T,) クラス index
labels = [LABELS[i] for i in frames] # 20ms ごとのラベル列
```
### JavaScript(onnxruntime-web)
```javascript
import * as ort from "onnxruntime-web";
const LABELS = ["a", "i", "u", "e", "o", "N", "cons", "pau"];
const session = await ort.InferenceSession.create("karin_vowel_v1_fp16.onnx");
// wav: 事前に取得した Float32Array (16 kHz mono, [-1, 1])
const tensor = new ort.Tensor("float32", wav, [1, wav.length]);
const { logits } = await session.run({ wav: tensor });
// logits.data は Float32Array (row-major, shape = [1, T, 8])
const T = logits.dims[1];
const frames = new Array(T);
for (let t = 0; t < T; t++) {
let best = 0;
for (let c = 1; c < 8; c++) {
if (logits.data[t * 8 + c] > logits.data[t * 8 + best]) best = c;
}
frames[t] = best;
}
const labels = frames.map(i => LABELS[i]); // 20ms ごとのラベル列
```
## 性能評価
`vowel_only_acc` は母音フレーム(a/i/u/e/o/N)のみで計算したフレーム単位精度です。\
JSUT は本 ONNX の学習に使用していないドメイン、AivisHub は学習データと同一ドメインでの評価です。
| Domain | Frames | acc | macro_f1 | vowel_f1 | vowel_only_acc |
| --- | --- | --- | --- | --- | --- |
| JSUT basic5000 (実音声) | 92,859 | 0.9081 | 0.8839 | 0.8854 | 0.9102 |
| AivisHub 合成 TTS | 175,259 | 0.8107 | 0.7600 | 0.7750 | 0.8692 |
## 学習データ
本モデルの学習に使用したコーパス・音声リソースは以下のとおりです。
- ReazonSpeech small
- つくよみちゃんコーパス Vol.1
- あみたろのITAコーパス読み上げ音声
- AivisHub の ACML 1.0 / CC0 公開モデルによる合成音声
JSUT は教師プローブの学習 GT と評価用にのみ使用しており、本 ONNX の学習には使用していません。\
詳細な出典・ライセンスは `NOTICE` ファイルを参照してください。
## ライセンス
Apache License 2.0
学習データのライセンス・出典は `NOTICE` ファイルに集約してあります。
## クレジット・謝辞
本モデルの学習に使用したリソース提供元への謝辞を以下に示します。
- あみたろのITAコーパス読み上げ音声()
- つくよみちゃんコーパス()
- ReazonSpeech()
- AivisHub()
## 組み込みアプリへのお願い
配布時には同梱の `NOTICE` ファイルの内容を含めてください。