【问题标题】:Speed up embedding 3M sentences with Sentence transformers and computing similarity使用句子转换器加速嵌入 3M 句子并计算相似度
【发布时间】:2022-08-14 07:47:18
【问题描述】:

我有一个带有 2 个文本句子列的熊猫数据框。我使用句子转换器来嵌入句子并生成文本嵌入并找到两个句子之间的余弦相似度。我的代码适用于较小的数据集,但是需要很长时间才能执行3M 句子.有什么办法可以优化代码

我确实尝试按照Speed up embedding of 2M sentences with RoBERTa 中的建议传递列表。但是没有解决问题,代码仍然运行缓慢。指针赞赏

data = { \'index\': [1, 2, 3],
         \'Sentence1\': [\'This is a foo bar sentence\', \'What is this string ? Totally not related to the other two lines\', \'Jack is playing guitar\'],
        \'Sentence2\': [\'This sentence is similar to a foo bar sentence\', \'Musical instrument are on display and can be played\', \'It is sunny outside\']}

df = pd.DataFrame(data)

我用于识别余弦相似度的代码

import numpy as np 
import pandas as pd
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import util 
model = SentenceTransformer(\'sentence-transformers/all-mpnet-base-v2\')
import torch

def cosine_sim_emb(df):
        
    #create sentence and theme embeddings 
    df[\'Sentence1_embeddings\'] = model.encode(df[\'Sentence1\']).tolist()
    df[\'Sentence2_embeddings\'] = model.encode(df[\'Sentence2\']).tolist()
    
    #extract cosine similarity score 
    cosine_similarity_score = []
    
    for index, row in df.iterrows():
        similarity_score = cosine_similarity(np.array(df[\'Sentence1_embeddings\'][index]).reshape(1,-1), np.array(df[\'Sentence2_embeddings\'][index]).reshape(1,-1))
        similarity_score = similarity_score[0][0]
        cosine_similarity_score.append(similarity_score)
    
    df[\"cosine_similarity\"] = cosine_similarity_score
    
    return df 

df1 = cosine_sim_emb(df)

    标签: python pandas nlp word-embedding sentence-transformers


    【解决方案1】:

    可以进行两个微小的更改来加快程序的速度。 embeddingcosine similarity 步骤已按顺序完成(一个接一个样本),我相信为小批量更改它们可能会提高程序的时间效率。请记住,小批量的最佳大小取决于主机的规格。

    model = SentenceTransformer('bert-base-uncased')
    data = { 'index': [1, 2, 3],
             'Sentence1': ['This is a foo bar sentence', 'What is this string ? Totally not related to the other two lines', 'Jack is playing guitar'],
            'Sentence2': ['This sentence is similar to a foo bar sentence', 'Musical instrument are on display and can be played', 'It is sunny outside']}
    
    df = pd.DataFrame(data)
    tic = time()
    for idx, row in df.iterrows():
      embeddings = model.encode(row['Sentence1'])
    print(f'Running embedder on a single sample took: {time()-tic} s')
    tic = time()
    embeddings = model.encode(df['Sentence1'].to_list())
    print(f'Running embedder in mini-batch manner took: {time()-tic} s')
    df['Emb1'] = model.encode(df['Sentence1'].to_list()).tolist()
    df['Emb2'] = model.encode(df['Sentence2'].to_list()).tolist()
    tic = time()
    for idx, row in df.iterrows():
      similarity = cosine_similarity(np.array(row['Emb1']).reshape(1, -1), np.array(row['Emb2']).reshape(1, -1))
    print(f'Running cosine similarity on a single sample took: {time()-tic} s')
    tic = time()
    similarity = cosine_similarity(np.array(df['Emb1'].to_list()), np.array(df['Emb2'].to_list()))
    print(f'Running cosine similarity in mini-batch manner took: {time()-tic} s')
    

    我的机器的输出:

    Running embedder on a single sample took: 0.27576375007629395 s
    Running embedder in mini-batch manner took: 0.18244028091430664 s
    Running cosine similarity on a single sample took: 0.0023124217987060547 s
    Running cosine similarity in mini-batch manner took: 0.0009903907775878906 s
    

    【讨论】:

    • 谢谢梅蒂。我不明白小批量的概念。 model.encode() 本身需要批处理并计算嵌入,然后上面的内容与我已经创建的内容有何不同。这无助于加快 3M 句子的编码速度
    • 有一些代数运算,包括矩阵乘法,可以使用一堆样本而不是一个样本来更有效地完成。另一种直觉是,一次喂一个批次理论上可以通过批次大小的因素减少开销。如果您认为值得,请试一试并告诉我。请记住,您需要测试各种批次大小才能找到合适的 :)
    猜你喜欢
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 2017-01-10
    • 2020-12-27
    • 2015-07-04
    • 1970-01-01
    相关资源
    最近更新 更多