„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Supersonic GPU MelSpectrogram für Ihre Echtzeitanwendungen

Supersonic GPU MelSpectrogram für Ihre Echtzeitanwendungen

Veröffentlicht am 08.11.2024
Durchsuche:789

Supersonic GPU MelSpectrogram for your real-time applications

Hier bei Simli liegt uns die Latenz am meisten am Herzen. Darum geht es uns schließlich: Videos mit geringer Latenz. Andererseits weisen einige der am häufigsten verwendeten Algorithmen beim Audio Machine Learning sehr, sehr langsame Implementierungen auf. Um es klar zu sagen: Diese Implementierungen eignen sich normalerweise gut für die Erstellung der Modelle selbst oder für Batch-Inferenzen. Aber für uns bei Simli könnten ein paar Millisekunden den Unterschied zwischen einem stotternden Durcheinander oder einem flüssigen Video ausmachen.
Zum Glück für mich (und stellvertretend für Sie als Leser) erfordert dieser Leitfaden keine großen Mathematikkenntnisse. Viel schlauere Leute haben bereits herausgefunden, wie sie die richtige Antwort erhalten. Wir machen die Berechnung lediglich effizienter. Wenn Sie weitere Informationen benötigen, um zu verstehen, was das MelSpectrogram überhaupt ist, können Sie diesen Artikel lesen. Es gibt mehrere Möglichkeiten, das Spektrogramm zu berechnen. Dies hängt stark von Ihrer Anwendung ab. Aus Gründen der Bequemlichkeit für den Autor konzentrieren wir uns daher auf die Mels, die zum Ausführen unserer internen Modelle erforderlich sind.

Die gemeinsame Lösung: Librosa

Sie sind höchstwahrscheinlich hier, nachdem Sie auf ein Repo gestoßen sind, das Librosa verwendet. Um ehrlich zu sein, ist es eine ziemlich praktische Bibliothek. Es gibt eine Menge Dienstprogramme, einfache Möglichkeiten zum Lesen des Audios auf der Festplatte und schnellen Zugriff auf viele häufig benötigte Funktionen wie Audio-Resampling, Kanal-Downmixing und andere. In unserem Fall sind wir an einer bestimmten Funktionalität interessiert: der Melspektrogrammberechnung. In librosa ist es einfach, das Melspektrogramm zu erhalten.

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),
)

Unkompliziert und dauert auf einer GCP g2-VM durchschnittlich etwa 2 ms. Nun, es gibt zwei Hauptprobleme:

  1. Normalerweise müssen Sie bei der Arbeit mit DL-Modellen das Modell auf einer GPU ausführen. Das bedeutet, dass ein Teil Ihrer Kette auf der CPU läuft und Sie die Ergebnisse dann zurück auf die GPU kopieren. Für Batch-Inferenzen ist dies größtenteils in Ordnung, da Sie so viele Daten sammeln sollten, wie auf die GPU/Übertragung passen. In unserem Fall arbeiten wir jedoch häufig mit jeweils einem Frame, um die Warte- und Bearbeitungszeit zu verkürzen.
  2. Unser gesamtes Zeitbudget beträgt ungefähr 33 ms/Frame. Dazu gehören die Übertragungslatenz vom API-Server zum ML-Inferenzserver, CPU-zu-GPU-Kopieren, Vorverarbeitung und Nachverarbeitung für die Modelle einschließlich des Melspektrogramms. Bei einem so knappen Budget zählt jede Millisekunde. Diese zwei Millisekunden trugen tatsächlich dazu bei, dass Simli einen funktionierenden, live gerenderten Videostream hatte (nun ja, es waren viele Optimierungen, die jeweils ein oder zwei Millisekunden wert waren).

Suchen Sie online nach Lösungen

Als ich mir anschaute, wie andere Leute es gemacht haben (zum Glück ist das kein einzigartiges Problem für uns), bin ich auf diesen Artikel gestoßen, der sowohl die Funktionsweise von Melspektrogrammen erklärt als auch eine Referenzimplementierung bereitstellt, die aus irgendeinem Grund nur 1 ms dauerte (50 % Verbesserung). Das ist ein guter Anfang, aber es gibt immer noch das erste Problem, nicht alles war auf der GPU. Wir verwenden PyTorch und verlassen uns für maximale Geschwindigkeitsverbesserungen auf Torch.compile mit mode=reduce-overhead. Eine solche Datenübertragung kann jedoch die Leistung beeinträchtigen, da der PyTorch-Compiler die Funktion nicht ebenfalls optimieren kann. Die Lösung ist etwas mühsam, aber relativ einfach. Schreiben Sie sie in Torch um. Das PyTorch-Team hat dafür gesorgt, dass ein Großteil seiner Syntax und Funktionalität NumPy so nahe wie möglich kommt (mit einigen Randfällen, die normalerweise gut dokumentiert sind, abgesehen von einem, der mich ein paar Tage gekostet hat, aber das ist eine Geschichte für einen anderen Blog). .

Die PyTorch-Umschreibung

Es müssen also ein paar Schritte ausgeführt werden, um alles in Pytorch erfolgreich neu zu schreiben. Melspektrogramme können in drei Schritte unterteilt werden:

  • Berechnung der Kurzzeit-Fourier-Transformation
  • Generieren der Mel-Scale-Frequenzbänke
  • Erzeugung des Spektrogramms.

Es gibt gute und schlechte Nachrichten. Die gute Nachricht ist, dass alle erforderlichen Funktionen in Pytorch oder Torchaudio verfügbar sind. Die schlechte Nachricht ist, dass sich das Standardverhalten stark von dem von librosa unterscheidet, sodass viel Konfiguration und Versuch und Irrtum erforderlich sind, um es richtig zu machen. Ich habe das durchgemacht und teile die Informationen, weil ich meinem schlimmsten Feind nicht einmal die Hölle wünschen kann. Eine Sache, die wir verstehen müssen, ist, dass dieser Code stark darauf angewiesen ist, einige unserer Ergebnisse zwischenzuspeichern, um sie später zu verwenden. Dies geschieht in einer Initialisierungsfunktion, die alle statischen Arrays vorgeneriert (Mel-Frequenzbänke hängen beispielsweise von der Abtastrate und der Anzahl der benötigten Mels ab). Hier ist unsere optimierte Version der Melspektrogramm-Funktion mit 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)
)

Nach dem ersten Kompilierungslauf haben wir gemessen, dass diese Funktion mit einer Nvidia L4-GPU (mit Zwischenspeicherung der hann_window- und melscale_fbanks) 350 Mikrosekunden benötigt. Der angepasste Aufruf sieht folgendermaßen aus:

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,
)

Dies ist Teil einer Artikelserie darüber, wie wir unsere bereitgestellten vorab trainierten Modelle optimiert haben und die Vorverarbeitungs- und Nachverarbeitungsschritte optimiert haben. Sie können auf https://www.simli.com/demo nachschauen, welche bereitgestellten Modelle und Avatare mit der niedrigsten Latenz wir anbieten

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/simli_ai/supersonic-gpu-melspectrogram-for-your-real-time-applications-gg1?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen Es
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3