必须在import torch前设置os.environ["cuda_visible_devices"],否则cuda上下文初始化失败导致torch.cuda.is_available()返回false;jupyter中%env或reload均无效,需重启内核。

在 Jupyter Notebook 里设环境变量,必须在 import 任何可能依赖它的库之前执行 os.environ 赋值,否则大概率不生效。
为什么 os.environ 设置后 torch.cuda.is_available() 还是 False?
常见于 PyTorch、Hugging Face、LangChain 等包——它们在模块首次 import 时就检查环境变量(比如 CUDA_VISIBLE_DEVICES、HF_ENDPOINT),之后再改 os.environ 已经晚了。
- 错误写法:
import torch; os.environ["CUDA_VISIBLE_DEVICES"] = "0"→torch.cuda.is_available()仍为False - 正确顺序:先设
os.environ,再import torch - 如果已 import 过,重启内核是唯一可靠方式;单纯 reload 模块风险高、不推荐
- 特别注意:Jupyter 内核启动时会预加载部分模块(如
numpy),所以越早设置越安全
%env 魔术命令和 os.environ 的区别在哪?
%env 是 IPython 提供的 shell 级环境变量设置,只影响当前 notebook 进程的 os.environ 副本,但对子进程(如 subprocess.run)或已加载模块无效;而直接操作 os.environ 更底层,但同样受限于“时机”。
-
%env CUDA_VISIBLE_DEVICES=1,2→ 等价于os.environ["CUDA_VISIBLE_DEVICES"] = "1,2",但不能替代 import 前设置 -
%env无法设置需要 shell 解析的变量(如带空格或特殊字符的路径),此时必须用os.environ - 若需传给子进程(比如调用
!pip install或subprocess.Popen),os.environ更可靠
远程服务器上启动前怎么预设环境变量?
当你通过 ssh 登录服务器手动启动 jupyter notebook,又需要加载 conda/cuda 环境时,不能只靠 notebook 里写代码——得在启动命令前完成环境准备。
- 先 source 环境脚本:
source /path/to/env.sh && conda activate myenv - 再设变量并启动:
CUDA_VISIBLE_DEVICES=3 PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 jupyter notebook --no-browser --port=8888 --ip=0.0.0.0 - 避免用
%env或os.environ替代这一步:它们无法影响 Jupyter 主进程的 CUDA 上下文初始化 - 如果用 VS Code 远程连接,确保 Remote-SSH 的
~/.bashrc或~/.profile中已导出关键变量(如export HF_ENDPOINT=https://hf-mirror.com)
最容易被忽略的是:环境变量不是“设了就全局生效”,它是一次性快照。Jupyter 内核一旦启动,其初始环境就固定了;后续修改只影响新创建的对象或子进程,旧模块(尤其是 C 扩展)完全感知不到。











