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)
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)
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コーパス読み上げ音声(https://amitaro.net/voice/corpus-list/ita/)
- つくよみちゃんコーパス(https://tyc.rei-yumesaki.net/material/corpus/)
- ReazonSpeech(https://research.reazon.jp/)
- AivisHub(https://hub.aivis-project.com/)
組み込みアプリへのお願い
配布時には同梱の NOTICE ファイルの内容を含めてください。
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support