mirroredstrategy报“no gpus found”主因是tensorflow未识别gpu,需先用tf.config.list_physical_devices('gpu')确认可见性,再检查cuda/cudnn版本匹配、驱动更新及是否安装了cpu-only版tensorflow。

为什么 MirroredStrategy 会报 “No GPUs found”
TensorFlow 的 MirroredStrategy 默认只在有可用 GPU 且 CUDA 环境正确时才激活多卡训练;如果看到 ValueError: No GPUs found 或策略实际退化为单卡,大概率是底层没识别到 GPU 设备。不是代码写错了,而是 tf.config.list_physical_devices('GPU') 返回空列表。需要先验证 CUDA/cuDNN 版本是否与 TensorFlow 编译版本严格匹配(比如 TF 2.15 要求 CUDA 12.2 + cuDNN 8.9),且 nvidia-smi 能正常显示显卡。Windows 用户尤其注意:WSL2 下的 GPU 支持需额外开启,原生 Windows 环境下必须安装 NVIDIA 驱动 + CUDA Toolkit,不能只靠 conda 安装 cudatoolkit 包。
如何正确初始化 MirroredStrategy 并包裹模型构建
MirroredStrategy 必须在任何张量、模型或变量创建前就初始化,否则会报 RuntimeError: Strategy has not been initialized。它不是装饰器,也不是后期注入工具,而是一个上下文管理器式的执行环境控制器。
- 用
strategy = tf.distribute.MirroredStrategy()创建实例(不传参数即自动检测所有可见 GPU) - 模型定义、数据集构建、编译等操作必须放在
with strategy.scope():块内 - 不能在
scope外创建tf.keras.Model实例再传入——那样权重不会被复制到各卡
示例关键片段:
strategy = tf.distribute.MirroredStrategy()
print('Number of devices: {}'.format(strategy.num_replicas_in_sync))
<p>with strategy.scope():
model = tf.keras.Sequential([tf.keras.layers.Dense(10)])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
</p>
数据集必须用 strategy.experimental_distribute_dataset 包装吗
不一定。对于标准 tf.data.Dataset 流水线,只要满足两个条件:batch_size 是 num_replicas_in_sync 的整数倍,且调用 model.fit(dataset) 时 dataset 已经 batch() 过,TensorFlow 内部会自动切分 batch 到各 GPU。但若要手动控制分发逻辑(比如做自定义预处理或非均匀 batch),就得显式调用 strategy.experimental_distribute_dataset(dataset)。注意:该方法返回的是 DistributedDataset,不能直接取 .numpy() 或遍历,只能喂给 strategy.run() 或模型训练接口。
- 推荐做法:用
global_batch_size = per_replica_batch_size * strategy.num_replicas_in_sync设置 batch - 避免在 dataset map 中调用
tf.py_function,容易因 GIL 或设备绑定导致死锁 - 使用
dataset.cache().prefetch(tf.data.AUTOTUNE)提升多卡吞吐,否则 I/O 可能成为瓶颈
训练后保存和加载模型要注意什么
用 MirroredStrategy 训练出的模型,model.save() 默认保存的是全局视角的权重(已聚合),可以直接用 tf.keras.models.load_model() 加载,无需策略上下文。但如果你用的是 model.save_weights_only=True,且保存路径是本地文件系统(非 GCS/S3),那没问题;若保存到分布式文件系统,得确保所有 worker 都有读写权限。另外,加载后如需继续训练,仍需在 strategy.scope() 中重建模型并调用 load_weights(),否则权重不会被广播到各副本。
- 保存时优先用
save_format='tf'(即 SavedModel 格式),比 h5 更兼容分布式场景 - 不要在
strategy.run()内部调用model.save(),会导致多进程重复写同一路径 - 检查
strategy.num_replicas_in_sync是否始终等于你物理 GPU 数——有时 Docker 或云环境会限制可见设备数
真正麻烦的从来不是写几行 strategy.scope(),而是环境一致性、batch 尺寸对齐、以及数据管道是否真的被均匀打散到了每张卡上。跑通第一轮训练后,务必用 nvidia-smi 观察各卡显存和利用率是否接近,否则很可能某张卡空转。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











