【严重Bug】鲲鹏 konnx 补丁在 ONNX Runtime 运行大维度矩阵 (如ViT模型) 时触发空指针段错误 (SGEMM Null Pointer Dereference)
收藏回复举报
【严重Bug】鲲鹏 konnx 补丁在 ONNX Runtime 运行大维度矩阵 (如ViT模型) 时触发空指针段错误 (SGEMM Null Pointer Dereference)
t('forum.solved') 已解决
新人帖
发表于2026-04-08 13:00:28
0 查看

问题描述

在使用带有华为鲲鹏 konnx 深度优化补丁的 ONNX Runtime (版本为 1.19.2) 进行推理时,发现运行轻量级模型可正常通过,但运行大维度矩阵模型(如 ViT_B_16)时,会稳定触发底层的 Segmentation fault 导致进程崩溃,并在崩溃前伴随 BLAS : Bad memory unallocation! 堆内存损坏警告。

经过开启 AddressSanitizer (ASAN) 深度排查,定位到崩溃最终发生在 libkonnx.sokonnx_sgemm 函数内。 核心根因推导: 魔改补丁在 Graph 层(如 gemm.cc / matmul.cc)破坏了矩阵 B (权重) 预打包状态的初始化(注释了 is_packed = false;),或者 konnx_sgemm_prepackB 打包时发生了越界写(Buffer Overflow)。这导致底层的 MlasSgemmThreaded 多线程调度器拿到了一个非法的野指针(如 ASAN 捕获的 0xfffa8bbb0400),将其强行传入了 konnx_sgemm,进而引发非法的 READ 内存访问。

运行环境

  • 操作系统: 欧拉容器环境 openeuler-22.03-lts-sp3:latest (aarch64)
  • 硬件架构: ARM64 / 鲲鹏920 (48核)
  • Python版本: 3.9.20
  • ONNX Runtime版本: 1.19.2 (根据的 konnx 优化 patch的魔改版本)

复现步骤

  1. 使用包含 konnx 优化的补丁编译 ONNX Runtime (无需特殊参数,正常编译即可)。
# 安装 ASAN 依赖 
yum install libasan -y 
# 告诉 ASAN:只抓内存越界,忽略编译期工具链的内存泄漏 
export ASAN_OPTIONS=detect_leaks=0
./build.sh --config RelWithDebInfo --build_shared_lib --parallel --compile_no_warning_as_error --skip_submodule_sync --allow_running_as_root --skip-keras-test --skip_onnx_tests --skip_tests --build_wheel --build_dir build --cmake_extra_defines CMAKE_C_FLAGS="-fsanitize=address -g -O0" CMAKE_CXX_FLAGS="-fsanitize=address -g -O0"
# 进入onnxruntime-rel-1.19.2/build/RelWithDebInfo/dist/ 安装编译好的库
pip install onnxruntime-1.19.2-cp39-cp39-linux_aarch64.whl
  1. 安装编译好的 Wheel 包:
pip install build/RelWithDebInfo/dist/onnxruntime-1.19.2-cp39-cp39-linux_aarch64.whl
  1. 运行测试脚本: 加载包含大尺寸注意力机制的模型(ViT_B_16.onnx),见附件 speed_demo.py
LD_PRELOAD=/usr/lib/gcc/aarch64-linux-gnu/10.3.1/libasan.so python speed_demo.py
  1. 观测现象: 程序首先会连续抛出 BLAS : Bad memory unallocation!,随后直接崩溃并抛出 Segmentation fault。ASAN 稳定拦截到 SEGV on unknown address 0xfffa8bbb0400。 (注:若运行极小尺寸模型,未达到 sgemm.cpp 中设定的 DOUBLE_THRESHOLD,则走入原生未打包路径,不会触发此 Bug。)

详细报错日志 (ASAN)

(onnx) [root@08d8c3db7a00 onnx_demo]# LD_PRELOAD=/usr/lib/gcc/aarch64-linux-gnu/10.3.1/libasan.so python speed_demo.py 
2026-04-08 11:49:08.640518743 [W:onnxruntime:Default, onnxruntime_pybind_state.cc:2239 CreateInferencePybindStateModule] Init provider bridge failed.
PyTorch 运行设备: cpu

==================================================
🚀 开始测试模型: ViT_B_16
==================================================
[ONNX] 检测到文件 ViT_B_16.onnx 已存在,跳过导出步骤。
BLAS : Bad memory unallocation! :   22
BLAS : Bad memory unallocation! :   37
BLAS : Bad memory unallocation! :    3
BLAS : Bad memory unallocation! :    3
Fatal Python error: Fatal Python error: Segmentation faultSegmentation fault



AddressSanitizerAddressSanitizerAddressSanitizerAddressSanitizerAddressSanitizerThread 0xAddressSanitizer:DEADLYSIGNAL
AddressSanitizer=================================================================
:DEADLYSIGNAL
:DEADLYSIGNAL
:DEADLYSIGNAL
:DEADLYSIGNAL
0000fffc46cd5fc0:DEADLYSIGNAL
:DEADLYSIGNAL
 (most recent call first):
  File "/root/miniforge3/envs/onnx/lib/python3.9/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 220 in run
  File "/root/PycharmProjects/onnx_demo/speed_demo.py", line 60 in benchmark_onnx
  File "/root/PycharmProjects/onnx_demo/speed_demo.py", line 121 in main
  File "/root/PycharmProjects/onnx_demo/speed_demo.py", line 130 in <module>
AddressSanitizer:DEADLYSIGNAL
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
AddressSanitizerAddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
==643==ERROR: AddressSanitizer: SEGV on unknown address 0xfffa8bbb0400 (pc 0xfffb32fb6094 bp 0xfffab7b5c090 sp 0xfffab7b5c090 T149)
AddressSanitizer:DEADLYSIGNAL
==643==The signal is caused by a READ memory access.
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
    #0 0xfffb32fb6094  (/usr/local/sra_inference/lib/neon/libkonnx.so.1+0x96094)
    #1 0xfffb32f222b4  (/usr/local/sra_inference/lib/neon/libkonnx.so.1+0x22b4)
    #2 0xfffb32f225f0  (/usr/local/sra_inference/lib/neon/libkonnx.so.1+0x25f0)
    #3 0xfffb32f216d4 in konnx_sgemm (/usr/local/sra_inference/lib/neon/libkonnx.so.1+0x16d4)
    #4 0xfffb13b59e30 in MlasSgemmThreaded(long, long, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, unsigned long, unsigned long, unsigned long, MLAS_SGEMM_DATA_PARAMS const*, long) /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/mlas/lib/sgemm.cpp:1705
    #5 0xfffb13b5a3a4 in operator() /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/mlas/lib/sgemm.cpp:1796
    #6 0xfffb13b5a3a4 in __invoke_impl<void, MlasGemmBatch(CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, size_t, size_t, size_t, const MLAS_SGEMM_DATA_PARAMS*, size_t, MLAS_THREADPOOL*)::<lambda(ptrdiff_t)>&, long int> /usr/include/c++/10.3.1/bits/invoke.h:60
    #7 0xfffb13b5a3a4 in __invoke_r<void, MlasGemmBatch(CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, size_t, size_t, size_t, const MLAS_SGEMM_DATA_PARAMS*, size_t, MLAS_THREADPOOL*)::<lambda(ptrdiff_t)>&, long int> /usr/include/c++/10.3.1/bits/invoke.h:110
    #8 0xfffb13b5a3a4 in _M_invoke /usr/include/c++/10.3.1/bits/std_function.h:291
    #9 0xfffb13c246cc in std::function<void (long)>::operator()(long) const /usr/include/c++/10.3.1/bits/std_function.h:622
    #10 0xfffb13c246cc in operator() /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/common/threadpool.cc:469
    #11 0xfffb13c246cc in __invoke_impl<void, onnxruntime::concurrency::ThreadPool::SimpleParallelFor(std::ptrdiff_t, const std::function<void(long int)>&)::<lambda(std::ptrdiff_t, std::ptrdiff_t)>&, long int, long int> /usr/include/c++/10.3.1/bits/invoke.h:60
    #12 0xfffb13c246cc in __invoke_r<void, onnxruntime::concurrency::ThreadPool::SimpleParallelFor(std::ptrdiff_t, const std::function<void(long int)>&)::<lambda(std::ptrdiff_t, std::ptrdiff_t)>&, long int, long int> /usr/include/c++/10.3.1/bits/invoke.h:110
    #13 0xfffb13c246cc in _M_invoke /usr/include/c++/10.3.1/bits/std_function.h:291
    #14 0xfffb13c25e0c in std::function<void (long, long)>::operator()(long, long) const /usr/include/c++/10.3.1/bits/std_function.h:622
    #15 0xfffb13c25e0c in operator() /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/common/threadpool.cc:433
    #16 0xfffb13c25e0c in __invoke_impl<void, onnxruntime::concurrency::ThreadPool::ParallelForFixedBlockSizeScheduling(std::ptrdiff_t, std::ptrdiff_t, const std::function<void(long int, long int)>&)::<lambda(unsigned int)>&, unsigned int> /usr/include/c++/10.3.1/bits/invoke.h:60
    #17 0xfffb13c25e0c in __invoke_r<void, onnxruntime::concurrency::ThreadPool::ParallelForFixedBlockSizeScheduling(std::ptrdiff_t, std::ptrdiff_t, const std::function<void(long int, long int)>&)::<lambda(unsigned int)>&, unsigned int> /usr/include/c++/10.3.1/bits/invoke.h:110
    #18 0xfffb13c25e0c in _M_invoke /usr/include/c++/10.3.1/bits/std_function.h:291
    #19 0xfffb13c26414 in std::function<void (unsigned int)>::operator()(unsigned int) const /usr/include/c++/10.3.1/bits/std_function.h:622
    #20 0xfffb13c26414 in onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}::operator()() const /root/PycharmProjects/onnxruntime-rel-1.19.2/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h:1107
    #21 0xfffb13c26414 in void std::__invoke_impl<void, onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}&>(std::__invoke_other, onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}&) /usr/include/c++/10.3.1/bits/invoke.h:60
    #22 0xfffb13c26414 in std::enable_if<is_invocable_r_v<void, onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}&>, std::enable_if>::type std::__invoke_r<void, onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}&>(void&&, (onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}&)...) /usr/include/c++/10.3.1/bits/invoke.h:110
    #23 0xfffb13c26414 in std::_Function_handler<void (), onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ScheduleOnPreferredWorkers(onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::PerThread&, onnxruntime::concurrency::ThreadPoolParallelSection&, absl::InlinedVector<int, 11ul, std::allocator<int> >&, unsigned int, unsigned int, std::function<void (unsigned int)>)::{lambda()#1}>::_M_invoke(std::_Any_data const&) /usr/include/c++/10.3.1/bits/std_function.h:291
    #24 0xfffb13c3860c in std::function<void ()>::operator()() const /usr/include/c++/10.3.1/bits/std_function.h:622
    #25 0xfffb13c3860c in onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::WorkerLoop(int) /root/PycharmProjects/onnxruntime-rel-1.19.2/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h:1628
    #26 0xfffb13c39f94 in onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::WorkerLoop(int, Eigen::ThreadPoolInterface*) /root/PycharmProjects/onnxruntime-rel-1.19.2/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h:706
    #27 0xfffb13c4aa34 in ThreadMain /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/platform/posix/env.cc:244
    #28 0xfffc45f320f4  (/usr/lib64/libc.so.6+0x820f4)
    #29 0xfffc45f99618  (/usr/lib64/libc.so.6+0xe9618)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/usr/local/sra_inference/lib/neon/libkonnx.so.1+0x96094) 
Thread T149 created by T0 here:
    #0 0xfffc46206f34 in pthread_create (/usr/lib/gcc/aarch64-linux-gnu/10.3.1/libasan.so+0x56f34)
    #1 0xfffb13c4f72c in PosixThread /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/platform/posix/env.cc:183
    #2 0xfffb13c50538 in CreateThread /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/platform/posix/env.cc:267
    #3 0xfffb13c35ea0 in onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>::ThreadPoolTempl(char const*, int, bool, onnxruntime::Env&, onnxruntime::ThreadOptions const&) /root/PycharmProjects/onnxruntime-rel-1.19.2/include/onnxruntime/core/platform/EigenNonBlockingThreadPool.h:799
    #4 0xfffb13c36620 in std::_MakeUniq<onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env> >::__single_object std::make_unique<onnxruntime::concurrency::ThreadPoolTempl<onnxruntime::Env>, char const*&, int&, bool&, onnxruntime::Env&, onnxruntime::ThreadOptions&>(char const*&, int&, bool&, onnxruntime::Env&, onnxruntime::ThreadOptions&) /usr/include/c++/10.3.1/bits/unique_ptr.h:962
    #5 0xfffb13c36620 in onnxruntime::concurrency::ThreadPool::ThreadPool(onnxruntime::Env*, onnxruntime::ThreadOptions const&, char const*, int, bool, bool) /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/common/threadpool.cc:393
    #6 0xfffb135f5a94 in std::_MakeUniq<onnxruntime::concurrency::ThreadPool>::__single_object std::make_unique<onnxruntime::concurrency::ThreadPool, onnxruntime::Env*&, onnxruntime::ThreadOptions&, char const*&, int&, bool&>(onnxruntime::Env*&, onnxruntime::ThreadOptions&, char const*&, int&, bool&) /usr/include/c++/10.3.1/bits/unique_ptr.h:962
    #7 0xfffb135f5a94 in CreateThreadPoolHelper /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/util/thread_utils.cc:159
    #8 0xfffb135f5a94 in onnxruntime::concurrency::CreateThreadPool(onnxruntime::Env*, OrtThreadPoolParams, onnxruntime::concurrency::ThreadPoolType) /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/util/thread_utils.cc:168
    #9 0xfffb11db0868 in onnxruntime::InferenceSession::ConstructorCommon(onnxruntime::SessionOptions const&, onnxruntime::Environment const&) /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/session/inference_session.cc:527
    #10 0xfffb11dcaaa8 in onnxruntime::InferenceSession::InferenceSession(onnxruntime::SessionOptions const&, onnxruntime::Environment const&) /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/core/session/inference_session.cc:642
    #11 0xfffb11c05630 in std::_MakeUniq<onnxruntime::InferenceSession>::__single_object std::make_unique<onnxruntime::InferenceSession, onnxruntime::SessionOptions const&, onnxruntime::Environment&>(onnxruntime::SessionOptions const&, onnxruntime::Environment&) /usr/include/c++/10.3.1/bits/unique_ptr.h:962
    #12 0xfffb11c05630 in onnxruntime::python::PyInferenceSession::PyInferenceSession(std::shared_ptr<onnxruntime::Environment>, OrtSessionOptions const&) /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/python/onnxruntime_pybind_state_common.h:226
    #13 0xfffb11c05630 in std::_MakeUniq<onnxruntime::python::PyInferenceSession>::__single_object std::make_unique<onnxruntime::python::PyInferenceSession, std::shared_ptr<onnxruntime::Environment>, OrtSessionOptions const&>(std::shared_ptr<onnxruntime::Environment>&&, OrtSessionOptions const&) /usr/include/c++/10.3.1/bits/unique_ptr.h:962
    #14 0xfffb11c05630 in operator() /root/PycharmProjects/onnxruntime-rel-1.19.2/onnxruntime/python/onnxruntime_pybind_state.cc:1964
    #15 0xfffb11c067f4 in operator() /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/detail/init.h:303
    #16 0xfffb11c067f4 in call_impl<void, pybind11::detail::initimpl::factory<Func, pybind11::detail::void_type (*)(), Return(Args ...)>::execute<pybind11::class_<onnxruntime::python::PyInferenceSession>, {}>::<lambda(pybind11::detail::value_and_holder&, const OrtSessionOptions&, std::__cxx11::basic_string<char>, bool, bool)>&, 0, 1, 2, 3, 4, pybind11::detail::void_type> /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/cast.h:1624
    #17 0xfffb11c067f4 in call<void, pybind11::detail::void_type, pybind11::detail::initimpl::factory<Func, pybind11::detail::void_type (*)(), Return(Args ...)>::execute<pybind11::class_<onnxruntime::python::PyInferenceSession>, {}>::<lambda(pybind11::detail::value_and_holder&, const OrtSessionOptions&, std::__cxx11::basic_string<char>, bool, bool)>&> /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/cast.h:1598
    #18 0xfffb11c1cc20 in operator() /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/pybind11.h:297
    #19 0xfffb11c1cc20 in _FUN /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/pybind11.h:267
    #20 0xfffb11a8cb40 in pybind11::cpp_function::dispatcher(_object*, _object*, _object*) /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/pybind11.h:987
    #21 0xaaadc54e30a8 in cfunction_call (/root/miniforge3/envs/onnx/bin/python3.9+0x2130a8)
    #22 0xaaadc534d37c in _PyObject_MakeTpCall (/root/miniforge3/envs/onnx/bin/python3.9+0x7d37c)
    #23 0xaaadc54cd808 in method_vectorcall (/root/miniforge3/envs/onnx/bin/python3.9+0x1fd808)
    #24 0xaaadc539ec38 in slot_tp_init (/root/miniforge3/envs/onnx/bin/python3.9+0xcec38)
    #25 0xaaadc5395658 in type_call (/root/miniforge3/envs/onnx/bin/python3.9+0xc5658)
    #26 0xfffb11a856b4 in pybind11_meta_call /root/PycharmProjects/onnxruntime-rel-1.19.2/build_num/RelWithDebInfo/_deps/pybind11_project-src/include/pybind11/detail/class.h:186
    #27 0xaaadc534d37c in _PyObject_MakeTpCall (/root/miniforge3/envs/onnx/bin/python3.9+0x7d37c)
    #28 0xaaadc533eca4 in _PyEval_EvalFrameDefault (/root/miniforge3/envs/onnx/bin/python3.9+0x6eca4)
    #29 0xaaadc53e635c in _PyEval_EvalCode (/root/miniforge3/envs/onnx/bin/python3.9+0x11635c)
    #30 0xaaadc534d188 in _PyFunction_Vectorcall (/root/miniforge3/envs/onnx/bin/python3.9+0x7d188)
    #31 0xaaadc533ccc4 in _PyEval_EvalFrameDefault (/root/miniforge3/envs/onnx/bin/python3.9+0x6ccc4)
    #32 0xaaadc53e635c in _PyEval_EvalCode (/root/miniforge3/envs/onnx/bin/python3.9+0x11635c)
    #33 0xaaadc534d188 in _PyFunction_Vectorcall (/root/miniforge3/envs/onnx/bin/python3.9+0x7d188)
    #34 0xaaadc534d630 in _PyObject_FastCallDictTstate (/root/miniforge3/envs/onnx/bin/python3.9+0x7d630)
    #35 0xaaadc534d8bc in _PyObject_Call_Prepend (/root/miniforge3/envs/onnx/bin/python3.9+0x7d8bc)
    #36 0xaaadc539ecc8 in slot_tp_init (/root/miniforge3/envs/onnx/bin/python3.9+0xcecc8)
    #37 0xaaadc5395658 in type_call (/root/miniforge3/envs/onnx/bin/python3.9+0xc5658)
    #38 0xaaadc534d37c in _PyObject_MakeTpCall (/root/miniforge3/envs/onnx/bin/python3.9+0x7d37c)
    #39 0xaaadc533d454 in _PyEval_EvalFrameDefault (/root/miniforge3/envs/onnx/bin/python3.9+0x6d454)
    #40 0xaaadc53e635c in _PyEval_EvalCode (/root/miniforge3/envs/onnx/bin/python3.9+0x11635c)
    #41 0xaaadc534d188 in _PyFunction_Vectorcall (/root/miniforge3/envs/onnx/bin/python3.9+0x7d188)
    #42 0xaaadc533c2e0 in _PyEval_EvalFrameDefault (/root/miniforge3/envs/onnx/bin/python3.9+0x6c2e0)
    #43 0xaaadc533624c in function_code_fastcall (/root/miniforge3/envs/onnx/bin/python3.9+0x6624c)
    #44 0xaaadc533c2e0 in _PyEval_EvalFrameDefault (/root/miniforge3/envs/onnx/bin/python3.9+0x6c2e0)
    #45 0xaaadc53e635c in _PyEval_EvalCode (/root/miniforge3/envs/onnx/bin/python3.9+0x11635c)
    #46 0xaaadc53e6720 in _PyEval_EvalCodeWithName (/root/miniforge3/envs/onnx/bin/python3.9+0x116720)
    #47 0xaaadc53e6774 in PyEval_EvalCodeEx (/root/miniforge3/envs/onnx/bin/python3.9+0x116774)
    #48 0xaaadc53e67b4 in PyEval_EvalCode (/root/miniforge3/envs/onnx/bin/python3.9+0x1167b4)
    #49 0xaaadc5421f2c in run_eval_code_obj (/root/miniforge3/envs/onnx/bin/python3.9+0x151f2c)
    #50 0xaaadc54221c0 in run_mod (/root/miniforge3/envs/onnx/bin/python3.9+0x1521c0)
    #51 0xaaadc542546c in pyrun_file (/root/miniforge3/envs/onnx/bin/python3.9+0x15546c)
    #52 0xaaadc5425668 in PyRun_SimpleFileExFlags (/root/miniforge3/envs/onnx/bin/python3.9+0x155668)
    #53 0xaaadc53406b4 in Py_RunMain (/root/miniforge3/envs/onnx/bin/python3.9+0x706b4)
    #54 0xaaadc5340d08 in Py_BytesMain (/root/miniforge3/envs/onnx/bin/python3.9+0x70d08)
    #55 0xfffc45edaffc  (/usr/lib64/libc.so.6+0x2affc)
    #56 0xfffc45edb0d4 in __libc_start_main (/usr/lib64/libc.so.6+0x2b0d4)
    #57 0xaaadc533f4dc  (/root/miniforge3/envs/onnx/bin/python3.9+0x6f4dc)
    #58 0xffffda7ff6aa  ([stack]+0x2f6aa)

==643==ABORTING

附件:复现脚本 speed_demo.py

import os
os.environ["ONNX_INTRA_NUM"] = "1"
os.environ["ONNX_INTER_NUM"] = "1"


import torch
import torchvision.models as models
import onnxruntime as ort
import time
import os
import numpy as np
import faulthandler
from tqdm import trange

def benchmark_pytorch(model, dummy_input, device, num_runs=100, warmup=10):
    """测试 PyTorch 模型的推理速度"""
    model.eval()
    model.to(device)
    dummy_input = dummy_input.to(device)

    with torch.no_grad():
        # 预热 (Warmup) 避免冷启动影响
        for _ in range(warmup):
            _ = model(dummy_input)

        # 测速
        if device.type == 'cuda':
            torch.cuda.synchronize()
        start_time = time.perf_counter()

        for _ in range(num_runs):
            _ = model(dummy_input)

        if device.type == 'cuda':
            torch.cuda.synchronize()
        end_time = time.perf_counter()

    avg_time = (end_time - start_time) / num_runs * 1000  # 转换为毫秒 (ms)
    return avg_time

def benchmark_onnx(onnx_path, dummy_input_np, num_runs=100, warmup=10):
    """测试 ONNX Runtime 的推理速度"""
    # 配置 ONNX Runtime 会话选项
    options = ort.SessionOptions()
    # 2. 限制算子内部和算子之间的线程数
    
    options.intra_op_num_threads = 128  # 控制单个算子内的线程数(建议先设为 1 测试)
    # options.inter_op_num_threads = 4  # 控制执行不同算子的线程数(建议先设为 1 测试)
    options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
    
    # 默认使用 CPU 执行提供者进行基准测试
    # 如果需要测试 GPU,可以改为 ['CUDAExecutionProvider', 'CPUExecutionProvider']
    providers = ['CPUExecutionProvider'] 
    
    session = ort.InferenceSession(onnx_path, sess_options=options, providers=providers)
    input_name = session.get_inputs()[0].name

    # 预热
    for _ in range(warmup):
        _ = session.run(None, {input_name: dummy_input_np})

    # 测速
    start_time = time.perf_counter()
    for _ in trange(num_runs):
        _ = session.run(None, {input_name: dummy_input_np})
    end_time = time.perf_counter()

    avg_time = (end_time - start_time) / num_runs * 1000  # ms
    return avg_time

def main():
    # 优先使用 GPU 测试 PyTorch,如果只有 CPU 则使用 CPU
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    print(f"PyTorch 运行设备: {device}")

    # 1. 定义要测试的模型字典 (自动从 torchvision 下载预训练权重)
    # 对于 Transformer,我们使用标准的 Vision Transformer (ViT-B/16)
    model_configs = {
        # "MobileNet_V3_Small": models.mobilenet_v3_small(weights='DEFAULT'),
        # "ResNet101": models.resnet101(weights='DEFAULT'),
        "ViT_B_16": models.vit_b_16(weights='DEFAULT') 
    }

    # 计算机视觉标准输入尺寸 [B, C, H, W]
    dummy_input = torch.randn(1, 3, 224, 224)
    dummy_input_np = dummy_input.numpy()

    for model_name, model in model_configs.items():
        print(f"\n{'='*50}")
        print(f"🚀 开始测试模型: {model_name}")
        print(f"{'='*50}")

        # # === 阶段一:PyTorch 测速 ===
        # pt_time = benchmark_pytorch(model, dummy_input, device)
        # print(f"[PyTorch] 平均推理耗时: {pt_time:.2f} ms")

        # === 阶段二:导出为 ONNX ===
        onnx_path = f"{model_name}.onnx"
        if not os.path.exists(onnx_path):
            print(f"[ONNX] 文件不存在,正在导出至 {onnx_path}...")
            model.eval()
            model.cpu() # 确保在 CPU 上进行导出以保证跨平台兼容性
            
            torch.onnx.export(
                model,
                torch.randn(1, 3, 224, 224), # 导出时重新生成 CPU tensor
                onnx_path,
                export_params=True,
                opset_version=14,            # ViT 等较新模型推荐使用较高的 opset (13或14)
                do_constant_folding=True,
                input_names=['input'],
                output_names=['output'],
                dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}}
            )
            print(f"[ONNX] 导出成功!文件大小: {os.path.getsize(onnx_path) / (1024 * 1024):.2f} MB")
        else:
            print(f"[ONNX] 检测到文件 {onnx_path} 已存在,跳过导出步骤。")

        # === 阶段三:ONNX Runtime 测速 ===
        try:
            ort_time = benchmark_onnx(onnx_path, dummy_input_np)
            print(f"[ONNX Runtime (CPU)] 平均推理耗时: {ort_time:.2f} ms")
        except Exception as e:
            print(f"[ONNX Runtime] 测速失败: {e}")

if __name__ == "__main__":
    # 启用故障处理
    faulthandler.enable()

    main()

本帖最后由 匿名用户2026/04/08 13:02:54 编辑

我要发帖子