wandb入门指南:从TensorBoard迁移到实验跟踪看板的完整实践 1. wandb是什么以及为什么我建议你从TensorBoard换过来先说一个我自己的经历。去年年中我在调一个图像分割模型每天要同时跑五六组对比实验超参数、Loss曲线、验证集指标散落在不同的本地日志文件里。TensorBoard虽然也能看曲线但每开一组实验就要手动指定一次logdir时间一长连我自己都记不清哪个曲线对应哪组参数。后来一个同事把wandbWeights Biases丢给我说你试试这个我用了一个下午把项目接进去当天晚上就决定彻底换掉TensorBoard。wandb本质上是一个实验跟踪与可视化工具它在你的训练脚本里加上几行代码就能把每次运行的超参数、指标曲线、模型结构、预测结果、甚至系统资源占用全部自动上传到一个统一的看板里。你不需要自己维护日志文件不需要手动记录哪组实验用了什么配置只要打开浏览器就能看到每一次run的完整生命周期。对比TensorBoard最打动我的三个点是多实验对比不用翻目录TensorBoard一次只能看一个logdirwandb可以在一个页面里勾选任意多次run曲线直接叠在一起。实验配置和指标放在同一处每个run自带的config区记录超参数summary区记录最终指标不用再对着命令行历史猜参数。团队协作天然支持只要大家都登录同一个账号或同一个团队谁跑的实验全组都能看到省掉了把你跑的实验结果打包发我一下这种沟通成本。当然TensorBoard并不是没有优势它在纯本地、低带宽环境下的渲染速度更快插件生态也成熟。但如果你像我一样需要频繁对比实验、追溯历史结果wandb带来的体验提升是断层级的。1.1 一个简单的对比TensorBoard vs wandb我没有要引战的意思只是从实际体验出发做一个横向对比。下面这个表格是我自己总结的适合纠结选哪个工具的人参考维度TensorBoardwandb安装与启动随TensorFlow/PyTorch附带本地起服务pip安装登录后云端看板也可自建私有化多实验对比需要指定多个logdir操作略繁琐网页端勾选run即可代码零改动超参数与指标关联弱主要靠命名规范强config和metric天然绑定在run上团队共享需自行搭建并处理端口访问同一workspace内所有人可见数据存储位置本地磁盘云端或自托管本地有缓存崩溃恢复日志文件留档但需要自行解析run状态可恢复支持离线重传调参辅助无Sweeps自动超参搜索模型/数据集版本管理无Artifacts我不是说TensorBoard一无是处如果你的实验都在单机且完全不需要协作用TensorBoard完全没问题。可一旦进入实验数量多、需要频繁回溯、团队要共享结果这个节奏wandb的组织方式明显更省心。1.2 wandb的核心概念run、config、log刚开始用wandb的时候我绕了很久才想明白三个词run、config、log。一个run就是一次代码运行对应你在训练脚本里调用wandb.init()创建的一条实验记录。每次run会有一个唯一的ID和名字你的所有指标、配置、文件都挂在它下面。你可以把run理解成一次训练从开始到结束的档案袋。config是挂在run上的超参数字典一般放learning rate、batch size、模型层数这类不会频繁变化的值。它最大的价值不是存储而是让每次run自带配方日后对比时一眼就能看出两组实验差异在哪。config的使用方式比较灵活可以在初始化时直接传字典也可以初始化后再像字典一样赋值。log是核心中的核心。wandb.log({})接收一个字典里面放你想记录的指标名和值比如{loss: loss.item(), acc: acc}。每调用一次就会在曲线上增加一个点。如果训练了100个epoch每个epoch调用一次你就能得到一条100个点的曲线。wandb在底层会自动按step排列不需要你手动传step除非你有特殊需求。搞清楚这三个概念wandb的基本使用其实已经掌握一半了。2. 从安装到跑通第一条实验记录环境准备与登录这部分我按实际操作顺序来讲方便你直接照着做。2.1 安装与登录API Key是新手第一个拦路虎安装非常简单用pip或者conda都行pip install wandb如果你的环境里有多个Python环境记得先激活目标环境再装避免装错地方。装完之后在终端执行wandb login这里会出现一个登录流程它会给你一个授权链接让你在浏览器里打开并授权。麻烦的点在于首次使用需要注册一个wandb账号然后拿到一个API Key一串40位左右的字符粘贴到终端回车确认。很多人在这一步卡住是因为没搞清楚API Key在哪找。正确路径是登录wandb官网后点击右上角头像选择Settings在页面里找到API Keys区域点New Key生成一个然后复制。这个Key相当于你访问wandb服务的凭证一定要保管好不要提交到Git仓库里。如果终端不方便交互也可以直接把Key写进环境变量export WANDB_API_KEY你的key或者在代码里指定import wandb wandb.login(key你的key)不过我不建议在代码里硬编码Key万一代码分享出去你的账号就被别人接管了。最稳妥的方式是wandb login登录一次Key会缓存在本机~/.netrc文件中后续运行代码会自动读取。2.2 最小示例三分钟跑通第一个run登录成功之后我们来写一个最小示例验证整条链路是否通。新建一个Python文件比如test_wandb.py内容如下import wandb import random # 初始化一个runproject名称可以随意起 wandb.init(projectdemo-project, namefirst-run) # 记录超参数 wandb.config.update({ learning_rate: 0.01, epochs: 10, batch_size: 32 }) # 模拟训练循环 for epoch in range(10): loss 1.0 / (epoch 1) random.uniform(0, 0.01) acc epoch * 0.1 random.uniform(0, 0.05) # 记录指标 wandb.log({loss: loss, acc: acc}) # 结束run wandb.finish()运行这个脚本python test_wandb.py只要看到终端输出里有Syncing run和View run at之类的信息说明数据已经开始上传。用浏览器打开输出的网址就能看到这个run的页面里面有config、loss曲线、acc曲线和系统日志。这里我提醒一下wandb.finish()一定要加。不加的话run在程序正常退出时也会自动结束但如果你用的是交互式环境比如Jupyter Notebook不显式调用finish可能导致run一直处于running状态看起来像卡住了。2.3 离线模式网络不稳定时的保命手段云服务固然方便但你在内网环境或者网络不稳定的情况下训练一断网就上传失败会很崩溃。wandb支持离线运行模式先本地存着等网络恢复再上传。使用方法是在初始化时指定wandb.init(projectdemo-project, modeoffline)或者通过环境变量export WANDB_MODEoffline离线模式下run的数据会先写入本地wandb/目录下的文件等你想同步时执行wandb sync wandb/offline-run-xxx把对应的离线目录同步到云端。我个人的习惯是在服务器上跑训练时默认开离线模式训练结束看结果满意了再统一sync这样既不受网络波动影响也不会产生大量实时上传的带宽压力。3. 训练循环中必须掌握的API与数据记录规范很多人用wandb只学会了log loss和acc然后觉得就这。实际上把记录能力用满对你的实验效率提升非常明显。这一节我把最核心的几个API和它们的正确用法过一遍。3.1 init/config/log/finish四个API的细节边界**wandb.init()**的参数虽然多但最常用的只有几个project项目名同一项目下的run会聚合在一起对比建议按研究课题划分。name当前run的显示名不加的话系统会自动生成一个随机名字写代码时显式命名会好追溯。entity团队用户名单人使用可以忽略。notes一段文本备注记录实验想法之类的团队协作时很有用。tags给run打标签比如baseline、with-aug、debug方便筛选。config可以直接把超参数字典传进去省去后面再update一步。wandb.config我会把它当做一个只增不减的配置存储区。训练开始后就不要再修改config里的值因为对比实验时config是判断两组实验差异的依据中途改掉会造成挂着羊头卖狗肉的混乱。如果需要记录动态变化的超参数比如带衰减的学习率应该用wandb.log记录而不是改config。**wandb.log()**接收字典值的类型可以是标量、matplotlib图片、PIL图片、音频、视频、表格等。有几个细节容易被忽略同一个run里log传的字典key要尽量保持一致。你今天传{loss: ...}明天改成{train_loss: ...}曲线图里就会出现两条断开的线看起来很难受。如果你在同一个step里想记录多个指标一次性传一个字典即可不要分开多次调用因为多次调用会占据多个step。默认情况下wandb会把每次log当成一个新step。如果想手动控制step比如每个epoch记录一次但内部跑了多个batch可以这样写wandb.log({loss: loss}, stepepoch)**wandb.finish()**用于显式结束run。建议把整个训练逻辑放在try...finally里确保异常时也能结束runwandb.init(projectmy-project) try: # 训练逻辑 pass finally: wandb.finish()这样做的原因在于如果训练途中抛出异常导致进程直接退出wandb会判定run为crashed。这不是不能看但有些可视化统计会把crashed的run单独区分开偶尔会造成误判。3.2 watch()自动记录梯度与模型结构wandb.watch()是我很喜欢的一个API它能自动记录模型的计算图、梯度、参数分布用法如下wandb.watch(model, log_freq100, loggradients, log_graphTrue)log_freq表示每多少步记录一次梯度信息log支持gradients和parameters两种模式log_graphTrue会把模型结构图也传上去。这个功能在排查训练问题时特别有用。比如模型loss不下降你可以去run页面看梯度的分布图如果某层梯度已经变成0或者爆炸性增大马上就能锁定问题层省去自己写一堆梯度打印代码的时间。但要注意watch会显著降低训练速度尤其是在batch比较小、模型比较大的情况下。我一般只在调试阶段开启正常大规模训练时会选择只记录参数不经梯度或者干脆关闭。3.3 多指标、多曲线、图像与音频的记录姿势除了标量曲线wandb还能直接在浏览器里渲染图像、音频和表格。以图像分割任务为例我经常在验证集上取几个样本把原图、预测mask、标注mask横向拼接成一张图记录下来import matplotlib.pyplot as plt fig, axes plt.subplots(1, 3, figsize(12, 4)) axes[0].imshow(image) axes[1].imshow(pred_mask) axes[2].imshow(gt_mask) wandb.log({validation_samples: wandb.Image(fig)})这里的wandb.Image()支持传入numpy数组、PIL对象或matplotlib figure非常方便。图像在网页端能按step滑动查看一张图对应一个step训练过程中随时可以回到某个step观察预测效果的变化。音频任务可以用wandb.Audio()点开就能在线播放不用下载文件。表格用wandb.Table()可以构建带列名的数据表在run页面直接筛选排序。文本类数据可以用wandb.Html()渲染HTML内容也可以用它做简单的富文本记录。这些能力看起来简单实际用起来会非常顺手。因为你不用再把样本文件一个个下载下来肉眼对比浏览器里直接看效率提升不是一点半点。4. 典型报错排查我在实际项目中遇到的几个坑作为工具wandb用着舒服但该踩的坑一个也躲不掉。我整理了自己和同事在项目中遇到频率最高的几类报错按排查链路拆解一遍。4.1 报错一Not logged in / 提示需要API Key这种现象常见于新环境或CI机器上代码运行到wandb.init()时直接报缺少凭证或者陷入交互式登录停滞。排查链路我是这样走的先在终端执行wandb login --verify如果提示Valid API key说明本机凭证没问题问题大概率出在代码里手动指定了别的key。如果提示无效或没有凭证重新执行wandb login。检查环境变量WANDB_API_KEY是否被错误地设置成一个空字符串或旧key因为在部分环境下环境变量优先级高于~/.netrc文件一个失效的key会覆盖掉正常凭证。如果是在容器里跑注意基础镜像是否包含~/.netrc。我踩过一次本地登录完成但打进Docker镜像后凭证没拷进去导致容器内一直报Not logged in。解决方式是用环境变量传入key或者在镜像构建时把.netrc复制进去。另外国内网络访问wandb服务的延迟较高有时登录时网页授权成功但终端迟迟等不到响应。这种情况下可以检查网络连通性后重试必要时切换一个更稳定的网络环境。4.2 报错二网络连接超时与上传失败这类报错的表现形式很多ConnectionError、TimeoutError、Failed to upload等。发生在数据同步阶段居多。排查思路确认当前网络访问外网是否正常。wandb的云端服务部署在海外公司内网或某些网络环境下可能访问受限。最简单的验证方式是在浏览器打开wandb官网看能否正常访问。检查代理设置。如果你的机器配置了HTTP代理但没有正确设置HTTP_PROXY和HTTPS_PROXY环境变量wandb的请求就会直连导致超时。反过来如果配置了代理但代理本身不稳定也会出现上传失败。查看离线缓存。看./wandb/目录下是否有大量*.wandb文件堆积如果有说明历史数据一直在排队没传上去。等一下重试或者手动执行wandb sync。对于内网环境我会建议直接用WANDB_MODEoffline跑训练最后统一同步时间上更可控。如果连最后同步都做不了那就考虑自建wandb私有化服务或者在公司内部选用其他替代工具。4.3 报错三训练进程卡死或重复输出同一run这个坑是我自己踩得最深的。现象是在Jupyter Notebook里反复运行同一个训练单元格每次都会创建一个新run但旧run并没有结束导致同一指标在多个run里重复出现。或者用PyTorch DataLoader的num_workers开启多进程时wandb在每个子进程里都被初始化一次日志混乱卡死。根因是wandb.init()被调用了多次且没有正确关闭。解决方式在Notebook环境里每次重新训练前先调用wandb.finish()确保旧run结束。使用wandb.init(reinitTrue)它允许在同一个Python进程里多次init而不是报错或复用旧run。多进程训练时把wandb初始化逻辑放到if __name__ __main__保护块内或者设num_workers0测试一次。如果多进程场景下确实需要在子进程记录日志要给每个进程独立的run name避免混淆。4.4 报错四磁盘占用暴涨本地缓存失控wandb会在本地缓存所有log数据包括图像和音频。训练时间长了wandb/目录可能膨胀到几十GB小磁盘的机器直接被写满。我的处理方式是分两类临时清理跑完实验后把不需要的wandb/offline-run-*目录删除或者用wandb artifact ls查看大文件。配置限制在wandb.init时设置sync_tensorboardFalse防止重复记录通过环境变量WANDB_DIR把缓存目录迁移到大磁盘。另外如果你确定某个run的数据已经在网页端看过了并且本地不再需要可以直接删除本地目录不影响网页端数据。数据同步完成后本地目录只是副本删掉不影响云端记录。5. 进阶玩法Sweeps超参搜索与Artifacts模型管理基本使用跑通之后你会发现wandb真正的威力在进阶功能上。这里我只挑两个我认为对日常实验最有效的Sweeps和Artifacts。5.1 Sweeps让机器替你调参Sweeps是wandb自带的超参数搜索模块。你不用像之前那样一个个手写for循环试learning rate只需要定义一个搜索配置wandb就会自动启动多个agent每个agent用不同的参数组合跑训练然后把结果汇总到同一个项目里。一个简单的sweep配置YAML格式长这样program: train.py method: bayes metric: name: val_acc goal: maximize parameters: learning_rate: min: 0.0001 max: 0.01 distribution: log_uniform batch_size: values: [16, 32, 64]保存为sweep.yaml然后执行wandb sweep sweep.yaml它会输出一个sweep ID然后你需要在多个终端或机器上执行wandb agent 你的sweep_id每个agent会从参数空间里取一组参数自动注入到环境变量里然后运行train.py。train.py里不再显式写死超参数而是从wandb.config中读取。这样跑完几十组实验后直接在Sweeps页面看平行坐标图和重要性分析哪些参数对结果影响大一目了然。我个人使用Sweeps的经验是先小规模跑十几组看参数重要性排序再根据结果收窄参数范围做第二轮搜索。直接上来就跑几百组既浪费算力也没太大意义。5.2 Artifacts把数据集和模型版本管起来Artifacts是wandb的版本控制模块可以管数据集、模型权重、任何文件。以前我把模型保存到本地命名规则是model_v1_0.87.pth、model_v2_0.89.pth时间一长根本分不清哪个对应哪个。用Artifacts之后每个run产出什么模型、基于什么数据集、效果如何全部串在一个链条上。保存一个模型artifact wandb.Artifact(resnet50-finetune, typemodel) artifact.add_file(model.pth) wandb.log_artifact(artifact)如果还想记录这个模型对应的数据集版本可以在定义Artifact时用add_reference()指向数据集目录或者在一个run里同时记录数据和模型让它们形成关联。之后需要复现时可以直接从某个run的Artifacts里下载对应文件不用再翻聊天记录找上一次用的那个模型。我这里有一条很实际的经验Artifacts的命名最好包含有意义的版本语义比如model-resnet50-aug-v1.0.0.pth。不要只写model.pth然后靠系统时间戳区分后期你会疯掉的。5.3 团队协作的体会与工作流建议最后聊点软的。真正把wandb用好不只是一个工具问题还是一个团队习惯问题。我们团队现在的日常流程是每个人开始新实验时wandb.init的project固定为当前课题名name用姓名缩写实验简述比如zc/lr-0.01-aug。所有对比实验都挂在同一个project下看板按run对比谁调的参、效果如何一目了然。每个run必须写notes哪怕只有一句话比如换了ResNet50当backbone这是为了一个月后回溯还能想起来当时为什么这么做。模型以Artifacts形式存储报告中附上run链接而不是粘贴一张截图。这套流程跑顺之后实验回溯成本大大降低。我经常上午来了先打开wandb页面看昨晚跑完的实验结果数据已经整整齐齐躺在那里比起翻log文件、写Excel记录不知道省了多少时间。不过我也得说句公道话如果你只是偶尔跑一两个模型、不需要对比、更不需要协作wandb对你来说确实有点重。它的学习曲线虽然不算陡但也是需要花时间适应的。项目真正进入规模化实验阶段你才会感受到埋点记录数据这件事带来的巨大回报。我个人目前最满意的用法是结合离线模式和Sweeps白天在本地机器把参数搜索范围定义好挂上agent让它自己跑晚上回家打开手机看结果第二天到公司直接根据分析图选定下一轮方向。这套流程帮我节省的时间保守估计每周能省出一个完整工作日。从最开始抵触多一个平台多一件事到现在把wandb当成实验流程的标配我这个转变还是很快的。工具的价值不在于功能列表有多长而在于它是否真的能让你把精力从记录转移到思考上。在这一点上wandb做到了。