SDK Bettere adalah alat bagi para peneliti yang memungkinkan mereka untuk membungkus model audio mereka sendiri dan menjalankannya dalam DAW menggunakan plugin Netone kami. Kami menawarkan fungsionalitas untuk memuat model secara lokal di plugin dan berkontribusi pada daftar model default yang tersedia untuk siapa saja yang menjalankan plugin. Kami berharap ini akan memungkinkan para peneliti untuk dengan mudah mencoba model mereka dalam DAW, tetapi juga memberi para pembuat kumpulan model yang menarik.
Juce adalah standar industri untuk membangun plugin audio. Karena itu, pengetahuan tentang C ++ diperlukan untuk dapat membangun bahkan plugin audio yang sangat sederhana. Namun, jarang bagi peneliti audio AI untuk memiliki pengalaman luas dengan C ++ dan dapat membangun plugin seperti itu. Selain itu, ini adalah investasi waktu yang serius yang dapat dihabiskan untuk mengembangkan algoritma yang lebih baik. Netone memungkinkan untuk membangun model menggunakan alat yang akrab seperti Pytorch dan dengan jumlah minimal kode Python membungkus model -model ini sehingga dapat dieksekusi oleh plugin Netone. Mendapatkan model dan berjalan di dalam DAW dapat dilakukan dalam waktu kurang dari satu hari tanpa perlu kode atau pengetahuan C ++.
SDK memberikan dukungan untuk buffering otomatis input dan output ke model Anda dan laju sampel on-the-fly dan konversi stereo-mono. Ini memungkinkan model yang hanya dapat dieksekusi dengan jumlah sampel yang telah ditentukan untuk digunakan dalam DAW pada tingkat pengambilan sampel dan ukuran buffer apa pun dengan mulus. Selain itu, di dalam alat SDK untuk pembandingan dan profil sudah tersedia sehingga Anda dapat dengan mudah men -debug dan menguji kinerja model Anda.
Anda dapat menginstal neutone_sdk menggunakan PIP:
pip install neutone_sdk
Plugin Netone tersedia di https://neutone.space. Kami saat ini menawarkan plugin VST3 dan AU yang dapat digunakan untuk memuat model yang dibuat dengan SDK ini. Silakan kunjungi situs web untuk informasi lebih lanjut.
Jika Anda hanya ingin membungkus model tanpa melalui deskripsi terperinci tentang apa yang kami siapkan contoh -contoh ini untuk Anda.
SDK menyediakan fungsionalitas untuk membungkus model Pytorch yang ada dengan cara yang dapat membuatnya dapat dieksekusi dalam plugin VST. Pada intinya plugin mengirimkan potongan sampel audio pada laju sampel tertentu sebagai input dan mengharapkan jumlah sampel yang sama pada output. Pengguna SDK dapat menentukan laju sampel dan ukuran buffer yang dilakukan model mereka secara optimal. SDK kemudian menjamin bahwa umpan depan model akan menerima audio pada salah satu kombinasi (sample_rate, buffer_size) ini. Tersedia empat tombol yang memungkinkan pengguna plugin untuk memberi makan dalam parameter tambahan untuk model saat runtime. Mereka dapat diaktifkan atau dinonaktifkan sesuai kebutuhan melalui SDK.
Menggunakan fungsi ekspor yang disertakan serangkaian tes secara otomatis dijalankan untuk memastikan model berperilaku seperti yang diharapkan dan siap untuk dimuat oleh plugin.
Benchmarking dan profil alat CLI tersedia untuk debugging lebih lanjut dan pengujian model yang dibungkus. Dimungkinkan untuk membandingkan kecepatan dan latensi model pada berbagai kombinasi daw umum (sampel_rate, buffere_size) yang disimulasikan serta profil memori dan penggunaan CPU.
Kami menyediakan beberapa model di Direktori Contoh. Kami akan melalui salah satu model paling sederhana, model distorsi, untuk diilustrasikan.
Asumsikan kami memiliki model Pytorch berikut. Parameter akan dibahas nanti, kami akan fokus pada input dan output untuk saat ini. Asumsikan model ini menerima tensor bentuk (2, buffer_size) sebagai input di mana buffer_size adalah parameter yang dapat ditentukan.
class ClipperModel ( nn . Module ):
def forward ( self , x : Tensor , min_val : float , max_val : float , gain : float ) -> Tensor :
return torch . clip ( x , min = min_val * gain , max = max_val * gain )Untuk menjalankan ini di dalam VST, pembungkus paling sederhana yang dapat kita tulis adalah dengan mensubklassing baseClass WaveFormToWAVformBase.
class ClipperModelWrapper ( WaveformToWaveformBase ):
@ torch . jit . export
def is_input_mono ( self ) -> bool :
return False
@ torch . jit . export
def is_output_mono ( self ) -> bool :
return False
@ torch . jit . export
def get_native_sample_rates ( self ) -> List [ int ]:
return [] # Supports all sample rates
@ torch . jit . export
def get_native_buffer_sizes ( self ) -> List [ int ]:
return [] # Supports all buffer sizes
def do_forward_pass ( self , x : Tensor , params : Dict [ str , Tensor ]) -> Tensor :
# ... Parameter unwrap logic
x = self . model . forward ( x , min_val , max_val , gain )
return x Metode yang melakukan sebagian besar pekerjaan adalah do_forward_pass . Dalam hal ini hanya passthrough sederhana, tetapi kami akan menggunakannya untuk menangani parameter nanti.
Secara default VST berjalan sebagai stereo-stereo tetapi ketika mono diinginkan untuk model kita dapat menggunakan is_input_mono dan is_output_mono untuk menginformasikan SDK dan memiliki input dan output yang dikonversi secara otomatis. Jika is_input_mono diaktifkan dengan tensor berbentuk rata -rata (1, buffer_size) akan dilewatkan sebagai input, bukan (2, buffer_size) . Jika is_output_mono diaktifkan, do_forward_pass diharapkan mengembalikan tensor mono (bentuk (1, buffer_size) ) yang kemudian akan digandakan di kedua saluran pada output VST. Ini dilakukan dalam SDK untuk menghindari alokasi memori yang tidak perlu selama setiap lulus.
get_native_sample_rates dan get_native_buffer_sizes dapat digunakan untuk menentukan tingkat sampel yang disukai atau ukuran buffer. Dalam kebanyakan kasus ini diharapkan hanya memiliki satu elemen tetapi fleksibilitas ekstra disediakan untuk model yang lebih kompleks. Dalam hal beberapa opsi disediakan, SDK akan mencoba menemukan yang terbaik untuk pengaturan DAW saat ini. Setiap kali laju sampel atau ukuran buffer berbeda dari salah satu DAW pembungkus secara otomatis dipicu yang dikonversi ke laju pengambilan sampel yang benar atau mengimplementasikan antrian FIFO untuk ukuran buffer yang diminta atau keduanya. Ini akan dikenakan penalti kinerja yang kecil dan menambah sejumlah keterlambatan. Dalam hal model kompatibel dengan laju sampel dan/atau ukuran buffer, daftar ini dapat dibiarkan kosong.
Ini berarti bahwa Tensor x dalam metode do_forward_pass dijamin bentuknya (1 if is_input_mono else 2, buffer_size) di mana buffer_size akan dipilih saat runtime dari daftar yang disediakan dalam metode get_native_buffer_sizes . Tensor x juga akan berada di salah satu tingkat pengambilan sampel dari daftar yang disediakan dalam metode get_native_sample_rates .
Kami menyediakan fungsi helper save_neutone_model yang menyimpan model ke disk. Secara default ini akan mengonversi model menjadi Torchscript dan menjalankannya melalui serangkaian cek untuk memastikan mereka dapat dimuat oleh plugin. File model.nm yang dihasilkan dapat dimuat di dalam plugin menggunakan tombol load your own . Baca di bawah ini untuk cara mengirimkan model ke koleksi default yang terlihat oleh semua orang menggunakan plugin.
Untuk model yang dapat menggunakan sinyal pengkondisian, kami saat ini menyediakan empat parameter kenop yang dapat dikonfigurasi. Di dalam ClipperModelWrapper yang ditentukan di atas kita dapat menyertakan yang berikut:
class ClipperModelWrapper ( WaveformToWaveformBase ):
...
def get_neutone_parameters ( self ) -> List [ NeutoneParameter ]:
return [ NeutoneParameter ( name = "min" , description = "min clip threshold" , default_value = 0.5 ),
NeutoneParameter ( name = "max" , description = "max clip threshold" , default_value = 1.0 ),
NeutoneParameter ( name = "gain" , description = "scale clip threshold" , default_value = 1.0 )]
def do_forward_pass ( self , x : Tensor , params : Dict [ str , Tensor ]) -> Tensor :
min_val , max_val , gain = params [ "min" ], params [ "max" ], params [ "gain" ]
x = self . model . forward ( x , min_val , max_val , gain )
return x Selama lulus ke depan, variabel params akan menjadi kamus seperti berikut:
{
"min" : torch . Tensor ([ 0.5 ] * buffer_size ),
"max" : torch . Tensor ([ 1.0 ] * buffer_size ),
"gain" : torch . Tensor ([ 1.0 ] * buffer_size )
} Kunci kamus ditentukan dalam fungsi get_parameters .
Parameter akan selalu mengambil nilai antara 0 dan 1 dan fungsi do_forward_pass dapat digunakan untuk melakukan pengembalian yang diperlukan sebelum menjalankan metode maju internal model.
Selain itu, parameter yang dikirim oleh plugin masuk pada granularitas level sampel. Secara default, kami mengambil rata -rata dari setiap buffer dan mengembalikan float tunggal (sebagai tensor), tetapi metode aggregate_param dapat digunakan untuk mengganti metode agregasi. Lihat file Ekspor Clipper lengkap untuk contoh melestarikan granularitas ini.
Beberapa model audio akan menunda audio untuk sejumlah sampel. Ini tergantung pada arsitektur masing -masing model tertentu. Agar sinyal basah dan kering yang terjadi melalui plugin untuk diselaraskan pengguna diminta untuk melaporkan berapa banyak sampel penundaan yang diinduksi oleh model mereka. calc_model_delay_samples dapat digunakan untuk menentukan jumlah sampel penundaan. Model rave rata -rata memiliki satu buffer penundaan (2048 sampel) yang dikomunikasikan secara statis dalam metode calc_model_delay_samples dan dapat dilihat dalam contoh. Model yang diimplementasikan dengan tumpang tindih-ADD akan memiliki penundaan yang sama dengan jumlah sampel yang digunakan untuk crossfading seperti yang terlihat dalam pembungkus model DEMUCS atau contoh filter spektral.
Menghitung penundaan yang ditambahkan model Anda bisa sulit, terutama karena mungkin ada beberapa sumber keterlambatan yang perlu digabungkan (misalnya penundaan cossfading, penundaan filter, penundaan buffer lookahead, dan / atau jaringan saraf yang dilatih pada audio kering dan basah yang tidak selaras) . Perlu menghabiskan waktu ekstra menguji model di DAW Anda untuk memastikan penundaan dilaporkan dengan benar.
Menambahkan buffer lookBehind ke model Anda dapat berguna untuk model yang membutuhkan sejumlah konteks tambahan untuk menghasilkan hasil yang bermanfaat. Buffer lookbehind dapat diaktifkan dengan mudah dengan menunjukkan berapa banyak sampel yang Anda butuhkan dalam metode get_look_behind_samples . Ketika metode ini mengembalikan angka yang lebih besar dari nol, metode do_forward_pass akan selalu menerima tensor bentuk (in_n_ch, look_behind_samples + buffer_size) , tetapi masih harus mengembalikan tensor bentuk (out_n_ch, buffer_size) dari sampel terbaru.
Kami sarankan menghindari penggunaan buffer yang terlihat di belakang jika memungkinkan karena membuat model Anda kurang efisien dan dapat menghasilkan perhitungan yang terbuang selama setiap umpan maju. Jika menggunakan model konvolusional murni, coba ganti semua konvolusi ke konvolusi yang di -cache sebagai gantinya.
Adalah umum bagi model AI untuk bertindak dengan cara yang tidak terduga ketika disajikan dengan input di luar yang hadir dalam distribusi pelatihan mereka. Kami menyediakan serangkaian filter umum (bass rendah, pass tinggi, pita pas, stop pita) di file neutone_sdk/filters.py. Ini dapat digunakan selama umpan maju untuk membatasi domain input yang masuk ke model. Beberapa dari mereka dapat menyebabkan sejumlah kecil penundaan, periksa file contoh/example_clipper_prefilter.py untuk contoh sederhana tentang cara mengatur filter.
Plugin ini berisi daftar model default yang ditujukan untuk pencipta yang ingin memanfaatkannya selama proses kreatif mereka. Kami mendorong pengguna untuk mengirimkan model mereka begitu mereka senang dengan hasil yang mereka dapatkan sehingga mereka dapat digunakan oleh masyarakat luas. Untuk pengiriman kami memerlukan beberapa metadata tambahan yang akan digunakan untuk menampilkan informasi tentang model yang ditujukan untuk pencipta dan peneliti lainnya. Ini akan ditampilkan di situs web Neutone dan di dalam plugin.
Melewati model Clipper sebelumnya, berikut adalah contoh yang lebih realistis berdasarkan model overdrive TCN acak yang terinspirasi oleh micro-TCN.
class OverdriveModelWrapper ( WaveformToWaveformBase ):
def get_model_name ( self ) -> str :
return "conv1d-overdrive.random"
def get_model_authors ( self ) -> List [ str ]:
return [ "Nao Tokui" ]
def get_model_short_description ( self ) -> str :
return "Neural distortion/overdrive effect"
def get_model_long_description ( self ) -> str :
return "Neural distortion/overdrive effect through randomly initialized Convolutional Neural Network"
def get_technical_description ( self ) -> str :
return "Random distortion/overdrive effect through randomly initialized Temporal-1D-convolution layers. You'll get different types of distortion by re-initializing the weight or changing the activation function. Based on the idea proposed by Steinmetz et al."
def get_tags ( self ) -> List [ str ]:
return [ "distortion" , "overdrive" ]
def get_model_version ( self ) -> str :
return "1.0.0"
def is_experimental ( self ) -> bool :
return False
def get_technical_links ( self ) -> Dict [ str , str ]:
return {
"Paper" : "https://arxiv.org/abs/2010.04237" ,
"Code" : "https://github.com/csteinmetz1/ronn"
}
def get_citation ( self ) -> str :
return "Steinmetz, C. J., & Reiss, J. D. (2020). Randomized overdrive neural networks. arXiv preprint arXiv:2010.04237."Lihatlah dokumentasi metode di dalam core.py, serta model overdrive acak di situs web dan di plugin untuk memahami di mana setiap bidang akan ditampilkan.
Untuk mengirimkan model, buka masalah di repositori GitHub. Saat ini kami membutuhkan yang berikut:
model.nm yang dikeluarkan oleh fungsi helper save_neutone_model SDK menyediakan tiga alat CLI yang dapat digunakan untuk men -debug dan menguji model yang dibungkus.
Contoh:
$ python -m neutone_sdk.benchmark benchmark-speed --model_file model.nm
INFO:__main__:Running benchmark for buffer sizes (128, 256, 512, 1024, 2048) and sample rates (48000,). Outliers will be removed from the calculation of mean and std and displayed separately if existing.
INFO:__main__:Sample rate: 48000 | Buffer size: 128 | duration: 0.014±0.002 | 1/RTF: 5.520 | Outliers: [0.008]
INFO:__main__:Sample rate: 48000 | Buffer size: 256 | duration: 0.028±0.003 | 1/RTF: 5.817 | Outliers: []
INFO:__main__:Sample rate: 48000 | Buffer size: 512 | duration: 0.053±0.003 | 1/RTF: 6.024 | Outliers: []
INFO:__main__:Sample rate: 48000 | Buffer size: 1024 | duration: 0.106±0.000 | 1/RTF: 6.056 | Outliers: []
INFO:__main__:Sample rate: 48000 | Buffer size: 2048 | duration: 0.212±0.000 | 1/RTF: 6.035 | Outliers: [0.213]
Menjalankan tolok ukur kecepatan akan secara otomatis menjalankan input acak melalui model pada laju sampel 48000 dan ukuran buffer (128, 256, 512, 1024, 2048) dan melaporkan waktu rata -rata yang dibutuhkan untuk menjalankan inferensi untuk satu buffer. Dari sini 1/RTF dihitung yang mewakili seberapa cepat dari realtime model tersebut. Karena angka ini semakin tinggi, model akan menggunakan sumber daya yang lebih sedikit di dalam DAW. Jumlah ini perlu lebih besar dari 1 agar model dapat dieksekusi secara realtime pada mesin tempat tolok ukur berjalan.
Tingkat sampel dan ukuran buffer yang sedang diuji, serta berapa kali patokan diulang secara internal untuk menghitung rata -rata dan jumlah utas yang digunakan untuk perhitungan tersedia sebagai parameter. Jalankan python -m neutone_sdk.benchmark benchmark-speed --help untuk informasi lebih lanjut. Saat menentukan laju sampel khusus atau ukuran buffer, masing -masing individu perlu diteruskan ke CLI secara terpisah. Misalnya: --sample_rate 48000 --sample_rate 44100 --buffer_size 32 --buffer_size 64 .
Sementara tolok ukur kecepatan harus cepat karena model umumnya berbicara untuk menjadi realtime, dimungkinkan untuk macet jika modelnya terlalu lambat. Pastikan Anda memilih jumlah laju sampel dan ukuran buffer yang sesuai untuk diuji.
Contoh:
$ python -m neutone_sdk.benchmark benchmark-latency model.nm
INFO:__main__:Native buffer sizes: [2048], Native sample rates: [48000]
INFO:__main__:Model exports/ravemodel/model.nm has the following delays for each sample rate / buffer size combination (lowest delay first):
INFO:__main__:Sample rate: 48000 | Buffer size: 2048 | Total delay: 0 | (Buffering delay: 0 | Model delay: 0)
INFO:__main__:Sample rate: 48000 | Buffer size: 1024 | Total delay: 1024 | (Buffering delay: 1024 | Model delay: 0)
INFO:__main__:Sample rate: 48000 | Buffer size: 512 | Total delay: 1536 | (Buffering delay: 1536 | Model delay: 0)
INFO:__main__:Sample rate: 48000 | Buffer size: 256 | Total delay: 1792 | (Buffering delay: 1792 | Model delay: 0)
INFO:__main__:Sample rate: 44100 | Buffer size: 128 | Total delay: 1920 | (Buffering delay: 1920 | Model delay: 0)
INFO:__main__:Sample rate: 48000 | Buffer size: 128 | Total delay: 1920 | (Buffering delay: 1920 | Model delay: 0)
INFO:__main__:Sample rate: 44100 | Buffer size: 256 | Total delay: 2048 | (Buffering delay: 2048 | Model delay: 0)
INFO:__main__:Sample rate: 44100 | Buffer size: 512 | Total delay: 2048 | (Buffering delay: 2048 | Model delay: 0)
INFO:__main__:Sample rate: 44100 | Buffer size: 1024 | Total delay: 2048 | (Buffering delay: 2048 | Model delay: 0)
INFO:__main__:Sample rate: 44100 | Buffer size: 2048 | Total delay: 2048 | (Buffering delay: 2048 | Model delay: 0) Menjalankan tolok ukur kecepatan akan secara otomatis menghitung latensi model pada kombinasi sample_rate=(44100, 48000) dan buffer_size=(128, 256, 512, 1024, 2048) . Ini memberikan gambaran umum tentang apa yang akan terjadi untuk pengaturan DAW umum. Total penundaan dibagi menjadi penundaan buffering dan penundaan model. Model penundaan dilaporkan oleh pencipta model dalam pembungkus model seperti yang dijelaskan di atas. Penundaan buffering secara otomatis dihitung oleh SDK dengan mempertimbangkan kombinasi (sample_rate, buffer_size) yang ditentukan oleh pembungkus (yang asli) dan yang ditentukan oleh DAW saat runtime. Menjalankan model pada kombinasi asalnya (sample_rate, buffer_size) akan menimbulkan penundaan minimum.
Mirip dengan tolok ukur kecepatan di atas, kombinasi yang diuji (sample_rate, buffer_size) dapat ditentukan dari CLI. Jalankan python -m neutone_sdk.benchmark benchmark-latency --help untuk info lebih lanjut.
$ python -m neutone_sdk.benchmark profile --model_file exports/ravemodel/model.nm
INFO:__main__:Profiling model exports/ravemodel/model.nm at sample rate 48000 and buffer size 128
STAGE:2023-09-28 14:34:53 96328:4714960 ActivityProfilerController.cpp:311] Completed Stage: Warm Up
30it [00:00, 37.32it/s]
STAGE:2023-09-28 14:34:54 96328:4714960 ActivityProfilerController.cpp:317] Completed Stage: Collection
STAGE:2023-09-28 14:34:54 96328:4714960 ActivityProfilerController.cpp:321] Completed Stage: Post Processing
INFO:__main__:Displaying Total CPU Time
INFO:__main__:-------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg CPU Mem Self CPU Mem # of Calls
-------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
forward 98.54% 799.982ms 102.06% 828.603ms 26.729ms 0 b -918.17 Kb 31
aten::convolution 0.12% 963.000us 0.95% 7.739ms 175.886us 530.62 Kb -143.50 Kb 44
...
...
Full output removed from GitHub.
Alat profil akan menjalankan model pada laju sampel 48000 dan ukuran buffer 128 di bawah profiler Pytorch dan output serangkaian wawasan, seperti total waktu CPU, penggunaan memori CPU total (per fungsi) dan dikelompokkan memori CPU memori CPU (per kelompok panggilan fungsi). Ini dapat digunakan untuk mengidentifikasi kemacetan dalam kode model Anda (bahkan dalam panggilan model dalam panggilan do_forward_pass ).
Mirip dengan benchmarking, dapat dijalankan pada berbagai kombinasi laju sampel dan ukuran buffer serta jumlah utas yang berbeda. Jalankan python -m neutone_sdk.benchmark profile --help untuk info lebih lanjut.
Kami menyambut setiap kontribusi untuk SDK. Harap tambahkan jenis sedapat mungkin dan gunakan formatter black untuk keterbacaan.
Peta jalan saat ini adalah:
Proyek Audacitorch adalah inspirasi utama untuk pengembangan SDK. Lihat di sini