Repository: flairNLP/flair

Issue:
Add support for Sentence Transformers
The [sentence transformers](https://github.com/UKPLab/sentence-transformers) library has great pre-trained models to produce embeddings for entire sentences. 

We should add a new `DocumentEmbeddings` class to support these embeddings in Flair.


Discussion:

Resolving patch:
diff --git a/flair/embeddings/__init__.py b/flair/embeddings/__init__.py
--- a/flair/embeddings/__init__.py
+++ b/flair/embeddings/__init__.py
@@ -25,6 +25,7 @@
 from .document import DocumentPoolEmbeddings
 from .document import DocumentRNNEmbeddings
 from .document import DocumentLMEmbeddings
+from .document import SentenceTransformerDocumentEmbeddings
 
 # Expose image embedding classes
 from .image import ImageEmbeddings
diff --git a/flair/embeddings/document.py b/flair/embeddings/document.py
--- a/flair/embeddings/document.py
+++ b/flair/embeddings/document.py
@@ -6,6 +6,8 @@
 from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
 from transformers import BertTokenizer, AlbertTokenizer, AutoTokenizer, AutoConfig, AutoModel
 
+from sentence_transformers import SentenceTransformer
+
 import flair
 from flair.data import Sentence
 from flair.embeddings.base import Embeddings, ScalarMix
@@ -514,4 +516,49 @@ def _add_embeddings_internal(self, sentences: List[Sentence]):
                         embedding.name, sentence[0]._embeddings[embedding.name]
                     )
 
-        return sentences
\ No newline at end of file
+        return sentences
+
+class SentenceTransformerDocumentEmbeddings(DocumentEmbeddings):
+    def __init__(
+        self,
+        model: str = "bert-base-nli-mean-tokens",
+        batch_size: int = 1,
+        convert_to_numpy: bool = False,
+    ):
+        """
+        :param model: string name of models from SentencesTransformer Class
+        :param name: string name of embedding type which will be set to Sentence object
+        :param batch_size: int number of sentences to processed in one batch
+        :param convert_to_numpy: bool whether the encode() returns a numpy array or PyTorch tensor
+        """
+        super().__init__()
+        self.model = SentenceTransformer(model)
+        self.name = 'sentence-transformers-' + str(model)
+        self.batch_size = batch_size
+        self.convert_to_numpy = convert_to_numpy
+        self.static_embeddings = True
+
+    def _add_embeddings_internal(self, sentences: List[Sentence]) -> List[Sentence]:
+
+        sentence_batches = [sentences[i * self.batch_size:(i + 1) * self.batch_size]
+                            for i in range((len(sentences) + self.batch_size - 1) // self.batch_size)]
+
+        for batch in sentence_batches:
+            self._add_embeddings_to_sentences(batch)
+
+        return sentences
+
+    def _add_embeddings_to_sentences(self, sentences: List[Sentence]):
+
+        # convert to plain strings, embedded in a list for the encode function
+        sentences_plain_text = [sentence.to_plain_string() for sentence in sentences]
+
+        embeddings = self.model.encode(sentences_plain_text, convert_to_numpy=self.convert_to_numpy)
+        for sentence, embedding in zip(sentences, embeddings):
+            sentence.set_embedding(self.name, embedding)
+
+    @property
+    @abstractmethod
+    def embedding_length(self) -> int:
+        """Returns the length of the embedding vector."""
+        return self.model.get_sentence_embedding_dimension()
\ No newline at end of file


Test patch: