做过深度学习项目的人大概率都经历过这样的场景:改了一处学习率、换了个batch size,重新训练一遍,结果上一次跑出来的准确率是多少已经记不清了,只能翻聊天记录、翻终端历史,甚至在本地建一堆命名混乱的文件夹来保存checkpoint。实验管理混乱带来的最大问题不是麻烦,而是不可复现——你无法准确回答“当时最好的那个模型用了什么配置”。Weights & Biases(简称wandb)就是为解决这个问题而生的实验追踪平台,它能在训练过程中实时记录各类metric,把超参数、代码版本、系统资源占用统统绑定到一次run上,并且内置了超参数搜索工具Sweep。这篇文章围绕metric日志记录和超参数搜索两个核心功能展开,配合可直接运行的代码示例。

一、wandb基础接入与初始化配置
使用wandb的第一步是安装并登录账号。安装通过pip完成:
pip install wandb wandb login
执行wandb login后,终端会提示输入API Key,去官网的个人设置页面复制粘贴即可。登录成功后,凭证会保存在本地的~/.netrc文件中,之后所有项目共用这个凭证。
在训练脚本中接入wandb只需要三步:初始化、记录配置、记录指标。下面是一个最小化的PyTorch接入示例:
import wandb
import torch
import torch.nn as nn
# 1. 初始化run,指定项目和run名称
run = wandb.init(
project="image-classification",
name="baseline-resnet18",
config={
"learning_rate": 1e-3,
"batch_size": 64,
"epochs": 20,
"model": "resnet18"
}
)
model = get_model(run.config.model) # 从config中读取超参数
optimizer = torch.optim.Adam(model.parameters(), lr=run.config.learning_rate)
for epoch in range(run.config.epochs):
train_loss = train_one_epoch(model, optimizer)
val_acc = evaluate(model)
# 2. 记录指标,step默认自动递增
wandb.log({"train_loss": train_loss, "val_acc": val_acc})
run.finish()这里的config参数非常关键。把所有超参数写进config而不是硬编码在脚本里,好处是wandb会把config和每一次run的结果永久绑定,之后在网页界面上可以通过任意字段筛选、分组、对比实验。比如你可以按learning_rate分组查看所有实验曲线,一眼看出学习率对收敛速度的影响。
二、Metric日志记录的进阶用法
最基本的wandb.log()调用已经能满足大部分需求,但实际使用中还有几个细节值得掌握。
第一个是step的控制。wandb内部维护一个全局step计数器,每次调用wandb.log()自动加一。但如果你的代码中每隔N个batch记录一次训练loss,每个epoch结束时记录验证指标,两者的频率不同,就会出现曲线错位的问题。解决办法是显式指定step参数,并且用define_metric声明各自的自定义x轴:
# 声明两个独立的横轴
wandb.define_metric("train/step")
wandb.define_metric("train/loss", step_metric="train/step")
wandb.define_metric("val/epoch")
wandb.define_metric("val/acc", step_metric="val/epoch")
global_step = 0
for epoch in range(num_epochs):
for batch in train_loader:
loss = train_step(batch)
global_step += 1
if global_step % 100 == 0:
wandb.log({
"train/step": global_step,
"train/loss": loss
})
wandb.log({
"val/epoch": epoch,
"val/acc": evaluate(model)
})第二个细节是命名规范。强烈建议用斜杠组织metric的层级结构,例如train/loss、val/loss、val/accuracy。wandb界面会自动按斜杠把指标分组折叠,曲线多了以后界面依然清爽,也能在同一个面板里方便地对比train和val曲线。
第三个是除了标量之外的记录类型。wandb.log并不局限于数字,你可以记录混淆矩阵、直方图、样本图片、文本输出等,这在调试生成模型或分类模型时特别有用:
# 记录模型权重分布直方图
wandb.log({"weights": wandb.Histogram(model.fc.weight.detach().cpu().numpy())})
# 记录预测样本图片
wandb.log({
"predictions": wandb.Image(img_tensor, caption=f"pred: {pred_label}")
})
# 记录混淆矩阵
wandb.log({"confusion_matrix": wandb.plot.confusion_matrix(
preds=predictions, y_true=labels, class_names=class_names
)})最后一个实用技巧是离线模式。如果在没有外网的服务器上训练,设置环境变量WANDB_MODE=offline,所有日志会写入本地目录,训练结束后执行wandb sync <run目录>即可同步到云端,数据不会丢失。
三、超参数搜索:Sweep的配置与运行
手动调参效率极低,wandb提供的Sweep功能可以自动化这个过程。Sweep的核心是一个YAML配置文件,其中定义三件事:搜索方法、参数空间和调度策略。
program: train.py
method: bayes # 搜索方法:random、grid、bayes
metric:
name: val/acc
goal: maximize # 优化目标:最大化验证准确率
parameters:
learning_rate:
distribution: log_uniform_values
min: 1e-5
max: 1e-2
batch_size:
values: [32, 64, 128]
epochs:
value: 30
optimizer:
values: ["adam", "sgd"]
early_terminate:
type: hyperband
min_iter: 5 # 至少跑5个epoch才允许提前终止
eta: 3配置中method支持三种策略:random随机采样,适合初期粗筛;grid网格搜索,参数空间小的时候可用;bayes是贝叶斯优化,会根据已完成的实验结果建立代理模型,把计算预算优先分配给有希望的区域,通常是性价比最高的选择。注意metric里指定的指标名必须和wandb.log中记录的名字完全一致,否则Sweep无法判断实验好坏。
训练脚本需要做少量修改,把超参数的来源从命令行改为wandb传入:
import wandb
def main():
# sweep模式下由wandb注入config
with wandb.init() as run:
config = run.config
model = build_model(config)
optimizer = build_optimizer(model, config.optimizer, config.learning_rate)
for epoch in range(config.epochs):
train_one_epoch(model, optimizer)
acc = evaluate(model)
wandb.log({"val/acc": acc, "epoch": epoch})
if __name__ == "__main__":
main()启动Sweep分两步:
# 1. 创建sweep,返回sweep_id wandb sweep sweep-config.yaml # 2. 启动agent,可以开多个agent并行 wandb agent your-entity/your-project/sweep_id
如果有多张GPU或多台机器,在每台机器上分别执行wandb agent即可,多个agent会自动从同一个参数服务器领取任务,天然实现并行搜索。hyperband提前终止策略则会在实验明显落后于同类时提前砍掉它,节省大量算力——对于要跑30个epoch的实验,一个注定失败的组合可能在第6个epoch就被终止了。
四、实验对比与团队协作技巧
Sweep跑完后,真正的价值挖掘发生在分析阶段。wandb的Runs Table支持按任意config字段排序和筛选,勾选多个run后可以直接在同一个图表中叠加曲线对比。还可以用平行坐标图(Parallel Coordinates)观察多个超参数与最终指标的联合关系,快速定位哪个参数对结果影响最大。
团队协作方面有几点建议:统一的项目命名规范,比如项目名-任务-版本;在wandb.init中通过tags和notes标注实验意图,例如tags=["尝试warmup", "resnet50"];把wandb.init的config和代码中的argparse打通,保证任何一次run都能从网页上看到完整配置。另外settings={"git_commit": True}可以让wandb自动记录代码的git commit哈希,复现实验时直接checkout对应的提交即可。
总的来说,wandb的学习成本很低——核心API就wandb.init和wandb.log两个,但带来的规范化收益巨大。建议从下一个项目一开始就接入,而不是等实验已经混乱了再补救,因为实验管理工具的价值恰恰在于记录那些你当时觉得不重要、事后却追悔莫及的信息。
Weights & BiasesMetric日志记录超参数搜索修改时间:2026-09-13 07:18:31