将 Word2Vec 模型有效地引入生产服务
Bring Word2Vec models efficiently into Production Service
这是一个远景,但我希望有人遇到过与我类似的情况,因为我正在寻找一些如何有效地将一组大型 word2vec 模型引入生产环境的建议。
我们有一系列经过训练的 w2v 模型,维度为 300。由于基础数据 - 带有 POS 标记词的庞大语料库;最多包含 1 个 mio 单词的专业词汇表 - 这些模型变得相当大,我们目前正在寻找有效的方法来向我们的用户公开这些内容 w/o 在基础设施方面付出了过高的代价。
除了试图更好地控制词汇量大小,显然,特征向量的降维也是一种选择。有没有人知道这方面的出版物,特别是关于这将如何影响模型质量,以及如何最好地衡量这一点?
另一种选择是预先计算与每个词汇表单词最相似的前 X 个单词并提供查找 table。由于模型尺寸那么大,目前这也是非常低效的。是否有任何已知的启发式方法可以将必要距离计算的数量从 n x n-1 减少到更低的数量?
非常感谢!
在高维空间中有用于相似性搜索的预索引技术,可以加速最近邻发现,但通常以绝对精度为代价。 (他们还需要更多内存用于索引。)
一个例子是ANNOY library. The gensim project includes a demo notebook showing its use with Word2Vec。
我曾经在 Word2Vec 模型中仅使用 16 位(而不是 32 位)浮点数做过一些实验。它在空闲状态下节省了内存,最近邻 top-N 结果几乎没有变化。但是,也许是因为在一对多的距离计算过程中,一些幕后的 32 位浮点数的向上转换仍在发生,操作速度实际上降低了。 (这表明每次距离计算都可能导致临时内存扩展抵消任何空闲状态节省。)所以这不是一个快速修复,但这里需要进一步研究——可能涉及 finding/implementing float16 数组操作的正确例程– 可能意味着节省 50% 的模型尺寸和同等甚至更好的速度。
对于许多应用程序,丢弃频率最低的词并没有太大的伤害——甚至,在训练之前完成,可以提高剩余向量的质量。由于包括 gensim 在内的许多实现按照从最频繁到最少的顺序对词向量数组进行排序,您可以丢弃数组的末尾以节省内存,或者将 most_similar()
搜索限制为前 N 个条目以加速计算。
一旦你最小化了词汇表的大小,你想要确保整个集合都在 RAM 中,并且在(典型的)全扫描距离计算期间不会触发交换。如果您需要多个进程来提供来自同一向量集的答案,例如在多核机器上的 Web 服务中,gensim 的内存映射操作可以防止每个进程加载自己的向量冗余副本。您可以在 中看到关于此技术的讨论。
最后,虽然为更大的词汇表预先计算前 N 个邻居既费时又占用内存,如果您的访问模式使得某些标记的检查次数远远超过其他标记,那么缓存 N 个最多的标记-recently 或 M 最频繁请求的 top-N 可以大大提高感知性能——只使不那么频繁请求的邻居列表需要到每个其他标记的完整距离计算。
这是一个远景,但我希望有人遇到过与我类似的情况,因为我正在寻找一些如何有效地将一组大型 word2vec 模型引入生产环境的建议。
我们有一系列经过训练的 w2v 模型,维度为 300。由于基础数据 - 带有 POS 标记词的庞大语料库;最多包含 1 个 mio 单词的专业词汇表 - 这些模型变得相当大,我们目前正在寻找有效的方法来向我们的用户公开这些内容 w/o 在基础设施方面付出了过高的代价。
除了试图更好地控制词汇量大小,显然,特征向量的降维也是一种选择。有没有人知道这方面的出版物,特别是关于这将如何影响模型质量,以及如何最好地衡量这一点?
另一种选择是预先计算与每个词汇表单词最相似的前 X 个单词并提供查找 table。由于模型尺寸那么大,目前这也是非常低效的。是否有任何已知的启发式方法可以将必要距离计算的数量从 n x n-1 减少到更低的数量?
非常感谢!
在高维空间中有用于相似性搜索的预索引技术,可以加速最近邻发现,但通常以绝对精度为代价。 (他们还需要更多内存用于索引。)
一个例子是ANNOY library. The gensim project includes a demo notebook showing its use with Word2Vec。
我曾经在 Word2Vec 模型中仅使用 16 位(而不是 32 位)浮点数做过一些实验。它在空闲状态下节省了内存,最近邻 top-N 结果几乎没有变化。但是,也许是因为在一对多的距离计算过程中,一些幕后的 32 位浮点数的向上转换仍在发生,操作速度实际上降低了。 (这表明每次距离计算都可能导致临时内存扩展抵消任何空闲状态节省。)所以这不是一个快速修复,但这里需要进一步研究——可能涉及 finding/implementing float16 数组操作的正确例程– 可能意味着节省 50% 的模型尺寸和同等甚至更好的速度。
对于许多应用程序,丢弃频率最低的词并没有太大的伤害——甚至,在训练之前完成,可以提高剩余向量的质量。由于包括 gensim 在内的许多实现按照从最频繁到最少的顺序对词向量数组进行排序,您可以丢弃数组的末尾以节省内存,或者将 most_similar()
搜索限制为前 N 个条目以加速计算。
一旦你最小化了词汇表的大小,你想要确保整个集合都在 RAM 中,并且在(典型的)全扫描距离计算期间不会触发交换。如果您需要多个进程来提供来自同一向量集的答案,例如在多核机器上的 Web 服务中,gensim 的内存映射操作可以防止每个进程加载自己的向量冗余副本。您可以在
最后,虽然为更大的词汇表预先计算前 N 个邻居既费时又占用内存,如果您的访问模式使得某些标记的检查次数远远超过其他标记,那么缓存 N 个最多的标记-recently 或 M 最频繁请求的 top-N 可以大大提高感知性能——只使不那么频繁请求的邻居列表需要到每个其他标记的完整距离计算。