Pyinstaller打包部署在Win2008上的Bug排查之路

server/2025/1/15 15:05:13/

1.前言

python项目的部署工作基本是属于算法的最后阶段,同样也是最容易出现问题的阶段,毕竟IDE中的运行甚至debug都是可以直接给出问题,再加上开发机器的版本较新,也很少会出现各种各样的dll系统问题。win和linux部署相比,linux由于其系统相对较为简单,部署问题较少,但windows的部署所面临的bug则千奇百怪,尤其是较为老的服务器版本。
本次问题主要是算法库版本与windows服务器不兼容导致的,开发机使用了windows11,并且算法库均为最新版本;测试人员不够专业,没有使用与生产环境相同的测试环境;直到上线前期,不兼容问题出现,搜集了各类资料,最终定位解决。

2.系统环境信息

硬件环境
  • 处理器 12th Gen Intel® Core™ i5-12500H 3.10 GHz
  • 机带 RAM 32.0 GB (31.7 GB 可用)
  • 设备 ID B3E450C9-FC4F-4934-9ADC-C643A1484672
  • 产品 ID 00342-30616-35677-AAOEM
  • 系统类型 64 位操作系统, 基于 x64 的处理器
系统信息
  • 版本 Windows 11 家庭中文版
  • 版本号 24H2
  • 安装日期 ‎2024/‎12/‎27
  • 操作系统版本 26100.2605
  • 体验 Windows 功能体验包 1000.26100.36.0
生产服务器系统
  • 版本win2008 R2
开发阶段算法库版本
算法库版本
pandas2.2.0
numpy1.26.4
lightgbm4.4.0
pyinstaller6.9.0
torch2.3.0

4.Bug排查过程

1.问题发生–dll丢失

打包程序部署后,在win2008服务器上,系统报错丢失api-ms-win-core-path-l1-1-0.dll, 这Microsoft Windows 操作系统中的一个动态链接库(DLL)文件,主要与文件路径操作和路径管理相关。它是 Windows API(应用程序编程接口)的一部分,提供了一些核心功能,帮助 Windows 应用程序在操作系统中进行路径相关的操作。
在这里插入图片描述

2.dll丢失问题解决

在DLL下载网站上下载这个库,分别放入C:\Windows\System32和C:\Windows\SysWOW64目录下,问题解决。此时运行框能够正常显示出来,表明dll确实问题已经解决,问题到这,都算是很简单的事件。
在这里插入图片描述

3.模型调用报错

紧接着,需要进行接口测试,传参后,程序报错,内容大致如下:

0SError:[winError193]x1 不是有效的 Win32 应用程序。
Failed to load \lightghm\win\lib.Lightgbm.dll’. Most likely this dynlib/dll was not found when the applicat ion wfrozen

4.Pyinstaller降版本

最显眼的winError193故障报错,第一时间对此进行了排查(被这个故障报错干扰了判断),很多内容答案显示可能在 64 位 Windows 系统上尝试运行一个 32 位应用程序,或者反过来。比如,尝试用 32 位的应用程序加载 64 位的动态链接库(DLL),或者使用 64 位的程序加载 32 位的 DLL,会出现这个错误。
针对这个问题,重新下载了dll文件,并且使用了dll depends工具进行了相应排查,并没有发现任何问题。怀疑是Pyinstaller问题,将其降级到3.0+版本,并且重新进行了多次打包,问题没有解决。

5.lightgbm问题排查

由于winError193故障并没有找到有效的解决方案,开始怀疑是lightgbm的版本问题导致,并对此进行了相应的搜索,发现存在此类相关可能,经搜索,lightgbm可能不完全支持 Windows 2008 及其早期版本,这将会导致兼容性问题。

6.lightgbm降版本

经过搜集,针对windows2008的支持情况,选择了2.2.3版本的lightgbm,为了快速验证,构建了一个小项目进行打包测试,使用了lightgbm和torch,代码如下:

import numpy as np
import lightgbm as lgb
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score# 1. 使用 LightGBM 进行分类任务
# 创建一个简单的二分类数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 将数据转换为 LightGBM Dataset 格式
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)# 设置 LightGBM 超参数
params = {'objective': 'binary','metric': 'binary_error','boosting_type': 'gbdt','num_leaves': 31,'learning_rate': 0.05,'feature_fraction': 0.9,
}# 训练 LightGBM 模型
lgb_model = lgb.train(params, train_data, valid_sets=[test_data], num_boost_round=100)# 使用 LightGBM 模型进行预测
y_pred_lgb = lgb_model.predict(X_test)
y_pred_lgb = (y_pred_lgb > 0.5).astype(int)# 评估 LightGBM 模型的准确度
accuracy_lgb = accuracy_score(y_test, y_pred_lgb)
print(f"LightGBM 分类模型准确率: {accuracy_lgb:.4f}")# 2. 使用 PyTorch 构建神经网络进行回归任务
# 创建一个简单的回归数据集
X_reg, y_reg = make_classification(n_samples=1000, n_features=20, n_informative=5, n_classes=2, random_state=42)# 划分训练集和测试集
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg, y_reg, test_size=0.2, random_state=42)# 将数据转换为 PyTorch Tensor
X_train_tensor = torch.tensor(X_train_reg, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train_reg, dtype=torch.float32).view(-1, 1)
X_test_tensor = torch.tensor(X_test_reg, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test_reg, dtype=torch.float32).view(-1, 1)# 定义一个简单的神经网络
class SimpleNN(nn.Module):def __init__(self):super(SimpleNN, self).__init__()self.fc1 = nn.Linear(20, 64)self.fc2 = nn.Linear(64, 32)self.fc3 = nn.Linear(32, 1)def forward(self, x):x = torch.relu(self.fc1(x))x = torch.relu(self.fc2(x))x = self.fc3(x)return x# 初始化模型,定义损失函数和优化器
model = SimpleNN()
criterion = nn.MSELoss()  # 由于是回归任务,使用均方误差损失
optimizer = optim.Adam(model.parameters(), lr=0.001)# 训练神经网络模型
epochs = 100
for epoch in range(epochs):model.train()optimizer.zero_grad()outputs = model(X_train_tensor)loss = criterion(outputs, y_train_tensor)loss.backward()optimizer.step()if (epoch + 1) % 10 == 0:print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}")# 使用神经网络模型进行预测
model.eval()
with torch.no_grad():y_pred_nn = model(X_test_tensor)# 计算模型的均方误差
mse = criterion(y_pred_nn, y_test_tensor)
print(f"神经网络回归模型均方误差: {mse.item():.4f}")

打包测试后发现,2.2.3版本的lightgbm能够正常运行在win2008上,说明lightgbm降版本可以解决当前的系统报错问题。

7.问题解决

lightgbm进行降版本,使用2.2.3版本,重新打包后,发到win2008的测试环境中测试,正常运行,正常建模,问题得到解决。

5.总结

1算法库版本与系统兼容性问题

  1. 在项目的部署过程中,算法库版本与生产环境的系统兼容性问题是常见的挑战。特别是在Windows 2008 R2服务器上部署现代算法库时,由于操作系统较旧且不再接收微软的更新,很多新的库和API可能无法正常工作。
  2. 例如,在此次部署中,开发环境中使用了较新的算法库版本(如lightgbm 4.4.0),而在Windows 2008服务器上,这些库可能存在兼容性问题,导致程序运行时出现报错(如dll丢失)。在这种情况下,选择适配服务器环境的较旧版本的算法库(如lightgbm 2.2.3)往往能够解决问题。
  3. 在进行生产环境部署时,确保开发环境与生产环境的一致性,包括操作系统和算法库版本的兼容性,对于顺利部署和避免不必要的技术障碍至关重要。

2.PyInstaller与系统环境的配合

  1. PyInstaller作为一个将Python程序打包为可执行文件的工具,尽管在现代开发环境中表现良好,但在老旧的操作系统上可能会遇到意外的兼容性问题。
  2. 在此次案例中,虽然PyInstaller被用于打包Python程序,但由于系统环境较为陈旧,导致报错(如winError193),这通常是因为32位与64位架构的不兼容所引起的。降级PyInstaller版本(如3.0+版本)并重新打包,未能直接解决问题。通过进一步排查发现,问题的根源在于使用的lightgbm版本与Windows 2008的兼容性。
  3. 在使用PyInstaller打包程序时,除了关注打包本身的设置外,还需要特别考虑目标服务器的操作系统版本及其支持的Python库版本,以确保打包后的程序能够在目标环境中正常运行。

http://www.ppmy.cn/server/158585.html

相关文章

【maptalks】加载SVG和GIF

加载SVG和GIF 一、加载SVG方法一:直接载入SVG文件,类似载入图片方法二:载入SVG路径 二、加载GIFVUEmaptalks实现GIF可拖拽点VUEmaptalks实现GIF跟随线条动画 一、加载SVG 方法一:直接载入SVG文件,类似载入图片 缺点&…

Redisson和可重入锁初认

文章目录 Redisson 简介Redisson 的主要特点Redisson 的核心模块Redisson的优势使用示例Maven 引入依赖配置 Redisson 客户端分布式锁使用示例 Redisson 使用场景总结 可重入锁关键特性为什么需要可重入锁可重入锁的实现方式可重入锁的实现原理可重入锁的优缺点优点缺点 可重入…

【Python】使用python 对excel文件进行加密

最近在跟同事对接工作的时候,我需要把Excel文件发给对方。 但是由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,保障数据的安全。 在Python中,有多种方法可以对Excel文件进行加密。以下是几…

好用的php商城源码有哪些?

选择一个优秀的商城工具,能更好地帮助大家建立一个好用的商城系统。目前比较流行的都是开源PHP商城系统,那么现实中都有哪些好用的PHP商城源码值得推荐呢?下面就带大家一起来了解一下。 1.TigShop 【推荐指数】:★★★★★☆ 【推…

day08_Kafka

文章目录 day08_Kafka课程笔记一、今日课程内容一、消息队列(了解)**为什么消息队列就像是“数据的快递员”?****实际意义**1、产生背景2、消息队列介绍2.1 常见的消息队列产品2.2 应用场景2.3 消息队列中两种消息模型 二、Kafka的基本介绍1、…

springboot基于安卓的反诈APP

Spring Boot基于安卓的反诈APP是一个结合了Spring Boot后端技术和安卓前端技术的反诈骗应用程序,旨在为用户提供全面、高效的反诈防护服务。 一、技术架构 后端:采用Spring Boot框架,利用其自动配置、简化依赖管理等功能,构建…

Open FPV VTX开源之第一次出图

Open FPV VTX开源之第一次出图 1. 源由2. 连线2.1 飞控2.2 调试 3. serial3.1 启动log - uboot3.2 登录版本 - linux3.3 获取有线IP 4. ssh - linux5. PixelPilot出图6. 总结7. 参考资料8. 补充8.1 8812AU网卡8.2 DEBUG串口部分乱码8.3 偶尔启动卡住8.4 花屏、丢包严重 1. 源由…

CSS3 弹性盒子

CSS3 弹性盒子 介绍 CSS3 弹性盒子(Flexbox)是一种用于布局设计的强大工具。它提供了一种更加高效的方式来对容器内的子元素进行排列、对齐和分配空间。Flexbox 的设计目标是提供一种统一的布局模型,能够适应不同屏幕尺寸和设备类型&#x…