大体积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
相关产品推荐
相关产品推荐

