From 3fe918017e49098b20737d7ad3181bc62e591107 Mon Sep 17 00:00:00 2001 From: J-Dymond Date: Fri, 15 Nov 2024 16:27:55 +0000 Subject: [PATCH] fixed pre-commit --- .pre-commit-config.yaml | 2 +- data/MultiEURLEX/data/README.md | 2 +- data/MultiEURLEX/data/eurovoc_concepts.json | 2 +- notebooks/tts_pipeline_nb.ipynb | 809 ------------------ scripts/variational_RTC_example.py | 14 +- src/arc_spice/__init__.py | 4 +- src/arc_spice/data/multieurlex_utils.py | 28 +- src/arc_spice/eval/classification_error.py | 5 +- src/arc_spice/eval/translation_error.py | 3 +- .../RTC_variational_pipeline.py | 62 +- 10 files changed, 62 insertions(+), 869 deletions(-) delete mode 100644 notebooks/tts_pipeline_nb.ipynb diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 30c2b37..2e653f2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,6 +34,6 @@ repos: hooks: - id: mypy files: src - args: [] + args: [--ignore-missing-imports] additional_dependencies: - pytest diff --git a/data/MultiEURLEX/data/README.md b/data/MultiEURLEX/data/README.md index ceace16..f592a59 100644 --- a/data/MultiEURLEX/data/README.md +++ b/data/MultiEURLEX/data/README.md @@ -1,2 +1,2 @@ # Multi-EURLEX files -This folder contains files for the loading of [Multi-EURLEX](https://aclanthology.org/2021.emnlp-main.559/), these files are taken from the [official repo](https://github.com/nlpaueb/multi-eurlex). \ No newline at end of file +This folder contains files for the loading of [Multi-EURLEX](https://aclanthology.org/2021.emnlp-main.559/), these files are taken from the [official repo](https://github.com/nlpaueb/multi-eurlex). diff --git a/data/MultiEURLEX/data/eurovoc_concepts.json b/data/MultiEURLEX/data/eurovoc_concepts.json index 4b80ac7..2949870 100644 --- a/data/MultiEURLEX/data/eurovoc_concepts.json +++ b/data/MultiEURLEX/data/eurovoc_concepts.json @@ -14797,4 +14797,4 @@ "4355", "5318" ] -} \ No newline at end of file +} diff --git a/notebooks/tts_pipeline_nb.ipynb b/notebooks/tts_pipeline_nb.ipynb deleted file mode 100644 index 2e10379..0000000 --- a/notebooks/tts_pipeline_nb.ipynb +++ /dev/null @@ -1,809 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# First pass at developing the TTS pipeline\n", - "\n", - "Using off the shelf hugging-face models to build the transcription -> translation -> summarisation pipeline." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Lets start with a transcription model\n", - "\n", - "Looks like the `openai/whisper-small` model would be appropriate, it does French to French transcription." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from transformers import WhisperProcessor, WhisperForConditionalGeneration\n", - "from datasets import Audio, load_dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# Loade model and processor\n", - "transcription_processor = WhisperProcessor.from_pretrained(\"openai/whisper-small\")\n", - "transcription_model = WhisperForConditionalGeneration.from_pretrained(\n", - " \"openai/whisper-small\"\n", - ")\n", - "forced_decoder_ids = transcription_processor.get_decoder_prompt_ids(\n", - " language=\"french\", task=\"transcribe\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "0244399d028f484dbb340dcc17a15787", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Resolving data files: 0%| | 0/48 [00:00]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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LSOy79ZbbzX93K1bN3Tv3h1t2rTB2rVrMXz4cBVbpg/3338/9uzZgz/++EPtpvgUe8d16tSppp+7deuGZs2aYfjw4Thy5AjatGnj7WZqDoeNnIiNjUVAQIBNZvXp06cRHx+vUqu0JSoqCu3bt8fhw4cRHx+PiooKFBQUWGxjfrzi4+NFj2fdc462iYiIQIMGDXz671LXfke/W3x8PM6cOWPxfFVVFfLz82U5zubPO2uLXiUnJyM2NhaHDx8GwGPqyPTp0/HLL79gzZo1aNGihelxLX3fpbRFa+wdVzEpKSkAYPF59efjyuDFieDgYPTp0werVq0yPVZTU4NVq1YhNTVVxZZpR0lJCY4cOYJmzZqhT58+CAoKsjheBw8eRHZ2tul4paamYvfu3RYXihUrViAiIgKdO3c2bWO+j7pt6vbhy3+X1q1bIz4+3uJ3KyoqwpYtWyyOYUFBATIzM03brF69GjU1NaaTXGpqKtavX4/KykrTNitWrECHDh0QHR1t2sbRcZbSFr36+++/cf78eTRr1gwAj6kYQRAwffp0LFmyBKtXr7YZMtPS911KW7TC2XEVk5WVBQAWn1e/Pq6qpQrryOLFi4WQkBDh008/Ffbt2ydMnTpViIqKssjy9iePPPKIsHbtWuHYsWPCxo0bhbS0NCE2NlY4c+aMIAi10+patmwprF69Wti2bZuQmpoqpKamml5fN8VvxIgRQlZWlpCeni40adJEdIrfY489Juzfv19YtGiR6BQ/vf5diouLhR07dgg7duwQAAivvfaasGPHDuHEiROCINROpY2KihJ+/PFHYdeuXcJ1110nOlW6V69ewpYtW4Q//vhDaNeuncW03oKCAiEuLk644447hD179giLFy8WwsLCbKb1BgYGCgsWLBD2798vzJ49W3Rar7O2aIGjY1pcXCw8+uijQkZGhnDs2DFh5cqVQu/evYV27doJly5dMu2Dx9TStGnThMjISGHt2rUWU3bLyspM22jp++6sLVrh7LgePnxYeP7554Vt27YJx44dE3788UchOTlZGDJkiGkf/n5cGbxI9NZbbwktW7YUgoODhf79+wubN29Wu0mqGT9+vNCsWTMhODhYaN68uTB+/Hjh8OHDpucvXrwo3HfffUJ0dLQQFhYm3HDDDcKpU6cs9nH8+HFh9OjRQoMGDYTY2FjhkUceESorKy22WbNmjdCzZ08hODhYSE5OFj755BObtuj177JmzRoBgM1/d955pyAItdNpn3nmGSEuLk4ICQkRhg8fLhw8eNBiH+fPnxduu+02oVGjRkJERIQwadIkobi42GKbnTt3CldccYUQEhIiNG/eXJg3b55NW7799luhffv2QnBwsNClSxdh2bJlFs9LaYsWODqmZWVlwogRI4QmTZoIQUFBQqtWrYQpU6bYBLo8ppbEjicAi++ilr7vUtqiBc6Oa3Z2tjBkyBAhJiZGCAkJEdq2bSs89thjFnVeBMG/j6tBEATBe/08RERERJ5hzgsRERHpCoMXIiIi0hUGL0RERKQrDF6IiIhIVxi8EBERka4weCEiIiJdYfBCREREusLghYiIiHSFwQsRERHpCoMXIiIi0hUGL0RERKQrDF6IiIhIV/4fMtR/XUHtB6YAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(input_speech[\"array\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "# generate token ids\n", - "predicted_ids = transcription_model.generate(\n", - " input_features, forced_decoder_ids=forced_decoder_ids\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[\"<|startoftranscript|><|fr|><|transcribe|><|notimestamps|> Pendant le second siècle, je fis serment d'ouvrir tous les trésors de la terre, à qui compte-me mettre en liberté. Mais je ne fus pas plus heureux. Dans le troisième, je promis de faire puissant mon arc, mon libérateur, d'être toujours près de lui en esprit.\"]" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# decode token ids to text\n", - "transcription = transcription_processor.batch_decode(predicted_ids)\n", - "transcription" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[\" Pendant le second siècle, je fis serment d'ouvrir tous les trésors de la terre, à qui compte-me mettre en liberté. Mais je ne fus pas plus heureux. Dans le troisième, je promis de faire puissant mon arc, mon libérateur, d'être toujours près de lui en esprit.\"]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# transcription without special characters\n", - "transcription = transcription_processor.batch_decode(\n", - " predicted_ids, skip_special_tokens=True\n", - ")\n", - "transcription" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### And now onto translation\n", - "\n", - "Should be relatively straightforward" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from transformers import MBartForConditionalGeneration, MBart50TokenizerFast" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/edable-heath/Documents/ARC-SPICE/.venv/lib/python3.11/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n", - " warnings.warn(\n" - ] - } - ], - "source": [ - "# load model and tokenizer\n", - "translation_model = MBartForConditionalGeneration.from_pretrained(\n", - " \"facebook/mbart-large-50-many-to-many-mmt\"\n", - ")\n", - "translation_tokenizer = MBart50TokenizerFast.from_pretrained(\n", - " \"facebook/mbart-large-50-many-to-many-mmt\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "# translate from french to english\n", - "translation_tokenizer.src_lang = \"fr_XX\"\n", - "encode_fr = translation_tokenizer(transcription, return_tensors=\"pt\")\n", - "generated_tokens = translation_model.generate(\n", - " **encode_fr, forced_bos_token_id=translation_tokenizer.lang_code_to_id[\"en_XX\"]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['In the second century, I swore to open all the treasures of the earth, to whom I was about to release, but I was no happier. In the third, I promised to make my bow, my liberator, powerful, to be always close to him in mind.']" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "translation = translation_tokenizer.batch_decode(\n", - " generated_tokens, skip_special_tokens=True\n", - ")\n", - "translation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### And Finally: Summarisation\n", - "\n", - "Lets use the facebook model" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/edable-heath/Documents/ARC-SPICE/.venv/lib/python3.11/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n", - " warnings.warn(\n", - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n" - ] - } - ], - "source": [ - "from transformers import pipeline\n", - "\n", - "summarizer = pipeline(\"summarization\", model=\"facebook/bart-large-cnn\")" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'summary_text': 'National Union of Rail, Maritime and Transport Workers (RMT) voted overwhelmingly to support the pay offers that will result in increases of more than 4 percent over the next two years. RMT held more than 30 days of industrial action since June 2022 over a previous pay dispute with Network Rail and rail operators.'}]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "article = \"\"\"\n", - "Rail workers have voted to accept pay offers by train companies and Network Rail, reducing the prospect of a repeat of the national strikes that have caused misery for passengers over the last two years.\n", - "\n", - "Members of the National Union of Rail, Maritime and Transport Workers (RMT) voted overwhelmingly to support the pay offers that will result in increases of more than 4 percent over the next two years.\n", - "\n", - "The RMT said the ballot result meant that the long-running national dispute was now over and the outcome reflected collective efforts to defend jobs and pay conditions from the attacks of private contractors and the previous Conservative government.\n", - "\n", - "LNER trains at King's Cross station in London\n", - "\n", - "The RMT held more than 30 days of industrial action since June 2022 over a previous pay dispute with Network Rail and rail operators.\n", - "\n", - "A deal was agreed in March last year with Network Rail, while its deal with operators was concluded in November last year.\n", - "\n", - "The latest pay deal will lead to union members at Network Rail, who are largely maintenance staff and signallers, receiving a 4.5 percent increase this year. Almost 89 percent of those members who voted were favour of the deal.\n", - "\n", - "The agreement with operators, which covers train crew and ticket office staff, will lead to a 4.75 percent backdated increase on last year’s pay, with a 4.5 percent rise for the current financial year. The ballot featured 99 percent of voting members voting in favour of the deal.\n", - "\n", - "In a statement, the RMT said: “We thank our members for their efforts during this long but successful campaign.\n", - "\n", - "“Their resolve has been essential in navigating the challenges posed during negotiations and in particular the previous Tory government’s refusal to negotiate in good faith, alongside relentless attacks by sections of the media and the employers.\n", - "\n", - "“RMT remains focused and committed to supporting public ownership as a path to building a stronger future for the rail industry for both workers and passengers.”\n", - "\n", - "The transport secretary, Louise Haigh, said: “This is a necessary step towards fixing our railways and getting the country moving.\n", - "\n", - "\n", - "“It will ensure a more reliable service by helping to protect passengers from national strikes, and crucially, it clears the way for vital reform and modernising working practices to ensure a better performing railway for everyone.\n", - "\n", - "“This Labour government won’t make the same mistake as the Conservatives who deliberately prolonged rail strikes and cost the economy more than £1bn.”\n", - "\n", - "Last week, train drivers who are members of the Aslef union voted to back a pay deal.\n", - "\n", - "The decision came after drivers had taken 18 days of strike action since July 2022, resulting in a near-complete shutdown of English lines and some cross-border services, as well as a run of overtime bans that caused widespread disruption.\n", - "\n", - "\n", - "\"\"\"\n", - "summarizer(\n", - " article,\n", - " # max_length=len(article.split()) // 2,\n", - " # min_length=len(article.split()) // 5,\n", - " # do_sample=False,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "95" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(article.split())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Summariser seems to work, but only for sufficiently long examples, which makes sense. Otherwise it just picks up the first part of the text. Need to find some french recordings on sufficient length." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Can this be tied together in one pipeline structure?\n", - "\n", - "This will make generalisation easier." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The transcription is: \n", - " Pendant le second siècle, je fis serment d'ouvrir tous les trésors de la terre, à qui compte-me mettre en liberté. Mais je ne fus pas plus heureux. Dans le troisième, je promis de faire puissant mon arc, mon libérateur, d'être toujours près de lui en esprit.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The translation is: \n", - " en the second century, I made a vow to open all the treasures of the earth, to whom I intend to release. But I was no happier. In the third, I promised to make my bow, my liberal, powerful, to be always close to him in mind.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n", - "Your max_length is set to 142, but your input_length is only 58. Since this is a summarization task, where outputs shorter than the input are typically wanted, you might consider decreasing max_length manually, e.g. summarizer('...', max_length=29)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The summary is: \n", - " In the second century, I made a vow to open all the treasures of the earth, to whom I intend to release. But I was no happier. In the third, I promised to make my bow, my liberal, powerful, to be always close to him in mind.\n" - ] - } - ], - "source": [ - "from transformers import pipeline\n", - "\n", - "# transcription\n", - "asr = pipeline(\"automatic-speech-recognition\", model=\"openai/whisper-small\")\n", - "transcription = asr(input_speech[\"array\"])\n", - "print(f\"The transcription is: \\n {transcription['text']}\")\n", - "\n", - "# translation\n", - "trltr = pipeline(\n", - " \"translation_fr_to_en\", model=\"facebook/mbart-large-50-many-to-many-mmt\"\n", - ")\n", - "translation = trltr(transcription[\"text\"])\n", - "print(f\"The translation is: \\n {translation[0]['translation_text']}\")\n", - "\n", - "# summarisation\n", - "summarizer = pipeline(\"summarization\", model=\"facebook/bart-large-cnn\")\n", - "summary = summarizer(translation[0][\"translation_text\"])\n", - "print(f\"The summary is: \\n {summary[0]['summary_text']}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Putting it all together into a single script" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [], - "source": [ - "from transformers import (\n", - " pipeline,\n", - ")\n", - "\n", - "\n", - "class TTSpipeline:\n", - " \"\"\"\n", - " Class for the transcription, translation, summarisation pipeline.\n", - "\n", - " pars:\n", - " - {'top_level_task': {'specific_task': str, 'model_name': str}}\n", - " \"\"\"\n", - "\n", - " def __init__(self, pars) -> None:\n", - " self.pars = pars\n", - " self.transcriber = pipeline(\n", - " pars[\"transcriber\"][\"specific_task\"], pars[\"transcriber\"][\"model\"]\n", - " )\n", - " self.translator = pipeline(\n", - " pars[\"translator\"][\"specific_task\"], pars[\"translator\"][\"model\"]\n", - " )\n", - " self.summariser = pipeline(\n", - " pars[\"summariser\"][\"specific_task\"], pars[\"summariser\"][\"model\"]\n", - " )\n", - " self.results = {}\n", - "\n", - " def print_pipeline(self):\n", - " \"\"\"Print the models in the pipeline\"\"\"\n", - " print(f\"Transcriber model: {self.pars['transcriber']['model']}\")\n", - " print(f\"Translator model: {self.pars['translator']['model']}\")\n", - " print(f\"Summariser model: {self.pars['summariser']['model']}\")\n", - "\n", - " def run_pipeline(self, x):\n", - " \"\"\"Run the pipeline on an input x\"\"\"\n", - " transcription = self.transcriber(x)\n", - " self.results[\"transcription\"] = transcription[\"text\"]\n", - " translation = self.translator(transcription[\"text\"])\n", - " self.results[\"translation\"] = translation[0][\"translation_text\"]\n", - " summarisation = self.summariser(translation[0][\"translation_text\"])\n", - " self.results[\"summarisation\"] = summarisation[0][\"summary_text\"]\n", - "\n", - " def print_results(self):\n", - " \"\"\"Print the results for quick scanning\"\"\"\n", - " for key, val in self.results.items():\n", - " print(f\"{key} result is: \\n {val}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n", - "/Users/edable-heath/Documents/ARC-SPICE/.venv/lib/python3.11/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n", - " warnings.warn(\n", - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n", - "Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Transcriber model: openai/whisper-small\n", - "Translator model: facebook/mbart-large-50-many-to-many-mmt\n", - "Summariser model: facebook/bart-large-cnn\n" - ] - } - ], - "source": [ - "TTS_pars = {\n", - " \"transcriber\": {\n", - " \"specific_task\": \"automatic-speech-recognition\",\n", - " \"model\": \"openai/whisper-small\",\n", - " },\n", - " \"translator\": {\n", - " \"specific_task\": \"translation_fr_to_en\",\n", - " \"model\": \"facebook/mbart-large-50-many-to-many-mmt\",\n", - " },\n", - " \"summariser\": {\n", - " \"specific_task\": \"summarization\",\n", - " \"model\": \"facebook/bart-large-cnn\",\n", - " },\n", - "}\n", - "\n", - "TTS_pipeline = TTSpipeline(TTS_pars)\n", - "\n", - "TTS_pipeline.print_pipeline()" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "de011c6e05be44708ba428bd65ff4aff", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Resolving data files: 0%| | 0/48 [00:00 torch.Tensor: torch.tensor(class_labels), num_classes=self.n_classes, ) - one_hot_multi_class = torch.sum(one_hot_class_labels, dim=0) - return one_hot_multi_class + return torch.sum(one_hot_class_labels, dim=0) def _extract_articles(text: str, article_1_marker: str): @@ -36,7 +34,7 @@ def _extract_articles(text: str, article_1_marker: str): return text[start:] -def extract_articles(item: LazyRow, lang_pair: dict[str:str]): +def extract_articles(item: LazyRow, lang_pair: dict[str, str]): lang_source = lang_pair["source"] lang_target = lang_pair["target"] return { @@ -54,13 +52,13 @@ def extract_articles(item: LazyRow, lang_pair: dict[str:str]): class PreProcesser: """Function to preprocess the data, for the purposes of removing unused languages""" - def __init__(self, language_pair: dict[str:str]) -> None: + def __init__(self, language_pair: dict[str, str]) -> None: self.source_language = language_pair["source"] self.target_language = language_pair["target"] def __call__( - self, data_row: dict[str : Union[str, list]] - ) -> dict[str : Union[str, list]]: + self, data_row: dict[str, dict[str, str]] + ) -> dict[str, str | dict[str, str]]: """ processes the row in the dataset @@ -73,17 +71,16 @@ def __call__( source_text = data_row["text"][self.source_language] target_text = data_row["text"][self.target_language] labels = data_row["labels"] - row = { + return { "source_text": source_text, "target_text": target_text, "class_labels": labels, } - return row def load_multieurlex( - data_dir: str, level: int, lang_pair: dict[str:str] -) -> tuple[list, dict[str : Union[int, list]]]: + data_dir: str, level: int, lang_pair: dict[str, str] +) -> tuple[list, dict[str, int | list]]: """ load the multieurlex dataset @@ -96,19 +93,16 @@ def load_multieurlex( List of datasets and a dictionary with some metadata information """ assert level in [1, 2, 3], "there are 3 levels of hierarchy: 1,2,3." - with open( - f"{data_dir}/MultiEURLEX/data/eurovoc_concepts.json", "r" - ) as concepts_file: + with open(f"{data_dir}/MultiEURLEX/data/eurovoc_concepts.json") as concepts_file: class_concepts = json.loads(concepts_file.read()) concepts_file.close() with open( - f"{data_dir}/MultiEURLEX/data/eurovoc_descriptors.json", "r" + f"{data_dir}/MultiEURLEX/data/eurovoc_descriptors.json" ) as descriptors_file: class_descriptors = json.loads(descriptors_file.read()) descriptors_file.close() # format level for the class descriptor dictionary, add these to a list - level = f"level_{level}" classes = class_concepts[level] descriptors = [] for class_id in classes: @@ -118,7 +112,7 @@ def load_multieurlex( data = load_dataset( "multi_eurlex", "all_languages", - label_level=level, + label_level=f"level_{level}", trust_remote_code=True, ) # define metadata diff --git a/src/arc_spice/eval/classification_error.py b/src/arc_spice/eval/classification_error.py index 45d043b..d17498f 100644 --- a/src/arc_spice/eval/classification_error.py +++ b/src/arc_spice/eval/classification_error.py @@ -3,8 +3,7 @@ def hamming_accuracy(preds: torch.Tensor, class_labels: torch.Tensor) -> torch.Tensor: # Inverse of the hamming loss (the fraction of labels incorrectly predicted) - accuracy = torch.mean((preds.float() == class_labels.float()).float()) - return accuracy + return torch.mean((preds.float() == class_labels.float()).float()) def aggregate_score(probs: torch.Tensor) -> torch.Tensor: @@ -16,7 +15,7 @@ def aggregate_score(probs: torch.Tensor) -> torch.Tensor: def MC_dropout_scores( variational_probs: list[float], epsilon: float = 1e-14 -) -> dict[str : torch.Tensor]: +) -> dict[str, torch.Tensor]: # aggregate over the classes, performing MC Dropout on each class treating it # as a binary classification problem stacked_probs = torch.stack( diff --git a/src/arc_spice/eval/translation_error.py b/src/arc_spice/eval/translation_error.py index 5d158fe..510b157 100644 --- a/src/arc_spice/eval/translation_error.py +++ b/src/arc_spice/eval/translation_error.py @@ -9,5 +9,4 @@ def get_bleu_score(target, translation): def get_comet_model(model_path="Unbabel/wmt22-comet-da"): # Load the model checkpoint: comet_model_pth = download_model(model=model_path) - comet_model = load_from_checkpoint(comet_model_pth) - return comet_model + return load_from_checkpoint(comet_model_pth) diff --git a/src/arc_spice/variational_pipelines/RTC_variational_pipeline.py b/src/arc_spice/variational_pipelines/RTC_variational_pipeline.py index d576e77..a2d33c3 100644 --- a/src/arc_spice/variational_pipelines/RTC_variational_pipeline.py +++ b/src/arc_spice/variational_pipelines/RTC_variational_pipeline.py @@ -1,6 +1,6 @@ import copy import logging -from typing import Any, Union +from typing import Any import torch from torch.nn.functional import softmax @@ -42,20 +42,21 @@ class RTCVariationalPipeline: def __init__( self, - model_pars: dict[str : dict[str:str]], + model_pars: dict[str, dict[str, str]], data_pars, n_variational_runs=5, translation_batch_size=8, ) -> None: - # device for inference device = ( "cuda" if torch.cuda.is_available() - else "mps" if torch.backends.mps.is_available() else "cpu" + else "mps" + if torch.backends.mps.is_available() + else "cpu" ) - - logging.info(f"Loading pipeline on device: {device}") + debug_msg_device = f"Loading pipeline on device: {device}" + logging.info(debug_msg_device) # defining the pipeline objects self.ocr = pipeline( @@ -144,8 +145,7 @@ def split_translate_inputs(text: str, split_key: str) -> list[str]: # for when string ends with with the delimiter if split_rows[-1] == "": split_rows = split_rows[:-1] - recovered_splits = [split + split_key for split in split_rows] - return recovered_splits + return [split + split_key for split in split_rows] def check_dropout(self): """ @@ -158,17 +158,20 @@ def check_dropout(self): for model_key, pl in self.pipeline_map.items(): # turn on dropout for this model set_dropout(model=pl.model, dropout_flag=True) - logger.debug(f"Model key: {model_key}") + debug_msg_key = f"Model key: {model_key}" + logger.debug(debug_msg_key) dropout_count = count_dropout(pipe=pl, dropout_flag=True) - logger.debug( + debug_msg_count = ( f"{dropout_count} dropout layers found in correct configuration." ) + logger.debug(debug_msg_count) if dropout_count == 0: - raise ValueError(f"No dropout layers found in {model_key}") + error_message = f"No dropout layers found in {model_key}" + raise ValueError(error_message) set_dropout(model=pl.model, dropout_flag=False) logger.debug("-------------------------------------------------------\n\n") - def recognise(self, inp) -> dict[str:str]: + def recognise(self, inp) -> dict[str, str]: """ Function to perform OCR @@ -182,7 +185,7 @@ def recognise(self, inp) -> dict[str:str]: # TODO https://github.com/alan-turing-institute/ARC-SPICE/issues/14 return {"outputs": inp} - def translate(self, text: str) -> dict[str : [torch.Tensor, str]]: + def translate(self, text: str) -> dict[str, torch.Tensor | str]: """ Function to perform translation @@ -224,12 +227,12 @@ def translate(self, text: str) -> dict[str : [torch.Tensor, str]]: confidence_metrics ) # add full output to the output dict - outputs = {"full_output": full_translation} + outputs: dict[str, Any] = {"full_output": full_translation} outputs.update(stacked_conf_metrics) # {full translation, sentence translations, logits, semantic embeddings} return outputs - def classify_topic(self, text: str) -> dict[str:str]: + def classify_topic(self, text: str) -> dict[str, str]: """ Runs the classification model @@ -240,8 +243,8 @@ def classify_topic(self, text: str) -> dict[str:str]: return {"scores": forward["scores"]} def stack_translator_sentence_metrics( - self, all_sentence_metrics: list[dict[str:Any]] - ) -> dict[str : list[Any]]: + self, all_sentence_metrics: list[dict[str, Any]] + ) -> dict[str, list[Any]]: """ Stacks values from dictionary list into lists under a single key @@ -256,15 +259,15 @@ def stack_translator_sentence_metrics( ] return stacked - def stack_variational_outputs(self, var_output): + def stack_variational_outputs(self, var_output: dict[str, list[Any]]): """ Similar to above but this stacks variational output dictinaries into lists under a single key. """ # Create new dict - new_var_dict = {} + new_var_dict: dict[str, Any] = {} # For each key create a new dict - for step in var_output.keys(): + for step in var_output: new_var_dict[step] = {} # for each metric in a clean inference run (naive_ouputs) for metric in self.naive_outputs[step]: @@ -333,7 +336,7 @@ def sentence_density( def translation_semantic_density( self, clean_output, var_output: dict - ) -> dict[str : Union[float, list[float]]]: + ) -> dict[str, float | list[Any]]: """ Runs the semantic density measurement from https://arxiv.org/pdf/2405.13845. @@ -353,8 +356,8 @@ def translation_semantic_density( var_steps = var_output["translation"] n_sentences = len(clean_out) # define empty lists for the measurements - densities = [None] * n_sentences - sequence_lengths = [None] * n_sentences + densities: list[Any] = [None] * n_sentences + sequence_lengths: list[Any] = [None] * n_sentences # stack the variational runs according to their sentences, then loop and pass to # density calculation function for sentence_index, clean_sentence in enumerate(clean_out): @@ -387,7 +390,7 @@ def translation_semantic_density( def get_classification_confidence( self, var_output: dict, epsilon: float = 1e-15 - ) -> dict[str : Union[float, torch.Tensor]]: + ) -> dict[str, float | torch.Tensor]: """ _summary_ @@ -431,10 +434,10 @@ def get_classification_confidence( ) return var_output - def clean_inference(self, x: torch.Tensor) -> dict[str:dict]: + def clean_inference(self, x: torch.Tensor) -> dict[str, dict]: """Run the pipeline on an input x""" # define output dictionary - clean_output = { + clean_output: dict[str, Any] = { "recognition": {}, "translation": {}, "classification": {}, @@ -452,14 +455,14 @@ def clean_inference(self, x: torch.Tensor) -> dict[str:dict]: ) return clean_output - def variational_inference(self, x: torch.Tensor) -> dict[str:dict]: + def variational_inference(self, x: torch.Tensor) -> tuple[dict, dict]: """ runs the variational inference with the pipeline """ # ...first run clean inference clean_output = self.clean_inference(x) # define output dictionary - var_output = { + var_output: dict[str, Any] = { "recognition": [None] * self.n_variational_runs, "translation": [None] * self.n_variational_runs, "classification": [None] * self.n_variational_runs, @@ -517,11 +520,10 @@ def postprocess( raw_out = copy.deepcopy(model_outputs) processed = super().postprocess(model_outputs, **postprocess_params) - new_output = { + return { "translation_text": processed[0]["translation_text"], "raw_outputs": raw_out, } - return new_output def _forward(self, model_inputs, **generate_kwargs): if self.framework == "pt":