
PyTorch Lightning 高级日志与实验追踪从进度条定制到分布式指标同步的完整指南【免费下载链接】pytorch-lightningPretrain, finetune ANY AI model of ANY size on 1 or 10,000 GPUs with zero code changes.项目地址: https://gitcode.com/gh_mirrors/py/pytorch-lightning导读本文聚焦 PyTorch Lightning 中实验记录Logging的高级玩法涵盖进度条定制、日志频率与刷盘flush调优、self.log全部关键参数的语义与默认值、分布式环境下基于 TorchMetrics 的指标聚合以及将日志写入 S3/GCS 等云文件系统。读完本文你将能够按训练性能需求精确控制 Lightning 的日志开销并在多卡环境中正确、安全地记录与同步指标且不触碰底层分布式通信细节。本文主体基于仓库文档 visualize/logging_advanced.rst并辅以 LightningModule.log 源码、日志默认值校验器 _FxValidator 等实现细节进行纵深解析。修改进度条默认显示内容进度条默认会显示版本号v_num等由 Trainer 注入的标准指标。若你希望调整显示项例如隐藏版本号、重命名指标、或只保留你关心的 loss可以继承Tqdm进度条类并覆写get_metrics方法from lightning.pytorch.callbacks.progress import Tqdm class CustomProgressBar(Tqdm): def get_metrics(self, *args, **kwargs): # dont show the version number items super().get_metrics() items.pop(v_num, None) return items在源码中ProgressBar基类的 get_metrics 负责把 Trainer 收集到的进度条指标与get_standard_metrics得到的标准指标合并因此子类中先调用super().get_metrics()拿到完整字典、再按需增删是最稳妥的覆写方式。仓库中还提供了一个 Rich 进度条实现 RichProgressBar.get_metrics它在父类结果的基础上把所有torch.Tensor转换为 Python float 再交给 Rich 渲染——这也是先继承再加工的典型范式可作为自定义进度条的参考。完成自定义类后将其作为 callback 传入 Trainertrainer Trainer(callbacks[CustomProgressBar()])定制记录策略以加速训练调整日志频率log_every_n_steps在每一个 batch 上都记录指标会拖慢训练。默认情况下Lightning 每 50 行即每 50 个训练步写一次日志。Trainer 构造参数 log_every_n_steps 的默认值即为50。k 10 trainer Trainer(log_every_n_stepsk)从源码看这个频率由_LoggerConnector.should_update_logs决定logger_connector.pyshould_log step % trainer.log_every_n_steps 0 return should_log or trainer.should_stop即当前步数对log_every_n_steps取模为 0 时才触发日志写入should_stop为真时也会强制写一次确保提前停止时指标不丢失。值得注意的是log_every_n_steps0会直接返回False相当于完全关闭按步日志。如果你使用的是Trainer(barebonesTrue)极速裸奔模式源码会强制log_every_n_steps为 0 并禁用进度条因为日志会影响裸速度见 trainer.py可见日志频率与训练吞吐之间存在直接的权衡。调整刷盘频率max_queue与flush_secs某些 Logger 会先把指标缓存在内存中 N 步再周期性刷到磁盘以减少 I/O 开销。不同 Logger 的刷盘机制各不相同这里以 TensorBoard 为例# Default used by TensorBoard: Write to disk after 10 logging events or every two minutes logger TensorBoardLogger(..., max_queue10, flush_secs120) # Faster training, more memory used logger TensorBoardLogger(..., max_queue100) # Slower training, less memory used logger TensorBoardLogger(..., max_queue1)TensorBoardLogger的构造器tensorboard.py会把max_queue、flush_secs等额外关键字参数直接透传给SummaryWritermax_queue表示刷盘前排队等待写入的日志条数flush_secs表示每隔多少秒自动刷盘。增大max_queue能减少写盘次数、加速训练但会占用更多内存将其调小则相反。日志记录本身属于簿记工作不应进入计算图——这正是LightningModule.log用torch.compiler.disable装饰的原因见 module.py在torch.compile包装模型后日志逻辑仍以 eager Python 方式执行。深入解析 self.log 的全部行为参数LightningModule.log是实验记录的核心 API其完整签名与参数注释位于 core/module.py。下面逐项说明每个参数的作用与默认值并补充源码层面的行为细节。add_dataloader_idx默认值True如果为True在使用多个 dataloader 时会把当前 dataloader 的索引追加到指标名中形如metric/dataloader_idx_0。如果为False则需要你为每个 dataloader 的指标起唯一的名字以免数值互相覆盖。self.log(add_dataloader_idxTrue)源码中有一层保护当add_dataloader_idxTrue时如果指标名中已经含有/dataloader_idx_会抛出MisconfigurationException防止用户手工拼写索引与自动追加逻辑冲突module.py。batch_size默认值None用于on_epochTrue时按 epoch 累积日志的当前 batch 大小。通常可以直接从加载的 batch 推断出来但对某些数据结构例如dataloader_iter风格的training_step需要显式指定。self.log(batch_size32)源码强制要求当training_step的签名显式使用dataloader_iter参数时必须提供batch_size否则直接抛出MisconfigurationExceptionmodule.py。enable_graph默认值True如果为True则不会自动 detach 计算图保留梯度图供后续反向传播使用。默认开启可避免因 detach 导致的反向传播中断仅在确认需要时再手动调整。self.log(enable_graphTrue)logger默认值True控制是否把日志发送给 Logger如 TensorBoard或任何通过Trainer(logger...)传入的自定义 Logger。self.log(loggerTrue)当loggerTrue但 Trainer 没有配置任何 Logger 时源码会发出rank_zero_warn警告module.py即使如此指标仍会被计算因为评测循环需要用它们作为返回值。所有 Logger 都继承自 Logger 基类通过实现log_metrics/log_hyperparams等抽象接口接入。on_epoch默认值因调用位置而异如果为True该次self.log调用会把指标累积起来并在 epoch 结束时统一归约reduce。默认值取决于调用所在的 hookdef training_step(self, batch, batch_idx): # Default: False self.log(on_epochFalse) def validation_step(self, batch, batch_idx): # Default: True self.log(on_epochTrue) def test_step(self, batch, batch_idx): # Default: True self.log(on_epochTrue)on_step默认值因调用位置而异如果为True该次self.log调用不会累积指标而是生成一条跨 step 的时间序列timeseries。def training_step(self, batch, batch_idx): # Default: True self.log(on_stepTrue) def validation_step(self, batch, batch_idx): # Default: False self.log(on_stepFalse) def test_step(self, batch, batch_idx): # Default: False self.log(on_stepFalse)prog_bar默认值False如果为True日志会同时发送到进度条显示。self.log(prog_barTrue)rank_zero_only默认值False告诉 Lightning 你是从每个进程都调用self.log默认还是只在 rank 0 上调用。这是为高级用户准备的如果你希望自己手工跨进程归约指标但又想享受self.log的自动记录便利可以用它。设为False默认所有进程都会调用self.logLightning 负责自动同步。设为True仅 rank 0 调用self.log。注意此时该指标不能用作回调中的 monitor例如 EarlyStopping 的监控指标因为回调需要全进程一致的数值。# Default self.log(..., rank_zero_onlyFalse) # If you call self.log on rank 0 only, you need to set rank_zero_onlyTrue if self.trainer.global_rank 0: self.log(..., rank_zero_onlyTrue) # DONT do this, it will cause deadlocks! self.log(..., rank_zero_onlyTrue)警告在不加 rank 判断的情况下直接设置rank_zero_onlyTrue会导致分布式死锁deadlock。因为 Lightning 内部会发起跨进程的集合通信collective而其他进程没有参与同一通信点训练将挂起。reduce_fx默认值torch.mean指定 epoch 结束时对 step 值做归约的函数默认使用torch.mean。当记录的是torchmetrics.Metric对象时该参数不生效因为 Metric 自身管理归约逻辑。self.log(..., reduce_fxtorch.mean)sync_dist默认值False如果为True指标会跨设备归约reduce。请谨慎使用因为它会带来显著的通信开销。self.log(sync_distFalse)源码中该开关只在分布式环境下生效sync_distsync_dist and trainer._accelerator_connector.is_distributed实际归约函数取自trainer.strategy.reducemodule.py。sync_dist_group默认值None指定用于同步的 DDP 通信组process group用于跨特定进程子集同步指标。import torch.distributed as dist group dist.init_process_group(nccl, rankself.global_rank, world_sizeself.world_size) self.log(sync_dist_groupgroup)分布式训练下的指标聚合使用 TorchMetrics对于需要复杂聚合的指标官方推荐基于 TorchMetrics 构建因为 TorchMetrics 完整封装了分布式环境下指标聚合的全部复杂性状态同步、归约函数、batch 边界处理等。首先实现自定义 Metricimport torch import torchmetrics class MyAccuracy(Metric): def __init__(self, dist_sync_on_stepFalse): # call self.add_statefor every internal state that is needed for the metrics computations # dist_reduce_fx indicates the function that should be used to reduce # state from multiple processes super().__init__(dist_sync_on_stepdist_sync_on_step) self.add_state(correct, defaulttorch.tensor(0), dist_reduce_fxsum) self.add_state(total, defaulttorch.tensor(0), dist_reduce_fxsum) def update(self, preds: torch.Tensor, target: torch.Tensor): # update metric states preds, target self._input_format(preds, target) assert preds.shape target.shape self.correct torch.sum(preds target) self.total target.numel() def compute(self): # compute final result return self.correct.float() / self.total在 Lightning 中使用该指标需要三步1) 在__init__中初始化2) 在 step 中计算指标3) 把指标传入self.logclass LitModel(LightningModule): def __init__(self): # 1. initialize the metric self.accuracy MyAccuracy() def training_step(self, batch, batch_idx): x, y batch preds self(x) # 2. compute the metric self.accuracy(preds, y) # 3. log it self.log(train_acc_step, self.accuracy)注意add_state中的dist_reduce_fxsum它定义了多个进程上的内部状态如何归约——这里用求和把各进程统计的correct与total汇总从而得到全局准确的准确率这正是self.log(sync_distTrue)无法完全替代的后者只是对已计算好的指标值做简单归约。从源码看当metric_attribute未指定且记录值是Metric时Lightning 会自动在模型的所有子模块中查找该 Metric 的引用用于在 checkpoint 中恢复指标状态若找不到会抛出MisconfigurationException并提示通过metric_attribute...显式指定module.py。将日志写入云文件系统S3 / GCS / ADLLightning 已与主流远程文件系统集成包括本地文件系统以及 AWS S3、Google Cloud GCS、Azure Data LakeADL等云存储。PyTorch Lightning 内部使用 fsspec 的实现即为fs, _ url_to_fs(str(path))即通过 URL 的协议前缀解析出对应的文件系统后端。要把日志保存到远程文件系统只需在 Logger 的save_dir即写入/读取模型数据的 root_dir前加上协议前缀即可from lightning.pytorch.loggers import TensorBoardLogger logger TensorBoardLogger(save_dirs3://my_bucket/logs/) trainer Trainer(loggerlogger) trainer.fit(model)同理gcs://...、adl://...等协议前缀对应各自的云存储后端。由于底层统一走 fsspeccheckpoint 保存、恢复等所有文件操作都能透明地迁移到云上无需改动业务代码。同时跟踪 step 与 epoch 两套指标如果希望既保留跨 step 的时间序列又得到按 epoch 累积的指标把on_step与on_epoch同时设为True即可self.log(on_stepTrue, on_epochTrue)此时 Lightning 会生成两张曲线图带_step后缀的 step 级时间序列以及带_epoch后缀的 epoch 累积指标二者互不干扰。理解 self.log 的自动行为默认值全表下表汇总了on_step与on_epoch在LightningModule与Callback不同方法中的默认值。这套默认规则在源码 fx_validator.py 中以_LogOptions的形式集中维护log()内部通过_FxValidator.check_logging_and_get_default_levels在运行时解析module.py。该校验器不仅提供默认值还会校验你在该 hook 中传入的on_step/on_epoch组合是否合法。在 LightningModule 中方法on_stepon_epochon_after_backward,on_before_backward,on_before_optimizer_step,optimizer_step,configure_gradient_clipping,on_before_zero_grad,training_stepTrueFalsetest_step,validation_stepFalseTrue在 Callback 中方法on_stepon_epochon_after_backward,on_before_backward,on_before_optimizer_step,on_before_zero_grad,on_train_batch_start,on_train_batch_endTrueFalseon_train_epoch_start,on_train_epoch_end,on_train_start,on_validation_batch_start,on_validation_batch_end,on_validation_start,on_validation_epoch_start,on_validation_epoch_endFalseTrue对照源码可以发现一条清晰的规律凡属于训练过程中高频触发、与单个 batch 紧密相关的 hookbackward、optimizer step、train batch 起止等默认走on_stepTrue的时序记录凡属于评测/epoch 边界性质的 hookvalidation/test step、epoch 起止、run 起止等默认走on_epochTrue的累积记录因为验证集指标天然需要在完整 epoch 上计算才有意义。注意如果希望在上述列表之外、尚未支持日志的 hook 中添加记录官方建议在 GitHub 上提交 issue并清晰描述其使用场景以便社区评估支持方案。小结高级日志定制的本质是在信息完整度与训练吞吐之间做权衡log_every_n_steps与max_queue/flush_secs控制写日志的频率与时机self.log的on_step/on_epoch/prog_bar/logger决定指标的流向与粒度sync_dist/sync_dist_group/rank_zero_only控制分布式同步语义TorchMetrics 则把分布式聚合的复杂度封装在 Metric 内部。理解_FxValidator的默认值机制后你便能在任何 hook 中准确地预测并控制日志行为做到既不遗漏关键指标也不为记录付出不必要的性能代价。【免费下载链接】pytorch-lightningPretrain, finetune ANY AI model of ANY size on 1 or 10,000 GPUs with zero code changes.项目地址: https://gitcode.com/gh_mirrors/py/pytorch-lightning创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考