先记录日志,然后再提问。
项目描述
noko
先记录日志,然后再提问。
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()
函数。 -
pyarrow
由noko.arrow_output.ArrowOutputEngine
用于将日志记录到parquet文件。请注意,默认情况下不会将此后端添加到日志记录器。 -
tensorboardX
被用于noko.tb_output.TensorBoardOutput
来记录到 TensorBoard。noko
还可以使用来自torch.utils.tensorboard
和tf.summary
的 tensorboardSummaryWriter
。默认情况下,此后端会添加到日志记录器中,并尝试首先使用 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
的值,请首先将其格式化为 str
或 bytes
,然后使用 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
)。