From 146138e109eadbc63c1af2334e09058f9e2e2ef5 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Fri, 21 Apr 2023 13:46:02 +0200 Subject: [PATCH 01/14] draft node --- haystack/preview/components/__init__.py | 0 haystack/preview/components/audio/__init__.py | 0 .../preview/components/audio/transcriber.py | 156 ++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 haystack/preview/components/__init__.py create mode 100644 haystack/preview/components/audio/__init__.py create mode 100644 haystack/preview/components/audio/transcriber.py diff --git a/haystack/preview/components/__init__.py b/haystack/preview/components/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/haystack/preview/components/audio/__init__.py b/haystack/preview/components/audio/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py new file mode 100644 index 0000000000..44752e1042 --- /dev/null +++ b/haystack/preview/components/audio/transcriber.py @@ -0,0 +1,156 @@ +from typing import List, Optional, Dict, Any, Union, BinaryIO, Literal, Tuple + +import os +import json + +import requests +import torch +import whisper +from requests import PreparedRequest +from generalimport import is_imported +from tenacity import retry, wait_exponential, retry_if_not_result + +from haystack.preview import component, Document +from haystack.errors import OpenAIError, OpenAIRateLimitError + + +OPENAI_TIMEOUT = float(os.environ.get("HAYSTACK_OPENAI_TIMEOUT_SEC", 30)) + + +WhisperModel = Literal["tiny", "small", "medium", "large", "large-v2"] + + +@component +class WhisperTranscriber: + """ + Transcribes audio files using OpenAI's Whisper. This class supports two underlying implementations: + + - API (default): Uses the OpenAI API and requires an API key. See the + [OpenAI blog post](https://beta.openai.com/docs/api-reference/whisper for more details. + - Local (requires installing Whisper): Uses the local installation + of [Whisper](https://github.com/openai/whisper). + + To use Whisper locally, install it following the instructions on the Whisper + [GitHub repo](https://github.com/openai/whisper) and omit the `api_key` parameter. + + To use the API implementation, provide an api_key. You can get one by signing up for an + [OpenAI account](https://beta.openai.com/). + + For the supported audio formats, languages, and other parameters, see the + [Whisper API documentation](https://platform.openai.com/docs/guides/speech-to-text) and the official Whisper + [github repo](https://github.com/openai/whisper). + """ + + def __init__( + self, + input: str = "audio", + output: str = "documents", + api_key: Optional[str] = None, + model_name_or_path: WhisperModel = "medium", + device: Optional[Union[str, torch.device]] = None, + ) -> None: + """ + Transcribes a list of audio files into a list of Documents. + + :param input: the name of the expected input for this node. + :param output: the name of the expected output of this node. + :param api_key: OpenAI API key. If None, a local installation of Whisper is used. + :param model_name_or_path: Name of the model to use. If using a local installation of Whisper, set this to one + of the following values: + - `tiny` + - `small` + - `medium` + - `large` + - `large-v2` + If using the API, set this value to: + - `whisper-1` (default) + :param device: Device to use for inference. Only used if you're using a local installation of Whisper. + If None, CPU is used. + """ + self.inputs = [input] + self.output = [output] + + self.api_key = api_key + self.model_name = model_name_or_path + self.device = device or torch.device("cpu") + self.use_local_whisper = is_imported("whisper") and self.api_key is None + + if not self.use_local_whisper and api_key is None: + raise ValueError( + "Provide a valid api_key for OpenAI API. Alternatively, install OpenAI Whisper (see " + "[Whisper](https://github.com/openai/whisper) for more details)." + ) + + def warm_up(self): + """ + If we're using a local model, load it here. + """ + if self.use_local_whisper and not self._model: + self._model = whisper.load_model(self.model_name, device=self.device) + + def run(self, name: str, data: List[Tuple[str, Any]], parameters: Dict[str, Dict[str, Any]]): + params = parameters.get(name, {}) + transcripts = [(audio_file, self.transcribe(audio_file, **params)) for audio_file in data[0][1]] + documents = [Document(content=transcript, metadata={"audio_file": audio}) for audio, transcript in transcripts] + return {self.output[0]: documents} + + def transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + """ + Transcribe the given audio files. Returns a list of strings. + + For the supported audio formats, languages, and other parameters, see the + [Whisper API documentation](https://platform.openai.com/docs/guides/speech-to-text) and the official Whisper + [github repo](https://github.com/openai/whisper). + + :param audio_files: a list of paths or binary streams to transcribe + :returns: a list of transcriptions. + """ + transcriptions = [] + for audio_file in audio_files: + if isinstance(audio_file, str): + audio_file = open(audio_file, "rb") + + if self.use_local_whisper: + transcription = self._invoke_local(audio_file, **kwargs) + else: + transcription = self._invoke_api(audio_file, **kwargs) + + transcriptions.append(transcription) + return transcriptions + + @retry(retry=retry_if_not_result(bool), wait=wait_exponential(min=1, max=10)) + def _invoke_api(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: + """ + Calls a remote Whisper model through OpenAI Whisper API. + """ + translate = kwargs.pop("translate", False) + + response = requests.post( + url=f"https://api.openai.com/v1/audio/{'translations' if translate else 'transcriptions'}", + data={"model": "whisper-1", **kwargs}, + headers={"Authorization": f"Bearer {self.api_key}"}, + files=[("file", (audio_file.name, audio_file, "application/octet-stream"))], + timeout=600, + ) + + if response.status_code != 200: + if response.status_code == 429: + raise OpenAIRateLimitError(f"API rate limit exceeded: {response.text}") + raise OpenAIError( + f"OpenAI returned an error.\n" + f"Status code: {response.status_code}\n" + f"Response body: {response.text}", + status_code=response.status_code, + ) + + return json.loads(response.content) + + def _invoke_local(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: + """ + Calls a local Whisper model. + """ + return_segments = kwargs.pop("return_segments", None) + transcription = self._model.transcribe(audio_file.name, **kwargs) + if not return_segments: + transcription.pop("segments", None) + return transcription From f334723c3cd1073477088c041dcbfc550734e869 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Fri, 21 Apr 2023 13:58:32 +0200 Subject: [PATCH 02/14] stub test --- haystack/preview/components/__init__.py | 1 + haystack/preview/components/audio/__init__.py | 1 + .../preview/components/audio/transcriber.py | 9 +++++++- test/preview/components/__init__.py | 1 + .../preview/components/test_component_base.py | 21 +++++++++++++++++++ .../components/test_transcriber_whisper.py | 16 ++++++++++++++ 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 test/preview/components/__init__.py create mode 100644 test/preview/components/test_component_base.py create mode 100644 test/preview/components/test_transcriber_whisper.py diff --git a/haystack/preview/components/__init__.py b/haystack/preview/components/__init__.py index e69de29bb2..0e34ac32bd 100644 --- a/haystack/preview/components/__init__.py +++ b/haystack/preview/components/__init__.py @@ -0,0 +1 @@ +from haystack.preview.components.audio.transcriber import WhisperTranscriber diff --git a/haystack/preview/components/audio/__init__.py b/haystack/preview/components/audio/__init__.py index e69de29bb2..0e34ac32bd 100644 --- a/haystack/preview/components/audio/__init__.py +++ b/haystack/preview/components/audio/__init__.py @@ -0,0 +1 @@ +from haystack.preview.components.audio.transcriber import WhisperTranscriber diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 44752e1042..53d6fa8fda 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -68,7 +68,14 @@ def __init__( If None, CPU is used. """ self.inputs = [input] - self.output = [output] + self.outputs = [output] + self.init_parameters = { + "input": input, + "output": output, + "api_key": api_key, + "model_name_or_path": model_name_or_path, + "device": device, + } self.api_key = api_key self.model_name = model_name_or_path diff --git a/test/preview/components/__init__.py b/test/preview/components/__init__.py new file mode 100644 index 0000000000..0e34ac32bd --- /dev/null +++ b/test/preview/components/__init__.py @@ -0,0 +1 @@ +from haystack.preview.components.audio.transcriber import WhisperTranscriber diff --git a/test/preview/components/test_component_base.py b/test/preview/components/test_component_base.py new file mode 100644 index 0000000000..5a713bd91e --- /dev/null +++ b/test/preview/components/test_component_base.py @@ -0,0 +1,21 @@ +from abc import ABC, abstractmethod + +import pytest + + +class _BaseTestComponent(ABC): + @pytest.fixture + @abstractmethod + def components(self): + pass + + def test_component_contract(self, components): + for component in components: + assert hasattr(component, "inputs") + assert hasattr(component, "outputs") + assert hasattr(component, "init_parameters") + assert hasattr(component, "run") + + def test_save_and_load(self, components): + # TODO + pass diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py new file mode 100644 index 0000000000..0bdbe80e8b --- /dev/null +++ b/test/preview/components/test_transcriber_whisper.py @@ -0,0 +1,16 @@ +import os + +import pytest + +from haystack.preview.components import WhisperTranscriber + +from test.preview.components.test_component_base import _BaseTestComponent + + +class TestTranscriber(_BaseTestComponent): + @pytest.fixture + def components(self): + return [WhisperTranscriber()] + + def test_transcribe(self): + pass From edfabfcbfb56cbe8c384461b6c5bf6d6f65f73be Mon Sep 17 00:00:00 2001 From: ZanSara Date: Fri, 21 Apr 2023 14:28:56 +0200 Subject: [PATCH 03/14] expand tests --- .../preview/components/audio/transcriber.py | 3 +- .../preview/components/test_component_base.py | 40 +++++++++++++++++- .../components/test_transcriber_whisper.py | 18 +++++++- .../this is the content of the document.wav | Bin 0 -> 89644 bytes 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 test/preview/test_files/audio/this is the content of the document.wav diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 53d6fa8fda..14c472f42a 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -82,6 +82,7 @@ def __init__( self.device = device or torch.device("cpu") self.use_local_whisper = is_imported("whisper") and self.api_key is None + self._model = None if not self.use_local_whisper and api_key is None: raise ValueError( "Provide a valid api_key for OpenAI API. Alternatively, install OpenAI Whisper (see " @@ -97,7 +98,7 @@ def warm_up(self): def run(self, name: str, data: List[Tuple[str, Any]], parameters: Dict[str, Dict[str, Any]]): params = parameters.get(name, {}) - transcripts = [(audio_file, self.transcribe(audio_file, **params)) for audio_file in data[0][1]] + transcripts = zip(data[0][1], self.transcribe(data[0][1], **params)) documents = [Document(content=transcript, metadata={"audio_file": audio}) for audio, transcript in transcripts] return {self.output[0]: documents} diff --git a/test/preview/components/test_component_base.py b/test/preview/components/test_component_base.py index 5a713bd91e..009fc8fa51 100644 --- a/test/preview/components/test_component_base.py +++ b/test/preview/components/test_component_base.py @@ -1,21 +1,57 @@ from abc import ABC, abstractmethod +from unittest.mock import MagicMock + +from requests import Response import pytest class _BaseTestComponent(ABC): + @pytest.fixture + def request_mock(self, monkeypatch): + request_mock = MagicMock() + monkeypatch.setattr("requests.request", MagicMock()) + return request_mock + @pytest.fixture @abstractmethod def components(self): pass + @pytest.mark.unit def test_component_contract(self, components): - for component in components: + for component, _ in components: assert hasattr(component, "inputs") assert hasattr(component, "outputs") assert hasattr(component, "init_parameters") assert hasattr(component, "run") + # TODO test run() signature + + @pytest.mark.unit + def test_warm_up_works(self, components): + for component in components: + if hasattr(component, "warm_up"): + component.warm_up() - def test_save_and_load(self, components): + # + # TODO + # + + @pytest.mark.unit + def test_output_respects_contract(self, components): + pass + + @pytest.mark.unit + def test_save_and_load_in_pipeline(self, components): + pass + + @pytest.mark.unit + def test_api_calls_handle_exceptions(self, request_mock, components): # TODO pass + + @pytest.mark.unit + def test_api_calls_attempt_retries(self, request_mock, components): + for component, run_params in components: + component.run("test_component", **run_params) + assert request_mock.call_count > 1 diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py index 0bdbe80e8b..93341428bb 100644 --- a/test/preview/components/test_transcriber_whisper.py +++ b/test/preview/components/test_transcriber_whisper.py @@ -1,5 +1,7 @@ import os +from pathlib import Path + import pytest from haystack.preview.components import WhisperTranscriber @@ -7,10 +9,24 @@ from test.preview.components.test_component_base import _BaseTestComponent +SAMPLES_PATH = Path(__file__).parent / "test_files" + + class TestTranscriber(_BaseTestComponent): @pytest.fixture def components(self): - return [WhisperTranscriber()] + comps = [ + ( + WhisperTranscriber(), + { + "data": [("audio", [SAMPLES_PATH / "audio" / "this is the content of the document.wav"])], + "parameters": {}, + }, + ) + ] + for comp, _ in comps: + comp.warm_up() + return comp def test_transcribe(self): pass diff --git a/test/preview/test_files/audio/this is the content of the document.wav b/test/preview/test_files/audio/this is the content of the document.wav new file mode 100644 index 0000000000000000000000000000000000000000..37d651fa9dd0755ab3aa9d6c71d19958c7d18719 GIT binary patch literal 89644 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

-&{zMv1^W?Xr?>wlI!cm-L192gLef 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 literal 0 HcmV?d00001 From 1c87b35a8b9acead1980276a86721617ef56ed8e Mon Sep 17 00:00:00 2001 From: ZanSara Date: Fri, 21 Apr 2023 14:59:06 +0200 Subject: [PATCH 04/14] more tests --- e2e/preview/components/test_transcriber.py | 21 ++++++++ .../this is the content of the document.wav | Bin 0 -> 89644 bytes .../preview/components/audio/transcriber.py | 47 ++++++++++++++++-- .../preview/components/test_component_base.py | 18 +++++-- .../components/test_transcriber_whisper.py | 19 ++++--- 5 files changed, 88 insertions(+), 17 deletions(-) create mode 100644 e2e/preview/components/test_transcriber.py create mode 100644 e2e/preview/test_files/audio/this is the content of the document.wav diff --git a/e2e/preview/components/test_transcriber.py b/e2e/preview/components/test_transcriber.py new file mode 100644 index 0000000000..e1a7afed6b --- /dev/null +++ b/e2e/preview/components/test_transcriber.py @@ -0,0 +1,21 @@ +from pathlib import Path + +from haystack.preview.components import WhisperTranscriber + +SAMPLES_PATH = Path(__file__).parent.parent / "test_files" + + +def test_raw_transcribe(): + comp = WhisperTranscriber() + output = comp._transcribe(audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"]) + assert "this is the content of the document" in output[0]["text"].lower() + + +# Probably unnecessary, a mocked test is enough +def test_transcribe_to_documents(): + comp = WhisperTranscriber() + output = comp.transcribe_to_documents( + audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"] + ) + assert "this is the content of the document" in output[0].content.lower() + assert "this is the content of the document.wav" in str(output[0].metadata["audio_file"]) diff --git a/e2e/preview/test_files/audio/this is the content of the document.wav b/e2e/preview/test_files/audio/this is the content of the document.wav new file mode 100644 index 0000000000000000000000000000000000000000..37d651fa9dd0755ab3aa9d6c71d19958c7d18719 GIT binary patch literal 89644 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

-&{zMv1^W?Xr?>wlI!cm-L192gLef zZPnRFe&Rb|RCj!)CV7|Jle8E)m1yP;`4`75d5h5Q0AE90tcn5 zN_mBR5wn4mt+bJ^m_Heb(ihq=Ni~Mp$!ff`h$z!=rJS>nRlze*z7ax~aqmfcyXjD=xM^bOuuo}Eg5=Ml-nd3q}mfI`+as!EOrT2S$}*BVIFaVD1e zSnZH>*LcF|<1e+W^vbtF`dS?;_prYsm$;R@U*BzCH|WzPt<{!D_3$tKEU#DaKPVgQ z(Z1`}5=SrXvf0&l!|J0oQkz+JAOkzTmo%M@rvE_0bCfLG@4sVDR5nSg3 z&L%?tHSwpG^sBgy_q#E+@#Sue=}m`|@TCRfVm?Q2#W>~Qj+><_Vs2TJ{^ z6s{|+lebXAx&%3y!n|Z5MOA66b;N#zKfeh6oEP$PCDKkXH`)f);(V;`jhqek*ni>qbS4sy6@CBTP-B_MJ{w@abVrwTARD-@)C_xi1Ucj# z@Ceo;0$g2Q1nx5}CtigguvQgl_gAW6x1i1H;?F#6i|$XtGRm+&MK_t~vt<5X3@w|E zz1asHH3w@$c+2hqwOZIYxoAiSmPsgDP|V%_iQK?YG@8g;9fZBMjq~XVyD3*4g~}VE zxo^{Xs3NtP#nI;~m4(mXp?=ul8h(yVoYFtxzkgDND$Y{R_}%2xGZCAm40>}m_=!OG z-@|fw%Z|mFuRHcfx?K&ctP`K80Hrs>)+o-iKfqG3u}Ku{hXTN9B^+}VnGwaR_am3e zQSZEuQ~Y##!hD5&S^)^}WwqH<;Pm5u7pW%egs0>=uwzsN4dRLp`{SIyDY!7!Tg#6RU{79lovm=l?6|@~y zR(KC9Bp2uyP<1UKqv+%l%f63*(bh3SS*=KSUSQ^^MMfuR+OKIJivgkg*i%`2_wW*SvyT-fK}(`z&|{!foxQ|yMGV;- zxnQUmb-pP?4Q$pVEVtLtLk|DBffW>sRep?JRRU|7+%Jkxr($b%0H5CAzQ%H15Y}8B zD83YUdCN8BdHzf2r3etq0TPMaw+Xvl0Zty^&C8-9cr)-3CxYXg`Pr#~CLK*&%!{C4uWZRwjBtRe;7)?b<-d;4fl| zq|E9Hg9G7>Fo1)geT&cJ12ehMY&3AKNQadGe<=!%6xLfD8h7xy2%hAEUNgZoSuDtj zS3oI}r@rIeV;~g@bkD*;q1eQJ@dl(K-~I6IdG7d{XQgBBpN5Bvvp#Wt_VCQo z!0IeiE<9DC{526B+7(D70X2bLC)6DauEnWK)S=&jT8lyje)!-mTw57x{g?Bqxc(h@ z`H#x-A*}u{_@yX!bwI86;G8l*5XlP-c%cpl-^HBJEGQ};5PWS{;T-n}xgg>mv2dh@ z^ooM&s&R*GXj7c8(&55PD7+SwoD6hwfWvEKwsfDeieLjpTC#o=WAqKdGMPN)Cl2VJP*uAb43-T)?J|7 zon4(l*OkX>Q&d{b>P4-bkPH{`5(tWm0#;jr@O$j;64dkvzAFs|Pr=Di;4+N$3D2Ap zDWcQs;W*H%4A-1Rl8XNe4dY>Te%9>e=|U1@aQ`@V7X!pgvX8>>kCXLQV`mTG=;FZq zG|zek)_vURAox{yca#0RU@z%NxLi0Q0}MuS=Kzo_%$-ZJ2hrE1EKq$9*t>zAfKNrf z3i7u)toAbZ9L!%1@T6{daV|j}6*=+7p^YxG%U;|iksS$(r#v`*gP+0!wCezslStN>nCiRjNFC7&LQL|#%hy||QgqyT$7=I~H3xi=inM9ON?x#k(fL92*byBg z!&qS!*SrSmE@Wsrye0Z+2~XfruyU7`l_Gxq7x+|zGFbGK5S-K;EZ%{#3qTJA*wYK% zm137V&lNIRaG1hp3PLp+R~F{e$Dyo2JaId)Eeqz0v9goUZhI<#e8|Qe?hyx03PNY1 zKS*CF=Ugy~-X6Q|INrc3@Lf6XdJf;(c_^(Pu>TdPH3p&ux!X-JT#0uYJemsj!k~#5 zF!c~zML{*0z)DOtt`6Q0@&Afo?;?0803T_{iX?P!)P+{u7dk`{Oq zaFM{WB2;k(?3PBZyWmA3Z3}UQ@LLNl{RWtGjD}a=!eKr*xBx2`ergc`5Z#+R$ku|K zXUYUMlo#$V3C%r3BE&&iHdwm|JVnREB<>;ZDXhBu(CumHL(sby4e**3M9`D*IPb(< z?<-h3qA#G2-wdFV0nNq0B_bPBWslW(avW4HyykD=GC%7!_)SD5bmC-}_)9+iFD6zC z$sYy<6+i|(;A-IqdkF=VgNvI5>CFvHW4Wua3Bq_+m~}s6ojQLPek;)}&&Mv@JR=R5 zWCMqIaQu$vRphF4AXF7xJE5B5SWQj1;yLgtz>2-dfy?YlSgv{45xamxA?|+)ZcK(d z!dS~a@FMhf6qwrwHJ0OEAwbNJwyMs`g?2H}(?!`)4!96@tQQD7SW$k~-GE&S`=}I_ zP%YM&%yptaRz9%fLOY1F!<(R|E)tEGA3A=7RV3_$8|a}^;QA%|dJWy323talYV;2{ z0Ice>yC-16fbycapTTEN^4apiU0>(Ac;KnQg(<*C`1ge8PfP%hfjSd`zwj+)u%}dZ zlg%0h8om7C(iC%UgUCsn0rWcM$WEFyUJ-}7S zpu()9DEupUxFGaVi|SKmAq7OX6G=)yNBkx_779)M8g7l{ z9=Y(opl!j!sjML?s4s*cnNn`xDMJ%E?6W+d$m1Egd|Cr0kNB%NQKtfvXV7mr&`bhH z0%qm8uQ-pC5AM;)onyJHSg+^>EP6c(Z?%w5qGPa-n?A7M1?HF7r3s9M_38kl26E&s zcQ4IKgsu+*Yq7jEAQlQ02@BuNS25@?Km2`;Yh!r!-5^HA`N{;EuXvKMmomWF3-IS= zC#gU>o81Vx7R}xSRb=oRflp+N#yv$;K<8dreD)4|d-VTuQmikN`w5wq7QDBJqLpHe z(d?!uKjWcB(cQ5C@7>%%>^Y9l2yPVp6vKG_Gw3*tXTE~7#R)*f-tu^|uo?ti#=#L4 zgP1G8-daM#8h8zdL*CK=KiL%3_5PSfy83mxyUZvY!_~y97_kkBpGul7>)H1oswwa|ND+ts!>r0{0J~ zcfk=t^QQ8D5wnQkE)v`!PM|`L3RV#UvarUInh{PiqcC*nFH zb0!(cN?_t0_Y0B3!BourpB2hx0irCdV=tfvDnXE@xB>8}yh~NnxFxk^hp6CVoUhbI(J%>Xh z(Lh8*>52kz5g~hzbvEKTPOgnX?l^ggC|o=ep#;wsk|HjMJK;eI<3DMvT0mYzl0=tR zVa3_3Uz`U1hd&`Z3bSId>s)ptI6zntAw0DV@81C9IChf>ZzlntB0N(>!wl#(gq5dr zcb#|9JWXJw09WM??)NQJ{hUue0(*DS>u32o3WeW*ZtsHGn?VW@eC-M1Q`ky^vxFrO z$Nj`ggw-0!Uj;>l^JL+H(7>4q}93xirk zv@@Ff3*A+mXGHKnVG-2kcM%V)4zE<;8l9Jbe-3v|0cSe66x=TC&IsQ7*s(bERtn0* zGT=n$Cvn;q_zFcfq#*$me!k}VB%mPp?gbR{6zmHQ5UVQ?q*~G4r3iAiELV%Zxz&*w zMS|=8U%XXVY@)wzHrHK2x{8yx@R3REN$gJn2V!r zs}P>lr{Lf=Yx1*~d+52B$QW@}5iw&KxJc-Qm)t*+wTWnNERw4QwtIe_CeCm1JVj`; zH0aCX`z>%OPV8x5P9DWx*%2@6$pe!;9guV;mxBR^Fv2tOFNAbJp85|zO xdKB-CAT{~9g9pe9EAtJI6W&2V*&bHz2505D-em2?;N9~4E-17JoKc$h{|A8EL;C;# literal 0 HcmV?d00001 diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 14c472f42a..5053b135a3 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -2,11 +2,11 @@ import os import json +from pathlib import Path import requests import torch import whisper -from requests import PreparedRequest from generalimport import is_imported from tenacity import retry, wait_exponential, retry_if_not_result @@ -27,13 +27,14 @@ class WhisperTranscriber: - API (default): Uses the OpenAI API and requires an API key. See the [OpenAI blog post](https://beta.openai.com/docs/api-reference/whisper for more details. + - Local (requires installing Whisper): Uses the local installation of [Whisper](https://github.com/openai/whisper). To use Whisper locally, install it following the instructions on the Whisper [GitHub repo](https://github.com/openai/whisper) and omit the `api_key` parameter. - To use the API implementation, provide an api_key. You can get one by signing up for an + To use the API implementation, provide an API key. You can get one by signing up for an [OpenAI account](https://beta.openai.com/). For the supported audio formats, languages, and other parameters, see the @@ -97,12 +98,47 @@ def warm_up(self): self._model = whisper.load_model(self.model_name, device=self.device) def run(self, name: str, data: List[Tuple[str, Any]], parameters: Dict[str, Dict[str, Any]]): + self.warm_up() params = parameters.get(name, {}) transcripts = zip(data[0][1], self.transcribe(data[0][1], **params)) - documents = [Document(content=transcript, metadata={"audio_file": audio}) for audio, transcript in transcripts] + documents = [ + Document(content=transcript.pop("text"), metadata={"audio_file": audio, **transcript}) + for audio, transcript in transcripts + ] return {self.output[0]: documents} - def transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + """ + Transcribe the given audio files. Returns a list of Documents. + + For the supported audio formats, languages, and other parameters, see the + [Whisper API documentation](https://platform.openai.com/docs/guides/speech-to-text) and the official Whisper + [github repo](https://github.com/openai/whisper). + + :param audio_files: a list of paths or binary streams to transcribe + :returns: a list of transcriptions. + """ + transcriptions = self._transcribe(audio_files=audio_files) + return [ + Document(content=transcript.pop("text"), metadata={"audio_file": audio, **transcript}) + for audio, transcript in zip(audio_files, transcriptions) + ] + + def transcribe_to_sringss(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + """ + Transcribe the given audio files. Returns a list of strings. + + For the supported audio formats, languages, and other parameters, see the + [Whisper API documentation](https://platform.openai.com/docs/guides/speech-to-text) and the official Whisper + [github repo](https://github.com/openai/whisper). + + :param audio_files: a list of paths or binary streams to transcribe + :returns: a list of transcriptions. + """ + transcriptions = self._transcribe(audio_files=audio_files) + return [transcription["text"] for transcription in transcriptions] + + def _transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: """ Transcribe the given audio files. Returns a list of strings. @@ -113,9 +149,10 @@ def transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[ :param audio_files: a list of paths or binary streams to transcribe :returns: a list of transcriptions. """ + self.warm_up() transcriptions = [] for audio_file in audio_files: - if isinstance(audio_file, str): + if isinstance(audio_file, (str, Path)): audio_file = open(audio_file, "rb") if self.use_local_whisper: diff --git a/test/preview/components/test_component_base.py b/test/preview/components/test_component_base.py index 009fc8fa51..43a86df8ac 100644 --- a/test/preview/components/test_component_base.py +++ b/test/preview/components/test_component_base.py @@ -1,12 +1,17 @@ +from typing import List, Tuple, Dict, Any + from abc import ABC, abstractmethod from unittest.mock import MagicMock -from requests import Response import pytest -class _BaseTestComponent(ABC): +class BaseTestComponent(ABC): + """ + Base tests for Haystack components. + """ + @pytest.fixture def request_mock(self, monkeypatch): request_mock = MagicMock() @@ -15,7 +20,12 @@ def request_mock(self, monkeypatch): @pytest.fixture @abstractmethod - def components(self): + def components(self) -> List[Tuple[object, Dict[str, Dict[str, Any]]]]: + """ + Provide here all the combinations of (component instance, {data and parameters}) + to be tested by this suite. Should cover most relevant combinations to get a good coverage of your component's + basic features. + """ pass @pytest.mark.unit @@ -38,7 +48,7 @@ def test_warm_up_works(self, components): # @pytest.mark.unit - def test_output_respects_contract(self, components): + def test_run_output_matches_declared_output(self, components): pass @pytest.mark.unit diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py index 93341428bb..5c1b2a7e04 100644 --- a/test/preview/components/test_transcriber_whisper.py +++ b/test/preview/components/test_transcriber_whisper.py @@ -1,4 +1,4 @@ -import os +from typing import List, Tuple, Dict, Any from pathlib import Path @@ -6,15 +6,19 @@ from haystack.preview.components import WhisperTranscriber -from test.preview.components.test_component_base import _BaseTestComponent +from test.preview.components.test_component_base import BaseTestComponent -SAMPLES_PATH = Path(__file__).parent / "test_files" +SAMPLES_PATH = Path(__file__).parent.parent / "test_files" -class TestTranscriber(_BaseTestComponent): +class TestTranscriber(BaseTestComponent): + """ + Tests for WhisperTranscriber. + """ + @pytest.fixture - def components(self): + def components(self) -> List[Tuple[object, Dict[str, Dict[str, Any]]]]: comps = [ ( WhisperTranscriber(), @@ -24,9 +28,8 @@ def components(self): }, ) ] - for comp, _ in comps: - comp.warm_up() - return comp + return comps def test_transcribe(self): pass + # TODO mock model From 4fbf74a9b98af24357014eebb5ee524d92f9c497 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Fri, 21 Apr 2023 15:12:49 +0200 Subject: [PATCH 05/14] remove stray method --- .../preview/components/audio/transcriber.py | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 5053b135a3..364b5897b6 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -100,11 +100,7 @@ def warm_up(self): def run(self, name: str, data: List[Tuple[str, Any]], parameters: Dict[str, Dict[str, Any]]): self.warm_up() params = parameters.get(name, {}) - transcripts = zip(data[0][1], self.transcribe(data[0][1], **params)) - documents = [ - Document(content=transcript.pop("text"), metadata={"audio_file": audio, **transcript}) - for audio, transcript in transcripts - ] + documents = self.transcribe_to_documents(data[0][1], **params) return {self.output[0]: documents} def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: @@ -124,20 +120,6 @@ def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwa for audio, transcript in zip(audio_files, transcriptions) ] - def transcribe_to_sringss(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: - """ - Transcribe the given audio files. Returns a list of strings. - - For the supported audio formats, languages, and other parameters, see the - [Whisper API documentation](https://platform.openai.com/docs/guides/speech-to-text) and the official Whisper - [github repo](https://github.com/openai/whisper). - - :param audio_files: a list of paths or binary streams to transcribe - :returns: a list of transcriptions. - """ - transcriptions = self._transcribe(audio_files=audio_files) - return [transcription["text"] for transcription in transcriptions] - def _transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: """ Transcribe the given audio files. Returns a list of strings. From ffcf13e31461c6100a7661244675779d88f59d18 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Wed, 26 Apr 2023 17:19:17 +0200 Subject: [PATCH 06/14] fix is_imported --- .../preview/components/audio/transcriber.py | 10 +--------- haystack/preview/utils/import_utils.py | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 364b5897b6..c548b402d6 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -7,11 +7,11 @@ import requests import torch import whisper -from generalimport import is_imported from tenacity import retry, wait_exponential, retry_if_not_result from haystack.preview import component, Document from haystack.errors import OpenAIError, OpenAIRateLimitError +from haystack.preview.utils.import_utils import is_imported OPENAI_TIMEOUT = float(os.environ.get("HAYSTACK_OPENAI_TIMEOUT_SEC", 30)) @@ -70,14 +70,6 @@ def __init__( """ self.inputs = [input] self.outputs = [output] - self.init_parameters = { - "input": input, - "output": output, - "api_key": api_key, - "model_name_or_path": model_name_or_path, - "device": device, - } - self.api_key = api_key self.model_name = model_name_or_path self.device = device or torch.device("cpu") diff --git a/haystack/preview/utils/import_utils.py b/haystack/preview/utils/import_utils.py index 282ce816e9..9f081ab243 100644 --- a/haystack/preview/utils/import_utils.py +++ b/haystack/preview/utils/import_utils.py @@ -1,7 +1,27 @@ from typing import Optional, Any + +import sys import importlib import logging +from generalimport import FakeModule, MissingOptionalDependency + + +# +# TEMPORARY: remove once generalimport>0.3.1 is released +# +def is_imported(module_name: str) -> bool: + """ + Returns True if the module was actually imported, False, if generalimport mocked it. + """ + module = sys.modules.get(module_name) + try: + return bool(module and not isinstance(module, FakeModule)) + except MissingOptionalDependency as exc: + # isinstance() raises MissingOptionalDependency: fake module + pass + return False + def optional_import(import_path: str, import_target: Optional[str], error_msg: str, importer_module: str) -> Any: """ From ec6b2d4a13f36c3536fb56bc10a6cb61516b86e8 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Wed, 26 Apr 2023 17:21:21 +0200 Subject: [PATCH 07/14] improve comment --- haystack/preview/utils/import_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haystack/preview/utils/import_utils.py b/haystack/preview/utils/import_utils.py index 9f081ab243..d2280dc542 100644 --- a/haystack/preview/utils/import_utils.py +++ b/haystack/preview/utils/import_utils.py @@ -8,7 +8,7 @@ # -# TEMPORARY: remove once generalimport>0.3.1 is released +# TEMPORARY: remove once generalimport>0.3.1 is released (https://github.com/ManderaGeneral/generalimport/pull/25) # def is_imported(module_name: str) -> bool: """ From c605a6b2fc0d4517c1e1a0bbbec053a397b5b01c Mon Sep 17 00:00:00 2001 From: ZanSara Date: Mon, 8 May 2023 11:35:55 +0200 Subject: [PATCH 08/14] new canals api --- e2e/preview/components/test_transcriber.py | 2 +- .../preview/components/audio/transcriber.py | 39 ++++++++----------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/e2e/preview/components/test_transcriber.py b/e2e/preview/components/test_transcriber.py index e1a7afed6b..83d2d1126d 100644 --- a/e2e/preview/components/test_transcriber.py +++ b/e2e/preview/components/test_transcriber.py @@ -7,7 +7,7 @@ def test_raw_transcribe(): comp = WhisperTranscriber() - output = comp._transcribe(audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"]) + output = comp.transcribe(audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"]) assert "this is the content of the document" in output[0]["text"].lower() diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index c548b402d6..9a1b5ddd50 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -3,6 +3,7 @@ import os import json from pathlib import Path +from dataclasses import dataclass import requests import torch @@ -42,19 +43,14 @@ class WhisperTranscriber: [github repo](https://github.com/openai/whisper). """ - def __init__( - self, - input: str = "audio", - output: str = "documents", - api_key: Optional[str] = None, - model_name_or_path: WhisperModel = "medium", - device: Optional[Union[str, torch.device]] = None, - ) -> None: + @dataclass + class Output: + documents: List[Document] + + def __init__(self, api_key: Optional[str] = None, model_name_or_path: WhisperModel = "medium", device: str = None): """ Transcribes a list of audio files into a list of Documents. - :param input: the name of the expected input for this node. - :param output: the name of the expected output of this node. :param api_key: OpenAI API key. If None, a local installation of Whisper is used. :param model_name_or_path: Name of the model to use. If using a local installation of Whisper, set this to one of the following values: @@ -68,11 +64,9 @@ def __init__( :param device: Device to use for inference. Only used if you're using a local installation of Whisper. If None, CPU is used. """ - self.inputs = [input] - self.outputs = [output] self.api_key = api_key self.model_name = model_name_or_path - self.device = device or torch.device("cpu") + self.device = torch.device(device) or torch.device("cpu") self.use_local_whisper = is_imported("whisper") and self.api_key is None self._model = None @@ -89,11 +83,10 @@ def warm_up(self): if self.use_local_whisper and not self._model: self._model = whisper.load_model(self.model_name, device=self.device) - def run(self, name: str, data: List[Tuple[str, Any]], parameters: Dict[str, Dict[str, Any]]): + def run(self, audios: List[Path], whisper_params: Dict[str, Any]) -> Output: self.warm_up() - params = parameters.get(name, {}) - documents = self.transcribe_to_documents(data[0][1], **params) - return {self.output[0]: documents} + documents = self.transcribe_to_documents(audios, **whisper_params) + return WhisperTranscriber.Output(documents) def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: """ @@ -106,13 +99,13 @@ def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwa :param audio_files: a list of paths or binary streams to transcribe :returns: a list of transcriptions. """ - transcriptions = self._transcribe(audio_files=audio_files) + transcriptions = self.transcribe(audio_files=audio_files, **kwargs) return [ Document(content=transcript.pop("text"), metadata={"audio_file": audio, **transcript}) for audio, transcript in zip(audio_files, transcriptions) ] - def _transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + def transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: """ Transcribe the given audio files. Returns a list of strings. @@ -130,15 +123,15 @@ def _transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict audio_file = open(audio_file, "rb") if self.use_local_whisper: - transcription = self._invoke_local(audio_file, **kwargs) + transcription = self._transcribe_locally(audio_file, **kwargs) else: - transcription = self._invoke_api(audio_file, **kwargs) + transcription = self._transcribe_with_api(audio_file, **kwargs) transcriptions.append(transcription) return transcriptions @retry(retry=retry_if_not_result(bool), wait=wait_exponential(min=1, max=10)) - def _invoke_api(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: + def _transcribe_with_api(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: """ Calls a remote Whisper model through OpenAI Whisper API. """ @@ -164,7 +157,7 @@ def _invoke_api(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: return json.loads(response.content) - def _invoke_local(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: + def _transcribe_locally(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: """ Calls a local Whisper model. """ From c4fd0a7060e4f34f7ea0ddd9eb2a862373969970 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Mon, 8 May 2023 13:15:09 +0200 Subject: [PATCH 09/14] move tests into canals --- .../preview/components/test_component_base.py | 55 +------------------ 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/test/preview/components/test_component_base.py b/test/preview/components/test_component_base.py index 43a86df8ac..d684061f4b 100644 --- a/test/preview/components/test_component_base.py +++ b/test/preview/components/test_component_base.py @@ -1,13 +1,10 @@ -from typing import List, Tuple, Dict, Any - -from abc import ABC, abstractmethod - from unittest.mock import MagicMock import pytest +from canals.testing import BaseTestComponent as CanalsBaseTestComponent -class BaseTestComponent(ABC): +class BaseTestComponent(CanalsBaseTestComponent): """ Base tests for Haystack components. """ @@ -17,51 +14,3 @@ def request_mock(self, monkeypatch): request_mock = MagicMock() monkeypatch.setattr("requests.request", MagicMock()) return request_mock - - @pytest.fixture - @abstractmethod - def components(self) -> List[Tuple[object, Dict[str, Dict[str, Any]]]]: - """ - Provide here all the combinations of (component instance, {data and parameters}) - to be tested by this suite. Should cover most relevant combinations to get a good coverage of your component's - basic features. - """ - pass - - @pytest.mark.unit - def test_component_contract(self, components): - for component, _ in components: - assert hasattr(component, "inputs") - assert hasattr(component, "outputs") - assert hasattr(component, "init_parameters") - assert hasattr(component, "run") - # TODO test run() signature - - @pytest.mark.unit - def test_warm_up_works(self, components): - for component in components: - if hasattr(component, "warm_up"): - component.warm_up() - - # - # TODO - # - - @pytest.mark.unit - def test_run_output_matches_declared_output(self, components): - pass - - @pytest.mark.unit - def test_save_and_load_in_pipeline(self, components): - pass - - @pytest.mark.unit - def test_api_calls_handle_exceptions(self, request_mock, components): - # TODO - pass - - @pytest.mark.unit - def test_api_calls_attempt_retries(self, request_mock, components): - for component, run_params in components: - component.run("test_component", **run_params) - assert request_mock.call_count > 1 From e2f08bebb4958b28ad9bbdeecbf0f7ff484e4466 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Mon, 8 May 2023 15:33:51 +0200 Subject: [PATCH 10/14] use canals base test class --- haystack/preview/components/audio/transcriber.py | 2 +- test/preview/components/test_transcriber_whisper.py | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 9a1b5ddd50..f7fbd268b5 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -66,7 +66,7 @@ def __init__(self, api_key: Optional[str] = None, model_name_or_path: WhisperMod """ self.api_key = api_key self.model_name = model_name_or_path - self.device = torch.device(device) or torch.device("cpu") + self.device = torch.device(device) if device else torch.device("cpu") self.use_local_whisper = is_imported("whisper") and self.api_key is None self._model = None diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py index 5c1b2a7e04..e9e1757484 100644 --- a/test/preview/components/test_transcriber_whisper.py +++ b/test/preview/components/test_transcriber_whisper.py @@ -18,17 +18,8 @@ class TestTranscriber(BaseTestComponent): """ @pytest.fixture - def components(self) -> List[Tuple[object, Dict[str, Dict[str, Any]]]]: - comps = [ - ( - WhisperTranscriber(), - { - "data": [("audio", [SAMPLES_PATH / "audio" / "this is the content of the document.wav"])], - "parameters": {}, - }, - ) - ] - return comps + def components(self): + return [WhisperTranscriber()] def test_transcribe(self): pass From 87206e14a2f39305806760c24ccda2280ef147fe Mon Sep 17 00:00:00 2001 From: ZanSara Date: Mon, 8 May 2023 17:55:35 +0200 Subject: [PATCH 11/14] improve tests --- e2e/preview/components/test_transcriber.py | 18 ++- .../preview/components/audio/transcriber.py | 49 ++++++-- .../components/test_transcriber_whisper.py | 112 +++++++++++++++++- 3 files changed, 156 insertions(+), 23 deletions(-) diff --git a/e2e/preview/components/test_transcriber.py b/e2e/preview/components/test_transcriber.py index 83d2d1126d..8f927a8172 100644 --- a/e2e/preview/components/test_transcriber.py +++ b/e2e/preview/components/test_transcriber.py @@ -1,21 +1,19 @@ +import os from pathlib import Path from haystack.preview.components import WhisperTranscriber + SAMPLES_PATH = Path(__file__).parent.parent / "test_files" -def test_raw_transcribe(): - comp = WhisperTranscriber() +def test_raw_transcribe_local(): + comp = WhisperTranscriber(model_name_or_path="tiny") output = comp.transcribe(audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"]) assert "this is the content of the document" in output[0]["text"].lower() -# Probably unnecessary, a mocked test is enough -def test_transcribe_to_documents(): - comp = WhisperTranscriber() - output = comp.transcribe_to_documents( - audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"] - ) - assert "this is the content of the document" in output[0].content.lower() - assert "this is the content of the document.wav" in str(output[0].metadata["audio_file"]) +def test_raw_transcribe_remote(): + comp = WhisperTranscriber(api_key=os.environ.get("OPENAI_API_KEY")) + output = comp.transcribe(audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"]) + assert "this is the content of the document" in output[0]["text"].lower() diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index f7fbd268b5..4c6ef1004e 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -1,7 +1,8 @@ -from typing import List, Optional, Dict, Any, Union, BinaryIO, Literal, Tuple +from typing import List, Optional, Dict, Any, Union, BinaryIO, Literal, get_args import os import json +import logging from pathlib import Path from dataclasses import dataclass @@ -15,10 +16,15 @@ from haystack.preview.utils.import_utils import is_imported +logger = logging.getLogger(__name__) + + OPENAI_TIMEOUT = float(os.environ.get("HAYSTACK_OPENAI_TIMEOUT_SEC", 30)) -WhisperModel = Literal["tiny", "small", "medium", "large", "large-v2"] +WhisperLocalModel = Literal["tiny", "small", "medium", "large", "large-v2"] +WhisperRemoteModel = Literal["whisper-1"] +WhisperModel = Union[WhisperLocalModel, WhisperRemoteModel] @component @@ -47,7 +53,9 @@ class WhisperTranscriber: class Output: documents: List[Document] - def __init__(self, api_key: Optional[str] = None, model_name_or_path: WhisperModel = "medium", device: str = None): + def __init__( + self, model_name_or_path: WhisperModel = "whisper-1", api_key: Optional[str] = None, device: str = None + ): """ Transcribes a list of audio files into a list of Documents. @@ -64,15 +72,43 @@ def __init__(self, api_key: Optional[str] = None, model_name_or_path: WhisperMod :param device: Device to use for inference. Only used if you're using a local installation of Whisper. If None, CPU is used. """ + if model_name_or_path not in (get_args(WhisperRemoteModel) + get_args(WhisperLocalModel)): + raise ValueError( + f"Model name not recognized. Choose one among: " + f"{', '.join(get_args(WhisperRemoteModel) + get_args(WhisperLocalModel))}." + ) + + if model_name_or_path in get_args(WhisperRemoteModel) and not api_key: + raise ValueError( + "Provide a valid API key for OpenAI API. Alternatively, install OpenAI Whisper (see " + "[Whisper](https://github.com/openai/whisper) for more details) " + f"and select a model size among: {', '.join(get_args(WhisperLocalModel))}" + ) + + if model_name_or_path in get_args(WhisperLocalModel) and not is_imported("whisper"): + raise ValueError( + "To use a local Whisper model, install Haystack's audio extras as `pip install farm-haystack[audio]` " + "or install Whisper yourself with `pip install openai-whisper`. You will need ffmpeg on your system " + "in either case, see: https://github.com/openai/whisper." + ) + + if model_name_or_path in get_args(WhisperLocalModel) and api_key: + logger.warning( + "An API Key was provided, but a local model was selected. " + "WhisperTranscriber will try to use the local model." + ) + self.api_key = api_key self.model_name = model_name_or_path - self.device = torch.device(device) if device else torch.device("cpu") - self.use_local_whisper = is_imported("whisper") and self.api_key is None + self.use_local_whisper = model_name_or_path in get_args(WhisperLocalModel) + + if self.use_local_whisper: + self.device = torch.device(device) if device else torch.device("cpu") self._model = None if not self.use_local_whisper and api_key is None: raise ValueError( - "Provide a valid api_key for OpenAI API. Alternatively, install OpenAI Whisper (see " + "Provide a valid API key for OpenAI API. Alternatively, install OpenAI Whisper (see " "[Whisper](https://github.com/openai/whisper) for more details)." ) @@ -84,7 +120,6 @@ def warm_up(self): self._model = whisper.load_model(self.model_name, device=self.device) def run(self, audios: List[Path], whisper_params: Dict[str, Any]) -> Output: - self.warm_up() documents = self.transcribe_to_documents(audios, **whisper_params) return WhisperTranscriber.Output(documents) diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py index e9e1757484..7d3630050e 100644 --- a/test/preview/components/test_transcriber_whisper.py +++ b/test/preview/components/test_transcriber_whisper.py @@ -1,9 +1,14 @@ -from typing import List, Tuple, Dict, Any - +import os +import sys from pathlib import Path +from unittest.mock import MagicMock import pytest +import torch +import whisper +from generalimport import FakeModule +from haystack.preview.dataclasses import Document from haystack.preview.components import WhisperTranscriber from test.preview.components.test_component_base import BaseTestComponent @@ -19,8 +24,103 @@ class TestTranscriber(BaseTestComponent): @pytest.fixture def components(self): - return [WhisperTranscriber()] + return [WhisperTranscriber(api_key="just a test"), WhisperTranscriber(model_name_or_path="large-v2")] + + @pytest.fixture + def mock_models(self, monkeypatch): + def mock_transcribe(_, audio_file, **kwargs): + return { + "text": "test transcription", + "other_metadata": ["other", "meta", "data"], + "kwargs received": kwargs, + } + + monkeypatch.setattr(WhisperTranscriber, "_transcribe_with_api", mock_transcribe) + monkeypatch.setattr(WhisperTranscriber, "_transcribe_locally", mock_transcribe) + monkeypatch.setattr(WhisperTranscriber, "warm_up", lambda self: None) + + def test_init_remote_unknown_model(self): + with pytest.raises(ValueError, match="not recognized"): + WhisperTranscriber(model_name_or_path="anything") + + def test_init_default_remote_missing_key(self): + with pytest.raises(ValueError, match="API key"): + WhisperTranscriber() + + def test_init_explicit_remote_missing_key(self): + with pytest.raises(ValueError, match="API key"): + WhisperTranscriber(model_name_or_path="whisper-1") + + def test_init_remote(self): + transcriber = WhisperTranscriber(api_key="just a test") + assert transcriber.model_name == "whisper-1" + assert not transcriber.use_local_whisper + assert not hasattr(transcriber, "device") + assert hasattr(transcriber, "_model") and transcriber._model is None + + def test_init_local(self): + transcriber = WhisperTranscriber(model_name_or_path="large-v2") + assert transcriber.model_name == "large-v2" # Doesn't matter if it's huge, the model is not loaded in init. + assert transcriber.use_local_whisper + assert hasattr(transcriber, "device") and transcriber.device == torch.device("cpu") + assert hasattr(transcriber, "_model") and transcriber._model is None + + def test_init_local_with_api_key(self): + transcriber = WhisperTranscriber(model_name_or_path="large-v2") + assert transcriber.model_name == "large-v2" # Doesn't matter if it's huge, the model is not loaded in init. + assert transcriber.use_local_whisper + assert hasattr(transcriber, "device") and transcriber.device == torch.device("cpu") + assert hasattr(transcriber, "_model") and transcriber._model is None + + def test_init_missing_whisper_lib(self, monkeypatch): + monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test message")) + with pytest.raises(ValueError, match="audio extra"): + WhisperTranscriber(model_name_or_path="large-v2") + + def test_init_missing_whisper_lib(self, monkeypatch): + monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test message")) + with pytest.raises(ValueError, match="audio extra"): + WhisperTranscriber(model_name_or_path="large-v2") + + def test_warmup_remote_model(self, monkeypatch): + load_model = MagicMock() + monkeypatch.setattr(whisper, "load_model", load_model) + component = WhisperTranscriber(model_name_or_path="whisper-1", api_key="doesn't matter") + component.warm_up() + assert not load_model.called + + def test_warmup_local_model(self, monkeypatch): + load_model = MagicMock() + load_model.side_effect = ["FAKE MODEL"] + monkeypatch.setattr(whisper, "load_model", load_model) + + component = WhisperTranscriber(model_name_or_path="large-v2") + component.warm_up() + + assert hasattr(component, "_model") + assert component._model == "FAKE MODEL" + load_model.assert_called_with("large-v2", device=torch.device(type="cpu")) + + def test_warmup_local_model_doesnt_reload(self, monkeypatch): + load_model = MagicMock() + monkeypatch.setattr(whisper, "load_model", load_model) + component = WhisperTranscriber(model_name_or_path="large-v2") + component.warm_up() + component.warm_up() + load_model.assert_called_once() - def test_transcribe(self): - pass - # TODO mock model + def test_transcribe_to_documents(self, mock_models): + comp = WhisperTranscriber(model_name_or_path="large-v2") + output = comp.transcribe_to_documents( + audio_files=[SAMPLES_PATH / "audio" / "this is the content of the document.wav"] + ) + assert output == [ + Document( + content="test transcription", + metadata={ + "audio_file": SAMPLES_PATH / "audio" / "this is the content of the document.wav", + "other_metadata": ["other", "meta", "data"], + "kwargs received": {}, + }, + ) + ] From 253b32415a0456be7bd548662ae4eac499b43977 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Mon, 8 May 2023 18:24:00 +0200 Subject: [PATCH 12/14] mypy and pylint --- .../preview/components/audio/transcriber.py | 18 ++++++++++++------ haystack/preview/utils/import_utils.py | 19 ------------------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/haystack/preview/components/audio/transcriber.py b/haystack/preview/components/audio/transcriber.py index 4c6ef1004e..9ab3769c1b 100644 --- a/haystack/preview/components/audio/transcriber.py +++ b/haystack/preview/components/audio/transcriber.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Dict, Any, Union, BinaryIO, Literal, get_args +from typing import List, Optional, Dict, Any, Union, BinaryIO, Literal, get_args, Sequence import os import json @@ -13,7 +13,7 @@ from haystack.preview import component, Document from haystack.errors import OpenAIError, OpenAIRateLimitError -from haystack.preview.utils.import_utils import is_imported +from haystack import is_imported logger = logging.getLogger(__name__) @@ -54,7 +54,10 @@ class Output: documents: List[Document] def __init__( - self, model_name_or_path: WhisperModel = "whisper-1", api_key: Optional[str] = None, device: str = None + self, + model_name_or_path: WhisperModel = "whisper-1", + api_key: Optional[str] = None, + device: Optional[str] = None, ): """ Transcribes a list of audio files into a list of Documents. @@ -123,7 +126,7 @@ def run(self, audios: List[Path], whisper_params: Dict[str, Any]) -> Output: documents = self.transcribe_to_documents(audios, **whisper_params) return WhisperTranscriber.Output(documents) - def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + def transcribe_to_documents(self, audio_files: Sequence[Union[str, Path, BinaryIO]], **kwargs) -> List[Document]: """ Transcribe the given audio files. Returns a list of Documents. @@ -140,7 +143,7 @@ def transcribe_to_documents(self, audio_files: List[Union[str, BinaryIO]], **kwa for audio, transcript in zip(audio_files, transcriptions) ] - def transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[str, Any]: + def transcribe(self, audio_files: Sequence[Union[str, Path, BinaryIO]], **kwargs) -> List[Dict[str, Any]]: """ Transcribe the given audio files. Returns a list of strings. @@ -151,7 +154,6 @@ def transcribe(self, audio_files: List[Union[str, BinaryIO]], **kwargs) -> Dict[ :param audio_files: a list of paths or binary streams to transcribe :returns: a list of transcriptions. """ - self.warm_up() transcriptions = [] for audio_file in audio_files: if isinstance(audio_file, (str, Path)): @@ -196,6 +198,10 @@ def _transcribe_locally(self, audio_file: BinaryIO, **kwargs) -> Dict[str, Any]: """ Calls a local Whisper model. """ + if not self._model: + self.warm_up() + if not self._model: + raise ValueError("WhisperTranscriber._transcribe_locally() can't work without a local model.") return_segments = kwargs.pop("return_segments", None) transcription = self._model.transcribe(audio_file.name, **kwargs) if not return_segments: diff --git a/haystack/preview/utils/import_utils.py b/haystack/preview/utils/import_utils.py index d2280dc542..6917309430 100644 --- a/haystack/preview/utils/import_utils.py +++ b/haystack/preview/utils/import_utils.py @@ -1,27 +1,8 @@ from typing import Optional, Any -import sys import importlib import logging -from generalimport import FakeModule, MissingOptionalDependency - - -# -# TEMPORARY: remove once generalimport>0.3.1 is released (https://github.com/ManderaGeneral/generalimport/pull/25) -# -def is_imported(module_name: str) -> bool: - """ - Returns True if the module was actually imported, False, if generalimport mocked it. - """ - module = sys.modules.get(module_name) - try: - return bool(module and not isinstance(module, FakeModule)) - except MissingOptionalDependency as exc: - # isinstance() raises MissingOptionalDependency: fake module - pass - return False - def optional_import(import_path: str, import_target: Optional[str], error_msg: str, importer_module: str) -> Any: """ From 709111579132de17dd189a9d28eb65e42fa2dfc8 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Tue, 9 May 2023 15:13:07 +0200 Subject: [PATCH 13/14] add markers --- test/preview/components/test_transcriber_whisper.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py index 7d3630050e..79509c7ef4 100644 --- a/test/preview/components/test_transcriber_whisper.py +++ b/test/preview/components/test_transcriber_whisper.py @@ -39,18 +39,22 @@ def mock_transcribe(_, audio_file, **kwargs): monkeypatch.setattr(WhisperTranscriber, "_transcribe_locally", mock_transcribe) monkeypatch.setattr(WhisperTranscriber, "warm_up", lambda self: None) + @pytest.mark.unit def test_init_remote_unknown_model(self): with pytest.raises(ValueError, match="not recognized"): WhisperTranscriber(model_name_or_path="anything") + @pytest.mark.unit def test_init_default_remote_missing_key(self): with pytest.raises(ValueError, match="API key"): WhisperTranscriber() + @pytest.mark.unit def test_init_explicit_remote_missing_key(self): with pytest.raises(ValueError, match="API key"): WhisperTranscriber(model_name_or_path="whisper-1") + @pytest.mark.unit def test_init_remote(self): transcriber = WhisperTranscriber(api_key="just a test") assert transcriber.model_name == "whisper-1" @@ -58,6 +62,7 @@ def test_init_remote(self): assert not hasattr(transcriber, "device") assert hasattr(transcriber, "_model") and transcriber._model is None + @pytest.mark.unit def test_init_local(self): transcriber = WhisperTranscriber(model_name_or_path="large-v2") assert transcriber.model_name == "large-v2" # Doesn't matter if it's huge, the model is not loaded in init. @@ -65,6 +70,7 @@ def test_init_local(self): assert hasattr(transcriber, "device") and transcriber.device == torch.device("cpu") assert hasattr(transcriber, "_model") and transcriber._model is None + @pytest.mark.unit def test_init_local_with_api_key(self): transcriber = WhisperTranscriber(model_name_or_path="large-v2") assert transcriber.model_name == "large-v2" # Doesn't matter if it's huge, the model is not loaded in init. @@ -72,16 +78,19 @@ def test_init_local_with_api_key(self): assert hasattr(transcriber, "device") and transcriber.device == torch.device("cpu") assert hasattr(transcriber, "_model") and transcriber._model is None + @pytest.mark.unit def test_init_missing_whisper_lib(self, monkeypatch): monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test message")) with pytest.raises(ValueError, match="audio extra"): WhisperTranscriber(model_name_or_path="large-v2") + @pytest.mark.unit def test_init_missing_whisper_lib(self, monkeypatch): monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test message")) with pytest.raises(ValueError, match="audio extra"): WhisperTranscriber(model_name_or_path="large-v2") + @pytest.mark.unit def test_warmup_remote_model(self, monkeypatch): load_model = MagicMock() monkeypatch.setattr(whisper, "load_model", load_model) @@ -89,6 +98,7 @@ def test_warmup_remote_model(self, monkeypatch): component.warm_up() assert not load_model.called + @pytest.mark.unit def test_warmup_local_model(self, monkeypatch): load_model = MagicMock() load_model.side_effect = ["FAKE MODEL"] @@ -101,6 +111,7 @@ def test_warmup_local_model(self, monkeypatch): assert component._model == "FAKE MODEL" load_model.assert_called_with("large-v2", device=torch.device(type="cpu")) + @pytest.mark.unit def test_warmup_local_model_doesnt_reload(self, monkeypatch): load_model = MagicMock() monkeypatch.setattr(whisper, "load_model", load_model) @@ -109,6 +120,7 @@ def test_warmup_local_model_doesnt_reload(self, monkeypatch): component.warm_up() load_model.assert_called_once() + @pytest.mark.unit def test_transcribe_to_documents(self, mock_models): comp = WhisperTranscriber(model_name_or_path="large-v2") output = comp.transcribe_to_documents( From a23b56c8cfbb906c6cb2b6d9bc2e27a4ae5acc45 Mon Sep 17 00:00:00 2001 From: ZanSara Date: Wed, 10 May 2023 16:43:34 +0200 Subject: [PATCH 14/14] deduplicate test --- test/preview/components/test_transcriber_whisper.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/preview/components/test_transcriber_whisper.py b/test/preview/components/test_transcriber_whisper.py index 79509c7ef4..ecd97e84a4 100644 --- a/test/preview/components/test_transcriber_whisper.py +++ b/test/preview/components/test_transcriber_whisper.py @@ -79,16 +79,16 @@ def test_init_local_with_api_key(self): assert hasattr(transcriber, "_model") and transcriber._model is None @pytest.mark.unit - def test_init_missing_whisper_lib(self, monkeypatch): - monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test message")) + def test_init_missing_whisper_lib_local_model(self, monkeypatch): + monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test")) with pytest.raises(ValueError, match="audio extra"): WhisperTranscriber(model_name_or_path="large-v2") @pytest.mark.unit - def test_init_missing_whisper_lib(self, monkeypatch): - monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test message")) - with pytest.raises(ValueError, match="audio extra"): - WhisperTranscriber(model_name_or_path="large-v2") + def test_init_missing_whisper_lib_remote_model(self, monkeypatch): + monkeypatch.setitem(sys.modules, "whisper", FakeModule(spec=MagicMock(), message="test")) + # Should not fail if the lib is missing and we're using API + WhisperTranscriber(model_name_or_path="whisper-1", api_key="doesn't matter") @pytest.mark.unit def test_warmup_remote_model(self, monkeypatch):