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

如何将np.einsum分解为np.dot操作以提升张量计算效率?

高效实现4维张量与系数的求和运算

你的需求是计算4维张量与对应系数的乘积求和,替代嵌套循环和默认np.einsum的低效实现,下面提供几种高效方案:

1. 优化版np.einsum(简洁且高效)

默认np.einsum用纯Python解析表达式,但开启optimize=True后,numpy会自动将表达式转换为底层BLAS优化的点积/矩阵乘法操作,既保留代码简洁性,又大幅提升速度:

import numpy as np

D = np.arange(4).reshape(2, 2)
i, j, k, l = 1, 0, 1, 1
tensor_S = np.arange(16).reshape(2, 2, 2, 2)

# 开启优化的einsum
SUM_ijkl_opt = np.einsum('a,b,c,d,abcd', D[i], D[j], D[k], D[l], tensor_S, optimize=True)
print(SUM_ijkl_opt)  # 输出1325,与原结果一致

2. 分步张量点积(手动拆解为BLAS操作)

你的求和本质是 ( \sum_{a,b,c,d} D_i(a) \cdot D_j(b) \cdot D_k(c) \cdot D_l(d) \cdot S(a,b,c,d) ),可以通过np.tensordot逐步对每个维度做求和点积,tensordot直接调用BLAS库,性能拉满:

# 第一步:对a维度求和
temp = np.tensordot(tensor_S, D[i], axes=([0], [0]))
# 第二步:对b维度求和
temp = np.tensordot(temp, D[j], axes=([0], [0]))
# 第三步:对c维度求和
temp = np.tensordot(temp, D[k], axes=([0], [0]))
# 第四步:对d维度求和,得到标量结果
SUM_ijkl_dot = np.dot(temp, D[l])
print(SUM_ijkl_dot)  # 输出1325,与原结果一致

也可以写成链式调用:

SUM_ijkl_chain = np.tensordot(
    np.tensordot(
        np.tensordot(tensor_S, D[i], axes=([0], [0])),
        D[j], axes=([0], [0])
    ),
    D[k], axes=([0], [0])
).dot(D[l])

3. Reshape + 矩阵乘法(灵活适配不同维度)

如果需要更灵活的维度操作,可以将张量reshape为矩阵,再通过np.dot逐步收缩维度:

# 把4维张量reshape为(2, 8),第一个维度对应a,剩下的b/c/d合并为一维
temp = tensor_S.reshape(2, -1).T.dot(D[i])
# 再reshape为(2,4),对应b维度和c/d合并维度
temp = temp.reshape(2, -1).T.dot(D[j])
# reshape为(2,2),对应c和d维度
temp = temp.reshape(2, -1).T.dot(D[k])
# 最后和D[l]点积得到标量
SUM_ijkl_reshape = temp.dot(D[l])
print(SUM_ijkl_reshape)  # 输出1325,与原结果一致

性能建议

  • 优先使用优化版einsum,兼顾简洁性和性能,numpy会自动选择最优运算路径;
  • 若需要更精细的控制,选择tensordot,它专门针对张量收缩做了优化;
  • 对于超大规模张量,可考虑使用cuPy替代numpy,利用GPU加速计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:55:38