加载Word2Vec预训练模型时出现解包错误的问题求助
加载Word2Vec预训练模型时出现解包错误的问题求助
从你遇到的错误和描述来看,最大的嫌疑就是gensim版本不兼容——你本地用最新版gensim训练的新模型,和AWS Lambda环境里的旧版gensim对不上,导致模型的序列化/反序列化(也就是pickle存、unpickle读)时出了格式问题,才会抛出invalid load key, '\xef'这种解包错误。
先给你理清楚为什么会这样:
pickle这个工具的序列化格式会跟着库的版本变,gensim在不同版本之间,对Word2Vec模型的存储细节可能做了调整。你用新版存的模型,旧版的gensim根本读不懂,自然就报错了。当然也有可能是模型文件上传到Lambda/EFS的时候损坏了,但你本地能正常加载,所以版本问题的概率远大于文件损坏。
下面给你几个靠谱的解决办法:
1. 统一gensim版本(最推荐)
这是从根源上解决问题的办法:
- 先搞清楚Lambda里用的是哪个版本的gensim:在你的lambda函数里加一行
print(gensim.__version__),跑一次就能看到版本号; - 本地把gensim降级到同一个版本,重新训练模型:
# 先卸载当前的gensim pip uninstall -y gensim # 安装和Lambda一样的版本,把x.x.x换成你查到的版本号 pip install gensim==x.x.x - 用这个匹配版本训练好新模型,再上传到Lambda/EFS,应该就能正常加载了。
2. 用兼容格式存储模型(不想降级的话选这个)
如果不想折腾本地的gensim版本,可以用gensim提供的通用格式来存模型:
- 本地训练完之后,用
save_word2vec_format保存成二进制或文本格式:# 保存成二进制格式,体积小加载快 model.save_word2vec_format('word2vec_model.bin', binary=True) # 要是需要文本格式也可以,就是体积大一些 # model.save_word2vec_format('word2vec_model.txt', binary=False) - 然后在Lambda里用
load_word2vec_format来加载:
注意:这种方式只保存词向量的权重,不会保存模型的训练参数(比如窗口大小、迭代次数这些),如果你的代码不需要用到这些训练参数,这个方案完全没问题。from gensim.models import KeyedVectors # 对应你保存的格式,binary参数要一致 model = KeyedVectors.load_word2vec_format('word2vec_model.bin', binary=True)
3. 排除文件损坏的可能(兜底检查)
要是上面两个方法都不管用,就得确认模型文件有没有在上传过程中坏了:
- 对比本地和Lambda上模型文件的MD5哈希值,看看是不是完全一样;
- 上传的时候一定要用二进制模式,别选文本模式,比如用S3上传的时候直接传文件,不要搞什么编码转换。
最后提个小建议:以后在Lambda+EFS这种环境里,安装依赖的时候最好和本地训练环境完全一致,包括所有库的版本,这样能少踩很多兼容性的坑。
备注:内容来源于stack exchange,提问作者Teja Rao
相关产品推荐
相关产品推荐

