llama-cpp-python 程序 Pyinstaller 打包后运行报错(RuntimeError: Failed to load shared library ‘llama.dll‘)

报错现象

本人基于 llama-cpp-python 构建了一个领域知识问答程序,并通过 Pyinstaller 打包成一个包含 .exe 运行文件的文件夹(记为 D)。

.exe 在本机(打包用的电脑,Windows 11)上运行正常,在把文件夹 D 拷贝到另外五台电脑(Windows 10)上后, .exe 在其中三台电脑上运行正常,但另两台报如下错误:

RuntimeError: Failed to load shared library 'D:\PPLocalChatbot\_internal\llama_cpp\llama.dll': 
Failed to load dynlib/dll 'D:\\PPLocalChatbot\\_internal\\llama_cpp\\llama.dll'. 
Most likely this dynlib/dll was not found when the application was frozen.

本机配置

  • Windows 11
  • Python 3.8
  • llama-cpp-python 0.2.73
  • Pyinstaller 6.6.0
  • kernel32.dll 10.0.22621.3527

问题分析

  1. 这里所示,通常 Pyinstaller 打包后的程序报错无法找到/加载 xx 文件,大概率是该文件在打包时未被 Pyinstaller 自动加入到指定文件夹引发的。然而这次不是,我已在打包配置文件 .spec 中通过 Analysis.binariesllama.dll 加入到了正确文件夹;此外,其他三台电脑能正常运行也表明了 llama.dll 其实正位于正确的文件夹下。
  2. 考虑到有些电脑能跑,有些不行,那可能与电脑版本或环境有关;
  3. 这里看到,该类报错也有可能是 .dll 所依赖其它 .dll 未在目标电脑上找到,可以采用 Dependencies 软件来检测 DLL 文件的依赖情况。
  4. 下图是本机使用 Dependencies 检测出的 llama.dll 的依赖情况,通过查找,发现除了 kernel32.dll,其它 DLL 文件均在打包后的文件夹 D 中存在。所以在运行 .exe 文件时,被调用的 llama.dll 会从目标电脑的 C:\Windows\System32 中调用 kernel32.dll。而这个 kernel32.dll 的版本在各电脑中都有所不同,因此 kernel32.dll 大概率就是问题所在。
    在这里插入图片描述

问题解决

  1. 本机的 kernel32.dll 的版本为 10.0.22621.3527,再查看五台测试电脑上的 kernel32.dll 的版本,发现正常运行的电脑的 kernel32.dll 的版本均在 10.0.17***.**** 以上,而报错的电脑的 kernel32.dll 的版本均在 10.0.16***.**** 以下;
    在这里插入图片描述

报错电脑的 kernel32.dll 版本(旧)

在这里插入图片描述

正常运行电脑的 kernel32.dll 版本

  1. Google 后了解到 kernel32.dll 与 Windows 版本直接关联,所以不能直接通过复制粘贴来更新。因此我不考虑更改 kernel32.dll,而是更改 llama.dll 让其适配旧版的 kernel32.dll
  2. 为了让 llama.dll 适配旧版的 kernel32.dll,最直接的方法就是:在旧版的 Windows 系统(即 kernel32.dll 版本低于 10.0.16***.****)中配置 Python 环境,安装 llama-cpp-python(这一步需要 cmake 等环境,可参考官方文档),并对程序进行打包;
  3. 经测试,在旧版 Windows 上打包的程序同时也可在新版 Windows 上正常运行(新版向下兼容)。
  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值