ここ Simli では、遅延を最も重視しています。結局のところ、私たちが目指しているのは低遅延ビデオです。一方で、オーディオ機械学習で最もよく使用されるアルゴリズムの中には、実装が非常に遅いものもあります。明確にしておきますが、これらの実装は通常、モデル自体の作成やバッチ推論に適しています。しかし、私たち Simli にとっては、数ミリ秒がビデオが途切れ途切れになるか滑らかになるかの違いを意味する可能性があります。
私にとって (そして読者であるあなたに代わって) 幸運なことに、このガイドは数学の知識をあまり必要としません。はるかに賢い人々はすでに正しい答えを得る方法を見つけています。私たちは計算をより効率的にしているだけです。 MelSpectrogram とは何かを理解するためにさらに詳しい情報が必要な場合は、この記事を読んでください。スペクトログラムを計算するには複数の方法があり、アプリケーションに大きく依存します。したがって、作成者の便宜を図るために、内部モデルの実行に必要なメルに焦点を当てています。
あなたはおそらく、Librosa を使用しているリポジトリに遭遇した後にここに来ているでしょう。正直に言うと、これはかなり便利なライブラリです。大量のユーティリティがあり、ディスク上のオーディオを読み取る簡単な方法があり、オーディオのリサンプリングやチャンネル ダウンミックスなどの一般的に必要な機能に素早くアクセスできます。私たちの場合、メルスペクトログラム計算という特定の機能に興味があります。 librosa では、メルスペクトログラムの取得は簡単です。
import librosa # load in any audio to test sampleAudio, sr = librosa.load("sample.mp3", sr=None) # sr=None means the original sampling rate spectrogram = librosa.feature.melspectrogram( y=sampleAudio, sr=sr, n_fft=int(0.05 * sr), # 50ms hop_length=int(0.0125 * sr), # 12.5ms win_length=int(0.05 * sr), )
簡単に説明すると、GCP g2 VM では平均で約 2 ミリ秒かかります。そうですね、主な問題が 2 つあります:
他の人がどのようにそれを実行したかを見ようとしていたときに (幸いなことに、これは私たちに特有の問題ではありません)、メルスペクトログラムがどのように機能するかを説明し、何らかの理由でわずか 1 ミリ秒 (50 ミリ秒) しかかからなかったリファレンス実装を提供するこの記事を見つけました。 % 改善)。これは良いスタートですが、最初の問題がまだ残っています。すべてが GPU 上にあるわけではありません。私たちは PyTorch を使用しており、最大速度の向上のために、mode=reduce-overhead を指定した torch.compile に依存しています。ただし、このようなデータ転送は、PyTorch コンパイラーが関数を最適化できないため、パフォーマンスが低下する可能性があります。解決策は少し面倒ですが、比較的簡単です。torch で書き直します。 PyTorch チームは、多くの構文と機能が可能な限り NumPy に近づくようにしました (いくつかのエッジ ケースは、通常は十分に文書化されていますが、私が数日費やしたケースは別ですが、これは別のブログでの話です) .
Pytorch ですべてを正常に書き直すには、いくつかの手順を実行する必要があります。メルスペクトログラムは 3 つのステップに分割できます:
良いニュースと悪いニュースがあります。良いニュースは、必要な機能がすべて pytorch または torchaudio ですぐに利用できることです。悪いニュースは、デフォルトの動作が librosa とは大きく異なるため、正しく動作させるには多くの設定と試行錯誤が必要になることです。私はそれを経験しており、最悪の敵に地獄を望むことさえできないので、情報を共有しています。理解する必要があることの 1 つは、このコードは後で使用するために結果の一部をキャッシュすることに大きく依存しているということです。これは、すべての静的配列を事前生成する初期化関数で行われます (たとえば、メル周波数バンクはサンプリング レートと必要なメルの数に依存します)。これは、PyTorch
を使用したメルスペクトログラム関数の最適化バージョンです。
import torch if torch.cuda.is_available @torch.compile(mode="reduce-overhead") else: @torch.compile def melspecrogram_torch(wav:torch.Tensor,sample_rate:int, hann_window: torch.Tensor, mel_basis: torch.Tensor): stftWav = torch.stft( wav, n_fft=int(sample_rate*0.05), win_length=int(sample_rate*0.05), hop_length=int(sample_rate*0.0125), window=hann_window, pad_mode="constant", return_complex=True, ).abs() stftWav = stftWav.squeeze() mel_stftWav = torch.mm(mel_basis, stftWav) return mel_stftWav device = "cuda" if torch.cuda.is_available() else "cpu" melspectrogram_torch( sampleAudio, sr, torch.hann_window(int(sample_rate*0.05), device=device, dtype=torch.float32), torchaudio.functional.melscale_fbanks( sample_rate=sr, n_freqs=(int(sample_rate*0.05) // 2 1), norm="slaney", # this is the normalization algorithm used by librosa # this is an example that's related to our own pipeline, check what you need for yours n_mels=80, f_min=55, f_max=7600, ) .T.to(device) )
最初のコンパイル実行後、Nvidia L4 GPU (hann_window および melscale_fbanks のキャッシュあり) を使用してこの関数にかかる時間が 350 マイクロ秒であると測定しました。調整された呼び出しは次のようになります:
hann=torch.hann_window(int(sample_rate*0.05), device=device, dtype=torch.float32), melscale=torchaudio.functional.melscale_fbanks( sample_rate=sr, n_freqs=(int(sample_rate*0.05) // 2 1), norm="slaney", # this is the normalization algorithm used by librosa # this is an example that's related to our own pipeline, check what you need for yours n_mels=80, f_min=55, f_max=7600, ) .T.to(device) melspectrogram_torch( sampleAudio, sr, hann, melscale, )
これは、デプロイされた事前トレーニング済みモデルをどのように最適化し、前処理と後処理のステップを最適化したかに関する一連の記事の一部です。 https://www.simli.com/demo をチェックして、デプロイされたモデルと提供されるレイテンシーの最も低いアバターを確認できます
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3