ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【Bug已解决】[Build] ONNX fails to build with CUDA 13.3 解决方案

【Bug已解决】[Build] ONNX fails to build with CUDA 13.3 解决方案 【Bug已解决】[Build] ONNX fails to build with CUDA 13.3 解决方案一、现象长什么样用 CUDA 13.3 工具链驱动/SDK/nvcc 13.3编译 ONNX Runtime带 CUDA EP编译直接失败报一系列与 CUDA API 相关的错误/ort/core/providers/cuda/.../foo.cu: error: some_deprecated_api was not declared in this scope /ort/.../nvrtc_helper.cpp: error: no matching function for call to nvrtcCompileProgram (签名变了) error: namespace cuda does not contain some_symbol (CUDA 13.3 挪走/改名)最小信号CUDA 12.x 编译通过CUDA 13.3 编译失败 失败集中在 CUDA EP 的 .cu / nvrtc 辅助代码 报“未声明符号 / 函数签名不匹配 / 头文件找不到”注意这是构建失败编译期不是运行时。CUDA 13.3 相对 12.x 改了部分 API/头文件ORT 的旧 CUDA 代码不兼容。二、背景NVIDIA 每次 CUDA 大版本尤其 12.x - 13.x都会废弃/移除一批旧 API如某些cuda*函数被合并或改名改动 nvrtc / nvrtc 编译接口签名调整头文件组织某些符号从cuda_runtime.h挪到更细的头或命名空间变化新增 compute capability 处理新架构的 PTX/SM 要求。ONNX Runtime 的 CUDA EP 大量直接调用这些 CUDA APIkernel launch、nvrtc 即时编译、memory 管理、graph capture。当 CUDA 13.3 改了上述接口ORT 代码里引用旧符号/旧签名的地方就编译不过。典型冲突点nvrtcCompileProgram在 13.x 可能要求新的nvrtcProgram创建方式或选项格式某些cuda*函数被标 deprecated 并在 13.3 默认移除需要新的替代 API 或加宏允许 deprecatedCUDA 13 的cuda_runtime头对 C 标准/编译器版本更严格触发原本被容忍的写法报错。三、根因根因是ONNX Runtime 的 CUDA EP 代码引用了 CUDA 13.3 已废弃/改名的 API 与头文件且 nvrtc 调用签名未更新导致编译失败废弃 API 未迁移代码里用的cuda*函数在 13.3 被移除ORT 没切到新替代 API或没定义允许 deprecated 的宏。nvrtc 签名不匹配nvrtcCompileProgram等调用按旧签名写13.3 改了参数/选项枚举编译报“无匹配函数”。头文件/命名空间变动某些符号换了头或命名空间旧#include找不到。不是运行时错纯编译期符号/签名不兼容CUDA 12.x 能过说明是版本鸿沟。所以这不是逻辑错而是ORT 的 CUDA 代码没跟上 CUDA 13.3 的 API 变更构建断在编译期。四、最小可运行复现下面用 C 伪代码模拟“调用已废弃/改名的 API 导致编译失败”// 假设 CUDA 12.x 有这个 API // cudaError_t cudaOldLaunch(void* f, dim3 g, dim3 b, void* args, size_t s, cudaStream_t st); // CUDA 13.3 把它移除/改名成 cudaLaunchKernelEx旧符号不存在 // ORT 旧代码仍调用 cudaOldLaunch - 编译报 “was not declared in this scope” // 兼容写法用宏根据 CUDA 版本切换 #if CUDA_VERSION 13000 // CUDA 13.3 新 API cudaLaunchKernelEx(cfg, f, args, /*ext*/nullptr); #else // 旧 API12.x cudaOldLaunch(f, grid, block, args, shared, stream); #endif真实场景里ORT 需要在所有直接调用 CUDA API 的地方加#if CUDA_VERSION ...的版本分支或迁移到新版 API才能用 13.3 编译。这复现了“旧 API 引用导致新 CUDA 编译失败”的机制。五、解决方案第一层最小直接修复最小修复更新 ORT 的 CUDA EP 代码以兼容 CUDA 13.3—— 把所有 13.3 不兼容的调用切到新 API或用版本宏隔离。对使用者只想编过临时规避是继续用 CUDA 12.x 工具链编译功能等价只是不是最新 CUDA# 临时用 CUDA 12.x 构建 ORT绕开 13.3 不兼容 export CUDA_HOME/usr/local/cuda-12.8 ./build.sh --use_cuda --cuda_home $CUDA_HOME对 ORT 仓库侧修复是系统性的// 对每一处不兼容调用做版本隔离 #if CUDA_VERSION 13000 // 13.3 新接口nvrtc 新签名、新 cuda* API NVRTC_CHECK(nvrtcCompileProgram(prog, numOpts, opts)); // 更新签名 #else // 旧接口 NVRTC_CHECK(nvrtcCompileProgram(prog, numOpts, opts)); // 旧签名 #endif // 对废弃 cuda* API定义允许 deprecated 或迁移到新 API #define CUDA_DEPRECATED_ENABLE // 或改用 cudaLaunchKernelEx这一层立刻让 ORT 用 CUDA 13.3 编过。六、解决方案第二层结构性改进把“ORT 支持的 CUDA 版本及对应 API 分支”收口成唯一的配置对象OrtBuildCuda133Policy构建脚本与代码读它from dataclasses import dataclass, field from typing import Tuple, Dict dataclass(frozenTrue) class OrtBuildCuda133Policy: ORT 兼容 CUDA 13.3 构建的单一事实来源。 # 支持的 CUDA 主版本 supported_cuda_versions: Tuple[int, ...] (120, 128, 130) # 每个大版本需要隔离的 API 清单 version_guarded_apis: Tuple[str, ...] ( nvrtcCompileProgram, cudaLaunchKernelEx, cudaGraphInstantiate, ) # 是否允许 deprecated API过渡期 allow_deprecated: bool True # 废弃 API - 新 API 映射 api_migration: Dict[str, str] field(default_factorylambda: { cudaOldLaunch: cudaLaunchKernelEx, }) def is_supported(self, cuda_major: int) - bool: return cuda_major in self.supported_cuda_versions def describe(self) - str: return CUDA 13.3 构建需版本隔离 nvrtc/cuda API迁移废弃符号 POLICY OrtBuildCuda133Policy() def plan_cuda_build(cuda_major: int, policy: OrtBuildCuda133Policy POLICY) - dict: if not policy.is_supported(cuda_major): raise RuntimeError(fCUDA {cuda_major} 未列支持) return {guarded: policy.version_guarded_apis, migrate: policy.api_migration}所有 CUDA 构建与代码读同一份POLICY版本兼容分支被固化新增 CUDA 版本必须登记。七、解决方案第三层断言 / CI 守护把“CUDA 13.3 能编过、API 分支正确”做成断言。下面用 pytest 风格守护import pytest def test_cuda_133_supported(policy): assert policy.is_supported(130) is True assert policy.is_supported(128) is True def test_nvrtc_guarded(policy): assert nvrtcCompileProgram in policy.version_guarded_apis def test_deprecated_migrated(policy): assert cudaOldLaunch in policy.api_migration assert policy.api_migration[cudaOldLaunch] cudaLaunchKernelEx def test_build_with_133_passes(policy): plan plan_cuda_build(130, policy) assert nvrtcCompileProgram in plan[guarded]这四组断言锁住(1) CUDA 13.3 在支持列表(2) nvrtc 被版本隔离(3) 废弃 API 有迁移映射(4) 13.3 构建规划正确。CI 跑通即代表 CUDA 13.3 构建被守护。八、排查清单遇到 ORT 用 CUDA 13.3 编译失败看报错是不是 CUDA API 符号/签名问题是 - 锁定版本不兼容。对比 CUDA 12.x12.x 能编、13.3 不能 - 确认是 13.3 API 变更。查具体废弃/改名 APInvrtc、cudaLaunchKernelEx、cudaGraphInstantiate 等。临时规避用 CUDA 12.x 工具链构建。根本修复所有不兼容调用加#if CUDA_VERSION分支或迁移新 API。统一策略对象用OrtBuildCuda133Policy固化版本支持。CI 守护断言 CUDA 13.3 在支持列表、API 分支正确。九、小结[Build] ONNX fails to build with CUDA 13.3的根因是CUDA 13.3 相比 12.x 废弃/改名了部分 API、改了 nvrtc 编译签名、调整了头文件组织而 ONNX Runtime 的 CUDA EP 代码仍引用旧符号/旧签名导致编译期“未声明符号 / 函数签名不匹配”而失败。最小修复是更新 ORT 的 CUDA 代码以兼容 13.3版本隔离或迁移新 API临时规避是用 CUDA 12.x 工具链构建结构性改进是用唯一的OrtBuildCuda133Policy固化支持的 CUDA 版本与 API 分支CI 用四组断言守护“13.3 支持、nvrtc 隔离、废弃有迁移、构建规划正确”。记住CUDA 大版本会改 API直接调用 cuda/nvrtc 的代码必须按版本隔离否则新版工具链一编就挂。
返回列表