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

加速大量2×2小型矩阵乘法运算的优化方案咨询

优化2×2矩阵批量相乘的方案

一、通过OpenBLAS配置多核心加速

1. 确认Numpy后端

先运行np.show_config()检查当前Numpy是否使用OpenBLAS。如果输出中无OpenBLAS相关信息,可通过conda安装OpenBLAS版本的Numpy:

conda install numpy openblas

2. 设置OpenBLAS线程数

OpenBLAS的线程数决定使用的CPU核心数,必须在导入numpy前设置环境变量:

import os
# 替换为你的CPU核心数,比如8
os.environ['OPENBLAS_NUM_THREADS'] = '8'
import numpy as np
import time

也可在运行脚本前通过系统环境变量设置:

  • Linux/macOS:export OPENBLAS_NUM_THREADS=8 && python your_script.py
  • Windows:set OPENBLAS_NUM_THREADS=8 && python your_script.py

二、优化多维数组运算逻辑(手动展开2×2矩阵乘法)

原生@运算符对2×2小矩阵的乘法存在BLAS调用开销,手动展开矩阵乘法为元素级广播运算,能大幅提升效率。具体实现如下:

import os
os.environ['OPENBLAS_NUM_THREADS'] = '8'
import numpy as np
import time

A_dim = 6*6
B_dim = 2**8
C_dim = B_dim
A = np.random.rand(A_dim,A_dim,2,2)
B = np.random.rand(B_dim,2,2)
C = np.random.rand(C_dim,2,2)

tic = time.perf_counter()

# 提取所有矩阵的元素
# A的元素:(A_dim, A_dim)
A00, A01 = A[:, :, 0, 0], A[:, :, 0, 1]
A10, A11 = A[:, :, 1, 0], A[:, :, 1, 1]
# B的元素:(B_dim,)
B00, B01 = B[:, 0, 0], B[:, 0, 1]
B10, B11 = B[:, 1, 0], B[:, 1, 1]
# C的元素:(C_dim,)
C00, C01 = C[:, 0, 0], C[:, 0, 1]
C10, C11 = C[:, 1, 0], C[:, 1, 1]

# 计算 A@B 的元素:(B_dim, A_dim, A_dim)
AB00 = A00[None, :, :] * B00[:, None, None] + A01[None, :, :] * B10[:, None, None]
AB01 = A00[None, :, :] * B01[:, None, None] + A01[None, :, :] * B11[:, None, None]
AB10 = A10[None, :, :] * B00[:, None, None] + A11[None, :, :] * B10[:, None, None]
AB11 = A10[None, :, :] * B01[:, None, None] + A11[None, :, :] * B11[:, None, None]

# 计算 (A@B)@A 的元素:(B_dim, A_dim, A_dim)
ABA00 = AB00 * A00[None, :, :] + AB01 * A10[None, :, :]
ABA01 = AB00 * A01[None, :, :] + AB01 * A11[None, :, :]
ABA10 = AB10 * A00[None, :, :] + AB11 * A10[None, :, :]
ABA11 = AB10 * A01[None, :, :] + AB11 * A11[None, :, :]

# 计算 ((A@B)@A)@C 的元素:(B_dim, C_dim, A_dim, A_dim)
X00 = ABA00[:, None, :, :] * C00[None, :, None, None] + ABA01[:, None, :, :] * C10[None, :, None, None]
X01 = ABA00[:, None, :, :] * C01[None, :, None, None] + ABA01[:, None, :, :] * C11[None, :, None, None]
X10 = ABA10[:, None, :, :] * C00[None, :, None, None] + ABA11[:, None, :, :] * C10[None, :, None, None]
X11 = ABA10[:, None, :, :] * C01[None, :, None, None] + ABA11[:, None, :, :] * C11[None, :, None, None]

# 合并为最终的 (B_dim, C_dim, A_dim, A_dim, 2, 2) 张量
X = np.stack([np.stack([X00, X01], axis=-1),
              np.stack([X10, X11], axis=-1)], axis=-2)

toc = time.perf_counter()
print(f"matrix multiplication took {toc - tic:0.4f} seconds")

优化原理

2×2矩阵乘法的运算规则固定,手动展开后所有操作均为元素级广播运算,避免了BLAS对小矩阵乘法的调用开销,同时Numpy的元素运算能更高效地利用CPU向量化指令和多核心资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:10:41