离线安装TensorFlow失败主因是pip自动补缺依赖,非网络问题;需手动下载并安装gast、protobuf、tensorboard等全部精确版本依赖包。

离线安装 TensorFlow 的核心不是“装一个包”,而是“装一整条依赖链”——漏掉任何一个 gast、protobuf 或 tensorboard 的精确版本,pip install tensorflow-1.15.0-cp37-cp37m-manylinux2010_x86_64.whl 就会当场失败。
为什么直接 pip install xxx.whl 会报 NewConnectionError
这不是网络问题,是 pip 在“自动补缺”:它看到你装的 tensorflow_gpu-1.15.0 声明了依赖 gast>=0.2.0, ,但本地没有,就试图连 PyPI 去找 <code>gast —— 离线环境当然连不上。错误里出现的 /simple/gast/ 就是 pip 正在拼的 URL 路径。
- 所有依赖必须提前下载好,不能靠 pip 在离线时“现场解析”
- 必须用
--no-index关闭远程索引,否则 pip 仍会尝试连接 - 必须用
--find-links指向本地 whl 目录,且该目录要包含全部递归依赖(不止第一层) - 不同 TensorFlow 版本对
numpy、absl-py等有隐式版本约束,比如tensorflow==1.15.0实际要求numpy,装高了会 import 失败
怎么拿到完整依赖列表(不靠联网机器对比)
最可靠的方式是反向解析目标 whl 文件的 METADATA,而不是靠 pip freeze 或 comm 差异比对——后者在 CPU/GPU、Linux/Windows、Python 小版本之间极易出错。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 下载目标 whl 后,用
unzip -l tensorflow_gpu-1.15.0-cp37-cp37m-manylinux2010_x86_64.whl | grep METADATA找到tensorflow_gpu-1.15.0.dist-info/METADATA - 解压并查看其中的
Requires-Dist字段,例如:Requires-Dist: gast (>=0.2.0, - 对每个依赖项,再下载其对应 whl,重复解析,直到所有
Requires-Dist都能在本地目录中找到匹配文件 - 特别注意
protobuf:TensorFlow 1.x 强制要求protobuf,但很多镜像默认只提供 4.x,必须手动指定旧版如 <code>protobuf-3.20.3-py3-none-any.whl
安装命令和路径写法容易错在哪
--find-links 的路径必须是绝对路径,且末尾不能加斜杠;file:// 协议在某些 pip 版本下不可靠,直接用 file: 前缀反而更稳。
立即学习“Python免费学习笔记(深入)”;
- 正确写法:
pip install tensorflow_gpu-1.15.0-cp37-cp37m-manylinux2010_x86_64.whl --no-index --find-links /path/to/wheels - 错误写法:
--find-links ./wheels/(相对路径 + 斜杠)、--find-links file:///path/to/wheels(三斜杠易触发权限拒绝) - 如果提示
ERROR: Could not find a version that satisfies the requirement xxx,说明该包的 whl 文件名不匹配当前 Python 平台标签(如cp37m对应 Python 3.7,但你的 Python 是 3.7.16 且编译时用了cp37标签),需检查python -c "import sysconfig; print(sysconfig.get_platform())" - 安装后运行
python -c "import tensorflow as tf; print(tf.__version__)"成功,不代表 GPU 可用——还需验证tf.test.is_gpu_available(),这又依赖cudnn和cuda的系统级离线安装,不在 pip 管理范围内
真正麻烦的从来不是下载多少个 whl,而是每个包的平台标签、Python ABI 标签、依赖版本范围三者必须严丝合缝;少一个 manylinux2010_x86_64,多一个 py3-none-any,都可能让整个链在最后一环断掉。

















