From d14ec6d56197b0f35535c16723aa36c3b6bce95d Mon Sep 17 00:00:00 2001 From: yonishelach Date: Tue, 31 Dec 2024 09:35:10 +0200 Subject: [PATCH] [text to audio generator] Replaced bark with openai tts models --- text_to_audio_generator/function.yaml | 88 ++++++++---------- text_to_audio_generator/item.yaml | 7 +- text_to_audio_generator/requirements.txt | 5 +- .../test_text_to_audio_generator.py | 18 ++-- .../text_to_audio_generator.ipynb | 12 +-- .../text_to_audio_generator.py | 91 +++++++++++++------ 6 files changed, 122 insertions(+), 99 deletions(-) diff --git a/text_to_audio_generator/function.yaml b/text_to_audio_generator/function.yaml index 88ef9cb89..65d8d82aa 100644 --- a/text_to_audio_generator/function.yaml +++ b/text_to_audio_generator/function.yaml @@ -1,32 +1,28 @@ -kind: job -metadata: - name: text-to-audio-generator - tag: '' - hash: 89fcaf3fab53e7b7fbba448a5e65c253d7fa66ed - project: '' - labels: - author: yonatans - categories: - - data-preparation - - machine-learning - - pytorch spec: - command: '' - args: [] image: '' + default_handler: generate_multi_speakers_audio build: - functionSourceCode: IyBDb3B5cmlnaHQgMjAyMyBJZ3VhemlvCiMKIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiMKIyAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAojCiMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQojIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAojIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgppbXBvcnQgbG9nZ2luZwppbXBvcnQgcGF0aGxpYgppbXBvcnQgcmFuZG9tCmltcG9ydCB0ZW1wZmlsZQpmcm9tIHR5cGluZyBpbXBvcnQgRGljdCwgTGlzdCwgT3B0aW9uYWwsIFR1cGxlLCBVbmlvbgoKaW1wb3J0IGJhcmsKaW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBwYW5kYXMgYXMgcGQKaW1wb3J0IHRvcmNoCmltcG9ydCB0b3JjaGF1ZGlvCmltcG9ydCB0cWRtCgojIEdldCB0aGUgZ2xvYmFsIGxvZ2dlcjoKX0xPR0dFUiA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKCkKCgpkZWYgZ2VuZXJhdGVfbXVsdGlfc3BlYWtlcnNfYXVkaW8oCiAgICBkYXRhX3BhdGg6IHN0ciwKICAgIHNwZWFrZXJzOiBVbmlvbltMaXN0W3N0cl0sIERpY3Rbc3RyLCBpbnRdXSwKICAgIGF2YWlsYWJsZV92b2ljZXM6IExpc3Rbc3RyXSwKICAgIG91dHB1dF9kaXJlY3Rvcnk6IHN0ciA9IE5vbmUsCiAgICB1c2VfZ3B1OiBib29sID0gVHJ1ZSwKICAgIHVzZV9zbWFsbF9tb2RlbHM6IGJvb2wgPSBGYWxzZSwKICAgIG9mZmxvYWRfY3B1OiBib29sID0gRmFsc2UsCiAgICBzYW1wbGVfcmF0ZTogaW50ID0gMTYwMDAsCiAgICBmaWxlX2Zvcm1hdDogc3RyID0gIndhdiIsCiAgICB2ZXJib3NlOiBib29sID0gVHJ1ZSwKICAgIGJpdHNfcGVyX3NhbXBsZTogT3B0aW9uYWxbaW50XSA9IE5vbmUsCikgLT4gVHVwbGVbc3RyLCBwZC5EYXRhRnJhbWUsIGRpY3RdOgogICAgIiIiCiAgICBHZW5lcmF0ZSBhdWRpbyBmaWxlcyBmcm9tIHRleHQgZmlsZXMuCgogICAgOnBhcmFtIGRhdGFfcGF0aDogICAgICAgICAgIFBhdGggdG8gdGhlIHRleHQgZmlsZSBvciBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgdGV4dCBmaWxlcyB0byBnZW5lcmF0ZSBhdWRpbyBmcm9tLgogICAgOnBhcmFtIHNwZWFrZXJzOiAgICAgICAgICAgIExpc3QgLyBEaWN0IG9mIHNwZWFrZXJzIHRvIGdlbmVyYXRlIGF1ZGlvIGZvci4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZiBhIGxpc3QgaXMgZ2l2ZW4sIHRoZSBzcGVha2VycyB3aWxsIGJlIGFzc2lnbmVkIHRvIGNoYW5uZWxzIGluIHRoZSBvcmRlciBnaXZlbi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZiBkaWN0aW9uYXJ5LCB0aGUga2V5cyB3aWxsIGJlIHRoZSBzcGVha2VycyBhbmQgdGhlIHZhbHVlcyB3aWxsIGJlIHRoZSBjaGFubmVscy4KICAgIDpwYXJhbSBhdmFpbGFibGVfdm9pY2VzOiAgICBMaXN0IG9mIGF2YWlsYWJsZSB2b2ljZXMgdG8gdXNlIGZvciB0aGUgZ2VuZXJhdGlvbi4KICAgICAgICAgICAgICAgICAgICAgICAgU2VlIGhlcmUgZm9yIHRoZSBhdmFpbGFibGUgdm9pY2VzOgogICAgICAgICAgICAgICAgICAgICAgICBodHRwczovL3N1bm8tYWkubm90aW9uLnNpdGUvOGI4ZTg3NDllZDUxNGIwY2JmM2Y2OTkwMTM1NDg2ODM/dj1iYzY3Y2ZmNzg2YjA0YjUwYjNjZWI3NTZmZDA1ZjY4YwogICAgOnBhcmFtIG91dHB1dF9kaXJlY3Rvcnk6ICAgIFBhdGggdG8gdGhlIGRpcmVjdG9yeSB0byBzYXZlIHRoZSBnZW5lcmF0ZWQgYXVkaW8gZmlsZXMgdG8uCiAgICA6cGFyYW0gdXNlX2dwdTogICAgICAgICAgICAgV2hldGhlciB0byB1c2UgdGhlIEdQVSBmb3IgdGhlIGdlbmVyYXRpb24uCiAgICA6cGFyYW0gdXNlX3NtYWxsX21vZGVsczogICAgV2hldGhlciB0byB1c2UgdGhlIHNtYWxsIG1vZGVscyBmb3IgdGhlIGdlbmVyYXRpb24uCiAgICA6cGFyYW0gb2ZmbG9hZF9jcHU6ICAgICAgICAgVG8gcmVkdWNlIHRoZSBtZW1vcnkgZm9vdHByaW50LCB0aGUgbW9kZWxzIGNhbiBiZSBvZmZsb2FkZWQgdG8gdGhlIENQVSBhZnRlciBsb2FkaW5nLgogICAgOnBhcmFtIHNhbXBsZV9yYXRlOiAgICAgICAgIFRoZSBzYW1wbGluZyByYXRlIG9mIHRoZSBnZW5lcmF0ZWQgYXVkaW8uCiAgICA6cGFyYW0gZmlsZV9mb3JtYXQ6ICAgICAgICAgVGhlIGZvcm1hdCBvZiB0aGUgZ2VuZXJhdGVkIGF1ZGlvIGZpbGVzLgogICAgOnBhcmFtIHZlcmJvc2U6ICAgICAgICAgICAgIFdoZXRoZXIgdG8gcHJpbnQgdGhlIHByb2dyZXNzIG9mIHRoZSBnZW5lcmF0aW9uLgogICAgOnBhcmFtIGJpdHNfcGVyX3NhbXBsZTogICAgIENoYW5nZXMgdGhlIGJpdCBkZXB0aCBmb3IgdGhlIHN1cHBvcnRlZCBmb3JtYXRzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRlZCBvbmx5IGluICJ3YXYiIG9yICJmbGFjIiBmb3JtYXRzLgoKICAgIDpyZXR1cm5zOiAgICAgICAgICAgICAgICAgICBBIHR1cGxlIG9mOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gVGhlIG91dHB1dCBkaXJlY3RvcnkgcGF0aC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIFRoZSBnZW5lcmF0ZWQgYXVkaW8gZmlsZXMgZGF0YWZyYW1lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gVGhlIGVycm9ycyBkaWN0aW9uYXJ5LgogICAgIiIiCgogICAgZ2xvYmFsIF9MT0dHRVIKICAgIF9MT0dHRVIgPSBfZ2V0X2xvZ2dlcigpCiAgICAjIEdldCB0aGUgaW5wdXQgdGV4dCBmaWxlcyB0byB0dXJuIHRvIGF1ZGlvOgogICAgZGF0YV9wYXRoID0gcGF0aGxpYi5QYXRoKGRhdGFfcGF0aCkuYWJzb2x1dGUoKQogICAgdGV4dF9maWxlcyA9IF9nZXRfdGV4dF9maWxlcyhkYXRhX3BhdGg9ZGF0YV9wYXRoKQoKICAgICMgTG9hZCB0aGUgYmFyayBtb2RlbHMgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBjb25maWd1cmF0aW9uczoKICAgIGJhcmsucHJlbG9hZF9tb2RlbHMoCiAgICAgICAgdGV4dF91c2VfZ3B1PXVzZV9ncHUsCiAgICAgICAgdGV4dF91c2Vfc21hbGw9dXNlX3NtYWxsX21vZGVscywKICAgICAgICBjb2Fyc2VfdXNlX2dwdT11c2VfZ3B1LAogICAgICAgIGNvYXJzZV91c2Vfc21hbGw9dXNlX3NtYWxsX21vZGVscywKICAgICAgICBmaW5lX3VzZV9ncHU9dXNlX2dwdSwKICAgICAgICBmaW5lX3VzZV9zbWFsbD11c2Vfc21hbGxfbW9kZWxzLAogICAgICAgIGNvZGVjX3VzZV9ncHU9dXNlX2dwdSwKICAgICAgICBmb3JjZV9yZWxvYWQ9b2ZmbG9hZF9jcHUsCiAgICApCgogICAgIyBDaGVjayBmb3IgcGVyIGNoYW5uZWwgZ2VuZXJhdGlvbjoKICAgIGlmIGlzaW5zdGFuY2Uoc3BlYWtlcnMsIGRpY3QpOgogICAgICAgIHNwZWFrZXJfcGVyX2NoYW5uZWwgPSBUcnVlCiAgICAgICAgIyBTb3J0IHRoZSBnaXZlbiBzcGVha2VycyBieSBjaGFubmVsczoKICAgICAgICBzcGVha2VycyA9IHsKICAgICAgICAgICAgc3BlYWtlcjogY2hhbm5lbAogICAgICAgICAgICBmb3Igc3BlYWtlciwgY2hhbm5lbCBpbiBzb3J0ZWQoc3BlYWtlcnMuaXRlbXMoKSwga2V5PWxhbWJkYSBpdGVtOiBpdGVtWzFdKQogICAgICAgIH0KICAgIGVsc2U6CiAgICAgICAgc3BlYWtlcl9wZXJfY2hhbm5lbCA9IEZhbHNlCgogICAgIyBQcmVwYXJlIHRoZSByZXNhbXBsaW5nIG1vZHVsZToKICAgIHJlc2FtcGxlciA9IHRvcmNoYXVkaW8udHJhbnNmb3Jtcy5SZXNhbXBsZSgKICAgICAgICBvcmlnX2ZyZXE9YmFyay5TQU1QTEVfUkFURSwgbmV3X2ZyZXE9c2FtcGxlX3JhdGUsIGR0eXBlPXRvcmNoLmZsb2F0MzIKICAgICkKCiAgICAjIFByZXBhcmUgdGhlIGdhcCBiZXR3ZWVuIGVhY2ggc3BlYWtlcjoKICAgIGdhcF9iZXR3ZWVuX3NwZWFrZXJzID0gbnAuemVyb3MoaW50KDAuNSAqIGJhcmsuU0FNUExFX1JBVEUpKQoKICAgICMgUHJlcGFyZSB0aGUgc3VjY2Vzc2VzIGRhdGFmcmFtZSBhbmQgZXJyb3JzIGRpY3Rpb25hcnkgdG8gYmUgcmV0dXJuZWQ6CiAgICBzdWNjZXNzZXMgPSBbXQogICAgZXJyb3JzID0ge30KCiAgICAjIENyZWF0ZSB0aGUgb3V0cHV0IGRpcmVjdG9yeToKICAgIGlmIG91dHB1dF9kaXJlY3RvcnkgaXMgTm9uZToKICAgICAgICBvdXRwdXRfZGlyZWN0b3J5ID0gdGVtcGZpbGUubWtkdGVtcCgpCiAgICBvdXRwdXRfZGlyZWN0b3J5ID0gcGF0aGxpYi5QYXRoKG91dHB1dF9kaXJlY3RvcnkpCiAgICBpZiBub3Qgb3V0cHV0X2RpcmVjdG9yeS5leGlzdHMoKToKICAgICAgICBvdXRwdXRfZGlyZWN0b3J5Lm1rZGlyKGV4aXN0X29rPVRydWUsIHBhcmVudHM9VHJ1ZSkKCiAgICAjIFN0YXJ0IGdlbmVyYXRpbmcgYXVkaW86CiAgICAjIEdvIG92ZXIgdGhlIGF1ZGlvIGZpbGVzIGFuZCB0cmFuc2NyaWJlOgogICAgZm9yIHRleHRfZmlsZSBpbiB0cWRtLnRxZG0oCiAgICAgICAgdGV4dF9maWxlcywgZGVzYz0iR2VuZXJhdGluZyIsIHVuaXQ9ImZpbGUiLCBkaXNhYmxlPW5vdCB2ZXJib3NlCiAgICApOgoKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgUmFuZG9taXplIHZvaWNlcyBmb3IgZWFjaCBzcGVha2VyOgogICAgICAgICAgICBjaG9zZW5fdm9pY2VzID0ge30KICAgICAgICAgICAgYXZhaWxhYmxlX3ZvaWNlc19jb3B5ID0gYXZhaWxhYmxlX3ZvaWNlcy5jb3B5KCkKICAgICAgICAgICAgZm9yIHNwZWFrZXIgaW4gc3BlYWtlcnM6CiAgICAgICAgICAgICAgICB2b2ljZSA9IHJhbmRvbS5jaG9pY2UoYXZhaWxhYmxlX3ZvaWNlc19jb3B5KQogICAgICAgICAgICAgICAgY2hvc2VuX3ZvaWNlc1tzcGVha2VyXSA9IHZvaWNlCiAgICAgICAgICAgICAgICBhdmFpbGFibGVfdm9pY2VzX2NvcHkucmVtb3ZlKHZvaWNlKQogICAgICAgICAgICAjIFJlYWQgdGV4dDoKICAgICAgICAgICAgd2l0aCBvcGVuKHRleHRfZmlsZSwgInIiKSBhcyBmcDoKICAgICAgICAgICAgICAgIHRleHQgPSBmcC5yZWFkKCkKICAgICAgICAgICAgIyBQcmVwYXJlIGEgaG9sZGVyIGZvciBhbGwgdGhlIGdlbmVyYXRlZCBwaWVjZXMgKGlmIHBlciBjaGFubmVsIGVhY2ggc3BlYWtlciB3aWxsIGhhdmUgaXRzIG93bik6CiAgICAgICAgICAgIGF1ZGlvX3BpZWNlcyA9ICgKICAgICAgICAgICAgICAgIHtzcGVha2VyOiBbXSBmb3Igc3BlYWtlciBpbiBzcGVha2Vyc30KICAgICAgICAgICAgICAgIGlmIHNwZWFrZXJfcGVyX2NoYW5uZWwKICAgICAgICAgICAgICAgIGVsc2UgeyJhbGwiOiBbXX0KICAgICAgICAgICAgKQoKICAgICAgICAgICAgIyBHZW5lcmF0ZSBhdWRpbyBwZXIgbGluZToKICAgICAgICAgICAgZm9yIGxpbmUgaW4gdGV4dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgICAgICAjIFZhbGlkYXRlIGxpbmUgaXMgaW4gY29ycmVjdCBzcGVha2VyIGZvcm1hdDoKCiAgICAgICAgICAgICAgICBpZiAiOiAiIG5vdCBpbiBsaW5lOgogICAgICAgICAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIF9MT0dHRVIud2FybmluZyhmIlNraXBwaW5nIGxpbmU6IHtsaW5lfSIpCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgICMgU3BsaXQgbGluZSB0byBzcGVha2VyIGFuZCBoaXMgd29yZHM6CiAgICAgICAgICAgICAgICBjdXJyZW50X3NwZWFrZXIsIHNlbnRlbmNlcyA9IGxpbmUuc3BsaXQoIjogIiwgMSkKICAgICAgICAgICAgICAgICMgVmFsaWRhdGUgc3BlYWtlciBpcyBrbm93bjoKICAgICAgICAgICAgICAgIGlmIGN1cnJlbnRfc3BlYWtlciBub3QgaW4gc3BlYWtlcnM6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgZiJVbmtub3duIHNwZWFrZXI6IHtjdXJyZW50X3NwZWFrZXJ9LiBHaXZlbiBzcGVha2VycyBhcmU6IHtzcGVha2Vyc30iCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgZm9yIHNlbnRlbmNlIGluIF9zcGxpdF9saW5lKGxpbmU9c2VudGVuY2VzKToKICAgICAgICAgICAgICAgICAgICAjIEdlbmVyYXRlIHdvcmRzIGF1ZGlvOgogICAgICAgICAgICAgICAgICAgIGF1ZGlvID0gYmFyay5nZW5lcmF0ZV9hdWRpbygKICAgICAgICAgICAgICAgICAgICAgICAgc2VudGVuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGhpc3RvcnlfcHJvbXB0PWNob3Nlbl92b2ljZXNbY3VycmVudF9zcGVha2VyXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2lsZW50PVRydWUsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIGlmIHNwZWFrZXJfcGVyX2NoYW5uZWw6CiAgICAgICAgICAgICAgICAgICAgICAgIHNpbGVuY2UgPSBucC56ZXJvc19saWtlKGF1ZGlvKQogICAgICAgICAgICAgICAgICAgICAgICBmb3Igc3BlYWtlciBpbiBhdWRpb19waWVjZXMua2V5cygpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgc3BlYWtlciA9PSBjdXJyZW50X3NwZWFrZXI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9fcGllY2VzW3NwZWFrZXJdICs9IFthdWRpbywgZ2FwX2JldHdlZW5fc3BlYWtlcnNdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvX3BpZWNlc1tzcGVha2VyXSArPSBbc2lsZW5jZSwgZ2FwX2JldHdlZW5fc3BlYWtlcnNdCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9fcGllY2VzWyJhbGwiXSArPSBbYXVkaW8sIGdhcF9iZXR3ZWVuX3NwZWFrZXJzXQogICAgICAgICAgICAjIENvbnN0cnVjdCBhIHNpbmdsZSBhdWRpbyBhcnJheSBmcm9tIGFsbCB0aGUgcGllY2VzIGFuZCBjaGFubmVsczoKCiAgICAgICAgICAgIGF1ZGlvID0gbnAudnN0YWNrKAogICAgICAgICAgICAgICAgW25wLmNvbmNhdGVuYXRlKGF1ZGlvX3BpZWNlc1tzcGVha2VyXSkgZm9yIHNwZWFrZXIgaW4gc3BlYWtlcnNdCiAgICAgICAgICAgICkuYXN0eXBlKGR0eXBlPW5wLmZsb2F0MzIpCiAgICAgICAgICAgICMgUmVzYW1wbGU6CiAgICAgICAgICAgIGF1ZGlvID0gdG9yY2guZnJvbV9udW1weShhdWRpbykKICAgICAgICAgICAgYXVkaW8gPSByZXNhbXBsZXIoYXVkaW8pCiAgICAgICAgICAgICMgU2F2ZSB0byBhdWRpbyBmaWxlOgogICAgICAgICAgICBhdWRpb19maWxlID0gb3V0cHV0X2RpcmVjdG9yeSAvIGYie3RleHRfZmlsZS5zdGVtfS57ZmlsZV9mb3JtYXR9IgoKICAgICAgICAgICAgdG9yY2hhdWRpby5zYXZlKAogICAgICAgICAgICAgICAgdXJpPXN0cihhdWRpb19maWxlKSwKICAgICAgICAgICAgICAgIHNyYz1hdWRpbywKICAgICAgICAgICAgICAgIHNhbXBsZV9yYXRlPXNhbXBsZV9yYXRlLAogICAgICAgICAgICAgICAgZm9ybWF0PWZpbGVfZm9ybWF0LAogICAgICAgICAgICAgICAgYml0c19wZXJfc2FtcGxlPWJpdHNfcGVyX3NhbXBsZSwKICAgICAgICAgICAgKQoKICAgICAgICAgICAgIyBDb2xsZWN0IHRvIHRoZSBzdWNjZXNzZXM6CiAgICAgICAgICAgIHN1Y2Nlc3Nlcy5hcHBlbmQoW3RleHRfZmlsZS5uYW1lLCBhdWRpb19maWxlLm5hbWVdKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZXhjZXB0aW9uOgogICAgICAgICAgICAjIE5vdGUgdGhlIGV4Y2VwdGlvbiBhcyBlcnJvciBpbiB0aGUgZGljdGlvbmFyeToKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIF9MT0dHRVIud2FybmluZyhmIkVycm9yIGluIGZpbGU6ICd7dGV4dF9maWxlLm5hbWV9JyIpCiAgICAgICAgICAgIHByaW50KGV4Y2VwdGlvbikKICAgICAgICAgICAgZXJyb3JzW3RleHRfZmlsZS5uYW1lXSA9IHN0cihleGNlcHRpb24pCgogICAgIyBDb25zdHJ1Y3QgdGhlIHRyYW5zbGF0aW9ucyBkYXRhZnJhbWU6CiAgICBzdWNjZXNzZXMgPSBwZC5EYXRhRnJhbWUoCiAgICAgICAgc3VjY2Vzc2VzLAogICAgICAgIGNvbHVtbnM9WyJ0ZXh0X2ZpbGUiLCAiYXVkaW9fZmlsZSJdLAogICAgKQoKICAgICMgUHJpbnQgdGhlIGhlYWQgb2YgdGhlIHByb2R1Y2VkIGRhdGFmcmFtZSBhbmQgcmV0dXJuOgogICAgaWYgdmVyYm9zZToKICAgICAgICBfTE9HR0VSLmluZm8oCiAgICAgICAgICAgIGYiRG9uZSAoe3N1Y2Nlc3Nlcy5zaGFwZVswXX0ve2xlbih0ZXh0X2ZpbGVzKX0pXG4iCiAgICAgICAgICAgIGYiVHJhbnNsYXRpb25zIHN1bW1hcnk6XG4iCiAgICAgICAgICAgIGYie3N1Y2Nlc3Nlcy5oZWFkKCl9IgogICAgICAgICkKICAgIHJldHVybiBzdHIob3V0cHV0X2RpcmVjdG9yeSksIHN1Y2Nlc3NlcywgZXJyb3JzCgoKZGVmIF9nZXRfdGV4dF9maWxlcygKICAgIGRhdGFfcGF0aDogcGF0aGxpYi5QYXRoLAopIC0+IExpc3RbcGF0aGxpYi5QYXRoXToKICAgICMgQ2hlY2sgaWYgdGhlIHBhdGggaXMgb2YgYSBkaXJlY3Rvcnkgb3IgYSBmaWxlOgogICAgaWYgZGF0YV9wYXRoLmlzX2RpcigpOgogICAgICAgICMgR2V0IGFsbCBmaWxlcyBpbnNpZGUgdGhlIGRpcmVjdG9yeToKICAgICAgICB0ZXh0X2ZpbGVzID0gbGlzdChkYXRhX3BhdGguZ2xvYigiKi4qIikpCiAgICBlbGlmIGRhdGFfcGF0aC5pc19maWxlKCk6CiAgICAgICAgdGV4dF9maWxlcyA9IFtkYXRhX3BhdGhdCiAgICBlbHNlOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCiAgICAgICAgICAgIGYiVW5yZWNvZ25pemVkIGRhdGEgcGF0aC4gVGhlIHBhcmFtZXRlciBgZGF0YV9wYXRoYCBtdXN0IGJlIGVpdGhlciBhIGRpcmVjdG9yeSBwYXRoIG9yIGEgZmlsZSBwYXRoLiAiCiAgICAgICAgICAgIGYiR2l2ZW46IHtzdHIoZGF0YV9wYXRoKX0gIgogICAgICAgICkKCiAgICByZXR1cm4gdGV4dF9maWxlcwoKCmRlZiBfc3BsaXRfbGluZShsaW5lOiBzdHIsIG1heF9sZW5ndGg6IGludCA9IDI1MCkgLT4gTGlzdFtzdHJdOgogICAgaWYgbGVuKGxpbmUpIDwgbWF4X2xlbmd0aDoKICAgICAgICByZXR1cm4gW2xpbmVdCgogICAgc2VudGVuY2VzID0gWwogICAgICAgIGYie3NlbnRlbmNlLnN0cmlwKCl9LiIgZm9yIHNlbnRlbmNlIGluIGxpbmUuc3BsaXQoIi4iKSBpZiBzZW50ZW5jZS5zdHJpcCgpCiAgICBdCgogICAgc3BsaXRzID0gW10KICAgIGN1cnJlbnRfbGVuZ3RoID0gbGVuKHNlbnRlbmNlc1swXSkKICAgIHNwbGl0ID0gc2VudGVuY2VzWzBdCiAgICBmb3Igc2VudGVuY2UgaW4gc2VudGVuY2VzWzE6XToKICAgICAgICBpZiBjdXJyZW50X2xlbmd0aCArIGxlbihzZW50ZW5jZSkgPiBtYXhfbGVuZ3RoOgogICAgICAgICAgICBzcGxpdHMuYXBwZW5kKHNwbGl0KQogICAgICAgICAgICBzcGxpdCA9IHNlbnRlbmNlCiAgICAgICAgICAgIGN1cnJlbnRfbGVuZ3RoID0gbGVuKHNlbnRlbmNlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGN1cnJlbnRfbGVuZ3RoICs9IGxlbihzZW50ZW5jZSkKICAgICAgICAgICAgc3BsaXQgKz0gIiAiICsgc2VudGVuY2UKICAgIGlmIHNwbGl0OgogICAgICAgIHNwbGl0cy5hcHBlbmQoc3BsaXQpCgogICAgcmV0dXJuIHNwbGl0cwoKCmRlZiBfZ2V0X2xvZ2dlcigpOgogICAgZ2xvYmFsIF9MT0dHRVIKICAgIHRyeToKICAgICAgICBpbXBvcnQgbWxydW4KICAgICAgICAjIENoZWNrIGlmIE1MUnVuIGlzIGF2YWlsYWJsZToKICAgICAgICBjb250ZXh0ID0gbWxydW4uZ2V0X29yX2NyZWF0ZV9jdHgobmFtZT0ibWxydW4iKQogICAgICAgIHJldHVybiBjb250ZXh0LmxvZ2dlcgogICAgZXhjZXB0IE1vZHVsZU5vdEZvdW5kRXJyb3I6CiAgICAgICAgcmV0dXJuIF9MT0dHRVIK - base_image: mlrun/mlrun - commands: [] - code_origin: '' - origin_filename: '' + functionSourceCode: IyBDb3B5cmlnaHQgMjAyMyBJZ3VhemlvCiMKIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiMKIyAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAojCiMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQojIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAojIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgppbXBvcnQgaW8KaW1wb3J0IGxvZ2dpbmcKaW1wb3J0IG9zCmltcG9ydCBwYXRobGliCmltcG9ydCByYW5kb20KaW1wb3J0IHRlbXBmaWxlCmZyb20gdHlwaW5nIGltcG9ydCBEaWN0LCBMaXN0LCBPcHRpb25hbCwgVHVwbGUsIFVuaW9uCgppbXBvcnQgbnVtcHkgYXMgbnAKaW1wb3J0IG9wZW5haQppbXBvcnQgcGFuZGFzIGFzIHBkCmltcG9ydCB0b3JjaAppbXBvcnQgdG9yY2hhdWRpbwppbXBvcnQgdHFkbQpmcm9tIHB5ZHViIGltcG9ydCBBdWRpb1NlZ21lbnQKCiMgR2V0IHRoZSBnbG9iYWwgbG9nZ2VyOgpfTE9HR0VSID0gbG9nZ2luZy5nZXRMb2dnZXIoKQoKT1BFTkFJX0FQSV9LRVkgPSAiT1BFTkFJX0FQSV9LRVkiCk9QRU5BSV9CQVNFX1VSTCA9ICJPUEVOQUlfQkFTRV9VUkwiClNBTVBMRV9SQVRFID0gMjQwMDAKCgpkZWYgZ2VuZXJhdGVfbXVsdGlfc3BlYWtlcnNfYXVkaW8oCiAgICBkYXRhX3BhdGg6IHN0ciwKICAgIHNwZWFrZXJzOiBVbmlvbltMaXN0W3N0cl0sIERpY3Rbc3RyLCBpbnRdXSwKICAgIGF2YWlsYWJsZV92b2ljZXM6IExpc3Rbc3RyXSwKICAgIG91dHB1dF9kaXJlY3Rvcnk6IHN0ciA9IE5vbmUsCiAgICBtb2RlbDogc3RyID0gInR0cy0xIiwKICAgIHNhbXBsZV9yYXRlOiBpbnQgPSAxNjAwMCwKICAgIGZpbGVfZm9ybWF0OiBzdHIgPSAid2F2IiwKICAgIHZlcmJvc2U6IGJvb2wgPSBUcnVlLAogICAgYml0c19wZXJfc2FtcGxlOiBPcHRpb25hbFtpbnRdID0gTm9uZSwKICAgIHNwZWVkOiBmbG9hdCA9IDEuMCwKKSAtPiBUdXBsZVtzdHIsIHBkLkRhdGFGcmFtZSwgZGljdF06CiAgICAiIiIKICAgIEdlbmVyYXRlIGF1ZGlvIGZpbGVzIGZyb20gdGV4dCBmaWxlcy4KCiAgICA6cGFyYW0gZGF0YV9wYXRoOiAgICAgICAgICAgUGF0aCB0byB0aGUgdGV4dCBmaWxlIG9yIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSB0ZXh0IGZpbGVzIHRvIGdlbmVyYXRlIGF1ZGlvIGZyb20uCiAgICA6cGFyYW0gc3BlYWtlcnM6ICAgICAgICAgICAgTGlzdCAvIERpY3Qgb2Ygc3BlYWtlcnMgdG8gZ2VuZXJhdGUgYXVkaW8gZm9yLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIGEgbGlzdCBpcyBnaXZlbiwgdGhlIHNwZWFrZXJzIHdpbGwgYmUgYXNzaWduZWQgdG8gY2hhbm5lbHMgaW4gdGhlIG9yZGVyIGdpdmVuLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIGRpY3Rpb25hcnksIHRoZSBrZXlzIHdpbGwgYmUgdGhlIHNwZWFrZXJzIGFuZCB0aGUgdmFsdWVzIHdpbGwgYmUgdGhlIGNoYW5uZWxzLgogICAgOnBhcmFtIGF2YWlsYWJsZV92b2ljZXM6ICAgIExpc3Qgb2YgYXZhaWxhYmxlIHZvaWNlcyB0byB1c2UgZm9yIHRoZSBnZW5lcmF0aW9uLgogICAgICAgICAgICAgICAgICAgICAgICBTZWUgaGVyZSBmb3IgdGhlIGF2YWlsYWJsZSB2b2ljZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHBzOi8vcGxhdGZvcm0ub3BlbmFpLmNvbS9kb2NzL2d1aWRlcy90ZXh0LXRvLXNwZWVjaCN2b2ljZS1vcHRpb25zCiAgICA6cGFyYW0gb3V0cHV0X2RpcmVjdG9yeTogICAgUGF0aCB0byB0aGUgZGlyZWN0b3J5IHRvIHNhdmUgdGhlIGdlbmVyYXRlZCBhdWRpbyBmaWxlcyB0by4KICAgIDpwYXJhbSBtb2RlbDogICAgICAgICAgICAgICBXaGljaCBtb2RlbCB0byB1c2UgZm9yIHRoZSBnZW5lcmF0aW9uLgogICAgOnBhcmFtIHNhbXBsZV9yYXRlOiAgICAgICAgIFRoZSBzYW1wbGluZyByYXRlIG9mIHRoZSBnZW5lcmF0ZWQgYXVkaW8uCiAgICA6cGFyYW0gZmlsZV9mb3JtYXQ6ICAgICAgICAgVGhlIGZvcm1hdCBvZiB0aGUgZ2VuZXJhdGVkIGF1ZGlvIGZpbGVzLgogICAgOnBhcmFtIHZlcmJvc2U6ICAgICAgICAgICAgIFdoZXRoZXIgdG8gcHJpbnQgdGhlIHByb2dyZXNzIG9mIHRoZSBnZW5lcmF0aW9uLgogICAgOnBhcmFtIGJpdHNfcGVyX3NhbXBsZTogICAgIENoYW5nZXMgdGhlIGJpdCBkZXB0aCBmb3IgdGhlIHN1cHBvcnRlZCBmb3JtYXRzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRlZCBvbmx5IGluICJ3YXYiIG9yICJmbGFjIiBmb3JtYXRzLgogICAgOnBhcmFtIHNwZWVkOiAgICAgICAgICAgICAgIFRoZSBzcGVlZCBvZiB0aGUgZ2VuZXJhdGVkIGF1ZGlvLiBTZWxlY3QgYSB2YWx1ZSBmcm9tIGAwLjI1YCB0byBgNC4wYC4gYDEuMGAgaXMgdGhlIGRlZmF1bHQuCgogICAgOnJldHVybnM6ICAgICAgICAgICAgICAgICAgIEEgdHVwbGUgb2Y6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBUaGUgb3V0cHV0IGRpcmVjdG9yeSBwYXRoLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gVGhlIGdlbmVyYXRlZCBhdWRpbyBmaWxlcyBkYXRhZnJhbWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBUaGUgZXJyb3JzJyBkaWN0aW9uYXJ5LgogICAgIiIiCgogICAgZ2xvYmFsIF9MT0dHRVIKICAgIF9MT0dHRVIgPSBfZ2V0X2xvZ2dlcigpCiAgICAjIEdldCB0aGUgaW5wdXQgdGV4dCBmaWxlcyB0byB0dXJuIHRvIGF1ZGlvOgogICAgZGF0YV9wYXRoID0gcGF0aGxpYi5QYXRoKGRhdGFfcGF0aCkuYWJzb2x1dGUoKQogICAgdGV4dF9maWxlcyA9IF9nZXRfdGV4dF9maWxlcyhkYXRhX3BhdGg9ZGF0YV9wYXRoKQoKICAgICMgY29ubmVjdCB0byBvcGVuYWkgY2xpZW50OgogICAgY2xpZW50ID0gX2dldF9vcGVuYWlfY2xpZW50KCkKCiAgICAjIENoZWNrIGZvciBwZXIgY2hhbm5lbCBnZW5lcmF0aW9uOgogICAgaWYgaXNpbnN0YW5jZShzcGVha2VycywgZGljdCk6CiAgICAgICAgc3BlYWtlcl9wZXJfY2hhbm5lbCA9IFRydWUKICAgICAgICAjIFNvcnQgdGhlIGdpdmVuIHNwZWFrZXJzIGJ5IGNoYW5uZWxzOgogICAgICAgIHNwZWFrZXJzID0gewogICAgICAgICAgICBzcGVha2VyOiBjaGFubmVsCiAgICAgICAgICAgIGZvciBzcGVha2VyLCBjaGFubmVsIGluIHNvcnRlZChzcGVha2Vycy5pdGVtcygpLCBrZXk9bGFtYmRhIGl0ZW06IGl0ZW1bMV0pCiAgICAgICAgfQogICAgZWxzZToKICAgICAgICBzcGVha2VyX3Blcl9jaGFubmVsID0gRmFsc2UKCiAgICAjIFByZXBhcmUgdGhlIHJlc2FtcGxpbmcgbW9kdWxlOgogICAgcmVzYW1wbGVyID0gdG9yY2hhdWRpby50cmFuc2Zvcm1zLlJlc2FtcGxlKAogICAgICAgIG9yaWdfZnJlcT1TQU1QTEVfUkFURSwgbmV3X2ZyZXE9c2FtcGxlX3JhdGUsIGR0eXBlPXRvcmNoLmZsb2F0MzIKICAgICkKCiAgICAjIFByZXBhcmUgdGhlIGdhcCBiZXR3ZWVuIGVhY2ggc3BlYWtlcjoKICAgIGdhcF9iZXR3ZWVuX3NwZWFrZXJzID0gbnAuemVyb3MoaW50KDAuNSAqIFNBTVBMRV9SQVRFKSkKCiAgICAjIFByZXBhcmUgdGhlIHN1Y2Nlc3NlcyBkYXRhZnJhbWUgYW5kIGVycm9ycyBkaWN0aW9uYXJ5IHRvIGJlIHJldHVybmVkOgogICAgc3VjY2Vzc2VzID0gW10KICAgIGVycm9ycyA9IHt9CgogICAgIyBDcmVhdGUgdGhlIG91dHB1dCBkaXJlY3Rvcnk6CiAgICBpZiBvdXRwdXRfZGlyZWN0b3J5IGlzIE5vbmU6CiAgICAgICAgb3V0cHV0X2RpcmVjdG9yeSA9IHRlbXBmaWxlLm1rZHRlbXAoKQogICAgb3V0cHV0X2RpcmVjdG9yeSA9IHBhdGhsaWIuUGF0aChvdXRwdXRfZGlyZWN0b3J5KQogICAgaWYgbm90IG91dHB1dF9kaXJlY3RvcnkuZXhpc3RzKCk6CiAgICAgICAgb3V0cHV0X2RpcmVjdG9yeS5ta2RpcihleGlzdF9vaz1UcnVlLCBwYXJlbnRzPVRydWUpCgogICAgIyBTdGFydCBnZW5lcmF0aW5nIGF1ZGlvOgogICAgIyBHbyBvdmVyIHRoZSBhdWRpbyBmaWxlcyBhbmQgdHJhbnNjcmliZToKICAgIGZvciB0ZXh0X2ZpbGUgaW4gdHFkbS50cWRtKAogICAgICAgIHRleHRfZmlsZXMsIGRlc2M9IkdlbmVyYXRpbmciLCB1bml0PSJmaWxlIiwgZGlzYWJsZT1ub3QgdmVyYm9zZQogICAgKToKCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIFJhbmRvbWl6ZSB2b2ljZXMgZm9yIGVhY2ggc3BlYWtlcjoKICAgICAgICAgICAgY2hvc2VuX3ZvaWNlcyA9IHt9CiAgICAgICAgICAgIGF2YWlsYWJsZV92b2ljZXNfY29weSA9IGF2YWlsYWJsZV92b2ljZXMuY29weSgpCiAgICAgICAgICAgIGZvciBzcGVha2VyIGluIHNwZWFrZXJzOgogICAgICAgICAgICAgICAgdm9pY2UgPSByYW5kb20uY2hvaWNlKGF2YWlsYWJsZV92b2ljZXNfY29weSkKICAgICAgICAgICAgICAgIGNob3Nlbl92b2ljZXNbc3BlYWtlcl0gPSB2b2ljZQogICAgICAgICAgICAgICAgYXZhaWxhYmxlX3ZvaWNlc19jb3B5LnJlbW92ZSh2b2ljZSkKICAgICAgICAgICAgIyBSZWFkIHRleHQ6CiAgICAgICAgICAgIHdpdGggb3Blbih0ZXh0X2ZpbGUsICJyIikgYXMgZnA6CiAgICAgICAgICAgICAgICB0ZXh0ID0gZnAucmVhZCgpCiAgICAgICAgICAgICMgUHJlcGFyZSBhIGhvbGRlciBmb3IgYWxsIHRoZSBnZW5lcmF0ZWQgcGllY2VzIChpZiBwZXIgY2hhbm5lbCBlYWNoIHNwZWFrZXIgd2lsbCBoYXZlIGl0cyBvd24pOgogICAgICAgICAgICBhdWRpb19waWVjZXMgPSAoCiAgICAgICAgICAgICAgICB7c3BlYWtlcjogW10gZm9yIHNwZWFrZXIgaW4gc3BlYWtlcnN9CiAgICAgICAgICAgICAgICBpZiBzcGVha2VyX3Blcl9jaGFubmVsCiAgICAgICAgICAgICAgICBlbHNlIHsiYWxsIjogW119CiAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgR2VuZXJhdGUgYXVkaW8gcGVyIGxpbmU6CiAgICAgICAgICAgIGZvciBsaW5lIGluIHRleHQuc3BsaXRsaW5lcygpOgogICAgICAgICAgICAgICAgIyBWYWxpZGF0ZSBsaW5lIGlzIGluIGNvcnJlY3Qgc3BlYWtlciBmb3JtYXQ6CgogICAgICAgICAgICAgICAgaWYgIjogIiBub3QgaW4gbGluZToKICAgICAgICAgICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgICAgICAgICBfTE9HR0VSLndhcm5pbmcoZiJTa2lwcGluZyBsaW5lOiB7bGluZX0iKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAjIFNwbGl0IGxpbmUgdG8gc3BlYWtlciBhbmQgaGlzIHdvcmRzOgogICAgICAgICAgICAgICAgY3VycmVudF9zcGVha2VyLCBzZW50ZW5jZXMgPSBsaW5lLnNwbGl0KCI6ICIsIDEpCiAgICAgICAgICAgICAgICAjIFZhbGlkYXRlIHNwZWFrZXIgaXMga25vd246CiAgICAgICAgICAgICAgICBpZiBjdXJyZW50X3NwZWFrZXIgbm90IGluIHNwZWFrZXJzOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIGYiVW5rbm93biBzcGVha2VyOiB7Y3VycmVudF9zcGVha2VyfS4gR2l2ZW4gc3BlYWtlcnMgYXJlOiB7c3BlYWtlcnN9IgogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGZvciBzZW50ZW5jZSBpbiBfc3BsaXRfbGluZShsaW5lPXNlbnRlbmNlcyk6CiAgICAgICAgICAgICAgICAgICAgIyBHZW5lcmF0ZSB3b3JkcyBhdWRpbzoKICAgICAgICAgICAgICAgICAgICBhdWRpbyA9IGNsaWVudC5hdWRpby5zcGVlY2guY3JlYXRlKAogICAgICAgICAgICAgICAgICAgICAgICBtb2RlbD1tb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ9c2VudGVuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHZvaWNlPWNob3Nlbl92b2ljZXNbY3VycmVudF9zcGVha2VyXSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VfZm9ybWF0PWZpbGVfZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICBzcGVlZD1zcGVlZCwKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgYXVkaW8gPSBhdWRpby5jb250ZW50CiAgICAgICAgICAgICAgICAgICAgYXVkaW8gPSBfYnl0ZXNfdG9fbnBfYXJyYXkoYXVkaW89YXVkaW8sIGZpbGVfZm9ybWF0PWZpbGVfZm9ybWF0KQoKICAgICAgICAgICAgICAgICAgICBpZiBzcGVha2VyX3Blcl9jaGFubmVsOgogICAgICAgICAgICAgICAgICAgICAgICBzaWxlbmNlID0gbnAuemVyb3NfbGlrZShhdWRpbykKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIHNwZWFrZXIgaW4gYXVkaW9fcGllY2VzLmtleXMoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHNwZWFrZXIgPT0gY3VycmVudF9zcGVha2VyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvX3BpZWNlc1tzcGVha2VyXSArPSBbYXVkaW8sIGdhcF9iZXR3ZWVuX3NwZWFrZXJzXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb19waWVjZXNbc3BlYWtlcl0gKz0gW3NpbGVuY2UsIGdhcF9iZXR3ZWVuX3NwZWFrZXJzXQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvX3BpZWNlc1siYWxsIl0gKz0gW2F1ZGlvLCBnYXBfYmV0d2Vlbl9zcGVha2Vyc10KICAgICAgICAgICAgIyBDb25zdHJ1Y3QgYSBzaW5nbGUgYXVkaW8gYXJyYXkgZnJvbSBhbGwgdGhlIHBpZWNlcyBhbmQgY2hhbm5lbHM6CgogICAgICAgICAgICBhdWRpbyA9IG5wLnZzdGFjaygKICAgICAgICAgICAgICAgIFtucC5jb25jYXRlbmF0ZShhdWRpb19waWVjZXNbc3BlYWtlcl0pIGZvciBzcGVha2VyIGluIHNwZWFrZXJzXQogICAgICAgICAgICApLmFzdHlwZShkdHlwZT1ucC5mbG9hdDMyKQogICAgICAgICAgICAjIFJlc2FtcGxlOgogICAgICAgICAgICBhdWRpbyA9IHRvcmNoLmZyb21fbnVtcHkoYXVkaW8pCiAgICAgICAgICAgIGF1ZGlvID0gcmVzYW1wbGVyKGF1ZGlvKQogICAgICAgICAgICAjIFNhdmUgdG8gYXVkaW8gZmlsZToKICAgICAgICAgICAgYXVkaW9fZmlsZSA9IG91dHB1dF9kaXJlY3RvcnkgLyBmInt0ZXh0X2ZpbGUuc3RlbX0ue2ZpbGVfZm9ybWF0fSIKCiAgICAgICAgICAgIHRvcmNoYXVkaW8uc2F2ZSgKICAgICAgICAgICAgICAgIHVyaT1zdHIoYXVkaW9fZmlsZSksCiAgICAgICAgICAgICAgICBzcmM9YXVkaW8sCiAgICAgICAgICAgICAgICBzYW1wbGVfcmF0ZT1zYW1wbGVfcmF0ZSwKICAgICAgICAgICAgICAgIGZvcm1hdD1maWxlX2Zvcm1hdCwKICAgICAgICAgICAgICAgIGJpdHNfcGVyX3NhbXBsZT1iaXRzX3Blcl9zYW1wbGUsCiAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgQ29sbGVjdCB0byB0aGUgc3VjY2Vzc2VzOgogICAgICAgICAgICBzdWNjZXNzZXMuYXBwZW5kKFt0ZXh0X2ZpbGUubmFtZSwgYXVkaW9fZmlsZS5uYW1lXSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGV4Y2VwdGlvbjoKICAgICAgICAgICAgIyBOb3RlIHRoZSBleGNlcHRpb24gYXMgZXJyb3IgaW4gdGhlIGRpY3Rpb25hcnk6CiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBfTE9HR0VSLndhcm5pbmcoZiJFcnJvciBpbiBmaWxlOiAne3RleHRfZmlsZS5uYW1lfSciKQogICAgICAgICAgICBwcmludChleGNlcHRpb24pCiAgICAgICAgICAgIGVycm9yc1t0ZXh0X2ZpbGUubmFtZV0gPSBzdHIoZXhjZXB0aW9uKQoKICAgICMgQ29uc3RydWN0IHRoZSB0cmFuc2xhdGlvbnMgZGF0YWZyYW1lOgogICAgc3VjY2Vzc2VzID0gcGQuRGF0YUZyYW1lKAogICAgICAgIHN1Y2Nlc3NlcywKICAgICAgICBjb2x1bW5zPVsidGV4dF9maWxlIiwgImF1ZGlvX2ZpbGUiXSwKICAgICkKCiAgICAjIFByaW50IHRoZSBoZWFkIG9mIHRoZSBwcm9kdWNlZCBkYXRhZnJhbWUgYW5kIHJldHVybjoKICAgIGlmIHZlcmJvc2U6CiAgICAgICAgX0xPR0dFUi5pbmZvKAogICAgICAgICAgICBmIkRvbmUgKHtzdWNjZXNzZXMuc2hhcGVbMF19L3tsZW4odGV4dF9maWxlcyl9KVxuIgogICAgICAgICAgICBmIlRyYW5zbGF0aW9ucyBzdW1tYXJ5OlxuIgogICAgICAgICAgICBmIntzdWNjZXNzZXMuaGVhZCgpfSIKICAgICAgICApCiAgICByZXR1cm4gc3RyKG91dHB1dF9kaXJlY3RvcnkpLCBzdWNjZXNzZXMsIGVycm9ycwoKCmRlZiBfZ2V0X29wZW5haV9jbGllbnQoKToKICAgIGFwaV9rZXkgPSBvcy5nZXRlbnYoT1BFTkFJX0FQSV9LRVkpCiAgICBiYXNlX3VybCA9IG9zLmdldGVudihPUEVOQUlfQkFTRV9VUkwpCiAgICAjIENoZWNrIGlmIHRoZSBrZXkgaXMgYWxyZWFkeSBpbiB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzOgogICAgaWYgbm90IGFwaV9rZXkgb3Igbm90IGJhc2VfdXJsOgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IG1scnVuCgogICAgICAgICAgICBjb250ZXh0ID0gbWxydW4uZ2V0X29yX2NyZWF0ZV9jdHgobmFtZT0iY29udGV4dCIpCiAgICAgICAgICAgICMgQ2hlY2sgaWYgdGhlIGtleSBpcyBpbiB0aGUgc2VjcmV0czoKICAgICAgICAgICAgYXBpX2tleSA9IGNvbnRleHQuZ2V0X3NlY3JldChPUEVOQUlfQVBJX0tFWSkKICAgICAgICAgICAgYmFzZV91cmwgPSBjb250ZXh0LmdldF9zZWNyZXQoT1BFTkFJX0JBU0VfVVJMKQogICAgICAgIGV4Y2VwdCBNb2R1bGVOb3RGb3VuZEVycm9yOgogICAgICAgICAgICByYWlzZSBFbnZpcm9ubWVudEVycm9yKAogICAgICAgICAgICAgICAgZiJPbmUgb3IgbW9yZSBvZiB0aGUgT3BlbkFJIHJlcXVpcmVkIGVudmlyb25tZW50IHZhcmlhYmxlcyAoJ3tPUEVOQUlfQVBJX0tFWX0nLCAne09QRU5BSV9CQVNFX1VSTH0nKSBhcmUgbWlzc2luZy4iCiAgICAgICAgICAgICAgICBmIlBsZWFzZSBzZXQgdGhlbSBhcyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgb3IgaW5zdGFsbCBtbHJ1biAoYHBpcCBpbnN0YWxsIG1scnVuYCkiCiAgICAgICAgICAgICAgICBmImFuZCBzZXQgdGhlbSBhcyBwcm9qZWN0IHNlY3JldHMgdXNpbmcgYHByb2plY3Quc2V0X3NlY3JldHNgLiIKICAgICAgICAgICAgKQogICAgcmV0dXJuIG9wZW5haS5PcGVuQUkoYXBpX2tleT1hcGlfa2V5LCBiYXNlX3VybD1iYXNlX3VybCkKCgpkZWYgX2J5dGVzX3RvX25wX2FycmF5KGF1ZGlvOiBieXRlcywgZmlsZV9mb3JtYXQ6IHN0cik6CiAgICBpZiBmaWxlX2Zvcm1hdCA9PSAibXAzIjoKICAgICAgICBhdWRpb19zZWdtZW50ID0gQXVkaW9TZWdtZW50LmZyb21fbXAzKGlvLkJ5dGVzSU8oYXVkaW8pKQoKICAgICAgICAjIENvbnZlcnQgdG8gcmF3IFBDTSBhdWRpbyBkYXRhCiAgICAgICAgc2FtcGxlcyA9IGF1ZGlvX3NlZ21lbnQuZ2V0X2FycmF5X29mX3NhbXBsZXMoKQoKICAgICAgICAjIENvbnZlcnQgdG8gbnVtcHkgYXJyYXkKICAgICAgICBhdWRpb19hcnJheSA9IG5wLmFycmF5KHNhbXBsZXMpCgogICAgICAgICMgTm9ybWFsaXplIHRvIGZsb2F0IGJldHdlZW4gLTEgYW5kIDEKICAgICAgICByZXR1cm4gYXVkaW9fYXJyYXkuYXN0eXBlKG5wLmZsb2F0MzIpIC8gbnAuaWluZm8oc2FtcGxlcy50eXBlY29kZSkubWF4CiAgICBlbHNlOgogICAgICAgIHJldHVybiBucC5mcm9tYnVmZmVyKGF1ZGlvLCBkdHlwZT1ucC5pbnQxNikgLyAzMjc2OC4wCgoKZGVmIF9nZXRfdGV4dF9maWxlcygKICAgIGRhdGFfcGF0aDogcGF0aGxpYi5QYXRoLAopIC0+IExpc3RbcGF0aGxpYi5QYXRoXToKICAgICMgQ2hlY2sgaWYgdGhlIHBhdGggaXMgb2YgYSBkaXJlY3Rvcnkgb3IgYSBmaWxlOgogICAgaWYgZGF0YV9wYXRoLmlzX2RpcigpOgogICAgICAgICMgR2V0IGFsbCBmaWxlcyBpbnNpZGUgdGhlIGRpcmVjdG9yeToKICAgICAgICB0ZXh0X2ZpbGVzID0gbGlzdChkYXRhX3BhdGguZ2xvYigiKi4qIikpCiAgICBlbGlmIGRhdGFfcGF0aC5pc19maWxlKCk6CiAgICAgICAgdGV4dF9maWxlcyA9IFtkYXRhX3BhdGhdCiAgICBlbHNlOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCiAgICAgICAgICAgIGYiVW5yZWNvZ25pemVkIGRhdGEgcGF0aC4gVGhlIHBhcmFtZXRlciBgZGF0YV9wYXRoYCBtdXN0IGJlIGVpdGhlciBhIGRpcmVjdG9yeSBwYXRoIG9yIGEgZmlsZSBwYXRoLiAiCiAgICAgICAgICAgIGYiR2l2ZW46IHtzdHIoZGF0YV9wYXRoKX0gIgogICAgICAgICkKCiAgICByZXR1cm4gdGV4dF9maWxlcwoKCmRlZiBfc3BsaXRfbGluZShsaW5lOiBzdHIsIG1heF9sZW5ndGg6IGludCA9IDI1MCkgLT4gTGlzdFtzdHJdOgogICAgaWYgbGVuKGxpbmUpIDwgbWF4X2xlbmd0aDoKICAgICAgICByZXR1cm4gW2xpbmVdCgogICAgc2VudGVuY2VzID0gWwogICAgICAgIGYie3NlbnRlbmNlLnN0cmlwKCl9LiIgZm9yIHNlbnRlbmNlIGluIGxpbmUuc3BsaXQoIi4iKSBpZiBzZW50ZW5jZS5zdHJpcCgpCiAgICBdCgogICAgc3BsaXRzID0gW10KICAgIGN1cnJlbnRfbGVuZ3RoID0gbGVuKHNlbnRlbmNlc1swXSkKICAgIHNwbGl0ID0gc2VudGVuY2VzWzBdCiAgICBmb3Igc2VudGVuY2UgaW4gc2VudGVuY2VzWzE6XToKICAgICAgICBpZiBjdXJyZW50X2xlbmd0aCArIGxlbihzZW50ZW5jZSkgPiBtYXhfbGVuZ3RoOgogICAgICAgICAgICBzcGxpdHMuYXBwZW5kKHNwbGl0KQogICAgICAgICAgICBzcGxpdCA9IHNlbnRlbmNlCiAgICAgICAgICAgIGN1cnJlbnRfbGVuZ3RoID0gbGVuKHNlbnRlbmNlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGN1cnJlbnRfbGVuZ3RoICs9IGxlbihzZW50ZW5jZSkKICAgICAgICAgICAgc3BsaXQgKz0gIiAiICsgc2VudGVuY2UKICAgIGlmIHNwbGl0OgogICAgICAgIHNwbGl0cy5hcHBlbmQoc3BsaXQpCgogICAgcmV0dXJuIHNwbGl0cwoKCmRlZiBfZ2V0X2xvZ2dlcigpOgogICAgZ2xvYmFsIF9MT0dHRVIKICAgIHRyeToKICAgICAgICBpbXBvcnQgbWxydW4KCiAgICAgICAgIyBDaGVjayBpZiBNTFJ1biBpcyBhdmFpbGFibGU6CiAgICAgICAgY29udGV4dCA9IG1scnVuLmdldF9vcl9jcmVhdGVfY3R4KG5hbWU9Im1scnVuIikKICAgICAgICByZXR1cm4gY29udGV4dC5sb2dnZXIKICAgIGV4Y2VwdCBNb2R1bGVOb3RGb3VuZEVycm9yOgogICAgICAgIHJldHVybiBfTE9HR0VSCg== requirements: - - bark + - openai - torchaudio + - pydub + origin_filename: '' + base_image: mlrun/mlrun + code_origin: '' + command: '' + disable_auto_mount: false + description: Generate audio file from text using different speakers entry_points: generate_multi_speakers_audio: - name: generate_multi_speakers_audio + has_varargs: false doc: Generate audio files from text files. + name: generate_multi_speakers_audio + outputs: + - doc: 'A tuple of: - The output directory path. - The generated audio files + dataframe. - The errors'' dictionary.' + type: Tuple[str, pd.DataFrame, dict] + has_kwargs: false parameters: - name: data_path type: str @@ -40,24 +36,15 @@ spec: - name: available_voices type: List[str] doc: 'List of available voices to use for the generation. See here for the - available voices: https://suno-ai.notion.site/8b8e8749ed514b0cbf3f699013548683?v=bc67cff786b04b50b3ceb756fd05f68c' + available voices: https://platform.openai.com/docs/guides/text-to-speech#voice-options' - name: output_directory type: str doc: Path to the directory to save the generated audio files to. default: null - - name: use_gpu - type: bool - doc: Whether to use the GPU for the generation. - default: true - - name: use_small_models - type: bool - doc: Whether to use the small models for the generation. - default: false - - name: offload_cpu - type: bool - doc: To reduce the memory footprint, the models can be offloaded to the CPU - after loading. - default: false + - name: model + type: str + doc: Which model to use for the generation. + default: tts-1 - name: sample_rate type: int doc: The sampling rate of the generated audio. @@ -75,21 +62,18 @@ spec: doc: Changes the bit depth for the supported formats. Supported only in "wav" or "flac" formats. default: null - outputs: - - doc: 'A tuple of: - The output directory path. - The generated audio files - dataframe. - The errors dictionary.' - type: Tuple[str, pd.DataFrame, dict] - lineno: 31 - has_varargs: false - has_kwargs: false - description: Generate audio file from text using different speakers - default_handler: generate_multi_speakers_audio - disable_auto_mount: false - clone_target_dir: '' - env: [] - priority_class_name: '' - preemption_mode: prevent - affinity: null - tolerations: null - security_context: {} + - name: speed + type: float + doc: The speed of the generated audio. Select a value from `0.25` to `4.0`. + `1.0` is the default. + default: 1.0 + lineno: 38 +kind: job +metadata: + categories: + - data-preparation + - machine-learning + - pytorch + tag: '' + name: text-to-audio-generator verbose: false diff --git a/text_to_audio_generator/item.yaml b/text_to_audio_generator/item.yaml index efa8afc90..3a6af1e7e 100644 --- a/text_to_audio_generator/item.yaml +++ b/text_to_audio_generator/item.yaml @@ -13,7 +13,7 @@ labels: author: yonatans maintainers: [] marketplaceType: '' -mlrunVersion: 1.5.1 +mlrunVersion: 1.7.1 name: text_to_audio_generator platformVersion: 3.5.3 spec: @@ -22,8 +22,9 @@ spec: image: mlrun/mlrun kind: job requirements: - - bark + - openai - torchaudio + - pydub url: '' -version: 1.2.0 +version: 1.3.0 test_valid: True diff --git a/text_to_audio_generator/requirements.txt b/text_to_audio_generator/requirements.txt index 36f17cd61..63dee64df 100644 --- a/text_to_audio_generator/requirements.txt +++ b/text_to_audio_generator/requirements.txt @@ -1,2 +1,3 @@ -bark -torchaudio>=2.1.0 \ No newline at end of file +openai>=1.58.0 +torchaudio>=2.1.0 +pydub \ No newline at end of file diff --git a/text_to_audio_generator/test_text_to_audio_generator.py b/text_to_audio_generator/test_text_to_audio_generator.py index 87ffe1496..94fd8c098 100644 --- a/text_to_audio_generator/test_text_to_audio_generator.py +++ b/text_to_audio_generator/test_text_to_audio_generator.py @@ -12,11 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mlrun +import os import tempfile + +import mlrun import pytest +@pytest.mark.skipif( + condition=os.getenv("OPENAI_BASE_URL") is None + and os.getenv("OPENAI_API_KEY") is None, + reason="OpenAI API key and base URL are required to run this test", +) @pytest.mark.parametrize("file_format,bits_per_sample", [("wav", 8), ("mp3", None)]) def test_generate_multi_speakers_audio(file_format, bits_per_sample): text_to_audio_generator_function = mlrun.import_function("function.yaml") @@ -28,12 +35,9 @@ def test_generate_multi_speakers_audio(file_format, bits_per_sample): "output_directory": test_directory, "speakers": {"Agent": 0, "Client": 1}, "available_voices": [ - "v2/en_speaker_0", - "v2/en_speaker_1", + "alloy", + "echo", ], - "use_small_models": True, - "use_gpu": False, - "offload_cpu": True, "file_format": file_format, "bits_per_sample": bits_per_sample, }, @@ -45,6 +49,6 @@ def test_generate_multi_speakers_audio(file_format, bits_per_sample): ], artifact_path=test_directory, ) - assert function_run.error == "Run state (completed) is not in error state" + assert function_run.error == "" for key in ["audio_files", "audio_files_dataframe", "text_to_speech_errors"]: assert key in function_run.outputs and function_run.outputs[key] is not None diff --git a/text_to_audio_generator/text_to_audio_generator.ipynb b/text_to_audio_generator/text_to_audio_generator.ipynb index 268fe2efb..a70882a44 100644 --- a/text_to_audio_generator/text_to_audio_generator.ipynb +++ b/text_to_audio_generator/text_to_audio_generator.ipynb @@ -31,10 +31,7 @@ "id": "bb20c4a6-f362-40e6-8f73-9145953959ec", "metadata": {}, "outputs": [], - "source": [ - "import mlrun\n", - "import tempfile" - ] + "source": "import mlrun" }, { "cell_type": "code", @@ -322,12 +319,9 @@ " \"output_directory\": \"./out\",\n", " \"speakers\": {\"Agent\": 0, \"Client\": 1},\n", " \"available_voices\": [\n", - " \"v2/en_speaker_0\",\n", - " \"v2/en_speaker_1\",\n", + " \"alloy\",\n", + " \"echo\",\n", " ],\n", - " \"use_small_models\": True,\n", - " \"use_gpu\": False,\n", - " \"offload_cpu\": True,\n", " \"file_format\": \"mp3\",\n", " # \"bits_per_sample\": 8,\n", " },\n", diff --git a/text_to_audio_generator/text_to_audio_generator.py b/text_to_audio_generator/text_to_audio_generator.py index 7602745ee..d47d6b865 100644 --- a/text_to_audio_generator/text_to_audio_generator.py +++ b/text_to_audio_generator/text_to_audio_generator.py @@ -11,35 +11,41 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import io import logging +import os import pathlib import random import tempfile from typing import Dict, List, Optional, Tuple, Union -import bark import numpy as np +import openai import pandas as pd import torch import torchaudio import tqdm +from pydub import AudioSegment # Get the global logger: _LOGGER = logging.getLogger() +OPENAI_API_KEY = "OPENAI_API_KEY" +OPENAI_BASE_URL = "OPENAI_BASE_URL" +SAMPLE_RATE = 24000 + def generate_multi_speakers_audio( data_path: str, speakers: Union[List[str], Dict[str, int]], available_voices: List[str], output_directory: str = None, - use_gpu: bool = True, - use_small_models: bool = False, - offload_cpu: bool = False, + model: str = "tts-1", sample_rate: int = 16000, file_format: str = "wav", verbose: bool = True, bits_per_sample: Optional[int] = None, + speed: float = 1.0, ) -> Tuple[str, pd.DataFrame, dict]: """ Generate audio files from text files. @@ -50,21 +56,20 @@ def generate_multi_speakers_audio( If dictionary, the keys will be the speakers and the values will be the channels. :param available_voices: List of available voices to use for the generation. See here for the available voices: - https://suno-ai.notion.site/8b8e8749ed514b0cbf3f699013548683?v=bc67cff786b04b50b3ceb756fd05f68c + https://platform.openai.com/docs/guides/text-to-speech#voice-options :param output_directory: Path to the directory to save the generated audio files to. - :param use_gpu: Whether to use the GPU for the generation. - :param use_small_models: Whether to use the small models for the generation. - :param offload_cpu: To reduce the memory footprint, the models can be offloaded to the CPU after loading. + :param model: Which model to use for the generation. :param sample_rate: The sampling rate of the generated audio. :param file_format: The format of the generated audio files. :param verbose: Whether to print the progress of the generation. :param bits_per_sample: Changes the bit depth for the supported formats. Supported only in "wav" or "flac" formats. + :param speed: The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is the default. :returns: A tuple of: - The output directory path. - The generated audio files dataframe. - - The errors dictionary. + - The errors' dictionary. """ global _LOGGER @@ -73,17 +78,8 @@ def generate_multi_speakers_audio( data_path = pathlib.Path(data_path).absolute() text_files = _get_text_files(data_path=data_path) - # Load the bark models according to the given configurations: - bark.preload_models( - text_use_gpu=use_gpu, - text_use_small=use_small_models, - coarse_use_gpu=use_gpu, - coarse_use_small=use_small_models, - fine_use_gpu=use_gpu, - fine_use_small=use_small_models, - codec_use_gpu=use_gpu, - force_reload=offload_cpu, - ) + # connect to openai client: + client = _get_openai_client() # Check for per channel generation: if isinstance(speakers, dict): @@ -98,11 +94,11 @@ def generate_multi_speakers_audio( # Prepare the resampling module: resampler = torchaudio.transforms.Resample( - orig_freq=bark.SAMPLE_RATE, new_freq=sample_rate, dtype=torch.float32 + orig_freq=SAMPLE_RATE, new_freq=sample_rate, dtype=torch.float32 ) # Prepare the gap between each speaker: - gap_between_speakers = np.zeros(int(0.5 * bark.SAMPLE_RATE)) + gap_between_speakers = np.zeros(int(0.5 * SAMPLE_RATE)) # Prepare the successes dataframe and errors dictionary to be returned: successes = [] @@ -156,11 +152,16 @@ def generate_multi_speakers_audio( ) for sentence in _split_line(line=sentences): # Generate words audio: - audio = bark.generate_audio( - sentence, - history_prompt=chosen_voices[current_speaker], - silent=True, + audio = client.audio.speech.create( + model=model, + input=sentence, + voice=chosen_voices[current_speaker], + response_format=file_format, + speed=speed, ) + audio = audio.content + audio = _bytes_to_np_array(audio=audio, file_format=file_format) + if speaker_per_channel: silence = np.zeros_like(audio) for speaker in audio_pieces.keys(): @@ -214,6 +215,43 @@ def generate_multi_speakers_audio( return str(output_directory), successes, errors +def _get_openai_client(): + api_key = os.getenv(OPENAI_API_KEY) + base_url = os.getenv(OPENAI_BASE_URL) + # Check if the key is already in the environment variables: + if not api_key or not base_url: + try: + import mlrun + + context = mlrun.get_or_create_ctx(name="context") + # Check if the key is in the secrets: + api_key = context.get_secret(OPENAI_API_KEY) + base_url = context.get_secret(OPENAI_BASE_URL) + except ModuleNotFoundError: + raise EnvironmentError( + f"One or more of the OpenAI required environment variables ('{OPENAI_API_KEY}', '{OPENAI_BASE_URL}') are missing." + f"Please set them as environment variables or install mlrun (`pip install mlrun`)" + f"and set them as project secrets using `project.set_secrets`." + ) + return openai.OpenAI(api_key=api_key, base_url=base_url) + + +def _bytes_to_np_array(audio: bytes, file_format: str): + if file_format == "mp3": + audio_segment = AudioSegment.from_mp3(io.BytesIO(audio)) + + # Convert to raw PCM audio data + samples = audio_segment.get_array_of_samples() + + # Convert to numpy array + audio_array = np.array(samples) + + # Normalize to float between -1 and 1 + return audio_array.astype(np.float32) / np.iinfo(samples.typecode).max + else: + return np.frombuffer(audio, dtype=np.int16) / 32768.0 + + def _get_text_files( data_path: pathlib.Path, ) -> List[pathlib.Path]: @@ -261,6 +299,7 @@ def _get_logger(): global _LOGGER try: import mlrun + # Check if MLRun is available: context = mlrun.get_or_create_ctx(name="mlrun") return context.logger