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

如何用PyInstaller打包Pickle序列化Sklearn模型EXE且不依赖Sklearn?

解决Pickle加载Voting Regressor模型时无需导入Sklearn打包EXE的问题

太懂你这种想压缩EXE体积的心情了——18MB和200MB的差别简直是天壤之别。先给你说透核心问题:Pickle根本不是用来打包依赖的,它只序列化了模型对象的结构和参数,加载时必须能找到原类的定义(也就是Sklearn的VotingRegressor),所以你没导入Sklearn的话,打包后运行肯定会报找不到模块的错。

下面给你三个可行的解决方案,按推荐程度排序:

1. 转成ONNX格式(最推荐,彻底脱离Sklearn)

ONNX是跨框架的模型格式,专门解决“模型部署脱离训练框架”的痛点。你只需要把训练好的Voting Regressor转成ONNX格式,用轻量的onnxruntime来推理,打包后的体积能控制在50MB以内,完全不需要Sklearn。

步骤1:训练时转换模型(仅需执行一次)

先安装依赖:

pip install onnx skl2onnx

然后运行转换代码:

from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import pickle

# 加载你原有的Voting Regressor模型
model = pickle.load(open('vt_model.pkl', 'rb'))
# 定义输入特征形状:你的模型是16个特征,所以设置为[None, 16](None表示支持批量预测)
initial_type = [('float_input', FloatTensorType([None, 16]))]
# 转换为ONNX格式
onnx_model = convert_sklearn(model, initial_types=initial_type)
# 保存ONNX模型
with open('vt_model.onnx', 'wb') as f:
    f.write(onnx_model.SerializeToString())

步骤2:修改部署代码

把原来用Pickle加载模型和预测的部分替换成以下代码:

# 替换原有的import pickle和模型加载逻辑
import onnxruntime as rt
import numpy as np  # 仅需这个轻量库,比Sklearn小得多

# 加载ONNX模型
sess = rt.InferenceSession(resource_path('vt_model.onnx'))
input_name = sess.get_inputs()[0].name
output_name = sess.get_outputs()[0].name

# 数据预处理、scaler转换部分保留不变
# ... 你的原有代码逻辑 ...

# 将处理好的特征转换为numpy数组(ONNX要求数组输入)
scale_array = scale_table  # 这是你scaler.transform后的二维数组结果
pred_value = sess.run([output_name], {input_name: scale_array})[0]
pred_value = int(np.round(pred_value[0]))

这样打包时只需要导入onnxruntime、PySimpleGUI等轻量库,体积会大幅下降,且完全脱离Sklearn依赖。

2. PyInstaller隐藏导入+裁剪Sklearn依赖(保留Pickle方案)

如果你不想更换模型格式,也可以让PyInstaller只打包Sklearn的必要部分,而非整个库。

打包命令示例:

pyinstaller --onefile --hidden-import sklearn.ensemble.VotingRegressor --exclude-module sklearn.datasets --exclude-module sklearn.utils.tests --exclude-module sklearn.dummy --exclude-module sklearn.svm test.py
  • --hidden-import:指定必须加载的Sklearn子模块(VotingRegressor属于sklearn.ensemble)
  • --exclude-module:排除Sklearn中完全无用的部分,比如数据集、测试模块、示例模型等

这样打包后的体积大概会降到80-100MB,远小于全量导入Sklearn的大小。

3. 模型蒸馏(适合对精度要求不高的场景)

如果你的模型精度要求不是极端苛刻,可以用简单回归模型拟合Voting Regressor的输出:

  1. 用大量输入数据喂给原Voting Regressor,得到预测结果
  2. 把这些输入和预测结果作为新训练数据,训练一个轻量回归器(比如线性回归、小型决策树)
  3. 打包这个轻量模型,依赖会极小(比如仅需sklearn.linear_model,体积非常小)

这个方法会损失少量精度,但胜在体积最小。

最后提醒

  • ONNX转换时注意Sklearn版本兼容性,skl2onnx对Sklearn 0.24-1.0版本支持较好
  • 用PyInstaller裁剪依赖时,可添加更多--exclude-module参数排除无用子模块,比如sklearn.metrics、sklearn.model_selection等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:08:02