From 4589289635c133fb6575fcf23af553dd3fa523ab Mon Sep 17 00:00:00 2001 From: congsh Date: Thu, 12 Feb 2026 13:31:49 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DPython=203.13=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E4=B8=8BPyInstaller=E6=9E=84=E5=BB=BA=E5=B4=A9?= =?UTF-8?q?=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - PyInstaller在分析阶段尝试导入torch/transformers等ML库 - 这些库与Python 3.13不兼容,导致"Windows fatal exception: access violation" - 构建过程无法完成,无法生成exe文件 解决方案: 1. 添加pyi_hooks/pyi_rth_ignore_torch.py运行时hook - 在PyInstaller分析阶段阻止torch等模块的导入 - 这些模块将在运行时动态安装 2. 添加pyi_hooks/hook-exclude-ml.py和hook-paddleocr.py - 明确告诉PyInstaller不收集这些ML库 3. 更新build.bat和build.sh - 使用--runtime-hook和--additional-hooks-dir - 添加--exclude-module参数排除所有ML库 测试: - 验证所有hook文件语法正确 - 验证项目核心功能可以在不导入torch的情况下正常工作 Co-Authored-By: Claude Opus 4.6 --- build.bat | 16 +++++++++++ build.sh | 29 +++++++++++++++++++ pyi_hooks/__init__.py | 7 +++++ pyi_hooks/hook-exclude-ml.py | 36 +++++++++++++++++++++++ pyi_hooks/hook-paddleocr.py | 29 +++++++++++++++++++ pyi_hooks/pyi_rth_ignore_torch.py | 47 +++++++++++++++++++++++++++++++ 6 files changed, 164 insertions(+) create mode 100644 pyi_hooks/__init__.py create mode 100644 pyi_hooks/hook-exclude-ml.py create mode 100644 pyi_hooks/hook-paddleocr.py create mode 100644 pyi_hooks/pyi_rth_ignore_torch.py diff --git a/build.bat b/build.bat index 177fbcf..90422c3 100644 --- a/build.bat +++ b/build.bat @@ -43,12 +43,16 @@ if exist dist rmdir /s /q dist echo. echo 4/5. Building executable... +echo NOTE: Using custom hooks to exclude heavy ML libraries that cause Python 3.13 issues +echo These will be installed dynamically at runtime if needed python -m PyInstaller ^ --noconfirm ^ --name "CutThenThink" ^ --windowed ^ --onefile ^ --add-data "src:src" ^ + --runtime-hook=pyi_hooks/pyi_rth_ignore_torch.py ^ + --additional-hooks-dir=pyi_hooks ^ --hidden-import=PyQt6.QtCore ^ --hidden-import=PyQt6.QtGui ^ --hidden-import=PyQt6.QtWidgets ^ @@ -67,6 +71,18 @@ python -m PyInstaller ^ --hidden-import=yaml ^ --hidden-import=requests ^ --collect-all pyqt6 ^ + --exclude-module=torch ^ + --exclude-module=transformers ^ + --exclude-module=tensorflow ^ + --exclude-module=onnx ^ + --exclude-module=onnxruntime ^ + --exclude-module=sentencepiece ^ + --exclude-module=tokenizers ^ + --exclude-module=diffusers ^ + --exclude-module=accelerate ^ + --exclude-module=datasets ^ + --exclude-module=huggingface_hub ^ + --exclude-module=safetensors ^ src/main.py if errorlevel 1 ( diff --git a/build.sh b/build.sh index 909c5eb..0869606 100644 --- a/build.sh +++ b/build.sh @@ -44,15 +44,44 @@ fi echo "" echo "4/4. 开始打包..." +echo "NOTE: 使用自定义 hooks 排除与 Python 3.13 不兼容的 ML 库" $PYTHON -m PyInstaller \ --name "CutThenThink" \ --windowed \ --onefile \ --add-data "src:src" \ + --runtime-hook=pyi_hooks/pyi_rth_ignore_torch.py \ + --additional-hooks-dir=pyi_hooks \ --hidden-import=PyQt6.QtCore \ --hidden-import=PyQt6.QtGui \ --hidden-import=PyQt6.QtWidgets \ --hidden-import=sqlalchemy \ + --hidden-import=sqlalchemy.orm \ + --hidden-import=PIL \ + --hidden-import=PIL.Image \ + --hidden-import=PIL.ImageEnhance \ + --hidden-import=PIL.ImageFilter \ + --hidden-import=numpy \ + --hidden-import=pyperclip \ + --hidden-import=tkinter \ + --hidden-import=tkinter.ttk \ + --hidden-import=tkinter.scrolledtext \ + --hidden-import=tkinter.messagebox \ + --hidden-import=yaml \ + --hidden-import=requests \ + --collect-all pyqt6 \ + --exclude-module=torch \ + --exclude-module=transformers \ + --exclude-module=tensorflow \ + --exclude-module=onnx \ + --exclude-module=onnxruntime \ + --exclude-module=sentencepiece \ + --exclude-module=tokenizers \ + --exclude-module=diffusers \ + --exclude-module=accelerate \ + --exclude-module=datasets \ + --exclude-module=huggingface_hub \ + --exclude-module=safetensors \ src/main.py echo "" diff --git a/pyi_hooks/__init__.py b/pyi_hooks/__init__.py new file mode 100644 index 0000000..941913a --- /dev/null +++ b/pyi_hooks/__init__.py @@ -0,0 +1,7 @@ +""" +PyInstaller hooks for CutThenThink + +This directory contains custom PyInstaller hooks to handle: +- Excluding heavy ML libraries (torch, transformers, etc.) +- Runtime-only dependencies like PaddleOCR +""" diff --git a/pyi_hooks/hook-exclude-ml.py b/pyi_hooks/hook-exclude-ml.py new file mode 100644 index 0000000..6f1ba61 --- /dev/null +++ b/pyi_hooks/hook-exclude-ml.py @@ -0,0 +1,36 @@ +""" +PyInstaller hook to exclude ML libraries during build + +This prevents PyInstaller from attempting to analyze and bundle +heavy ML libraries that are incompatible with Python 3.13 or +cause build crashes. + +These libraries will be installed at runtime if needed. +""" + +# Collect any hidden imports (empty for this hook) +hiddenimports = [] + +# Exclude all heavy ML dependencies +excludedimports = [ + 'torch', + 'torch.nn', + 'torch.utils', + 'torchvision', + 'transformers', + 'tensorflow', + 'tensorflow.keras', + 'onnx', + 'onnxruntime', + 'sentencepiece', + 'tokenizers', + 'diffusers', + 'accelerate', + 'datasets', + 'huggingface_hub', + 'safetensors', + 'optimum', + 'coloredlogs', + 'docutils', + 'tqdm', +] diff --git a/pyi_hooks/hook-paddleocr.py b/pyi_hooks/hook-paddleocr.py new file mode 100644 index 0000000..a3ea1ae --- /dev/null +++ b/pyi_hooks/hook-paddleocr.py @@ -0,0 +1,29 @@ +""" +PyInstaller hook for PaddleOCR + +Prevents PyInstaller from trying to bundle PaddleOCR and its dependencies. +These will be installed dynamically at runtime. +""" + +from PyInstaller.utils.hooks import is_module_satisfies + +# Tell PyInstaller to NOT collect these modules +# They will be installed at runtime via ensure_paddleocr() + +hiddenimports = [] + +# Explicitly exclude heavy ML dependencies +excludedimports = [ + 'torch', + 'transformers', + 'tensorflow', + 'onnx', + 'onnxruntime', + 'sentencepiece', + 'tokenizers', + 'diffusers', + 'accelerate', + 'datasets', + 'huggingface_hub', + 'safetensors', +] diff --git a/pyi_hooks/pyi_rth_ignore_torch.py b/pyi_hooks/pyi_rth_ignore_torch.py new file mode 100644 index 0000000..2ba5adf --- /dev/null +++ b/pyi_hooks/pyi_rth_ignore_torch.py @@ -0,0 +1,47 @@ +""" +PyInstaller runtime hook to prevent torch import during analysis + +This hook runs before PyInstaller's module analysis phase. +It blocks problematic modules from being imported during the build process. +""" + +import sys + +# List of modules to block during PyInstaller analysis +BLOCKED_MODULES = [ + 'torch', + 'transformers', + 'tensorflow', + 'onnx', + 'onnxruntime', + 'sentencepiece', + 'tokenizers', + 'diffusers', + 'accelerate', + 'datasets', + 'huggingface_hub', + 'safetensors', +] + +# Override the import mechanism to block these modules +class BlockModuleImport: + """Meta path importer to block specific modules during PyInstaller build""" + + def find_module(self, fullname, path=None): + if fullname in BLOCKED_MODULES or any( + fullname.startswith(m + '.') for m in BLOCKED_MODULES + ): + # Return self to handle the import (will raise ImportError) + return self + return None + + def load_module(self, fullname): + raise ImportError( + f"Module '{fullname}' is excluded from PyInstaller build. " + f"It will be installed at runtime if needed." + ) + +# Install the blocker at the start of PyInstaller analysis +if '_MEIPASS' not in sys.__dict__: + # Only during build time (not when running the frozen app) + sys.meta_path.insert(0, BlockModuleImport())