0

我想从转换器模型中获得短文本嵌入,所以我测试了 3 种计算方法。所有 3 个案例都使用 Huggingface Hub 的模型。

inputs = tokenizer(text, padding=True, return_tensors="pt")

def embedding_1(text):
    
    inputs = tokenizer(text, padding=True, return_tensors="pt")
    outputs = model(**inputs)
    output_tensors = outputs[1]
    output_numpy = output_tensors.detach().numpy()

    return output_numpy

def embedding_2(text):
    model_output = model(**inputs)
    token_embeddings = model_output[0]
    input_mask_expanded = inputs['attention_mask'].unsqueeze(-1).expand(token_embeddings.size()).float()
        return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)

两种方法都使用中国模式:

tokenizer = BertTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")
model = BertModel.from_pretrained("hfl/chinese-roberta-wwm-ext")

第三种方法直接使用句子转换器模型(https://www.sbert.net/):

def embedding_3(text):
    model = SentenceTransformer('sentence-transformers/distiluse-base-multilingual-cased')
    embedding = model.encode(text)
    return embedding

现在我测试了'这个好'和其他几个句子的相似度,结果如下(基于cosine_similarity):

simi 1: 这个好 | 这个非常好: tensor([0.9844]) 
simi 2: 这个好 | 这个非常好: tensor([0.8641]) 
simi 3: 这个好 | 这个非常好: tensor([[0.8629]]) 


simi 1: 这个好 | 这个非常不好: tensor([0.9840]) 
simi 2: 这个好 | 这个非常不好: tensor([0.8403]) 
simi 3: 这个好 | 这个非常不好: tensor([[0.5878]]) 

simi 1: 这个好 | 他很傻: tensor([0.9737]) 
simi 2: 这个好 | 他很傻: tensor([0.7483]) 
simi 3: 这个好 | 他很傻: tensor([[0.3601]]) 

simi 1: 这个好 | 中国人民解放军: tensor([0.9171]) 
simi 2: 这个好 | 中国人民解放军: tensor([0.5162]) 
simi 3: 这个好 | 中国人民解放军: tensor([[0.0597]]) 

很明显,这 3 种方法产生了非常不同的相似度分数,第 3 种方法似乎是最好的。如果它们略有不同,那是可以理解的。如果它们如此不同,应该使用哪一个?

我喜欢第三种方法的结果,但是在测试这几句话时,它在 CPU 和 GPU 机器上都非常慢。其他2个要快得多。

4

0 回答 0