You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何减少归一化余弦相似度的计算量与运行耗时?

你的代码在计算翻译概率时存在明显的效率瓶颈,尤其是遍历整个词表计算余弦相似度的Python循环,以及重复计算向量范数的操作。下面是几个针对性的优化方案,能大幅降低运行耗时:


核心优化方向

  • 预计算词向量范数:词向量是固定不变的,提前计算所有词向量的L2范数,避免每次计算余弦相似度时重复调用np.linalg.norm。
  • 向量化批量运算替代Python循环:用numpy矩阵运算一次性完成目标向量与所有词向量的相似度计算,比Python循环快几十倍甚至上百倍。
  • 复用目标向量范数:同一个目标词的向量范数只需计算一次,无需重复计算。
  • 缓存相似度总和(可选):如果频繁针对同一目标词计算概率,缓存其与全词表的相似度总和,避免重复计算。

优化后的代码

首先执行一次初始化操作(预计算范数、矩阵和索引映射):

import numpy as np

# 预计算所有词向量的L2范数(仅需执行一次)
word_norms = {word: np.linalg.norm(word_embeddings[word]) for word in word_embeddings.index_to_key}
# 将所有词向量转换为numpy矩阵,用于批量运算
embedding_matrix = np.array([word_embeddings[word] for word in word_embeddings.index_to_key])
# 建立词到矩阵索引的映射,方便快速定位
word_to_idx = {word: idx for idx, word in enumerate(word_embeddings.index_to_key)}

然后改写计算函数:

def cosine_similarity(vec1, vec2, norm1, norm2):
    # 直接使用预计算好的范数,避免重复计算
    dot_product = np.dot(vec1, vec2)
    return dot_product / (norm1 * norm2)

def compute_translation_probability(target_word, candidate_word, word_embeddings, word_norms, embedding_matrix, sum_cache=None):
    # 提前校验词是否存在,减少无效计算
    if target_word not in word_norms or candidate_word not in word_norms:
        return 0.0
    
    target_vec = word_embeddings[target_word]
    target_norm = word_norms[target_word]
    candidate_vec = word_embeddings[candidate_word]
    candidate_norm = word_norms[candidate_word]
    
    # 计算目标词与候选词的余弦相似度
    cosine_sim = cosine_similarity(target_vec, candidate_vec, target_norm, candidate_norm)
    
    # 优先使用缓存的相似度总和,避免重复计算全词表
    if sum_cache is not None and target_word in sum_cache:
        sum_cos = sum_cache[target_word]
    else:
        # 批量计算目标向量与所有词向量的点积
        dot_products = np.dot(embedding_matrix, target_vec)
        # 批量生成所有余弦相似度并求和
        all_cos_sims = dot_products / (target_norm * np.array(list(word_norms.values())))
        sum_cos = all_cos_sims.sum()
        # 存入缓存(如果启用缓存)
        if sum_cache is not None:
            sum_cache[target_word] = sum_cos
    
    return cosine_sim / sum_cos if sum_cos != 0 else 0.0

使用示例

如果需要多次计算同一目标词的概率,初始化缓存字典来复用结果:

sum_cache = {}
probability = compute_translation_probability("apple", "pomme", word_embeddings, word_norms, embedding_matrix, sum_cache)

内容的提问来源于stack exchange,提问作者Bini Yoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:15:13