跟踪
简介
Trackio 帮助你在 项目 中组织实验。 项目是一组 运行 的集合,其中每次运行代表使用特定参数集和结果执行代码的一次过程。
初始化
要开始使用 Trackio 跟踪实验,首先需要调用 init() 函数来初始化一个项目:
import trackio
trackio.init(project="my_project")- 如果项目已存在,则会加载该项目。
- 否则,Trackio 将创建一个新的。
在这两种情况下,都会自动启动一个新的运行,随时准备记录数据。
命名你的运行
为每次运行赋予一个有意义的名称,便于后续整理和引用,这是一个好习惯。
你可以通过 name 参数来设置名称:
trackio.init(project="my_project", name="my_first_run")如果未提供名称,Trackio 将生成一个默认名称。
分组运行
你可以使用 group 参数将相关的运行组织成组。当你使用不同配置运行多个实验并希望将它们放在一起进行比较时,这一点特别有用:
# Group runs by experiment type
trackio.init(project="my_project", name="baseline_run_1", group="baseline")
trackio.init(project="my_project", name="augmented_run_1", group="augmented")
trackio.init(project="my_project", name="tuned_run_1", group="tuned")使用相同组名的运行可以在侧边栏中分组显示,便于比较相关实验。您还可以通过任何其他配置参数对运行进行分组(参见下文中的跟踪配置)。
远程日志记录(Hugging Face Space 或自托管服务器)
默认情况下,指标会存储在本地,并且您会在自己的机器上打开仪表板。您也可以将指标发送到:
- 通过传入
space_id(或设置TRACKIO_SPACE_ID)来指定一个 Hugging Face Space。Trackio 可以创建或复用该 Space,并将数据同步到其中。 - 通过传入
server_url(或设置TRACKIO_SERVER_URL)来使用 自托管的 Trackio 服务器(HTTP 或 HTTPS)。请使用trackio.show()提供的具有写入权限的 URL(可选地在查询参数中包含write_token),或者使用基础 URL 加上TRACKIO_WRITE_TOKEN。客户端使用与仪表板相同的 写入令牌 进行身份验证(而非您的 Hugging Face 令牌)。
如果同时配置了 Space 和自托管 URL(space_id / TRACKIO_SPACE_ID 与 server_url / TRACKIO_SERVER_URL),则 Space 优先,自托管 URL 将被忽略。诸如 dataset_id(已弃用;请改用 bucket_id)和 bucket_id 等选项适用于 Hugging Face 部署;当仅 server_url 生效时,请在运行服务器的托管方上配置存储(参见 环境变量)。
有关设置步骤(运行 trackio show、绑定到 0.0.0.0、写入令牌),请参阅 自托管服务器。
内置仪表板在本地主机上每 1 秒 轮询一次新的运行和指标,在 Hugging Face Space(*.hf.space)上打开时则每 2 秒 轮询一次,以缓解 Space URL 的速率限制。
记录数据
初始化运行后,您可以使用 log() 函数开始记录数据:
trackio.log({"loss": 0.05})Trackio 采用防御性编程方式编写,因此 Trackio 端的故障绝不会导致您的主实验代码崩溃。在正常使用情况下,Trackio 日志记录、刷新或传输路径中出现的问题会降级为警告和本地缓冲,而不会从您的训练循环中抛出异常。
每次调用 log() 都会自动递增步骤计数器。 如果您想一次性记录多个指标,请将它们一起传入:
trackio.log({
"loss": 0.05,
"accuracy": 0.95,
})日志表格
您可以使用 Table 类来记录表格数据。这对于跟踪预测结果或任何结构化数据都非常有用。表格可以使用 Image 类包含图像列。
import pandas as pd
df = pd.DataFrame(
{
"prompt": ["Trackio", "Logging is"],
"completion": ["is great!", "easy and fun!"],
"reward": [0.123, 0.456],
}
)
trackio.log(
{
...
"texts": trackio.Table(dataframe=df),
}
)日志报告(Markdown)
您可以使用 Markdown 类记录报告。报告将显示在仪表板的 Reports 页面中,最新的报告会排在最前面。
trackio.log(
{
"training_report": trackio.Markdown(
"""# Training Report
Final validation accuracy: **0.92**
- Best epoch: 18
- Early stopping: enabled
"""
)
}
)您可以在一次运行中多次记录报告(例如,每个检查点记录一份报告),Trackio 会保留跨步骤的完整历史记录。
完整的可运行脚本,请参见 examples/training-with-report.py。
记录图像
您可以使用 Image 类来记录图像。
trackio.log({"image": trackio.Image(value="path/to/image.png", caption="Image caption")})图像可以从路径、numpy 数组或 PIL Image 进行记录。
记录视频
您可以使用 Video 类来记录视频。
import trackio
import numpy as np
# Create a simple video from numpy array
frames = np.random.randint(0, 255, (10, 3, 64, 64), dtype=np.uint8)
video = trackio.Video(frames, caption="Random video", fps=30)
trackio.log({"my_video": video})
# Create a batch of videos
batch_frames = np.random.randint(0, 255, (3, 10, 3, 64, 64), dtype=np.uint8)
batch_video = trackio.Video(batch_frames, caption="Batch of videos", fps=15)
trackio.log({"batch_videos": batch_video})
# Create video from file path
video = trackio.Video("path/to/video.mp4", caption="Video from file")
trackio.log({"file_video": video})视频可以从文件路径或 numpy 数组记录。
Numpy 数组要求:
- 类型必须为
np.uint8,RGB 值范围为[0, 255] - 形状应为以下之一:
- 单个视频的
(frames, channels, height, width) (batch, frames, channels, height, width)用于多个视频(将被平铺为网格)
- 单个视频的
记录音频
您可以使用 Audio 类来记录音频。
import trackio
import numpy as np
# Generate a 1-second 440 Hz sine wave (mono)
sr = 16000
t = np.linspace(0, 1, sr, endpoint=False)
wave = 0.2 * np.sin(2 * np.pi * 440 * t)
audio = trackio.Audio(wave, caption="A4 sine", sample_rate=sr, format="wav")
trackio.log({"tone": audio})
# Stereo from numpy array (shape: samples, 2)
stereo = np.stack([wave, wave], axis=1)
audio = trackio.Audio(stereo, caption="Stereo", sample_rate=sr, format="mp3")
trackio.log({"stereo": audio})
# From an existing file
audio = trackio.Audio("path/to/audio.wav", caption="From file")
trackio.log({"file_audio": audio})音频可以从文件路径或 numpy 数组记录。
Numpy 数组要求:
- Shape 应为
(samples,)(单声道)或(samples, 2)(立体声) sample_rate在从 numpy 数组记录时必须提供- 值可以是浮点数或整数;浮点数会进行峰值归一化并转换为 16 位 PCM
format在从 numpy 数组记录日志时可以是"wav"或"mp3"(默认值为"wav")
记录 3D 对象
使用 Object3D,并采用与其他媒体相同的 trackio.log() API:
import numpy as np
import trackio
trackio.log({"scene": trackio.Object3D("path/to/scene.glb", caption="Prediction")})
points = np.random.normal(size=(50_000, 3))
trackio.log({"point_cloud": trackio.Object3D.from_numpy(points)})| 格式 | Mesh | 点云 | 高斯泼溅 |
|---|---|---|---|
.glb / .gltf | 是的 | 通过 glTF | No |
.obj | 是的 | No | No |
.stl | 是的 | No | No |
.ply | 是的 | 是的 | 是的 |
.splat | No | No | 是的 |
NumPy 数组必须具有以下形状之一:
(N, 3)表示 XYZ 坐标。(N, 4)表示 XYZ 加上一个从 1 到 14 的整数类别。Trackio 会应用一个确定性的类别调色板。(N, 6)表示 XYZ 加上 0 到 255 之间的整数 RGB 值。
坐标必须是有限值。普通点云在渲染时确定性地限制为 300,000 个点;其原始点数和渲染点数仍然可见。Trackio 不会对网格或高斯泼溅进行抽稀。
模型必须是自包含的。支持嵌入的 glTF 数据 URI,但不支持外部 glTF 资源、OBJ 材质库和 PLY 纹理。所有对象都使用与图像、视频和音频相同的 <project>/<run>/<step>/<uuid>.<ext> 布局。
3D 对象也可以在表格中使用:
table = trackio.Table(
columns=["sample", "reconstruction"],
data=[["chair", trackio.Object3D("chair.gltf")]],
)
trackio.log({"reconstructions": table})记录 HTML 和图表
您可以使用 Html 类来记录 HTML。
trackio.log({"report": trackio.Html("<h1>Results</h1>")})Matplotlib 和 Plotly 图表会被转换为 HTML:
import plotly.express as px
fig = px.line(x=[1, 2, 3], y=[4, 5, 6])
trackio.log({"plot": fig})记录系统指标
Trackio 可以在后台自动记录系统指标。它同时支持 NVIDIA GPU 和 Apple Silicon(M 系列)Mac。
安装:
# NVIDIA GPU monitoring
pip install trackio[gpu]
# Apple Silicon system monitoring
pip install trackio[apple-gpu]自动记录(默认):
当安装了相应的软件包并检测到兼容的硬件时,系统指标会在后台自动记录(默认每 10 秒一次):
import trackio
# Auto-enabled when hardware is detected
trackio.init(project="my_project")
for step in range(100):
# ... training code ...
trackio.log({"loss": loss})
# System metrics are logged automatically in the background
trackio.finish()您可以自定义间隔或禁用自动日志记录:
# Custom interval
trackio.init(project="my_project", gpu_log_interval=5.0)
# Disable auto-logging
trackio.init(project="my_project", auto_log_gpu=False)手动记录:
您还可以使用 log_gpu() 在特定时间手动记录系统指标:
import trackio
trackio.init(project="my_project", auto_log_gpu=False)
for step in range(100):
# ... training code ...
trackio.log({"loss": loss})
trackio.log_gpu() # Log system metrics at current time
trackio.finish()NVIDIA GPU 指标:
单 GPU 指标(gpu/{i}/{metric}):
gpu/0/utilization- GPU 利用率 %gpu/0/memory_utilization- 内存控制器利用率 %gpu/0/allocated_memory- 以 GiB 为单位的已分配内存gpu/0/total_memory- 以 GiB 为单位的总内存gpu/0/memory_usage- 内存使用率(0-1)gpu/0/temp- 摄氏温度gpu/0/power- 功耗(瓦特)gpu/0/power_percent- 功耗占上限的百分比gpu/0/power_limit- 以瓦特为单位的功率限制gpu/0/sm_clock- 以 MHz 为单位的 SM 时钟速度gpu/0/memory_clock- 以 MHz 为单位的内存时钟速度gpu/0/fan_speed- 风扇转速 %gpu/0/performance_state- 性能状态(P0-P15)gpu/0/energy_consumed- 自运行开始以来消耗的电能,单位为焦耳gpu/0/pcie_tx- PCIe 发送带宽,单位为 MB/sgpu/0/pcie_rx- PCIe 接收带宽,单位为 MB/sgpu/0/throttle_thermal- 热节流(0/1)gpu/0/throttle_power- 功率调节(0/1)gpu/0/throttle_hw_slowdown- 硬件降速(0/1)gpu/0/throttle_apps- 应用程序时钟节流(0/1)gpu/0/corrected_memory_errors- ECC 已纠正错误gpu/0/uncorrected_memory_errors- ECC 不可纠正错误
聚合指标:
gpu/mean_utilization- 所有 GPU 的平均利用率gpu/total_allocated_memory- 所有 GPU 上使用的总内存(以 GiB 为单位)gpu/total_power- 所有 GPU 的总功耗gpu/max_temp- 所有 GPU 的最高温度
Apple Silicon 指标:
cpu/utilization- 整体 CPU 使用率 %cpu/{i}/utilization- 每个核心的 CPU 使用率 %cpu/frequency- 当前 CPU 频率(单位:MHz)cpu/frequency_max- 最大 CPU 频率(单位:MHz)memory/used- 以 GiB 为单位的已用内存memory/total- 以 GiB 为单位的总内存memory/available- 可用内存(GiB)memory/percent- 内存使用率swap/used- 已使用的交换空间(GiB)swap/total- 总交换空间(GiB)swap/percent- 交换分区使用率temp/{label}- 温度传感器读数,单位为摄氏度(如果可用)gpu/detected- 是否检测到 Apple GPU(0/1)
捕获控制台输出和启动命令
Trackio 会记录用于启动每次运行的命令(例如 python train.py --lr 1e-3),并在仪表板中该运行页面的顶部显示该命令,同时提供一键复制按钮。对于名称看起来像密钥的参数(例如 --hub_token、--api-key 或 password=...),其值会被替换为 REDACTED。该命令会存储在运行的配置中,位于保留键 _Command 下。
Trackio 还可以捕获脚本写入 stdout 和 stderr 的所有内容,包括 print() 调用、logging 输出以及回溯信息,这样即使您不在终端旁,也可以从仪表板跟踪运行的日志。控制台捕获默认处于关闭状态。使用 capture_console=True 将其开启:
import logging
import trackio
logging.basicConfig(level=logging.INFO)
trackio.init(project="my_project", capture_console=True)
for step in range(100):
loss = ...
logging.info("step %d loss=%.4f", step, loss)
trackio.log({"loss": loss})
trackio.finish()或者,通过设置 TRACKIO_CAPTURE_CONSOLE 环境变量来启用它,而无需更改代码:
TRACKIO_CAPTURE_CONSOLE=1 python train.py
捕获的输出会显示在运行页面的 Console output 部分(从 Runs 页面打开某个运行)。在运行进行期间,该部分每 10 秒刷新一次,Download 按钮可将完整日志保存为文本文件。每一行都会记录其写入时的 UTC 时间;仪表板会将其显示为您的本地时间。输出每 10 秒保存一次,并在运行结束时保存,适用于本地运行以及记录到 Space 或自托管服务器的运行,每个运行的上限为 20 MB。
如果进程被 SIGTERM 停止(例如 Slurm 时间限制、docker stop 或 Kubernetes 驱逐),自上次保存以来写入的输出将会丢失。设置 TRACKIO_HANDLE_SIGTERM=1 可在进程退出前保存这些输出。
控制台捕获通过包装 sys.stdout 和 sys.stderr 的 write 方法来实现,因此它也能捕获在调用 trackio.init() 之前配置的 logging 处理器。直接写入底层文件描述符的输出(例如来自 C 扩展或子进程的消息)不会被捕获。
注意: 如果您记录到公共 Space,捕获的控制台输出将对任何可以查看仪表板的人可见。在启用控制台捕获之前,请确保您的脚本不会打印机密信息。
结束运行
当您的运行完成后,使用 finish() 将其标记为结束。 这会将该运行标记为已完成,并保存所有已记录的数据:
trackio.finish()
恢复运行
Trackio 在内部通过稳定的 run_id 来识别运行。人类可读的 name 不再要求唯一,因此您可以创建多个具有相同显示名称的运行。
如果需要继续运行指定名称的最新运行(例如,在运行中断后),请再次调用 init(),使用相同的项目和运行名称,并设置 resume="must":
trackio.init(project="my_project", name="my_first_run", resume="must")这将加载最近创建的具有该名称的运行,以便您可以继续使用相同的 run_id 记录数据。但如果您设置 resume="must",且不存在具有相同名称的先前运行,Trackio 将引发错误。
为了获得更大的灵活性,请使用 resume="allow"。如果存在同名运行,则会恢复最近一次运行;否则,将创建新的运行。
默认值为 resume="never",即始终创建一个带有新 run_id 的全新运行,即使已存在具有相同 name 的其他运行也是如此。
跟踪配置
您还可以跟踪运行中的配置参数。这对于记录实验中使用超参数或其他设置非常有用。您可以在 init() 函数中使用 config 参数来记录配置数据:
for batch_size in [16, 32, 64]:
for lr in [0.001, 0.01, 0.1]:
trackio.init(
project="hyperparameter_tuning",
name=f"lr_{lr}_batch_{batch_size}_run",
config={
"learning_rate": lr,
"batch_size": batch_size,
}
)
# ... your training code ...
trackio.finish()在仪表板中,您可以按“learning_rate”或“batch_size”进行分组,以便更轻松地比较具有不同超参数的运行。
Update on GitHub