使用不在其中心的 HuggingFace 模型将句子列表编码为嵌入

问题描述 投票:0回答:1

我正在尝试将句子列表编码为嵌入列表。当我使用 HuggingFace 中心中的模型时,它按预期工作。但是,当我使用不在中心的模型时,在本例中是 Facebook 的

M2M100
模型,我没有得到预期的结果。

当使用

SentenceTransformer()
内的模型时,我的结果如下所示:

from sentence_transformers import SentenceTransformer
dat = ['Meteorite fell on the road ', 'I went in the wrong direction']
model_1 = SentenceTransformer('all-distilroberta-v1')
embeddings_1 = model_1.encode(dat)
embeddings_1.shape
> (2, 768)

但是,当我使用

M2M100
模型时,我的结果看起来根本不正确,特别是我期望 2 行结果:

from transformers import M2M100Tokenizer
model_m2m = M2M100Tokenizer.from_pretrained("facebook/m2m100_418M")
model_m2m.src_lang = "en"
embeddings_m2m = model_m2m.encode(dat, return_tensors="pt")
embeddings_m2m.shape
> torch.Size([1, 4])

我应该如何格式化它,以便它返回一个 n 维嵌入列表,其中每行对应一个句子,列数等于嵌入的维数?

(请注意,最终我将对其他语言的句子执行此操作,这就是我使用多语言模型的原因。)

nlp huggingface-transformers encode embedding huggingface
1个回答
0
投票

您提供的代码仅使用模型的分词器,它将文本映射到不代表任何(语义)含义的整数 id。

从以下位置检索句子嵌入(即表示文本的向量): facebook/m2m100_418M,这是一个编码器-解码器模型,您需要对编码器的最后隐藏状态执行某种池化。 常见方法,即 cls 和均值池,如下例所示:

import torch
from transformers import M2M100Tokenizer, M2M100Model

def mean_pooling(last_hidden_state, attention_mask):
  non_pad_tokens = attention_mask.sum(1)
  sum_embeddings =  torch.sum(attention_mask.unsqueeze(-1) * last_hidden_state, 1)
  return sum_embeddings/non_pad_tokens.unsqueeze(-1)

def cls_pooling(last_hidden_state):
  return last_hidden_state[:,0]

dat = ['Meteorite fell on the road ', 'I went in the wrong direction']


model_id = "facebook/m2m100_418M"
t_m2m = M2M100Tokenizer.from_pretrained(model_id)
t_m2m.src_lang = "en"
m_m2m = M2M100Model.from_pretrained(model_id)

tokenized = t_m2m(dat, padding=True, return_tensors='pt')

with torch.inference_mode():
  encoder_o = m_m2m.encoder(**tokenized)

encoder_last_hidden_state = encoder_o.last_hidden_state
print(encoder_last_hidden_state.shape)
mean_pooling_embeddings = mean_pooling(encoder_last_hidden_state, tokenized.attention_mask)
print(mean_pooling_embeddings.shape)
cls_pooling_embeddings = cls_pooling(encoder_last_hidden_state)
print(cls_pooling_embeddings.shape)

输出:

torch.Size([2, 9, 1024])
torch.Size([2, 1024])
torch.Size([2, 1024])

这两种方法中哪一种更适合您的下游任务,必须用您的数据进行测试。另请注意,即使您现在有了句子嵌入,也不意味着它们在语义上有意义(即嵌入对您的下游任务毫无用处)。请参阅此 StackOverflow answer 以获取进一步说明。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.