
1. 为什么我还在用 Colab 跑深度学习实验第一次接触 Colab 是在一个本地显卡烧掉的下午。当时手头一个图像分类的小项目刚跑到一半风扇突然狂转然后黑屏拆开一看显卡供电模块糊了。那段时间显卡价格又离谱重新买一张的钱够我吃好几个月外卖。一个做算法的朋友随口说了句你试试 Colab 啊免费给 GPU我就这么入了坑一用就是好几年。Colab 本质上是 Google 提供的一个云端 Jupyter Notebook 环境你打开浏览器就能写 Python、跑训练、存数据背后挂着一块真实的 GPU 或者 TPU。免费档位最常见的就是 Tesla K80偶尔能分到 T4运气好还能碰到 P100。K80 这块卡放到今天确实老了——Kepler 架构24GB 显存但被拆成两块 12GB算力也就那样FP32 大概 8.7 TFLOPS。但关键在于免费两个字对于学生党、刚入门的新手、或者只是想快速验证一个想法的人来说这个门槛低到几乎没有。我写这个系列的第二篇是因为第一篇发出去之后后台收到一堆问题怎么保持连接不掉、数据集怎么传上去、为什么我的 GPU 用着用着就没了、断点续训到底怎么写。这些问题我在实际使用中全都踩过而且每一个都让我浪费过至少半天时间。所以这篇不打算讲怎么打开 Colab这种基础操作而是聚焦在真正影响你实验效率的那些细节上——环境配置、数据流转、训练稳定性、资源调度以及那些官方文档不会告诉你的坑。适合读这篇的人手上有 Colab 账号、跑过一两次 notebook、但总觉得用得不顺手、经常被断开或者速度慢到怀疑人生的朋友。如果你完全没接触过建议先去看第一篇把基础跑通再回来抠这些细节。2. Colab 的运行机制与资源分配逻辑2.1 免费 GPU 到底是怎么分给你的很多人以为 Colab 是打开就有 K80其实不是。你拿到的硬件是动态分配的取决于当前时段、你的账号历史使用情况、以及后台的调度策略。我做过一个粗略统计工作日下午打开大概率是 K80凌晨或者周末碰到 T4 的概率明显上升。T4 是 Turing 架构16GB 显存FP32 算力 8.1 TFLOPS但支持 FP16 和 INT8 加速实际跑推理和混合精度训练比 K80 快不少。分配逻辑官方从来没公开过但根据社区里大量用户的反馈和我自己的观察大致有这么几条规律新账号或者长期不活跃的账号前几次使用往往能拿到较好的卡连续高强度使用比如一天跑好几个小时之后分配到的资源会变差甚至直接给你 CPU 实例同一个账号同时开多个 notebook只有第一个能拿到 GPU后面的全是 CPU。这个机制其实很好理解——资源池就那么大平台要保证尽可能多的人能用上所以会做限流。提示如果你打开 notebook 发现torch.cuda.is_available()返回 False先别急着骂大概率是当前时段 GPU 池满了。关掉等十几分钟再开或者换个时间段通常就能恢复。2.2 会话生命周期与断连的本质Colab 的会话session不是永久的。免费用户最长连续运行 12 小时但这只是理论上限实际中经常更短。触发断连的原因主要有三类一是空闲超时浏览器标签页不活跃大概 90 分钟就会被回收二是资源超限比如你显存爆了、内存吃太多、或者磁盘写满三是平台主动调度这个没法预测。这里有个很多人搞混的点浏览器关掉不等于会话结束。只要 notebook 还在后台执行代码会话就还活着。但如果你把标签页关了又不去管它过一段时间照样会被回收。反过来就算你一直开着页面如果代码跑完了停在那里不动空闲计时器一样会走。理解这个机制之后策略就清晰了要么让代码一直有活干要么用脚本定期制造活动。我自己的做法是在训练循环里加一个轻量的心跳输出比如每个 epoch 打印一次时间戳这样既能看到进度又能让系统认为会话是活跃的。但注意这个只能延缓空闲回收不能突破 12 小时的硬上限。2.3 存储结构哪些东西会丢哪些不会Colab 的存储分两块搞不清楚这块会吃大亏。/content目录是临时的会话一结束全部清空你下载的数据集、训练好的权重、写的中间文件统统没了。而挂载到/content/drive的 Google Drive 是持久的除非你手动删否则一直在。我刚用的时候不知道这个区别辛辛苦苦跑了一晚上的模型第二天打开发现啥都没了那种心情你们体会一下。后来学乖了所有重要产出第一时间往 Drive 里写。但 Drive 也有坑它的读写速度比本地磁盘慢很多尤其是大量小文件的时候IO 会成为瓶颈。所以我的习惯是——数据集解压到/content本地跑训练完的权重和日志再同步回 Drive。存储位置持久性读写速度适合放什么/content会话结束即清空快解压后的数据集、临时文件、checkpoint/content/drive持久保存慢最终权重、训练日志、代码备份/tmp会话结束即清空最快高频读写的缓存文件这个表格是我踩了无数次坑之后总结的你可以直接照着用。核心原则就一句话跑的时候用本地存的时候用 Drive。3. 环境配置的实操细节与避坑3.1 挂载 Drive 与目录规划挂载 Drive 的代码很简单但里面有个授权流程容易卡住from google.colab import drive drive.mount(/content/drive)运行之后会弹出一个授权链接点进去选账号、复制验证码、粘贴回来。这一步在无痕模式下经常失败建议用正常窗口。挂载成功后你的 Drive 根目录就出现在/content/drive/MyDrive下面。我强烈建议在 Drive 里建一个固定的项目目录结构比如MyDrive/ colab_projects/ project_a/ data/ checkpoints/ logs/ notebooks/这样每次开新会话挂载完直接cd进去就行不用每次重新找路径。而且多个项目之间不会互相干扰清理的时候也方便。我见过有人把所有东西堆在 Drive 根目录几百个文件混在一起找都找不到。3.2 依赖安装的正确姿势Colab 预装了一堆常用库——PyTorch、TensorFlow、NumPy、Pandas 基本都有。但版本不一定是你想要的而且有些冷门库需要自己装。这里有个关键技巧pip 安装默认装到系统环境重启会话就没了。所以每次开新会话依赖都要重装。我的做法是写一个setup.sh或者一个初始化 cell把所有安装命令集中起来开新会话第一件事就是跑它。比如pip install -q transformers4.30.0 pip install -q datasets pip install -q wandb-q是 quiet 模式减少输出刷屏。装完之后建议验证一下版本import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))这三行是我每次开新会话必跑的确认环境没问题再往下走。曾经有一次我没检查直接开训跑了半小时才发现装的是 CPU 版本的 torch白费功夫。注意Colab 的预装环境偶尔会更新导致你之前能跑的代码突然报错。遇到这种情况先pip list看看关键库的版本大概率是某个依赖被升级了。锁定版本号是最稳妥的办法。3.3 GPU 型号检测与适配不同 GPU 的显存和算力差异很大代码里最好做一下适配。比如 batch size 的设置K80 上可能只能开到 16T4 上能开到 64。我通常会在开头加一段检测逻辑import torch gpu_name torch.cuda.get_device_name(0) if K80 in gpu_name: BATCH_SIZE 16 elif T4 in gpu_name: BATCH_SIZE 64 elif P100 in gpu_name: BATCH_SIZE 48 else: BATCH_SIZE 32 print(fUsing {gpu_name}, batch size {BATCH_SIZE})这样不管分到什么卡代码都能自动调整不用手动改来改去。虽然简单但省心。4. 数据流转从本地到 Colab 的高效方案4.1 小数据集的直接上传如果你数据量不大几百 MB 以内最简单的方式就是直接拖拽上传到/content。Colab 左侧有个文件面板点上传按钮选文件就行。但这种方式有两个限制一是单个文件不能太大超过一定大小会失败二是上传速度取决于你的网络而且上传过程中页面不能关。我一般只在小规模测试的时候用这招比如传个几百张图片验证代码能不能跑通。正式训练的数据集还是走 Drive 或者命令行下载。4.2 大数据集走 Drive 挂载数据量大的话先把数据集传到 Drive然后在 Colab 里从 Drive 读取。但前面说过Drive 的 IO 慢直接在上面训练会很卡。所以标准流程是数据集压缩包放 DriveColab 里cp到/content本地在本地解压从本地路径读取训练cp /content/drive/MyDrive/colab_projects/project_a/data/dataset.zip /content/ cd /content unzip -q dataset.zip -d ./data解压到本地之后训练速度会快很多。我实测过同样一个 5GB 的图像数据集从 Drive 直接读每个 epoch 要 8 分钟拷到本地之后降到 2 分钟出头。这个差距在跑几十个 epoch 的时候非常明显。4.3 从公开源直接下载很多常用数据集可以直接在 Colab 里用命令下载省去上传的麻烦。比如wget -q https://example.com/dataset.tar.gz tar -xzf dataset.tar.gz或者用 Python 的下载库import urllib.request urllib.request.urlretrieve(https://example.com/data.zip, data.zip)这种方式的好处是不占用你的上传带宽Colab 的下载速度通常很快。但要注意下载链接必须是公开可访问的而且下载过程中如果会话断了得重新来。所以大文件建议配合断点续传工具或者先下到 Drive 再拷本地。4.4 数据同步的自动化脚本训练过程中checkpoint 和日志需要定期同步回 Drive防止会话突然断掉导致丢失。我通常写一个简单的同步函数在每个 epoch 结束时调用import shutil import os def sync_to_drive(local_path, drive_path): if not os.path.exists(drive_path): os.makedirs(drive_path) shutil.copy(local_path, drive_path) print(fSynced {local_path} to {drive_path})然后在训练循环里for epoch in range(EPOCHS): train_one_epoch() save_checkpoint(f/content/checkpoint_epoch_{epoch}.pt) sync_to_drive( f/content/checkpoint_epoch_{epoch}.pt, f/content/drive/MyDrive/colab_projects/project_a/checkpoints/checkpoint_epoch_{epoch}.pt )这样即使会话在下一个 epoch 中途断了你至少还有上一个 epoch 的权重。我吃过一次亏跑了 6 个小时没同步结果断连之后全部重来从那以后就养成了每个 epoch 同步的习惯。5. 训练稳定性断点续训与资源监控5.1 断点续训的完整实现断点续训是 Colab 上跑长任务的必备技能。核心思路很简单定期保存模型状态、优化器状态、当前 epoch 数下次启动时先检查有没有 checkpoint有就加载继续。import os import torch def save_checkpoint(model, optimizer, epoch, loss, path): torch.save({ epoch: epoch, model_state_dict: model.state_dict(), optimizer_state_dict: optimizer.state_dict(), loss: loss, }, path) def load_checkpoint(model, optimizer, path): if os.path.exists(path): checkpoint torch.load(path) model.load_state_dict(checkpoint[model_state_dict]) optimizer.load_state_dict(checkpoint[optimizer_state_dict]) start_epoch checkpoint[epoch] 1 print(fResumed from epoch {start_epoch}) return start_epoch return 0然后在主训练脚本里start_epoch load_checkpoint(model, optimizer, CHECKPOINT_PATH) for epoch in range(start_epoch, EPOCHS): train_loss train_one_epoch(model, optimizer, train_loader) save_checkpoint(model, optimizer, epoch, train_loss, CHECKPOINT_PATH) sync_to_drive(CHECKPOINT_PATH, DRIVE_CHECKPOINT_PATH)这里有个细节优化器状态也要存。很多人只存模型权重恢复之后发现学习率调度、动量这些全丢了训练效果会打折扣。完整的 checkpoint 应该包含模型、优化器、epoch、loss有时候还要存学习率调度器的状态。5.2 显存与内存监控Colab 免费档的显存和内存都是有限的K80 是 12GB 可用显存另外 12GB 被系统占用内存大概 12GB 左右。跑大模型或者大 batch 的时候很容易爆。监控方法有两种一是用nvidia-smi命令!nvidia-smi输出会显示当前显存占用、GPU 利用率、温度等信息。我习惯在每个 epoch 结束后跑一次看看有没有异常增长。二是用 Python 的 psutil 监控内存import psutil print(fRAM used: {psutil.virtual_memory().percent}%)如果发现显存持续增长不释放大概率是某个地方张量没 detach 或者梯度没清零。这种问题在训练循环里很常见尤其是自定义 loss 的时候。提示显存爆了不一定报错有时候会静默地变慢因为系统开始用内存做交换。所以定期监控比等报错更靠谱。5.3 防止空闲断连的实用技巧前面说过空闲 90 分钟会被回收。但空闲的定义是浏览器不活跃不是代码不执行。所以如果你在跑一个很长的训练浏览器标签页一直开着通常不会被回收。但如果你关了浏览器去睡觉那就危险了。我的做法是训练脚本里加一个心跳打印每个 epoch 输出一次时间戳和当前 loss。这样即使我关了浏览器只要代码在跑会话就还活着。另外Colab 的浏览器端有个自动重连机制偶尔断一下它会自己恢复但前提是会话本身还在。还有一个技巧是用while True循环配合time.sleep制造持续活动但这个不推荐因为会浪费资源而且平台可能会检测到异常行为。正常训练的心跳输出就够了。6. 常见问题排查与实战经验6.1 典型问题速查表问题现象可能原因解决方法CUDA out of memorybatch 太大或显存泄漏减小 batch size检查梯度清零会话突然断开超时或资源超限检查心跳输出减少内存占用GPU 不可用当前时段资源紧张换时间段重试或等十几分钟Drive 挂载失败授权过期或网络问题重新运行挂载代码换浏览器训练速度突然变慢显存交换或 GPU 降频用 nvidia-smi 检查状态pip 安装后 import 失败装到了错误的环境重启会话后重装检查路径这张表是我这几年遇到问题之后一条条记下来的基本覆盖了 90% 的情况。遇到问题先对照查一遍能省不少时间。6.2 几个我踩过的深坑第一个坑是在 Drive 上直接训练。刚开始图省事数据集放 Drive 不解压直接读。结果每个 epoch 要等十几分钟还以为是模型太复杂。后来拷到本地才发现是 IO 瓶颈。这个教训告诉我Colab 上的存储分层一定要用对。第二个坑是忘记设置随机种子。Colab 每次重启环境都是新的随机种子不固定的话同样的代码跑出来的结果不一样调试的时候非常痛苦。现在我所有实验开头都会加import random import numpy as np import torch def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) set_seed(42)第三个坑是依赖版本冲突。Colab 预装的库版本经常变有一次我装了个新库把 numpy 升级了结果 pandas 用不了。后来学乖了装任何库之前先pip list看一眼有冲突就锁定版本。6.3 资源使用的经验法则用了这么久我总结了几条资源使用的经验法则分享出来供参考batch size 从小的开始试逐步往上加直到显存占用到 80% 左右。留 20% 余量给系统和其他开销。数据集能小则小训练前先做 EDA去掉明显无用的数据减少 IO 和内存压力。checkpoint 频率要合理太频繁影响训练速度太稀疏断连损失大。我一般每个 epoch 存一次epoch 特别短的话每 5 个 epoch 存一次。日志输出要精简每个 batch 都打印会拖慢速度每个 epoch 打印一次就够了。会话用完主动断开释放资源给其他人也避免后台继续占用你的配额。这些法则看起来简单但都是实际跑过几十次实验之后才形成的习惯。新手最容易犯的错就是一开始就把 batch size 拉满结果各种 OOM然后怀疑人生。7. 把 Colab 用成生产力工具的几点体会Colab 免费 GPU 这个东西说它强吧限制一大堆说它弱吧关键时刻真能救急。我的态度是把它当成一个快速验证想法的工具而不是长期跑大实验的平台。一个想法从代码到初步结果Colab 能在半小时内给你答案这个价值就足够了。真要跑几天的训练还是得想办法搞本地卡或者租云服务器。用久了之后我形成了一套固定的工作流开新会话先挂 Drive、跑初始化脚本、检查 GPU、设种子训练时本地跑、定期同步、心跳输出遇到问题先查速查表、再搜社区、最后自己调试。这套流程让我在 Colab 上的效率比刚开始高了不止一倍。最后分享一个小技巧如果你经常用 Colab建议把常用的初始化代码、工具函数、检查逻辑整理成一个colab_utils.py放在 Drive 里每次开新会话直接sys.path.append然后 import。这样不用每次复制粘贴一大堆代码省时省力。我现在这个工具文件已经攒了几十个函数从数据加载到模型保存到可视化基本覆盖了日常需求。