{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[38;5;226m2022-07-01 14:28:43,377 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,378 | INFO | Found credentials file (/data/projects/scoutinscience/platform/projects/highlights-service2/mongo.ini), initialising MongoDbDriver\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,379 | INFO | Found credentials file (/data/projects/scoutinscience/platform/projects/highlights-service2/s3.ini), initialising LargeFileS3\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,380 | INFO | Settings: configured ✅\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,380 | INFO | 🔩 tracing_database: MongoDbDriver\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,381 | INFO | 🔩 large_file_implementation: LargeFileS3\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,381 | INFO | 🔩 is_production: False\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,382 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,382 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:43,383 | INFO | 🔩 dashboard_table_size: 50\u001b[0m\n", "\u001b[38;5;226m2022-07-01 14:28:43,384 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", "\u001b[38;5;226m2022-07-01 14:28:43,385 | WARNING | > Find out more at https://se-ml.github.io/practices/\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:44,082 | INFO | Latest version of scibert-highlights is 0 (from versions: 0)\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:44,083 | INFO | File scibert-highlights-0 found in cache\u001b[0m\n", "\u001b[38;5;39m2022-07-01 14:28:44,084 | INFO | File scibert-highlights-0 found in cache\u001b[0m\n" ] } ], "source": [ "from great_ai import GreatAI, use_model, MongoDbDriver, configure\n", "from great_ai.utilities import clean\n", "from pathlib import Path\n", "from transformers import (\n", " AutoConfig,\n", " AutoModelForSequenceClassification,\n", " AutoTokenizer,\n", ")\n", "import re\n", "import numpy as np\n", "import torch\n", "from transformers.modeling_outputs import SequenceClassifierOutput\n", "from transformers import (\n", " PreTrainedModel,\n", " PreTrainedTokenizer,\n", ")\n", "from views import EvaluatedSentence, Match\n", "from great_ai.large_file import LargeFileS3\n", "\n", "LargeFileS3.configure_credentials_from_file(\"config.ini\")\n", "MongoDbDriver.configure_credentials_from_file(\"config.ini\")\n", "configure(dashboard_table_size=100)\n", "\n", "ORIGINAL_MODEL = \"allenai/scibert_scivocab_uncased\"\n", "\n", "loaded_model: PreTrainedModel = None\n", "tokenizer: PreTrainedTokenizer = None\n", "\n", "\n", "@GreatAI.create\n", "@use_model(\"scibert-highlights\", version=\"latest\")\n", "def find_highlights(sentence: str, model: Path) -> EvaluatedSentence:\n", " global loaded_model, tokenizer\n", "\n", " if loaded_model is None:\n", " config = AutoConfig.from_pretrained(\n", " model, output_hidden_states=True, output_attentions=True\n", " )\n", " loaded_model = AutoModelForSequenceClassification.from_pretrained(\n", " model, config=config\n", " )\n", " if tokenizer is None:\n", " tokenizer = AutoTokenizer.from_pretrained(ORIGINAL_MODEL)\n", "\n", " sentence = clean(sentence, convert_to_ascii=True, remove_brackets=True)\n", "\n", " return evaluate_sentence(sentence=sentence)\n", "\n", "\n", "def evaluate_sentence(sentence: str) -> EvaluatedSentence:\n", " tensors = tokenizer(sentence, return_tensors=\"pt\", truncation=True, max_length=512)\n", "\n", " with torch.no_grad():\n", " result: SequenceClassifierOutput = loaded_model(**tensors)\n", " positive_likelihood = torch.nn.Softmax(dim=1)(result.logits)[0][1]\n", " tokens = tensors[\"input_ids\"][0]\n", "\n", " attentions = np.sum(result.attentions[-1].numpy()[0], axis=0)[0][\n", " 1:-1\n", " ] # Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, sequence_length)`.\n", " matches = []\n", "\n", " token_attentions = list(zip(attentions, tokens[1:-1]))\n", " for token in re.split(r\"([ .,])\", sentence):\n", " token = token.strip()\n", " if not token:\n", " continue\n", " bert_tokens = tokenizer(\n", " token, return_tensors=\"pt\", truncation=True, max_length=512\n", " )[\"input_ids\"][0][\n", " 1:-1\n", " ] # truncation=True needed to fix RuntimeError: Already borrowed\n", " score = 0\n", " for t1 in bert_tokens:\n", " if not token_attentions:\n", " break\n", " a, t2 = token_attentions.pop(0)\n", " assert t1 == t2, sentence\n", " score += a\n", " matches.append(\n", " Match(phrase=token if token in \".,\" else \" \" + token, score=round(score, 4))\n", " )\n", " if not token_attentions:\n", " break\n", "\n", " return EvaluatedSentence(\n", " score=positive_likelihood, text=sentence, explanation=matches\n", " )" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.10.4 ('.env': venv)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.4" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "02dd6d3afbfa9fbbe1037d64ad9014965528a1ccad21929d6e72f466389a68ad" } } }, "nbformat": 4, "nbformat_minor": 2 }