原帖 torch.cuda.is_available() 为 True,却在 torch.utils.cpp_extension 构建路径中失败:
OSError: CUDA_HOME environment variable is not set. Please set it to your CUDA install root.
is_available 检查的是运行能力
原帖堆栈来自 cpp_extension 的 CUDA 根目录拼接,已经进入本地构建流程。运行预编译算子成功,并不能证明系统有 nvcc 与开发头文件。应先证明哪个 Toolkit 安装是完整的,再把根目录告诉构建进程。
运行已编译好的 torch,和在本机编译 CUDA 扩展,需要的东西不同。前者可以使用随包分发的运行库;后者通常还需要包含 nvcc、头文件和开发库的 CUDA Toolkit。
先在构建扩展使用的同一 Python 进程中检查:
import os
import sys
import shutil
import torch
print("josh050608")
print("python:", sys.executable)
print("torch CUDA:", torch.version.cuda)
print("CUDA_HOME env:", os.environ.get("CUDA_HOME"))
print("nvcc:", shutil.which("nvcc"))
若找不到 nvcc,不能凭 conda 环境里有运行库就随便设置 CUDA_HOME。先安装与扩展和 torch 构建兼容的 Toolkit;也检查项目是否提供可用的预编译扩展,避免不必要编译。
若已安装完整 Toolkit,在 Linux 构建终端把 CUDA_HOME 指向真实安装根目录。例如确认 /usr/local/cuda-11.8/bin/nvcc 存在后:
export CUDA_HOME=/usr/local/cuda-11.8
export PATH="$CUDA_HOME/bin:$PATH"
nvcc --version
CUDA_HOME 应是单个 Toolkit 根目录,不要像 PATH 那样把多个目录用冒号拼接进去。上面的 11.8 是路径示例,不能据此认定原帖需要这个版本。先查 torch.version.cuda 与扩展要求,再选实际版本。环境变量应在导入 cpp_extension、启动构建进程之前设置;Notebook 修改后可能需要重启进程。
验证 python -c "from torch.utils.cpp_extension import CUDA_HOME; print(CUDA_HOME)" 返回预期目录,再重新构建原扩展。若出现编译器或 CUDA 版本不一致错误,应沿新错误继续处理,不能把 CUDA_HOME 有值等同于编译工具链完整。
CUDA_HOME 应指向根目录,而不是 bin 或库文件
若终端 which nvcc 返回 /usr/local/cuda-11.8/bin/nvcc,CUDA_HOME 示例是 /usr/local/cuda-11.8,不是 .../bin。系统多版本并存时,检查实际执行的 nvcc 以及 CUDA_HOME/bin/nvcc --version 是否一致,避免 PATH 和环境变量指向不同版本。
下面标准库片段只检查路径是否齐全,不调用编译器。把环境变量设置好后,在同一个构建终端运行:
import os
from pathlib import Path
root_text = os.environ.get("CUDA_HOME")
if root_text:
root = Path(root_text)
executable = root / "bin" / ("nvcc.exe" if os.name == "nt" else "nvcc")
print("root:", root.resolve())
print("nvcc exists:", executable.is_file())
print("include exists:", (root / "include").is_dir())
else:
print("CUDA_HOME is not set in this process")
这些文件存在只是必要检查,不能证明编译器版本与扩展兼容。继续核对 torch.version.cuda、nvcc 版本、C++ 编译器以及目标 GPU 架构支持。若项目提供与本机 torch/Python 匹配的预编译 wheel,可以选择它,避免本地构建依赖;但不应下载来源不明的二进制来填空。
环境变量必须传入真正启动构建的进程。Notebook 中先导入 cpp_extension,再改环境,可能仍使用模块初始化时缓存的路径;重启 kernel 并在导入前设置更容易验证。最后以实际扩展构建和一个最小扩展调用为验收,而不是仅看到 CUDA_HOME 打印了字符串。
参考:原始求助帖;技术依据:PyTorch C++/CUDA 扩展(2.5)、PyTorch CUDA 语义(2.5)。