Search code examples
machine-learningnlphuggingface-transformersspacy-transformers

Getting sentence embedding from huggingface Feature Extraction Pipeline


How do i get an embedding for the whole sentence from huggingface's feature extraction pipeline?

I understand how to get the features for each token (below) but how do i get the overall features for the sentence as a whole?

feature_extraction = pipeline('feature-extraction', model="distilroberta-base", tokenizer="distilroberta-base")
features = feature_extraction("i am sentence")

Solution

  • To explain more on the comment that I have put under stackoverflowuser2010's answer, I will use "barebone" models, but the behavior is the same with the pipeline component.

    BERT and derived models (including DistilRoberta, which is the model you are using in the pipeline) agenerally indicate the start and end of a sentence with special tokens (mostly denoted as [CLS] for the first token) that usually are the easiest way of making predictions/generating embeddings over the entire sequence. There is a discussion within the community about which method is superior (see also a more detailed answer by stackoverflowuser2010 here), however, if you simply want a "quick" solution, then taking the [CLS] token is certainly a valid strategy.

    Now, while the documentation of the FeatureExtractionPipeline isn't very clear, in your example we can easily compare the outputs, specifically their lengths, with a direct model call:

    from transformers import pipeline, AutoTokenizer
    
    # direct encoding of the sample sentence
    tokenizer = AutoTokenizer.from_pretrained('distilroberta-base')
    encoded_seq = tokenizer.encode("i am sentence")
    
    # your approach
    feature_extraction = pipeline('feature-extraction', model="distilroberta-base", tokenizer="distilroberta-base")
    features = feature_extraction("i am sentence")
    
    # Compare lengths of outputs
    print(len(encoded_seq)) # 5
    # Note that the output has a weird list output that requires to index with 0.
    print(len(features[0])) # 5
    

    When inspecting the content of encoded_seq, you will notice that the first token is indexed with 0, denoting the beginning-of-sequence token (in our case, the embedding token). Since the output lengths are the same, you could then simply access a preliminary sentence embedding by doing something like

    sentence_embedding = features[0][0]