【发布时间】:2021-09-21 00:53:12
【问题描述】:
我在使用sentence_transformers 库对大量文档(超过一百万)进行编码时遇到问题。
给定一个非常相似的corpus 字符串列表。当我这样做时:
from sentence_transformers import SentenceTransformer
embedder = SentenceTransformer('msmarco-distilbert-base-v2')
corpus_embeddings = embedder.encode(corpus, convert_to_tensor=False)
几个小时后,进程似乎被卡住了,因为它永远不会完成,并且在检查进程查看器时没有任何运行。
由于我怀疑这是一个 ram 问题(GPU 板没有足够的内存来一次性容纳所有内容),我尝试将语料库分成批次,将它们转换为 NumPy 数组,然后将它们连接到单个矩阵如下:
from itertools import zip_longest
from sentence_transformers import SentenceTransformer, util
import torch
from loguru import logger
import glob
from natsort import natsorted
def grouper(iterable, n, fillvalue=np.nan):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
embedder = SentenceTransformer('msmarco-distilbert-base-v2')
for j, e in enumerate(list(grouper(corpus, 3))):
try:
# print('------------------')
for i in filter(lambda v: v==v, e):
corpus_embeddings=embedder.encode(i, convert_to_tensor=False)
torch.save(corpus_embeddings, f'/Users/user/Downloads/embeddings_part_{j}.npy')
except TypeError:
print(j, e)
logger.debug("TypeError in batch {batch_num}", batch_num=j)
l = []
for e in natsorted(glob.glob("/Users/user/Downloads/*.npy")):
l.append(torch.load(e))
corpus_embeddings = np.vstack(l)
corpus_embeddings
尽管如此,上述过程似乎不起作用。原因是当我尝试使用和不使用批处理方法的语料库的小样本时,我得到的矩阵是不同的,例如:
没有批处理方法:
array([[-0.6828216 , -0.26541945, 0.31026787, ..., 0.19941986,
0.02366139, 0.4489861 ],
[-0.45781 , -0.02955275, 1.0897563 , ..., -0.20077021,
-0.37821707, 0.2248317 ],
[ 0.8532193 , -0.13642257, -0.8872398 , ..., -0.57482916,
0.12760726, -0.66986346],
...,
[-0.04036704, 0.06745373, -0.6010259 , ..., -0.08174597,
-0.18513843, -0.64744204],
[-0.30782765, -0.04935509, -0.11624689, ..., 0.10423593,
-0.14073376, -0.09206307],
[-0.77139395, -0.08119706, 0.43753916, ..., 0.1653319 ,
0.06861683, -0.16276269]], dtype=float32)
采用批处理方式:
array([[ 0.8532191 , -0.13642241, -0.8872397 , ..., -0.5748289 ,
0.12760736, -0.6698637 ],
[ 0.3679317 , -0.21968201, 0.9932826 , ..., -0.86282325,
-0.04683857, 0.18995859],
[ 0.23026675, 0.69587034, -0.8116473 , ..., 0.23903558,
0.413471 , -0.23438476],
...,
[ 0.923319 , 0.4152724 , -0.3153545 , ..., -0.6863369 ,
0.01149149, -0.51300013],
[-0.30782777, -0.04935484, -0.11624689, ..., 0.10423636,
-0.1407339 , -0.09206269],
[-0.77139413, -0.08119693, 0.43753892, ..., 0.16533189,
0.06861652, -0.16276267]], dtype=float32)
执行上述批处理程序的正确方法是什么?
更新
检查上述批处理过程后,我发现当我将上述代码(enumerate(list(grouper(corpus, 1)))) 的批处理大小设置为1 时,无论是否使用批处理,我都能获得相同的矩阵输出。因此,我的问题是,将编码器应用于大量文档的正确方法是什么?
【问题讨论】:
标签: python numpy machine-learning nlp pytorch