一、说明
要分清词嵌入和句子嵌入的区别。
句子嵌入是指将句子或文档表示为固定长度的向量的过程,使得向量能够捕获句子的语义和上下文信息。它是自然语言处理 (NLP) 和机器学习中的常见任务,因为它可以帮助对句子之间的关系和相似性进行建模,并执行各种下游任务,例如情感分析、文本分类和机器翻译。句子嵌入有多种技术,例如 Word2Vec、GloVe 和 BERT。
二、计算句子嵌入
计算句子嵌入的基本函数如下所示:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
#Our sentences we like to encode
sentences = ['This framework generates embeddings for each input sentence',
'Sentences are passed as a list of string.',
'The quick brown fox jumps over the lazy dog.']
#Sentences are encoded by calling model.encode()
embeddings = model.encode(sentences)
#Print the embeddings
for sentence, embedding in zip(sentences, embeddings):
print("Sentence:", sentence)
print("Embedding:", embedding)
print("")
注意:即使我们谈论句子嵌入,您也可以将其用于较短的短语以及具有多个句子的较长文本。有关段落嵌入的更多说明,请参阅输入序列长度部分。
首先,我们加载一个句子转换器模型:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('model_name_or_path')
您可以指定预先训练的模型,也可以在光盘上传递路径以从该文件夹加载句子转换器模型。
如果可用,模型将在 GPU 上自动执行。您可以像这样为模型指定设备:
model = SentenceTransformer('model_name_or_path', device='cuda')
使用设备任何 pytorch 设备(如 CPU、cuda、cuda:0等)
对一组句子/文本进行编码的相关方法是。在下文中,您可以找到此方法接受的参数。一些相关参数是batch_size(取决于您的 GPU,不同的批大小是最佳的)以及convert_to_numpy(返回 numpy 矩阵)和convert_to_tensor(返回 pytorch 张量)。model.encode()
.classsentence_transformers。句子转换器(model_name_or_path: 可选[str] = 无, 模块: 可选[可迭代[torch.nn.modules.module.Module]] = 无,设备:可选[str] = 无,cache_folder : 可选[str] = 无, use_auth_token: 可选[联合[布尔值, str] ] = 无)
加载或创建一个句子转换器模型,该模型可用于将句子/文本映射到嵌入。
参数
-
model_name_or_path – 如果它是光盘上的文件路径,则从该路径加载模型。如果它不是路径,它首先尝试下载预先训练的 SentenceTransformer 模型。如果失败,则尝试使用该名称从Huggingface模型存储库构建模型。
-
模块 – 此参数可用于从头开始创建自定义句子转换器模型。
-
设备 – 应该用于计算的设备(如“cuda”/“CPU”)。如果为“无”,则检查是否可以使用 GPU。
-
cache_folder – 存储模型的路径
-
use_auth_token – HuggingFace 身份验证令牌以下载私有模型。
初始化由两个 nn 共享的内部模块状态。模块和脚本模块。
编码(句子: Union[str, List[str]], batch_size: int = 32, show_progress_bar: 可选[bool] = 无, output_value: str = 'sentence_ 嵌入',convert_to_numpy:布尔 = 真,convert_to_tensor:布尔 = 假,设备: 可选[str] = 无,normalize_embeddings:bool = 假) → 联合[列表 [火炬。Tensor], numpy.ndarray, torch.张量]
计算句子嵌入
参数
-
句子 – 要嵌入的句子
-
batch_size – 用于计算的批大小
-
show_progress_bar – 编码句子时输出进度条
-
output_value – 默认sentence_embedding,用于获取句子嵌入。可以设置为 token_embeddings 以获取词片标记嵌入。设置为“无”,以获取所有输出值
-
convert_to_numpy – 如果为 true,则输出是 numpy 向量的列表。否则,它是一个 pytorch 张量列表。
-
convert_to_tensor – 如果为 true,您将获得一个大张量作为返回。覆盖convert_to_numpy中的任何设置
-
device – 用于计算的火炬设备
-
normalize_embeddings – 如果设置为 true,则返回的向量的长度为 1。在这种情况下,可以使用更快的点积 (util.dot_score) 而不是余弦相似性。
返回
默认情况下,返回张量列表。如果convert_to_tensor,则返回堆叠张量。如果convert_to_numpy,则返回 numpy 矩阵。
三、输入序列长度
变压器模型如BERT / RoBERTa / DistilBERT等,运行时和内存要求随输入长度呈二次增长。这将变压器限制为一定长度的输入。BERT&Co.的一个共同值是512个单词,相当于大约300-400个单词(英语)。比这更长的文本被截断为前 x 个单词片段。
默认情况下,提供的方法使用限制为 128 个字段,较长的输入将被截断。您可以像这样获取和设置最大序列长度:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
print("Max Sequence Length:", model.max_seq_length)
#Change the length to 200
model.max_seq_length = 200
print("Max Sequence Length:", model.max_seq_length)
注意:您不能增加的长度高于相应变压器型号支持的最大长度。另请注意,如果模型是在短文本上训练的,则长文本的表示可能不是那么好。
四、存储和加载嵌入
最简单的方法是使用 pickle 将预先计算的嵌入存储在光盘上并从光盘加载。如果您需要对大量句子进行编码,这尤其有用。
from sentence_transformers import SentenceTransformer
import pickle
model = SentenceTransformer('all-MiniLM-L6-v2')
sentences = ['This framework generates embeddings for each input sentence',
'Sentences are passed as a list of string.',
'The quick brown fox jumps over the lazy dog.']
embeddings = model.encode(sentences)
#Store sentences & embeddings on disc
with open('embeddings.pkl', "wb") as fOut:
pickle.dump({'sentences': sentences, 'embeddings': embeddings}, fOut, protocol=pickle.HIGHEST_PROTOCOL)
#Load sentences & embeddings from disc
with open('embeddings.pkl', "rb") as fIn:
stored_data = pickle.load(fIn)
stored_sentences = stored_data['sentences']
stored_embeddings = stored_data['embeddings']
五、进程/多GPU编码
您可以使用多个 GPU(或 CPU 计算机上的多个进程)对输入文本进行编码。有关示例,请参阅:computing_embeddings_mutli_gpu.py。
相关方法是 ,它启动多个用于编码的进程。start_multi_process_pool()
句子变形金刚。start_multi_process_pool(target_devices:可选[列表[str]] = 无)
启动多进程以使用多个独立进程处理编码。 如果要在多个 GPU 上进行编码,建议使用此方法。建议 为每个 GPU 仅启动一个进程。此方法与encode_multi_process一起使用
参数
target_devices – PyTorch 目标设备,例如 cuda:0、cuda:1...如果为“无”,则将使用所有可用的 CUDA 设备
返回
返回包含目标进程、输入队列和输出队列的字典。
六、使用转换器嵌入句子
我们的大多数预训练模型都基于 Huggingface.co/Transformers,并且也托管在Huggingface的模型存储库中。可以在不安装句子转换器的情况下使用我们的句子嵌入模型:
from transformers import AutoTokenizer, AutoModel
import torch
#Mean Pooling - Take attention mask into account for correct averaging
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0] #First element of model_output contains all token embeddings
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
sum_embeddings = torch.sum(token_embeddings * input_mask_expanded, 1)
sum_mask = torch.clamp(input_mask_expanded.sum(1), min=1e-9)
return sum_embeddings / sum_mask
#Sentences we want sentence embeddings for
sentences = ['This framework generates embeddings for each input sentence',
'Sentences are passed as a list of string.',
'The quick brown fox jumps over the lazy dog.']
#Load AutoModel from huggingface model repository
tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
#Tokenize sentences
encoded_input = tokenizer(sentences, padding=True, truncation=True, max_length=128, return_tensors='pt')
#Compute token embeddings
with torch.no_grad():
model_output = model(**encoded_input)
#Perform pooling. In this case, mean pooling
sentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
七、后记
您可以在此处找到可用的型号:sentence-transformers (Sentence Transformers)
在上面的示例中,我们在AutoModel(将加载BERT模型)之上添加了平均池化。我们也有具有最大池化的模型以及我们使用 CLS 令牌的模型。如何正确应用此池化,
请查看句子转换器/bert-base-nli-max-tokens 和 /sentence-transformers/bert-base-nli-cls-token。
参考资料地址:利用 Embedding 层学习词嵌入 · python深度学习 · 看云 (kancloud.cn)