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

使用Numpy创建超大矩阵遇内存错误,尝试memmap存文件存疑

解决超大Numpy矩阵创建的MemoryError及memmap异常问题

首先得说,你要创建的这个矩阵规模实在太夸张了,咱们先算笔账:
(347101 * 400 * 347101) 个float32元素,每个元素占4字节,总大小大概是 190TB——这已经远远超出了普通服务器甚至专业存储设备的承载能力,这就是你用memmap也失败的核心原因:你的磁盘根本装不下这么大的文件,或者文件系统不支持单个这么大的文件(比如很多默认文件系统对单个文件大小有隐性限制,哪怕理论上限够,实际硬件也跟不上)。

接下来给你几个可行的解决方向:

1. 先检查你的矩阵维度是否合理

这是最常见的问题——几乎没有实际的机器学习/数据处理场景需要两个维度都是347101的3D矩阵。比如你是不是把样本数和词汇表大小/特征维度搞混了?比如常见的编码器输入数据形状应该是 (样本数, 序列长度, 特征维度),其中特征维度一般是几百到几千(比如512、1024),而不是和样本数一样大。如果是维度写错了,修正形状后问题会迎刃而解。

2. 如果维度确实合理,改用稀疏矩阵存储

如果这个矩阵大部分元素是0(比如是one-hot编码、邻接矩阵这类场景),那完全没必要用密集矩阵。用scipy.sparse里的稀疏矩阵格式(比如csr_matrix、csc_matrix),只存储非零元素,能把存储空间压缩几个数量级。示例代码:

from scipy.sparse import csr_matrix
import scipy.io

# 创建稀疏矩阵(这里假设你有非零元素的坐标和值)
rows = [...]  # 非零元素的行索引
cols = [...]  # 非零元素的列索引
data = [...]  # 非零元素的值
sparse_matrix = csr_matrix((data, (rows, cols)), shape=(347101, 347101))

# 若要扩展为3D结构,可考虑存储多个2D稀疏矩阵,或设计分层存储逻辑
# 保存到文件
scipy.io.savemat('sparse_encoder_data.mat', {'encoder_data': sparse_matrix})

3. 分块处理矩阵

如果必须用密集矩阵,那就把大矩阵拆分成多个小的子块,比如按第一个维度切分成多个小批次,每个批次单独存储为memmap或者numpy文件,使用的时候按需加载。示例:

import numpy as np

block_size = 1000  # 每个块的样本数,可根据你的存储容量调整
total_samples = 347101

for i in range(0, total_samples, block_size):
    end_idx = min(i + block_size, total_samples)
    # 创建当前块的memmap文件
    block = np.memmap(f'encoder_block_{i}.memmap', dtype='float32', mode='w+', shape=(end_idx - i, 400, 347101))
    # 填充当前块的数据(替换成你的数据填充逻辑)
    # block[:] = your_data_chunk
    del block  # 释放关联,确保数据写入磁盘

使用的时候,只加载需要的块进行处理即可,不用一次性加载整个大矩阵。

4. 改用HDF5格式存储

HDF5是专门为超大数据集设计的存储格式,支持分块存储、按需读取,比memmap更灵活。用h5py库实现:

import h5py

# 创建HDF5文件,设置分块大小(可根据你的数据访问模式调整)
with h5py.File('encoder_input_data.h5', 'w') as f:
    dset = f.create_dataset('encoder_data', shape=(347101, 400, 347101), dtype='float32', chunks=(100, 400, 100))
    # 分批次写入数据
    for i in range(0, 347101, 100):
        end_idx = min(i + 100, 347101)
        dset[i:end_idx] = your_data_chunk  # 替换成你的数据块

读取的时候可以直接切片,不需要加载整个文件到内存:

with h5py.File('encoder_input_data.h5', 'r') as f:
    chunk = f['encoder_data'][0:100]  # 只读取前100个样本

最后提醒一下:如果你的业务场景真的需要这么大的密集矩阵,那你得先准备好足够的存储设备(比如PB级的存储集群),否则任何软件层面的方案都救不了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:16:51