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

运行GitHub开源word2vec.py遇_pickle.PicklingError问题求助

解决word2vec.py中多进程Pickle序列化失败的问题

我帮你定位并解决这个_pickle.PicklingError问题!你猜的没错,这个错误确实是因为多进程Pool在传递参数时,需要对对象进行Pickle序列化,但numpy的c_double_Array_100这类ctypes数组类型无法被正常序列化——这类动态生成的ctypes数组类,Pickle找不到对应的全局属性定义,所以序列化失败。

下面是几个可行的解决方案,按推荐优先级排序:

1. 替换为原生支持Pickle的numpy数组

最直接的方法是把代码中c_double_Array_100类型的数组替换成numpy的ndarray,因为ndarray是原生支持Pickle序列化的,而且和原数组的功能完全兼容。

比如原来的代码如果是这样创建数组的:

from numpy.ctypeslib import c_double
arr_type = c_double * 100
weights = arr_type()

可以改成:

import numpy as np
weights = np.zeros(100, dtype=np.float64)

如果代码中需要和ctypes函数交互,也可以随时把ndarray转换成ctypes数组(比如用weights.ctypes.data_as(ctypes.POINTER(ctypes.c_double))),不影响功能,但传递给多进程时用ndarray就不会有Pickle问题。

2. 使用进程间共享对象传递数组

如果必须保留ctypes数组的形式,可以用multiprocessing.Manager创建可共享的数组对象,这样不需要Pickle整个数组,而是在进程间共享内存:

from multiprocessing import Pool, Manager
import numpy as np
import ctypes

def worker(shared_arr):
    # 将共享数组转换成numpy数组使用
    arr = np.frombuffer(shared_arr.get_obj(), dtype=np.float64)
    # 这里写你的worker逻辑,比如更新词向量权重
    arr[0] += 1.0

if __name__ == "__main__":
    manager = Manager()
    # 创建长度为100的double类型共享数组
    shared_weights = manager.Array('d', 100)
    with Pool() as pool:
        pool.apply(worker, (shared_weights,))

这种方式适合需要在多个进程间共享更新同一个数组的场景。

3. 调整代码逻辑,避免传递不可序列化对象

检查你的代码中,传递给Pool.map或Pool.apply的参数里是否直接包含了c_double_Array_100对象。如果是某个类的属性持有这个数组,可以把数组转换成普通Python列表(比如list(weights))传递给子进程,在子进程里再重新构建成需要的类型;或者把数组的初始化逻辑放到子进程内部,不在主进程创建后传递。

另外,顺带提醒一下:你运行代码的命令-train test_word2vec.py -model out.txt看起来有点问题——原仓库的word2vec.py中-train参数应该指定训练文本数据文件,而不是代码文件,这可能会导致后续其他错误,记得改成对应的训练数据路径哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:56:48