【Bug已解决】In Colaboratory, CUDA cannot be used for Pytorch 解决方案问题描述Google ColaboratoryColab是深度学习领域最受欢迎的免费 GPU 云端开发环境之一。然而许多开发者在使用 PyTorch 时会遇到 CUDA 不可用的问题表现为以下几种典型场景torch.cuda.is_available()返回False尝试将模型或数据移到 GPU 时报错AssertionError: Torch not compiled with CUDA enabledColab 分配的 GPU 无法被 PyTorch 识别安装 PyTorch 后 CUDA 版本不匹配运行 GPU 代码时出现CUDA error: no kernel image is available for execution on the device这些问题的根源通常不是单一的而是涉及 Colab 的运行时配置、PyTorch 安装方式、CUDA 版本兼容性、以及 Colab 后端 GPU 类型等多个因素。本文将系统性地分析每种情况并提供完整的诊断和修复方案。错误复现错误场景一torch.cuda.is_available() 返回 Falseimport torch print(fPyTorch version: {torch.__version__}) print(fCUDA available: {torch.cuda.is_available()}) # False print(fCUDA version: {torch.version.cuda}) # None 或版本不匹配输出PyTorch version: 2.0.1 CUDA available: False CUDA version: None错误场景二尝试使用 GPU 时报错import torch # 尝试将张量移到 GPU x torch.randn(10, 10) try: x x.cuda() except Exception as e: print(fError: {e}) # AssertionError: Torch not compiled with CUDA enabled # 或 RuntimeError: CUDA is not available错误场景三CUDA 版本不匹配import torch # 安装了 CPU 版本的 PyTorch print(torch.__version__) # 2.0.1cpu # 或者 CUDA 版本不匹配 try: model torch.nn.Linear(100, 10).cuda() x torch.randn(32, 100).cuda() output model(x) except RuntimeError as e: print(fError: {e}) # CUDA error: no kernel image is available for execution on the device错误场景四Colab 运行时类型未更改# 在 Colab 中默认运行时是 CPU-only import torch print(fDevice: {torch.cuda.get_device_name(0) if torch.cuda.is_available() else CPU}) # 输出: Device: CPU根因分析1. Colab 运行时类型未设置为 GPUColab 默认分配 CPU 运行时。用户需要手动将运行时类型更改为 GPU操作路径运行时→更改运行时类型→硬件加速器→ 选择T4 GPU或其他 GPU 选项这是最常见的原因。如果运行时类型是NoneCPU无论怎么安装 PyTorchCUDA 都不可用。2. 安装了 CPU 版本的 PyTorch在 Colab 中默认安装的 PyTorch 可能是 CPU 版本。或者用户通过pip install torch安装时pip 可能根据系统环境选择 CPU 版本。# 检查安装的 PyTorch 版本 import torch print(torch.__version__) # 如果输出包含 cpu说明安装的是 CPU 版本 # 例如: 2.0.1cpu3. CUDA 版本不匹配Colab 的 CUDA 驱动版本和 PyTorch 编译时使用的 CUDA 版本需要兼容。如果安装了错误版本的 PyTorch可能导致 CUDA 不可用或运行时错误。Colab CUDA 驱动版本: 12.x PyTorch 编译 CUDA 版本: 11.8 或 12.1PyTorch 对 CUDA 版本有向后兼容性较新的驱动可以运行较旧的 CUDA 运行时但不保证向前兼容。4. CUDA 架构不匹配Colab 提供的 GPU 类型会变化T4, V100, A100, L4 等。不同 GPU 有不同的计算能力Compute Capability。如果安装的 PyTorch 没有包含对应 GPU 架构的内核会报no kernel image is available错误。GPU计算能力架构名T47.5TuringV1007.0VoltaA1008.0AmpereL48.9Ada5. Colab 环境重置Colab 的运行时会在一段时间不活动后断开重新连接时可能分配不同的 GPU。如果之前安装的 PyTorch 版本与新的 GPU 不兼容就会出现问题。6. 混合安装导致冲突在 Colab 中如果先通过pip install torch安装了 CPU 版本然后又通过conda install或其他方式安装了 GPU 版本可能导致环境冲突。解决方案方案一正确设置 Colab 运行时类型这是最基本也是最重要的步骤在 Colab 菜单栏点击运行时Runtime选择更改运行时类型Change runtime type在硬件加速器Hardware accelerator中选择T4 GPU点击保存Save运行时会重新启动验证import torch # 验证 GPU 是否可用 print(fCUDA available: {torch.cuda.is_available()}) print(fGPU device count: {torch.cuda.device_count()}) if torch.cuda.is_available(): print(fGPU name: {torch.cuda.get_device_name(0)}) print(fGPU capability: {torch.cuda.get_device_capability(0)}) print(fCUDA version: {torch.version.cuda})方案二正确安装 GPU 版本的 PyTorch如果默认安装的是 CPU 版本需要重新安装 GPU 版本# 在 Colab 单元格中运行 # 方法1使用 pip 安装指定 CUDA 版本的 PyTorch # 对于 CUDA 12.1 !pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # 对于 CUDA 11.8 # !pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装后需要重启运行时 # 运行时 - 重启运行时# 方法2检查并修复安装 import subprocess import sys def ensure_gpu_pytorch(): 确保安装了 GPU 版本的 PyTorch import torch if torch.cuda.is_available(): print(fPyTorch GPU is already available: {torch.__version__}) print(fGPU: {torch.cuda.get_device_name(0)}) return True print(fCurrent PyTorch version: {torch.__version__}) if cpu in torch.__version__: print(CPU-only PyTorch detected. Reinstalling GPU version...) # 卸载 CPU 版本 subprocess.check_call([sys.executable, -m, pip, uninstall, torch, torchvision, torchaudio, -y]) # 安装 GPU 版本 subprocess.check_call([sys.executable, -m, pip, install, torch, torchvision, torchaudio, --index-url, https://download.pytorch.org/whl/cu121]) print(Please restart the runtime and run again.) return False print(Unknown issue. Check Colab runtime type (Runtime - Change runtime type - GPU)) return False ensure_gpu_pytorch()方案三完整的 Colab GPU 环境检查脚本import torch import subprocess import sys import os def full_gpu_diagnostic(): 完整的 GPU 环境诊断 print( * 60) print(GPU Environment Diagnostic) print( * 60) # 1. PyTorch 版本 print(f\n1. PyTorch version: {torch.__version__}) print(f CUDA compiled version: {torch.version.cuda}) print(f cuDNN version: {torch.backends.cudnn.version()}) # 2. CUDA 可用性 print(f\n2. CUDA available: {torch.cuda.is_available()}) if torch.cuda.is_available(): print(f Device count: {torch.cuda.device_count()}) print(f Current device: {torch.cuda.current_device()}) print(f Device name: {torch.cuda.get_device_name(0)}) print(f Device capability: {torch.cuda.get_device_capability(0)}) # GPU 内存 props torch.cuda.get_device_properties(0) print(f Total memory: {props.total_mem / 1024**3:.2f} GB) print(f Multi-processors: {props.multi_processor_count}) # 3. 测试 GPU 计算 print(\n3. Testing GPU computation...) try: x torch.randn(1000, 1000, devicecuda) y torch.randn(1000, 1000, devicecuda) z torch.mm(x, y) torch.cuda.synchronize() print(f GPU computation test: PASSED) print(f Result shape: {z.shape}, Device: {z.device}) except Exception as e: print(f GPU computation test: FAILED - {e}) else: print(\n CUDA is NOT available. Possible causes:) print( a) Colab runtime type is not set to GPU) print( b) PyTorch is CPU-only version (check for cpu in version)) print( c) CUDA version mismatch) # 检查 nvidia-smi print(\n4. Checking nvidia-smi...) try: result subprocess.run([nvidia-smi], capture_outputTrue, textTrue) if result.returncode 0: print( nvidia-smi output:) for line in result.stdout.split(\n)[:10]: print(f {line}) else: print( nvidia-smi not found. GPU runtime may not be active.) except FileNotFoundError: print( nvidia-smi not found. GPU runtime may not be active.) # 5. 检查 PyTorch 安装来源 print(\n5. PyTorch installation info:) try: import torch.version print(f CUDA: {torch.version.cuda}) print(f Git hash: {torch.version.git_version}) except: pass print(\n * 60) # 运行诊断 full_gpu_diagnostic()方案四处理 CUDA 架构不匹配import torch import os def fix_cuda_arch_mismatch(): 处理 CUDA 架构不匹配问题 if not torch.cuda.is_available(): print(CUDA not available. Cannot fix architecture mismatch.) return # 获取当前 GPU 的计算能力 major, minor torch.cuda.get_device_capability(0) gpu_arch fsm_{major}{minor} print(fGPU compute capability: {major}.{minor} ({gpu_arch})) # 检查 PyTorch 支持的架构 supported_archs torch.cuda.get_arch_list() print(fPyTorch compiled for architectures: {supported_archs}) if gpu_arch not in supported_archs: print(fWARNING: {gpu_arch} not in compiled architectures!) print(This may cause no kernel image available errors.) print(Solution: Reinstall PyTorch with correct CUDA support.) # 设置环境变量强制使用兼容架构 os.environ[TORCH_CUDA_ARCH_LIST] gpu_arch print(fSet TORCH_CUDA_ARCH_LIST{gpu_arch}) else: print(fArchitecture {gpu_arch} is supported.) # 测试 try: x torch.randn(100, 100, devicecuda) y torch.mm(x, x) print(fGPU computation test: PASSED) except RuntimeError as e: print(fGPU computation test: FAILED - {e}) fix_cuda_arch_mismatch()完整修复代码以下是一个完整的 Colab PyTorch GPU 环境配置和训练脚本# # Colab PyTorch GPU 环境配置和训练完整脚本 # 在 Google Colab 中逐单元格运行 # # 单元格 1: 环境检查和修复 import torch import subprocess import sys import os class ColabGPUSetup: Colab GPU 环境自动配置工具。 staticmethod def check_runtime(): 检查 Colab 运行时类型 print(--- Runtime Check ---) # 检查 nvidia-smi try: result subprocess.run([nvidia-smi, --query-gpuname,driver_version,memory.total, --formatcsv,noheader], capture_outputTrue, textTrue) if result.returncode 0: print(fGPU detected: {result.stdout.strip()}) return True else: print(No GPU detected via nvidia-smi) except FileNotFoundError: print(nvidia-smi not found) print(\nTo enable GPU:) print( 1. Go to: Runtime - Change runtime type) print( 2. Select: T4 GPU (or other GPU option)) print( 3. Click: Save) print( 4. Runtime will restart) return False staticmethod def check_pytorch(): 检查 PyTorch 安装状态 print(\n--- PyTorch Check ---) print(fVersion: {torch.__version__}) print(fCUDA version: {torch.version.cuda}) print(fAvailable: {torch.cuda.is_available()}) if cpu in torch.__version__: print(\nWARNING: CPU-only PyTorch detected!) return cpu if torch.cuda.is_available(): print(fGPU: {torch.cuda.get_device_name(0)}) cap torch.cuda.get_device_capability(0) print(fCapability: {cap[0]}.{cap[1]}) return gpu return unknown staticmethod def install_gpu_pytorch(cuda_versioncu121): 安装 GPU 版本的 PyTorch print(f\n--- Installing PyTorch with {cuda_version} ---) # 卸载现有版本 subprocess.check_call([sys.executable, -m, pip, uninstall, torch, torchvision, torchaudio, -y]) # 安装 GPU 版本 url fhttps://download.pytorch.org/whl/{cuda_version} subprocess.check_call([sys.executable, -m, pip, install, torch, torchvision, torchaudio, --index-url, url]) print(Installation complete. Please restart runtime:) print( Runtime - Restart runtime) print(Then run the next cell.) staticmethod def full_setup(): 完整的环境设置流程 print( * 60) print(Colab PyTorch GPU Environment Setup) print( * 60) # Step 1: 检查运行时 has_gpu ColabGPUSetup.check_runtime() if not has_gpu: print(\nPlease enable GPU runtime first, then run this cell again.) return False # Step 2: 检查 PyTorch status ColabGPUSetup.check_pytorch() if status cpu: print(\nNeed to reinstall PyTorch with GPU support.) ColabGPUSetup.install_gpu_pytorch() return False if status gpu: print(\nGPU PyTorch is ready!) # 额外检查 try: x torch.randn(100, 100, devicecuda) y torch.mm(x, x) torch.cuda.synchronize() print(fGPU computation test: PASSED) return True except RuntimeError as e: print(fGPU computation test: FAILED - {e}) print(Try reinstalling with different CUDA version.) return False print(\nUnknown status. Try reinstalling PyTorch.) return False # 运行设置 ready ColabGPUSetup.full_setup() # 单元格 2: GPU 训练示例 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader import numpy as np import time class GPUDataset(Dataset): 合成数据集 def __init__(self, num_samples5000, dim784, num_classes10): self.data torch.randn(num_samples, dim) self.labels torch.randint(0, num_classes, (num_samples,)) def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx], self.labels[idx] class GPUModel(nn.Module): def __init__(self, input_dim784, num_classes10): super().__init__() self.features nn.Sequential( nn.Linear(input_dim, 512), nn.BatchNorm1d(512), nn.ReLU(), nn.Dropout(0.3), nn.Linear(512, 256), nn.BatchNorm1d(256), nn.ReLU(), nn.Dropout(0.3), nn.Linear(256, num_classes) ) def forward(self, x): return self.features(x) def train_on_colab_gpu(): 在 Colab GPU 上训练模型 device torch.device(cuda if torch.cuda.is_available() else cpu) print(fTraining device: {device}) if device.type cpu: print(WARNING: Training on CPU. GPU not available!) return # 打印 GPU 信息 print(fGPU: {torch.cuda.get_device_name(0)}) print(fGPU Memory: {torch.cuda.get_device_properties(0).total_mem / 1024**3:.2f} GB) # 超参数 BATCH_SIZE 128 NUM_EPOCHS 10 LR 0.001 # 数据 dataset GPUDataset(num_samples5000) train_size int(0.8 * len(dataset)) val_size len(dataset) - train_size train_ds, val_ds torch.utils.data.random_split(dataset, [train_size, val_size]) train_loader DataLoader(train_ds, batch_sizeBATCH_SIZE, shuffleTrue, num_workers2) val_loader DataLoader(val_ds, batch_sizeBATCH_SIZE, shuffleFalse, num_workers2) # 模型 model GPUModel().to(device) criterion nn.CrossEntropyLoss() optimizer optim.AdamW(model.parameters(), lrLR) scheduler optim.lr_scheduler.CosineAnnealingLR(optimizer, T_maxNUM_EPOCHS) print(f\nModel parameters: {sum(p.numel() for p in model.parameters()):,}) print(fStarting training for {NUM_EPOCHS} epochs...\n) best_val_acc 0.0 for epoch in range(NUM_EPOCHS): # 训练 model.train() train_loss 0.0 train_correct 0 train_total 0 epoch_start time.time() for batch_x, batch_y in train_loader: batch_x batch_x.to(device, non_blockingTrue) batch_y batch_y.to(device, non_blockingTrue) optimizer.zero_grad() output model(batch_x) loss criterion(output, batch_y) loss.backward() optimizer.step() train_loss loss.item() * batch_x.size(0) train_correct (output.argmax(1) batch_y).sum().item() train_total batch_y.size(0) train_loss / train_total train_acc train_correct / train_total # 验证 model.eval() val_loss 0.0 val_correct 0 val_total 0 with torch.no_grad(): for batch_x, batch_y in val_loader: batch_x batch_x.to(device, non_blockingTrue) batch_y batch_y.to(device, non_blockingTrue) output model(batch_x) loss criterion(output, batch_y) val_loss loss.item() * batch_x.size(0) val_correct (output.argmax(1) batch_y).sum().item() val_total batch_y.size(0) val_loss / val_total val_acc val_correct / val_total epoch_time time.time() - epoch_start scheduler.step() if val_acc best_val_acc: best_val_acc val_acc # GPU 内存使用 gpu_mem torch.cuda.memory_allocated() / 1024**2 gpu_mem_peak torch.cuda.max_memory_allocated() / 1024**2 print(fEpoch [{epoch1}/{NUM_EPOCHS}] ({epoch_time:.1f}s) fTrain: {train_loss:.4f}/{train_acc:.4f} | fVal: {val_loss:.4f}/{val_acc:.4f} | fGPU Mem: {gpu_mem:.0f}MB (peak: {gpu_mem_peak:.0f}MB)) print(f\nBest validation accuracy: {best_val_acc:.4f}) print(Training complete!) # 清理 GPU 缓存 torch.cuda.empty_cache() print(fGPU cache cleared. Memory allocated: {torch.cuda.memory_allocated()/1024**2:.0f}MB) # 运行训练 if ready: train_on_colab_gpu() else: print(Please fix GPU setup first (run Cell 1).) # 单元格 3: GPU 性能基准测试 def gpu_benchmark(): GPU 性能基准测试 if not torch.cuda.is_available(): print(GPU not available for benchmark.) return device torch.device(cuda) print(fGPU: {torch.cuda.get_device_name(0)}) print(fCapability: {torch.cuda.get_device_capability(0)}) print() # 矩阵乘法基准 sizes [512, 1024, 2048, 4096, 8192] print(f{Size:10} {FP32 (ms):15} {FP16 (ms):15} {Speedup:10}) print(- * 50) for size in sizes: # FP32 x torch.randn(size, size, devicedevice) y torch.randn(size, size, devicedevice) # 预热 for _ in range(3): torch.mm(x, y) torch.cuda.synchronize() # FP32 测试 start torch.cuda.Event(enable_timingTrue) end torch.cuda.Event(enable_timingTrue) start.record() for _ in range(10): z torch.mm(x, y) end.record() torch.cuda.synchronize() fp32_time start.elapsed_time(end) / 10 # FP16 测试 x16 x.half() y16 y.half() for _ in range(3): torch.mm(x16, y16) torch.cuda.synchronize() start.record() for _ in range(10): z16 torch.mm(x16, y16) end.record() torch.cuda.synchronize() fp16_time start.elapsed_time(end) / 10 speedup fp32_time / fp16_time print(f{size}x{size:5} {fp32_time:15.2f} {fp16_time:15.2f} {speedup:.2f}x) del x, y, x16, y16, z, z16 torch.cuda.empty_cache() print(\nBenchmark complete!) gpu_benchmark()常见陷阱与注意事项1. 运行时断开后的环境重置Colab 运行时会在 12 小时后或长时间不活动后断开。重新连接后所有安装的包和环境变量都会丢失。需要重新设置 GPU 运行时类型并重新安装 PyTorch。2. Colab Pro/Free 的 GPU 差异Free Colab通常分配 T4 GPU16GB有时可能分配更差的 GPU 或无 GPUColab Pro可能分配 V10016GB/32GB或 A10040GBColab Pro优先分配 A100不同 GPU 的计算能力不同确保 PyTorch 版本支持你的 GPU 架构。3. 不要在每次运行时都重新安装 PyTorchColab 默认已经安装了 GPU 版本的 PyTorch。只有在确认安装的是 CPU 版本时才需要重新安装。频繁重新安装会浪费时间并可能导致版本冲突。4. CUDA OOM内存不足Colab GPU 的内存有限T4: 16GB。如果模型或 batch size 太大会遇到 CUDA OOM# 解决方案 # 1. 减小 batch size # 2. 使用梯度累积 # 3. 使用混合精度训练 # 4. 使用梯度检查点 # 梯度累积示例 accumulation_steps 4 for i, (batch_x, batch_y) in enumerate(dataloader): output model(batch_x) loss criterion(output, batch_y) / accumulation_steps loss.backward() if (i 1) % accumulation_steps 0: optimizer.step() optimizer.zero_grad()5. 多 GPU 训练Colab 通常只分配一个 GPU。不要尝试使用nn.DataParallel或nn.parallel.DistributedDataParallel除非确认有多个 GPU。6. 混合精度训练在 Colab GPU 上使用混合精度可以加速训练并减少内存使用from torch.cuda.amp import autocast, GradScaler scaler GradScaler() with autocast(): output model(batch_x) loss criterion(output, batch_y) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()7. 持久化模型和数据Colab 运行时断开后本地文件会丢失。需要将模型和数据保存到 Google Drivefrom google.colab import drive drive.mount(/content/drive) # 保存模型 torch.save(model.state_dict(), /content/drive/MyDrive/model.pth) # 加载模型 model.load_state_dict(torch.load(/content/drive/MyDrive/model.pth))8. 检查 Colab 的 CUDA 驱动版本# 查看 Colab 的 CUDA 驱动版本 !nvcc --version # 或 !nvidia-smi确保安装的 PyTorch CUDA 版本与驱动版本兼容。9. 避免在 CPU 上做数据预处理在 Colab 中CPU 性能有限。尽量将数据预处理移到 GPU 上或使用num_workers加速数据加载。10. 使用 Colab 的 TPU如果 GPU 不可用或性能不足可以考虑使用 Colab 的 TPU# 安装 TPU 版本的 PyTorch !pip install torch-xla import torch_xla import torch_xla.core.xla_model as xm device xm.xla_device() model model.to(device)总结在 Google Colaboratory 中使用 PyTorch CUDA 时遇到的问题绝大多数可以通过以下步骤解决设置 GPU 运行时类型这是最基本也是最常见的解决方案。通过运行时 → 更改运行时类型 → GPU启用 GPU。检查 PyTorch 版本确保安装的是 GPU 版本而非 CPU 版本。检查torch.__version__是否包含cpu。正确安装 PyTorch使用 PyTorch 官方的 CUDA 版本安装命令指定正确的 CUDA 版本。检查 CUDA 架构兼容性确保 PyTorch 编译时包含了当前 GPU 的架构支持。处理运行时重置Colab 运行时会定期重置需要重新配置环境。将重要文件保存到 Google Drive。优化 GPU 使用使用混合精度训练、梯度累积等技术充分利用有限的 GPU 资源。通过本文提供的诊断脚本和完整训练代码你应该能够在 Colab 中顺利使用 PyTorch 进行 GPU 加速的深度学习训练。记住遇到问题时首先运行诊断脚本根据输出信息定位具体原因然后采取对应的解决方案。