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

M1 Pro Mac用PyInstaller打包torch等库程序报错求助

问题描述

环境:M1 Pro MacBook + Python 3.10 Conda环境
现象:直接运行tester.py正常,PyInstaller打包后执行出现SIGABRT错误,错误栈如下:

Exception raised from operator() at /Users/runner/work/pytorch/pytorch/pytorch/aten/src/ATen/core/jit_type.h:1735 (most recent call first):
frame #0: c10::detail::torchCheckFail(char const*, char const*, unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 92 (0x1718d5718 in libc10.dylib)
frame #1: c10::detail::getTypePtr_<c10::intrusive_ptr<ConvPackedParamsBase<2>, c10::detail::intrusive_target_default_null_type<ConvPackedParamsBase<2> > > >::call()::'lambda'()::operator()() const + 300 (0x288dd22b4 in libtorch_cpu.dylib)
frame #2: c10::Type::SingletonOrSharedTypePtr<c10::Type> c10::getTypePtrCopy<c10::intrusive_ptr<ConvPackedParamsBase<2>, c10::detail::intrusive_target_default_null_type<ConvPackedParamsBase<2> > > >() + 32 (0x288dd2014 in libtorch_cpu.dylib)
frame #3: c10::detail::infer_schema::(anonymous namespace)::createArgumentVector(c10::ArrayRef<c10::detail::infer_schema::ArgumentDef>) + 188 (0x2887e0b88 in libtorch_cpu.dylib)
frame #4: c10::detail::infer_schema::make_function_schema(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, c10::ArrayRef<c10::detail::infer_schema::ArgumentDef>, c10::ArrayRef<c10::detail::infer_schema::ArgumentDef>) + 96 (0x2887e0948 in libtorch_cpu.dylib)
frame #5: c10::detail::infer_schema::make_function_schema(c10::ArrayRef<c10::detail::infer_schema::ArgumentDef>, c10::ArrayRef<c10::detail::infer_schema::ArgumentDef>) + 60 (0x2887e0e70 in libtorch_cpu.dylib)
frame #6: std::__1::unique_ptr<c10::FunctionSchema, std::__1::default_delete<c10::FunctionSchema> > c10::detail::inferFunctionSchemaFromFunctor<at::Tensor (*)(at::Tensor, c10::intrusive_ptr<ConvPackedParamsBase<2>, c10::detail::intrusive_target_default_null_type<ConvPackedParamsBase<2> > > const&, double, long long)>() + 76 (0x288e42ad4 in libtorch_cpu.dylib)
frame #7: torch::CppFunction::CppFunction<at::Tensor (at::Tensor, c10::intrusive_ptr<ConvPackedParamsBase<2>, c10::detail::intrusive_target_default_null_type<ConvPackedParamsBase<2> > > const&, double, long long)>(at::Tensor (*)(at::Tensor, c10::intrusive_ptr<ConvPackedParamsBase<2>, c10::detail::intrusive_target_default_null_type<ConvPackedParamsBase<2> > > const&, double, long long), std::__1::enable_if<c10::guts::is_function_type<at::Tensor (at::Tensor, c10::intrusive_ptr<ConvPackedParamsBase<2>, c10::detail::intrusive_target_default_null_type<ConvPackedParamsBase<2> > > const&, double, long long)>::value, std::nullptr_t>::type) + 124 (0x288e429fc in libtorch_cpu.dylib)
frame #8: at::native::(anonymous namespace)::TORCH_LIBRARY_IMPL_init_quantized_QuantizedCPU_4(torch::Library&) + 40 (0x288e40d48 in libtorch_cpu.dylib)
frame #9: torch::detail::TorchLibraryInit::TorchLibraryInit(torch::Library::Kind, void (*)(torch::Library&), char const*, c10::optional<c10::DispatchKey>, char const*, unsigned int) + 208 (0x288689a70 in libtorch_cpu.dylib)
frame #10: _GLOBAL__sub_I_qconv.cpp + 88 (0x288e46ba4 in libtorch_cpu.dylib)
frame #11: invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 164 (0x103c55f4c in dyld)
frame #12: invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 168 (0x103c7f550 in dyld)
frame #13: invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 528 (0x103c75ed8 in dyld)
frame #14: dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 168 (0x103c41f98 in dyld)
frame #15: dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 192 (0x103c75c80 in dyld)
frame #16: dyld3::MachOAnalyzer::forEachInitializerPointerSection(Diagnostics&, void (unsigned int, unsigned int, unsigned char const*, bool&) block_pointer) const + 148 (0x103c7ee80 in dyld)
frame #17: dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 432 (0x103c7f180 in dyld)
frame #18: dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 172 (0x103c55e8c in dyld)
frame #19: dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 216 (0x103c56038 in dyld)
frame #20: dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 180 (0x103c56014 in dyld)
frame #21: dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 180 (0x103c56014 in dyld)
frame #22: dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const + 124 (0x103c56104 in dyld)
frame #23: dyld4::APIs::dlopen_from(char const*, int, void*) + 520 (0x103c65c64 in dyld)
frame #24: py_dl_open + 160 (0x103fdb5ac in _ctypes.cpython-39-darwin.so)
<omitting python frames>

fish: Job 1, './tester' terminated by signal SIGABRT (Abort)

待打包文件tester.py:

import tensorflow as tf
import numpy as np
import torch
import torchaudio

print("hallo")

使用的tester.spec文件:

# -*- mode: python ; coding: utf-8 -*- 


block_cipher = None

env_base_path = '/opt/homebrew/Caskroom/miniconda/base/envs/test3.9'

a = Analysis(
    ['tester.py'],
    pathex=[env_base_path],
    binaries=[(env_base_path + '/lib/libc++.1.0.dylib','.')],
    datas=[],
    hiddenimports=['torchaudio.lib.libtorchaudio'],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='tester',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='tester',
)
解决思路与方案
  • 禁用UPX压缩:UPX压缩可能破坏PyTorch动态库的结构,导致加载失败。修改spec文件中EXE和COLLECT部分的upx=True为upx=False:

    exe = EXE(
        # 其他参数保持不变
        upx=False,
        # 其他参数保持不变
    )
    coll = COLLECT(
        # 其他参数保持不变
        upx=False,
        # 其他参数保持不变
    )
    
  • 手动添加PyTorch相关动态库:PyInstaller可能未自动收集所有依赖,在Analysis的binaries中补充核心库(路径需根据实际环境调整):

    binaries=[
        (env_base_path + '/lib/libc++.1.0.dylib','.'),
        (env_base_path + '/lib/python3.10/site-packages/torch/lib/libtorch_cpu.dylib', '.'),
        (env_base_path + '/lib/python3.10/site-packages/torch/lib/libc10.dylib', '.'),
        (env_base_path + '/lib/python3.10/site-packages/torchaudio/lib/libtorchaudio.dylib', '.')
    ],
    
  • 指定目标架构为arm64:明确适配M1的arm架构,避免架构混淆。修改EXE部分的target_arch:

    exe = EXE(
        # 其他参数保持不变
        target_arch='arm64',
        # 其他参数保持不变
    )
    
  • 补充隐藏导入:添加PyTorch的核心内部模块,避免动态加载缺失:

    hiddenimports=[
        'torchaudio.lib.libtorchaudio',
        'torch._C',
        'torch._C._jit',
        'torch._C._dlpack'
    ],
    
  • 开启非归档模式:将Python模块不打包成单个归档文件,解决路径加载问题。修改Analysis中的noarchive参数:

    a = Analysis(
        # 其他参数保持不变
        noarchive=True,
        # 其他参数保持不变
    )
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:36:16