自作プロジェクトです。
- FastEnhancer-Medium(48 kHzストリーミング音声強調モデル)のランタイムを純粋なCで再実装したライブラリです
- 元のモデル: https://github.com/aask1357/fastenhancer (Ahn ほか, 2025)
- 元のリポジトリが論文(16 kHz)公開後に追加公開した48 kHz重みをそのまま使用しています。再学習・ファインチューニング・calibration setはありません
- モデルと重みは原著者のもので、最適化したのはランタイム側です
■ 性能
- Apple M2の1コアでreal-time factor 0.069です。同じマシンで同一グラフをONNX Runtimeで動かすと0.230なので、3.3倍です
- Galaxy S23+(Snapdragon 8 Gen 2)では0.096です
- 品質低下はほとんどありません。VoiceBank-DEMANDの824発話でfp32モデル比 -0.006 PESQにとどまります。聞いて区別できるレベルではありません
■ 適用した最適化
1つの手法で3倍になったのではなく、複数の層をそれぞれ手直ししています。
- 量子化: 活性値の範囲を毎フレーム再計算します。そのためcalibration setを合わせたり同梱したりする必要がまったくなく、入力分布が変わっても壊れません
- 畳み込み: k=3 convにWinograd F(2,3)を適用し、後続のエピローグ(dequant + bias + SiLU + fp16 write)まで同じパスに折り込んで中間バッファをなくしています
- 再帰: GRUをティアごとに1つのカーネルへ完全に融合しています。入力側行列積、隠れ状態側行列積、r/z/nの3ゲート、hidden更新までを1つのカーネルで完結させ、int32アキュムレータがメモリへ漏れません
- アテンション: softmaxがint32スコアをそのまま受けて処理します。fp32のスコア行列をそもそも作らないため、その分のメモリ往復がなくなります
- メモリ: cross-stage状態(GRU hidden, encoder skip)をfp16で保持し、フレーム間帯域幅を半減しています
- カーネル: ISAごとにint8 GEMMカーネル6種を直接実装し、初期化時に自動選択します(ARM NEON/DOTPROD/I8MM, x86 AVX2/AVX-VNNI/AVX-512)
- そのほかの最適化リストはプロジェクトのGithubで確認できます
■ リアルタイム安定性
- 37秒のベンチマークを1回回して終わりではなく、実際のオーディオコールバック周期で30分連続動作させて確認しました
- M2は30分間ずっとフレーム予算内に収まりました(p99 0.56)
■ その他
- 外部依存性は0です。cmake + makeでビルドでき、静的ライブラリは162 KiBです
- 公開APIは関数4個です(fe_init / fe_run / fe_reset / fe_free)
- 重みblob 565 KB、パラメータ 511,754個
- MITライセンス
まだコメントはありません。