我正在尝试从基于转换器的模型中提取一些词向量。步骤是:
- 使用 . 通过管道运行文本
nlp()
。 - 将文本分解成句子(分别分类为二进制类别)。
- 将句子向量保存到列表中(一旦发生分类,将被腌制并用作模型输入)。
实际模型运行得足够快,但是(与 skipgram 向量不同),从spacy.tokens.span.Span
对象中提取向量并将它们保存到列表或数组对象的简单操作非常慢。
这是一个可重现的示例:
import spacy
import requests
import numpy as np
nlp = spacy.load('en_stsb_roberta_large') # from https://github.com/MartinoMensio/spacy-sentence-bert
# Get some random text
def get_text(
url = "https://raw.githubusercontent.com/erikthiem/pride-and-prejudice/master/starwars4.txt",
num_chars = 10_000):
response = requests.get(url)
text = response.content.decode().replace("\n", "")
text = text[0:num_chars]
return text
运行实际nlp()
命令只需要很少的时间:
# This takes 0.2 seconds to run
text = get_text()
doc = nlp(text)
sents = list(doc.sents) # doc.sents is a generator
但是,如果我想将第一句(36 个单词)中的向量保存到一个列表中,它会非常慢:
# Get vectors - takes 5 seconds
example_sent = sents[0]
sent_vectors = [word.vector for word in example_sent]
显然,这不能很好地扩展。
我不明白为什么它这么慢,好像你运行type(example_sent[0].vector)
它,它返回numpy.ndarray
,即不是生成器,所以向量已经被计算出来了。
为什么将它从跨度移动到列表需要这么长时间?数组是(1024,)
每个单词的维度,而不是(300,)
几乎立即复制的 skip-gram 向量。据我所知,这是唯一的区别。
我还创建了一个所需维度的空数组(而不是列表),但这没有区别。
有任何想法吗?