"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > وحدة معالجة الرسومات MelSpectrogram الأسرع من الصوت لتطبيقاتك في الوقت الفعلي

وحدة معالجة الرسومات MelSpectrogram الأسرع من الصوت لتطبيقاتك في الوقت الفعلي

تم النشر بتاريخ 2024-11-08
تصفح:151

Supersonic GPU MelSpectrogram for your real-time applications

هنا في Simli، نحن نهتم أكثر بزمن الوصول. هذا ما نحن بصدده بعد كل شيء: فيديو بزمن وصول منخفض. من ناحية أخرى، فإن بعض الخوارزميات الأكثر استخدامًا في التعلم الآلي الصوتي لها تطبيقات بطيئة جدًا. للتوضيح، عادةً ما تكون هذه التطبيقات جيدة لإنشاء النماذج نفسها أو للاستدلال المجمع. لكن بالنسبة لنا في Simli، بضعة أجزاء من الثانية يمكن أن تعني الفرق بين فوضى متقطعة أو مقطع فيديو سلس.
لحسن الحظ بالنسبة لي (وبالوكالة أنت القارئ)، لا يتطلب هذا الدليل الكثير من المعرفة في الرياضيات، لقد اكتشف الأشخاص الأكثر ذكاءً بالفعل كيفية الحصول على الإجابة الصحيحة، نحن فقط نجعل الحساب أكثر كفاءة. إذا كنت بحاجة إلى مزيد من المعلومات لفهم ما هو MelSpectrogram، فيمكنك قراءة هذه المقالة. هناك طرق متعددة لحساب المخطط الطيفي، ويعتمد ذلك بشكل كبير على التطبيق الذي تستخدمه. لذلك، نحن نركز على العناصر المطلوبة لتشغيل نماذجنا الداخلية من أجل راحة المؤلف.

الحل المشترك: Librosa

أنت على الأرجح هنا بعد أن واجهت الريبو الذي يستخدم Librosa. إنها مكتبة مفيدة جدًا، لأكون صادقًا. هناك الكثير من الأدوات المساعدة، وطرق سهلة لقراءة الصوت الموجود على القرص، والوصول السريع إلى العديد من الوظائف المطلوبة بشكل شائع مثل إعادة تشكيل الصوت، وخلط القنوات، وغيرها. في حالتنا، نحن مهتمون بوظيفة معينة: حساب melspectrogram. في librosa، يعد الحصول على melspectrogram أمرًا بسيطًا.

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

مباشر ويستغرق الأمر في المتوسط ​​حوالي 2 مللي ثانية على جهاز GCP g2 VM. حسنًا، هناك مسألتان رئيسيتان:

  1. عادة، عند العمل مع نماذج DL، ستحتاج إلى تشغيل النموذج على وحدة معالجة الرسومات. هذا يعني أن جزءًا من سلسلتك يعمل على وحدة المعالجة المركزية ثم تقوم بنسخ النتائج مرة أخرى إلى وحدة معالجة الرسومات. بالنسبة للاستدلال المُجمَّع، يعد هذا أمرًا جيدًا في الغالب نظرًا لأنه يجب عليك جمع أكبر قدر ممكن من البيانات التي يمكنك وضعها على وحدة معالجة الرسومات/النقل. ومع ذلك، في حالتنا، غالبًا ما نعمل باستخدام إطار واحد في كل مرة لتقليل وقت الانتظار والمعالجة.
  2. تبلغ ميزانيتنا الزمنية الإجمالية حوالي 33 مللي ثانية/إطار. يتضمن ذلك زمن انتقال النقل من خادم API إلى خادم استدلال ML، ووحدة المعالجة المركزية (CPU) إلى نسخة GPU، والمعالجة المسبقة، والمعالجة اللاحقة للنماذج بما في ذلك melspectrogram. كل مللي ثانية مهم عندما تعمل بميزانية محدودة. ساهمت هاتان الميلي ثانية فعليًا في الحصول على دفق فيديو مباشر عملي لـ Simli (حسنًا، كان هناك العديد من التحسينات التي تبلغ قيمة كل منها مللي ثانية أو اثنين).

البحث عبر الإنترنت عن حلول

أثناء محاولتي إلقاء نظرة على كيفية قيام الأشخاص الآخرين بذلك (لحسن الحظ، هذه ليست مشكلة فريدة بالنسبة لنا)، وجدت هذه المقالة التي تشرح كيفية عمل melspectrograms وتوفر تطبيقًا مرجعيًا استغرق لسبب ما 1 مللي ثانية فقط (50 % التحسن). هذه بداية جيدة ولكن لا تزال هناك المشكلة الأولى، لم يكن كل شيء على وحدة معالجة الرسومات. نحن نستخدم PyTorch ونعتمد على torch.compile مع الوضع=reduce-overhead لتحسين السرعة القصوى. ومع ذلك، فإن نقل البيانات بهذه الطريقة قد يؤثر على الأداء لأن مترجم PyTorch لن يتمكن من تحسين الوظيفة أيضًا. الحل ممل بعض الشيء ولكنه سهل نسبيًا، أعد كتابته في الشعلة. لقد تأكد فريق PyTorch من أن الكثير من بناء الجملة والوظائف الخاصة بهم قريبة من NumPy قدر الإمكان (مع بعض الحالات المتطورة التي عادةً ما تكون موثقة جيدًا، بصرف النظر عن الحالة التي أضاعتني بضعة أيام ولكن هذه قصة لمدونة مختلفة) .

إعادة كتابة PyTorch

إذن هناك خطوتان يتعين علينا القيام بهما لإعادة كتابة كل شيء في Pytorch بنجاح. يمكن تقسيم Melspectrograms إلى ثلاث خطوات:

  • حساب تحويل فورييه قصير الأمد
  • إنشاء بنوك التردد بمقياس ميل
  • توليد المخطط الطيفي.

هناك أخبار جيدة وسيئة. والخبر السار هو أن جميع الوظائف المطلوبة متاحة بسهولة في pytorch أو torchaudio. الأخبار السيئة هي أن السلوك الافتراضي يختلف كثيرًا عن librosa، لذا هناك الكثير من التكوينات والتجربة والخطأ لتصحيح الأمر. لقد مررت بذلك وأنا أشارك المعلومات لأنني لا أستطيع حتى أن أتمنى ذلك الجحيم لأسوأ أعدائي. الشيء الوحيد الذي نحتاج إلى فهمه هو أن هذا الرمز يعتمد بشكل كبير على التخزين المؤقت لبعض نتائجنا لاستخدامها لاحقًا. يتم ذلك في وظيفة التهيئة التي تقوم بإنشاء جميع المصفوفات الثابتة مسبقًا (تعتمد بنوك تردد الميل على سبيل المثال على معدل أخذ العينات وعدد الميلات التي تحتاجها). إليك نسختنا المحسنة من وظيفة melspectrogram باستخدام 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)
)

بعد التشغيل الأولي للتجميع، قمنا بقياس هذه الوظيفة لتستغرق 350 ميكروثانية باستخدام وحدة معالجة الرسوميات Nvidia L4 (مع التخزين المؤقت لـ hann_window وmelscale_fbanks). ستبدو المكالمة المعدلة كما يلي:

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 لرؤية النماذج المنشورة والصور الرمزية ذات زمن الاستجابة الأقل التي نقدمها

بيان الافراج هذه المقالة مستنسخة على: https://dev.to/simli_ai/supersonic-gpu-melspectrogram-for-your-real-time-applications-gg1?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] للحذف هو - هي
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3