跳转到主要内容

先记录日志,然后再提问。

项目描述

noko

[API参考]

先记录日志,然后再提问。

noko是一个数值日志库,旨在尽可能一次记录尽可能多的变量和多个时间尺度。

noko的典型使用案例如下

loss.backward()
noko.log_row("grad_step", locals(), level=noko.TRACE)
optimizer.step()

这将生成一个名为"grad_step.csv"的日志文件,其中包含每个梯度步骤所有局部变量的信息。

库状态

noko已经很有用,但我仍在继续改进API,添加我发现需要的新功能,并修复遇到的错误。

如果您现在使用此库,请预期API会有所变化,因此请依赖于特定版本。

当前推荐的安装方法是

pip install "noko[recommended]==0.3.0"

您也可以直接从github安装

pip install "git+https://github.com/krzentner/noko.git@v0.3.0#egg=noko[recommended]"

“推荐”额外组件添加了可以轻松安装并支持有用但可选功能的包

  • GitPython用于create_git_checkpoint选项和noko.noko_git.checkpoint_repo()函数。

  • pyarrownoko.arrow_output.ArrowOutputEngine用于将日志记录到parquet文件。请注意,默认情况下不会将此后端添加到日志记录器。

  • tensorboardX 被用于 noko.tb_output.TensorBoardOutput 来记录到 TensorBoard。noko 还可以使用来自 torch.utils.tensorboardtf.summary 的 tensorboard SummaryWriter。默认情况下,此后端会添加到日志记录器中,并尝试首先使用 torch API。

关键思想

大多数数值日志库都期望你一次记录一个键。而 noko 期望你一次记录一个“行”,到一个命名的“表格”中。在上面的例子中,表格名为“grad_step”,行是所有局部变量。

noko 然后遍历行中的所有值,并确定如何总结它们。例如,它将使用每个参数的最小值、最大值、平均值和标准差来总结 PyTorch 神经网络,以及每个参数的梯度值(如果可用)。

一旦总结完成,noko 就会将该行输出到所有日志级别至少与提供的级别敏感的 noko 后端。

后端

始终可用

  • 换行符分隔的 JSON (.ndjson)
  • 逗号分隔值 (.csv)
  • pprint(通常仅用于 stdout)

需要可选依赖项

  • tensorboard(将使用 torch.utils.tensorboard 或 tensorboardX 或 tf.summary)
  • parquet(需要 pyarrow)

行总结

noko 在记录之前会对每个提供的行运行预处理步骤。此预处理通常是 有损的,并将大型输入数组总结为几个标量。这是记录所有局部变量所必需的,并且是 noko 设计中不可避免的权衡。如果您希望能够精确恢复传递给 noko 的值,请首先将其格式化为 strbytes,然后使用 csv、ndjson 或 parquet 后端。

对于内置数据类型(字典、列表、元组),预处理是递归运行的。对于常用的数值库(numpy、pytorch),存在适配器模块来总结常见数据类型。

如果您希望您的类型被展开,您可以定义一个自定义总结器。标准的做法是使用 declare_summarizer,这可以在不修改正在总结的特定类型源的情况下使用。

总结自定义类型 "MyPoint" 的示例

from noko import declare_summarizer, summarize, ScalarTypes

@declare_summarizer(MyPoint):
def summarize_mypoint(point, prefix: str, dst: dict[str, ScalarTypes]):
    # Include x and y fields directly
    dst[f"{prefix}.x"] = point.x
    dst[f"{prefix}.y"] = point.y
    # Recursively summarize metadata
    summarize(point.metadata, f"{prefix}.metadata", dst)

有时您可能会有一些局部变量,在 noko 中记录它们没有意义(例如,长的列表)。在这种情况下,建议的模式是

row = locals()
del row["my_long_list"]
noko.log_row("my_locals", row)

额外工具

noko 有一些其他有用的技巧,可以提高可重现性,可以通过调用 noko.init_extra() 来访问。

这包括

  • wandb 同步和配置记录(如果安装了 wandb)。
  • 如果配置中存在,自动设置大多数库的全局种子值。
  • 自动在单独的分支 noko-checkpoints 上创建当前代码的 git 提交,并使用该检查点添加差异到日志目录(需要安装 GitPython)。

由以下支持