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

大体积pkl文件加载失败求助:16G内存加载9.6GB文件崩溃

问题描述

我正在学习Python和深度学习,老师给了一个9.6GB的pkl数据文件,但我的计算机只有16G内存。

  • 直接用pickle.load(open('data.pkl', 'rb'))加载整个文件,电脑直接崩溃
  • 尝试缓冲读取(代码如下),依然崩溃:
import pickle
import gc
block_size = 512 * 1024 * 1024 # 512Mb
data = b''
count_num = 0
with open('../data.pkl', 'rb') as f:
    while True:
        buffer = f.read(block_size)
        if not buffer:
            break;
        count_num += 1
        data += buffer
        print("read" + str(count_num*512) + "Mb")
        gc.collect()
print("finish")
  • 尝试按字节拆分文件(代码如下),但加载拆分后的文件时出现UnpicklingError: pickle data was truncated和UnpicklingError: A load persistent id instruction was encountered, but no persistent_load function was specified.错误:
import pickle
import gc
block_size = 10 * 1024 * 1024
count_num = 0
with open('../data.pkl', 'rb') as f:
    while True:
        buffer = f.read(block_size)
        if not buffer:
            break;
        count_num += 1
        print("read" + str(count_num) + "0Mb")
        fw = open("data/wiki-data-statement-"+str(count_num)+".pkl", "wb")
        pickle.dump(buffer, fw)
        print("split"+ str(count_num) + "block")
        gc.collect()
print("finish")
可行解决方案

1. 逐对象加载pickle文件

如果原pkl文件是多个序列化对象的集合,不要一次性全部加载,而是逐个读取处理,每次仅在内存中保留单个对象:

import pickle

def load_large_pkl(file_path):
    with open(file_path, 'rb') as f:
        while True:
            try:
                yield pickle.load(f)
            except EOFError:
                break

# 用法示例:遍历每个对象并处理
for item in load_large_pkl('../data.pkl'):
    # 替换为你的处理逻辑,比如存入数据库、转存为小文件等
    process_item(item)

2. 用joblib替代pickle处理大数值数据

joblib对numpy数组等数值型大对象的序列化/反序列化更高效,内存占用更低,同样支持逐对象加载:

from joblib import load

with open('../data.pkl', 'rb') as f:
    while True:
        try:
            chunk = load(f)
            # 处理单个数据块
            process_chunk(chunk)
        except EOFError:
            break

3. 修正文件拆分逻辑

之前的按字节拆分破坏了pickle的结构,正确的做法是先读取完整的pickle对象,再分别保存为小文件:

import pickle

def split_large_pkl(input_path, output_prefix):
    count = 0
    with open(input_path, 'rb') as f:
        while True:
            try:
                item = pickle.load(f)
                count += 1
                with open(f"{output_prefix}_{count}.pkl", 'wb') as fw:
                    pickle.dump(item, fw)
                print(f"已保存第{count}个小文件")
            except EOFError:
                break

# 用法示例
split_large_pkl('../data.pkl', 'data/wiki-data-statement')

拆分后的每个小文件都是完整的pickle对象,加载时不会报错。

4. 临时扩展虚拟内存

如果以上方法仍有压力,可以扩大系统虚拟内存,让硬盘空间补充内存不足:

  • Windows:设置→系统→关于→高级系统设置→性能→设置→高级→虚拟内存→更改,调整分页文件大小
  • macOS:通过终端查看当前交换空间:sysctl -w vm.swapusage,需关闭SIP后修改配置文件或用第三方工具调整(Ventura及以后版本注意权限)

推荐工具

  • dill:扩展pickle功能,支持更多对象类型,可结合生成器逐对象加载
  • pandas:若数据是表格型结构,用pd.read_pickle()结合分块处理(需确认原pkl存储的是DataFrame)
  • PyArrow:高效的列式存储格式,可将pkl转换为Arrow格式后分块处理,适合大数据场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:08:20