如何使用非Hugging Face Hub的M2M100模型生成标准句子嵌入?
解决M2M100模型生成句子嵌入的问题
你当前的问题是只使用了M2M100的Tokenizer,它的encode方法仅负责将文本转换为token ID序列,并非生成语义嵌入。要得到符合预期的n维句子嵌入(每行对应一个句子,列数为嵌入维度),需要同时加载M2M100的模型主体,并对模型输出做池化处理。
正确实现步骤及代码示例
from transformers import M2M100Tokenizer, M2M100Model import torch dat = ['Meteorite fell on the road ', 'I went in the wrong direction'] # 同时加载Tokenizer和模型主体 tokenizer = M2M100Tokenizer.from_pretrained("facebook/m2m100_418M") model = M2M100Model.from_pretrained("facebook/m2m100_418M") # 设置源语言(处理其他语言时,修改为对应代码即可,如"zh"代表中文) tokenizer.src_lang = "en" # 批量编码输入文本,开启padding和truncation保证输入维度统一 inputs = tokenizer(dat, return_tensors="pt", padding=True, truncation=True) # 禁用梯度计算,提升推理效率 with torch.no_grad(): outputs = model(**inputs) # 提取模型最后一层的隐藏状态,形状为[批量数, 序列长度, 隐藏层维度] last_hidden_states = outputs.last_hidden_state # 方式1:对每个句子的所有token隐藏状态取均值,得到句子嵌入 embeddings = torch.mean(last_hidden_states, dim=1) # 查看结果形状:(2, 1024),其中1024是M2M100_418M的隐藏层维度 print(embeddings.shape) # > torch.Size([2, 1024])
关键补充说明
- Tokenizer与Model的区别:Tokenizer仅完成文本到token ID的转换,只有模型主体才能生成带语义信息的隐藏状态。
- 池化方式选择:
- 平均池化:能较好捕捉句子整体语义,实现简单且效果稳定。
- 取token输出:若更关注句子结尾的语义指向,可提取每个句子中token对应的隐藏状态,示例代码如下:
# 定位每个句子中的</s>token位置 eos_mask = inputs['input_ids'] == tokenizer.eos_token_id # 提取对应位置的隐藏状态并处理padding eos_embeddings = torch.stack([last_hidden_states[i, mask].mean(0) for i, mask in enumerate(eos_mask)]) print(eos_embeddings.shape) # > torch.Size([2, 1024])
- 多语言适配:处理其他语言时,只需将
tokenizer.src_lang设置为对应语言代码(如"fr"代表法语、"ja"代表日语),Tokenizer会自动适配该语言的分词规则。
内容的提问来源于stack exchange,提问作者Adam_G
相关产品推荐
相关产品推荐

