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

Scipy.Optimize多进程优化如何实现迭代断点续存?

解决方案:多进程差分进化优化的迭代保存与恢复

你遇到的问题核心是多进程模式下,DifferentialEvolutionSolver内部的进程池(_pool)对象无法被pickle序列化——这是Python多进程模块的固有限制,进程池本身不能在进程间传递或持久化。要同时实现多进程加速和迭代保存,我们可以通过「序列化前清理进程池,恢复时重建进程池」的思路来解决。

具体实现步骤

  1. 保存求解器前,临时移除进程池
    在调用pickle.dump()之前,将求解器的_pool属性设为None,避开无法序列化的进程池对象。
  2. 加载求解器后,重建进程池
    从pickle文件加载求解器后,重新创建进程池,并修复求解器依赖的映射方法(_map)。

修改后的测试代码

import pickle
from scipy.optimize._differentialevolution import DifferentialEvolutionSolver
from multiprocessing import Pool

def converter(x):
    # 替换为你的目标函数
    return sum(x**2)

bounds = [(-1, 1)] * 66

if __name__ == '__main__':
    # 初始化多进程模式的求解器
    solver = DifferentialEvolutionSolver(converter, bounds, disp=True, seed=9, workers=-1, maxiter=1)
    
    # 迭代优化并逐次保存
    for i in range(100):
        best_x, best_cost = next(solver)
        print(f"Iteration {i}: Minimum energy = {solver.population_energies.min()}")
        
        # 保存前移除进程池,避免pickle报错
        solver._pool = None
        with open(f'solver_{i}.pkl', 'wb') as f:
            pickle.dump(solver, f)
    
    # ---------------------------
    # 加载并恢复优化的示例代码
    # ---------------------------
    # 加载指定迭代进度的求解器
    with open('solver_50.pkl', 'rb') as f:
        restored_solver = pickle.load(f)
    
    # 重建进程池并修复映射方法
    restored_solver._pool = Pool(processes=restored_solver.workers)
    restored_solver._map = restored_solver._pool.map
    
    # 继续迭代优化
    for i in range(50, 100):
        best_x, best_cost = next(restored_solver)
        print(f"Restored Iteration {i}: Minimum energy = {restored_solver.population_energies.min()}")
        
        # 再次保存前移除进程池
        restored_solver._pool = None
        with open(f'solver_{i}.pkl', 'wb') as f:
            pickle.dump(restored_solver, f)
    
    # 程序结束时关闭进程池,避免资源泄漏
    restored_solver._pool = Pool(processes=restored_solver.workers)
    restored_solver._pool.close()
    restored_solver._pool.join()

关键注意事项

  • 进程池重建时机:必须在if __name__ == '__main__':代码块内重建进程池,避免多进程环境下的重复初始化问题。
  • 资源清理:在程序结束后,记得关闭并join进程池,防止系统资源泄漏。
  • 替代序列化工具:如果上述方法仍有问题,可以尝试用dill库代替pickle(执行pip install dill安装),它支持更多Python对象的序列化,但进程池本身的限制依然存在,所以清理重建的步骤还是必要的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:23:09