2 ポイント 投稿者 kdrkdrkdr 7 시간 전 | まだコメントはありません。 | WhatsAppで共有

自作プロジェクトです。

  • 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ライセンス

まだコメントはありません。

まだコメントはありません。