diff --git a/en/api/cli-swanlab-api.md b/en/api/cli-swanlab-api.md index 5bfdd360..8b705eae 100644 --- a/en/api/cli-swanlab-api.md +++ b/en/api/cli-swanlab-api.md @@ -251,20 +251,21 @@ Get scalar metrics for an experiment, returned as JSON. swanlab api run metrics --keys [OPTIONS] ``` -| Argument/Option | Type | Default | Description | -| -------------------- | ---------- | -------- | ----------------------------------------------------------------------------------------- | -| `path` | Positional | Required | Experiment path | -| `--keys` | `str` | Required | Comma-separated metric keys, e.g. `"loss,acc"` | -| `--sample` / `-s` | `int` | `1500` | Sample size; auto-capped if exceeded | -| `--ignore-timestamp` | Flag | `False` | Remove timestamp field from metric data | -| `--all` | Flag | `False` | Fetch full data (CSV export for scalars) | -| `--range-type` | `str` | `None` | Range query type: `step` or `timestamp` | -| `--range-start` | `int` | `None` | Range start (inclusive), step number or unix timestamp in ms | -| `--range-end` | `int` | `None` | Range end (inclusive), step number or unix timestamp in ms | -| `--range-head` | `int` | `None` | Return first N data points | -| `--range-tail` | `int` | `None` | Return last N data points | -| `--range-last` | `int` | `None` | Data from the last N milliseconds (mutually exclusive with `--range-start`/`--range-end`) | -| `--save` | Option | — | Save output as JSON file | +| Argument/Option | Type | Default | Description | +| -------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `path` | Positional | Required | Experiment path | +| `--keys` | `str` | Required | Comma-separated metric keys, e.g. `"loss,acc"` | +| `--sample` / `-s` | `int` | `1500` | Sample size; auto-capped if exceeded | +| `--ignore-timestamp` | Flag | `False` | Remove timestamp field from metric data | +| `--all` | Flag | `False` | Fetch full data (CSV export for scalars) | +| `--x-axis` | `str` | `"step"` | X axis of the returned data: `step` (default), built-in axes `time` / `relative_time`, or a custom X-axis metric key (`swanlab >= 0.10.1`) | +| `--range-type` | `str` | `None` | Range query type: `step`, `timestamp`, or `custom` (custom X-axis value domain; requires `--x-axis`) | +| `--range-start` | `float` | `None` | Range start (inclusive), step number, unix timestamp in ms, or custom X-axis value | +| `--range-end` | `float` | `None` | Range end (inclusive), step number, unix timestamp in ms, or custom X-axis value | +| `--range-head` | `int` | `None` | Return first N data points | +| `--range-tail` | `int` | `None` | Return last N data points | +| `--range-last` | `int` | `None` | Data from the last N milliseconds (mutually exclusive with `--range-start`/`--range-end`) | +| `--save` | Option | — | Save output as JSON file | **Notes:** @@ -272,6 +273,7 @@ swanlab api run metrics --keys [OPTIONS] - `--range-last` is mutually exclusive with `--range-start`/`--range-end`. - `--range-head`/`--range-tail` can be combined with `--range-start`/`--range-end` or `--range-last` (range filter is applied first, then truncation). - `--range-start` and `--range-end` work with `--range-type` (`step` or `timestamp`); timestamps are in milliseconds. +- `--range-type custom` is only valid when `--x-axis` is a custom metric key; in that case `--range-start`/`--range-end` accept any floats (including negatives). `step` / `timestamp` types require non-negative integers. ```bash # Get loss metric (default 1500 samples) @@ -295,6 +297,14 @@ swanlab api run metrics my-team/image-classification/abc123 \ # Step range + first 50 points swanlab api run metrics my-team/image-classification/abc123 \ --keys loss --range-type step --range-start 0 --range-end 500 --range-head 50 + +# Custom X axis: plot loss against epoch +swanlab api run metrics my-team/image-classification/abc123 \ + --keys loss --x-axis epoch + +# Range filter on the custom X-axis value domain (floats allowed) +swanlab api run metrics my-team/image-classification/abc123 \ + --keys loss --x-axis lr --range-type custom --range-start 0.0001 --range-end 0.001 ``` ### run summary diff --git a/en/api/py-api.md b/en/api/py-api.md index 11ae8bf7..ace06e63 100644 --- a/en/api/py-api.md +++ b/en/api/py-api.md @@ -393,24 +393,25 @@ for run in api.runs_get(path="my-team/my-project", page=1, size=100, all=True): Fetch scalar metric data (e.g. loss, acc), supports sampling control and range queries, returns structured data. -| Parameter | Type | Default | Description | -| ------------------ | ---------------------- | ------- | -------------------------------------------------------------------------- | -| `keys` | `list[str]` | — | Metric key list, e.g. `["loss", "acc"]` | -| `sample` | `int` | `1500` | Sample count (SCALAR max 1500), ignored when `all` or `range_query` is set | -| `all` | `bool` | `False` | Get full data (no sampling limit) | -| `range_query` | `dict` or `RangeQuery` | `None` | Range query, only valid for SCALAR type | -| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields | +| Parameter | Type | Default | Description | +| ------------------ | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `keys` | `list[str]` | — | Metric key list, e.g. `["loss", "acc"]` | +| `sample` | `int` | `1500` | Sample count (SCALAR max 1500), ignored when `all` or `range_query` is set | +| `all` | `bool` | `False` | Get full data (no sampling limit) | +| `range_query` | `dict` or `RangeQuery` | `None` | Range query, only valid for SCALAR type | +| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields | +| `x_axis` | `str` | `"step"` | X axis of the returned data: `"step"` (default), built-in axes `"time"` / `"relative_time"`, or any other non-empty string as a custom X-axis metric key (SCALAR only, `swanlab >= 0.10.1`) | **RangeQuery fields:** -| Field | Type | Default | Description | -| ------- | ----- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | `str` | `"step"` | Filter axis: `"step"` or `"timestamp"` | -| `start` | `int` | `None` | Lower bound (inclusive), `None` means no limit. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds** | -| `end` | `int` | `None` | Upper bound (inclusive), `None` means up to the last step. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds** | -| `last` | `int` | `None` | Last N milliseconds (mutually exclusive with `start`/`end`) | -| `head` | `int` | `None` | Take first N data points (mutually exclusive with `tail`, applied after range filtering) | -| `tail` | `int` | `None` | Take last N data points (mutually exclusive with `head`, applied after range filtering) | +| Field | Type | Default | Description | +| ------- | ----- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | `str` | `"step"` | Filter axis: `"step"`, `"timestamp"`, or `"custom"` (filters on the custom X-axis value domain; only valid when `x_axis` is a custom metric key) | +| `start` | `int` | `None` | Lower bound (inclusive), `None` means no limit. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds**; when `type` is `custom`, any float is allowed (including negatives) | +| `end` | `int` | `None` | Upper bound (inclusive), `None` means up to the last step. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds**; when `type` is `custom`, any float is allowed (including negatives) | +| `last` | `int` | `None` | Last N milliseconds (mutually exclusive with `start`/`end`) | +| `head` | `int` | `None` | Take first N data points (mutually exclusive with `tail`, applied after range filtering) | +| `tail` | `int` | `None` | Take last N data points (mutually exclusive with `head`, applied after range filtering) | **Mutual exclusion rules:** @@ -478,6 +479,16 @@ result = run.metrics( # Take last 30 data points result = run.metrics(keys=["loss"], range_query={"tail": 30}) + +# Custom X axis: plot loss against epoch (the X-axis metric must have been logged, e.g. defined via swanlab.define_metric) +result = run.metrics(keys=["loss"], x_axis="epoch") + +# Range filter on the custom X-axis value domain (floats / negatives allowed) +result = run.metrics( + keys=["loss"], + x_axis="lr", + range_query={"type": "custom", "start": 1e-4, "end": 1e-3}, +) ``` ::: @@ -847,12 +858,13 @@ Represents the list of metric keys under an experiment (recommended in `0.9.0+`, ### Key.metric() parameters -| Parameter | Type | Default | Description | -| ------------------ | ------ | ------- | ------------------------------------------------- | -| `sample` | `int` | `1500` | Sample count (max 1500) | -| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields | -| `media_step` | `int` | `None` | Only effective for MEDIA type, specifies the step | -| `all` | `bool` | `False` | Get full data (no sampling limit) | +| Parameter | Type | Default | Description | +| ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sample` | `int` | `1500` | Sample count (max 1500) | +| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields | +| `media_step` | `int` | `None` | Only effective for MEDIA type, specifies the step | +| `all` | `bool` | `False` | Get full data (no sampling limit) | +| `x_axis` | `str` | `"step"` | X axis of the returned data: `"step"` (default), built-in axes `"time"` / `"relative_time"`, or a custom X-axis metric key (SCALAR only, `swanlab >= 0.10.1`) | ### Series / Key method examples diff --git a/en/guide_cloud/experiment_track/log-experiment-metric.md b/en/guide_cloud/experiment_track/log-experiment-metric.md index cf5e7f16..019e67c8 100644 --- a/en/guide_cloud/experiment_track/log-experiment-metric.md +++ b/en/guide_cloud/experiment_track/log-experiment-metric.md @@ -54,6 +54,12 @@ swanlab.log({"train/batch_cost": batch_cost}) swanlab.log({"val/acc": acc}) ``` +:::tip +For metric names with multiple `/` separators, the current strategy uses the last separator. +For example, a metric named `a/b/c` is grouped under `a/b` by default. +If you need a custom group name, you can define it via [swanlab.define_metric()](../../api/py-define_metric.md) before the metric is logged. +::: + ## Specify the Step for Logging When the logging frequency of some metrics is inconsistent but you want their steps to be aligned, you can achieve alignment by setting the `step` parameter of `swanlab.log`: @@ -119,3 +125,30 @@ swanlab.finish() ``` `swanlab.async_log()` supports multiple execution modes (`threading`, `asyncio`, `spawn`). For detailed usage and all mode options, see the [async_log API documentation](../../api/py-async-log.md). + +## Custom X Axis + +:::info +`swanlab.define_metric()` requires SwanLab SDK **v0.10.0 or higher**. +::: + +By default, metric charts use step as the X axis. In some training scenarios (e.g., you want to view metric changes by epoch, learning rate, etc.), you can use `swanlab.define_metric()` to associate a chart's X axis with another metric: + +```python +import swanlab + +swanlab.init(project="my-project") + +# Use train/epoch as the X axis of train/loss +swanlab.define_metric("train/loss", x_axis="train/epoch") + +for epoch in range(num_epochs): + # Log the X-axis metric first + swanlab.log({"train/epoch": epoch}) + # ... training ... + swanlab.log({"train/loss": loss}) +``` + +X-axis and Y-axis metrics can be logged separately — the SDK automatically fills in the most recent X value for each Y value. The `key` also supports glob batch matching (e.g., `train/*`), making it easy to define the X axis for a group of metrics at once. + +For detailed parameter descriptions and notes on custom X axes, see the [define_metric API documentation](../../api/py-define_metric.md). diff --git a/en/guide_cloud/general/changelog.md b/en/guide_cloud/general/changelog.md index 0a8d39ba..8b1ccfb4 100644 --- a/en/guide_cloud/general/changelog.md +++ b/en/guide_cloud/general/changelog.md @@ -5,6 +5,17 @@ Upgrade to latest version: `pip install -U swanlab` Github: https://github.com/SwanHubX/SwanLab ::: +## v0.10.1 - 2026.09.22 + +**🚀 New Features** + +- `OpenAPI/CLI` now supports a custom X-axis parameter when querying experiment metrics + +**🔧 Bug Fixes** + +- Fixed an issue where the writability probe could trigger an IO error on network file systems such as FUSE +- Fixed an issue where experiment metrics synced via `swanlab sync` in `offline` mode were not visible on the frontend charts + ## v0.10.0 - 2026.09.01 **🚀 New Features** diff --git a/zh/api/cli-swanlab-api.md b/zh/api/cli-swanlab-api.md index 5c014fed..048f021d 100644 --- a/zh/api/cli-swanlab-api.md +++ b/zh/api/cli-swanlab-api.md @@ -251,20 +251,21 @@ swanlab api run filter my-team/image-classification -f ./filter.json swanlab api run metrics --keys [OPTIONS] ``` -| 参数/选项 | 类型 | 默认值 | 描述 | -| -------------------- | -------- | ------- | ---------------------------------------------------------- | -| `path` | 位置参数 | 必填 | 实验路径 | -| `--keys` | `str` | 必填 | 逗号分隔的指标名,如 `"loss,acc"` | -| `--sample` / `-s` | `int` | `1500` | 采样数量,超过自动截断 | -| `--ignore-timestamp` | 布尔标志 | `False` | 去掉指标数据中的时间戳字段 | -| `--all` | 布尔标志 | `False` | 获取全量数据(CSV 导出) | -| `--range-type` | `str` | `None` | 范围查询类型:`step` 或 `timestamp` | -| `--range-start` | `int` | `None` | 范围起始值(含),步数或毫秒时间戳 | -| `--range-end` | `int` | `None` | 范围结束值(含),步数或毫秒时间戳 | -| `--range-head` | `int` | `None` | 返回前 N 条数据 | -| `--range-tail` | `int` | `None` | 返回后 N 条数据 | -| `--range-last` | `int` | `None` | 最近 N 毫秒的数据(与 `--range-start`/`--range-end` 互斥) | -| `--save` | 选项 | — | 保存输出为 JSON 文件 | +| 参数/选项 | 类型 | 默认值 | 描述 | +| -------------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------- | +| `path` | 位置参数 | 必填 | 实验路径 | +| `--keys` | `str` | 必填 | 逗号分隔的指标名,如 `"loss,acc"` | +| `--sample` / `-s` | `int` | `1500` | 采样数量,超过自动截断 | +| `--ignore-timestamp` | 布尔标志 | `False` | 去掉指标数据中的时间戳字段 | +| `--all` | 布尔标志 | `False` | 获取全量数据(CSV 导出) | +| `--x-axis` | `str` | `"step"` | 返回数据的 X 轴:`step`(默认)、内置轴 `time` / `relative_time`,或自定义 X 轴指标 key(`swanlab >= 0.10.1`) | +| `--range-type` | `str` | `None` | 范围查询类型:`step`、`timestamp` 或 `custom`(自定义 X 轴值域,需配合 `--x-axis` 使用) | +| `--range-start` | `float` | `None` | 范围起始值(含),步数、毫秒时间戳或自定义 X 轴值 | +| `--range-end` | `float` | `None` | 范围结束值(含),步数、毫秒时间戳或自定义 X 轴值 | +| `--range-head` | `int` | `None` | 返回前 N 条数据 | +| `--range-tail` | `int` | `None` | 返回后 N 条数据 | +| `--range-last` | `int` | `None` | 最近 N 毫秒的数据(与 `--range-start`/`--range-end` 互斥) | +| `--save` | 选项 | — | 保存输出为 JSON 文件 | **注意事项:** @@ -272,6 +273,7 @@ swanlab api run metrics --keys [OPTIONS] - `--range-last` 与 `--range-start`/`--range-end` 互斥。 - `--range-head`/`--range-tail` 可与 `--range-start`/`--range-end` 或 `--range-last` 组合(先范围过滤,再截取)。 - `--range-start` 和 `--range-end` 配合 `--range-type` 使用(`step` 或 `timestamp`),时间戳单位为毫秒。 +- `--range-type custom` 仅在 `--x-axis` 为自定义指标 key 时有效,此时 `--range-start`/`--range-end` 支持任意浮点数(含负数);`step` / `timestamp` 类型要求非负整数。 ```bash # 获取 loss 指标(默认采样 1500 条) @@ -295,6 +297,14 @@ swanlab api run metrics my-team/image-classification/abc123 \ # 步数范围 + 取前 50 个点 swanlab api run metrics my-team/image-classification/abc123 \ --keys loss --range-type step --range-start 0 --range-end 500 --range-head 50 + +# 自定义 X 轴:按 epoch 查看 loss +swanlab api run metrics my-team/image-classification/abc123 \ + --keys loss --x-axis epoch + +# 按自定义 X 轴的值域范围过滤(支持浮点数) +swanlab api run metrics my-team/image-classification/abc123 \ + --keys loss --x-axis lr --range-type custom --range-start 0.0001 --range-end 0.001 ``` ### run summary diff --git a/zh/api/py-api.md b/zh/api/py-api.md index b3403438..71edc28c 100644 --- a/zh/api/py-api.md +++ b/zh/api/py-api.md @@ -393,24 +393,25 @@ for run in api.runs_get(path="my-team/my-project", page=1, size=100, all=True): 获取标量指标数据(如 loss、acc),支持采样控制、范围查询,返回结构化数据。 -| 参数 | 类型 | 默认值 | 描述 | -| ------------------ | ---------------------- | ------- | ---------------------------------------------------------------- | -| `keys` | `list[str]` | — | 指标 key 名称列表,如 `["loss", "acc"]` | -| `sample` | `int` | `1500` | 采样数量(SCALAR 最大 1500),使用 `all` 或 `range_query` 时忽略 | -| `all` | `bool` | `False` | 获取全量数据(不受采样限制) | -| `range_query` | `dict` 或 `RangeQuery` | `None` | 范围查询,仅对 SCALAR 类型有效 | -| `ignore_timestamp` | `bool` | `False` | 是否去除时间戳字段 | +| 参数 | 类型 | 默认值 | 描述 | +| ------------------ | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `keys` | `list[str]` | — | 指标 key 名称列表,如 `["loss", "acc"]` | +| `sample` | `int` | `1500` | 采样数量(SCALAR 最大 1500),使用 `all` 或 `range_query` 时忽略 | +| `all` | `bool` | `False` | 获取全量数据(不受采样限制) | +| `range_query` | `dict` 或 `RangeQuery` | `None` | 范围查询,仅对 SCALAR 类型有效 | +| `ignore_timestamp` | `bool` | `False` | 是否去除时间戳字段 | +| `x_axis` | `str` | `"step"` | 返回数据的 X 轴:`"step"`(默认)、内置轴 `"time"` / `"relative_time"`,或其他非空字符串作为自定义 X 轴指标 key(仅 SCALAR 有效,`swanlab >= 0.10.1`) | **RangeQuery 字段:** -| 字段 | 类型 | 默认值 | 描述 | -| ------- | ----- | -------- | ---------------------------------------------------------------------------------------- | -| `type` | `str` | `"step"` | 过滤轴:`"step"` 或 `"timestamp"` | -| `start` | `int` | `None` | 下界(含),`None` 表示不限制,`type` 为 `timestamp` 时**须为 UNIX 毫秒时间戳** | -| `end` | `int` | `None` | 上界(含),`None` 表示到最后一个 step,`type` 为 `timestamp` 时**须为 UNIX 毫秒时间戳** | -| `last` | `int` | `None` | 最近 N 毫秒(与 `start`/`end` 互斥) | -| `head` | `int` | `None` | 取前 N 个数据点(与 `tail` 互斥,在范围过滤后截取) | -| `tail` | `int` | `None` | 取后 N 个数据点(与 `head` 互斥,在范围过滤后截取) | +| 字段 | 类型 | 默认值 | 描述 | +| ------- | ----- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | `str` | `"step"` | 过滤轴:`"step"`、`"timestamp"` 或 `"custom"`(按自定义 X 轴的值域过滤,仅当 `x_axis` 为自定义指标 key 时有效) | +| `start` | `int` | `None` | 下界(含),`None` 表示不限制,`type` 为 `timestamp` 时**须为 UNIX 毫秒时间戳**;`type` 为 `custom` 时支持任意浮点数(含负数) | +| `end` | `int` | `None` | 上界(含),`None` 表示到最后一个 step,`type` 为 `timestamp` 时**须为 UNIX 毫秒时间戳**;`type` 为 `custom` 时支持任意浮点数(含负数) | +| `last` | `int` | `None` | 最近 N 毫秒(与 `start`/`end` 互斥) | +| `head` | `int` | `None` | 取前 N 个数据点(与 `tail` 互斥,在范围过滤后截取) | +| `tail` | `int` | `None` | 取后 N 个数据点(与 `head` 互斥,在范围过滤后截取) | **互斥规则:** @@ -478,6 +479,16 @@ result = run.metrics( # 取最后 30 个数据点 result = run.metrics(keys=["loss"], range_query={"tail": 30}) + +# 自定义 X 轴:按 epoch 查看 loss(X 轴指标需已随指标上报,如通过 swanlab.define_metric 定义) +result = run.metrics(keys=["loss"], x_axis="epoch") + +# 按自定义 X 轴的值域范围过滤(支持浮点数 / 负数) +result = run.metrics( + keys=["loss"], + x_axis="lr", + range_query={"type": "custom", "start": 1e-4, "end": 1e-3}, +) ``` ::: @@ -847,12 +858,13 @@ if result.ok: ### Key.metric() 入参 -| 参数 | 类型 | 默认值 | 描述 | -| ------------------ | ------ | ------- | ---------------------------- | -| `sample` | `int` | `1500` | 采样数量(最大 1500) | -| `ignore_timestamp` | `bool` | `False` | 是否去除时间戳字段 | -| `media_step` | `int` | `None` | 仅 MEDIA 类型生效,指定 step | -| `all` | `bool` | `False` | 获取全量数据(不受采样限制) | +| 参数 | 类型 | 默认值 | 描述 | +| ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `sample` | `int` | `1500` | 采样数量(最大 1500) | +| `ignore_timestamp` | `bool` | `False` | 是否去除时间戳字段 | +| `media_step` | `int` | `None` | 仅 MEDIA 类型生效,指定 step | +| `all` | `bool` | `False` | 获取全量数据(不受采样限制) | +| `x_axis` | `str` | `"step"` | 返回数据的 X 轴:`"step"`(默认)、内置轴 `"time"` / `"relative_time"`,或自定义 X 轴指标 key(仅 SCALAR 有效,`swanlab >= 0.10.1`) | ### Series / Key 方法示例 diff --git a/zh/guide_cloud/experiment_track/log-experiment-metric.md b/zh/guide_cloud/experiment_track/log-experiment-metric.md index 749eba4e..c78cccc7 100644 --- a/zh/guide_cloud/experiment_track/log-experiment-metric.md +++ b/zh/guide_cloud/experiment_track/log-experiment-metric.md @@ -43,7 +43,7 @@ swanlab.log({"loss": loss, "iter": iter}) ## 指标分组 -在脚本中可以通过指标名的前缀(以“/”为分隔)进行图表分组,例如 `train/loss` 会被分到名为“train”的分组、`val/loss` 会被分到名为“val”的分组: +在脚本中可以通过指标名的前缀(以“/”为分隔)进行图表分组,例如 `train/loss` 会被分到名为“train”的分组、`val/loss` 会被分到名为 `val` 的分组: ```python # 分到train组 @@ -54,6 +54,12 @@ swanlab.log({"train/batch_cost": batch_cost}) swanlab.log({"val/acc": acc}) ``` +:::tip +对于存在多个 `/` 分割线的指标名,目前的策略以最后一个分割线为准。 +例如指标名称为 `a/b/c`,默认以 `a/b` 作为分组名称。 +如果需要自定义分组名称,可以通过 [swanlab.define_metric()](../../api/py-define_metric.md) 在指标被上报之前进行定义。 +::: + ## 指定记录的step 在一些指标的记录频率不一致,但希望它们的step可以对齐时,可以通过设置 `swanlab.log` 的 `step` 参数实现对齐: @@ -119,3 +125,30 @@ swanlab.finish() ``` `swanlab.async_log()` 支持多种执行模式(`threading`、`asyncio`、`spawn`)。详细用法和所有模式选项请参阅 [async_log API 文档](../../api/py-async-log.md)。 + +## 自定义 X 轴 + +:::info +`swanlab.define_metric()` 自定义 X 轴需要 SwanLab SDK **v0.10.0 或更高版本**。 +::: + +默认情况下,指标图表以 step 作为 X 轴。在部分训练场景下(如希望按 epoch、学习率等查看指标变化),可以通过 `swanlab.define_metric()` 将图表的 X 轴关联为另一个指标: + +```python +import swanlab + +swanlab.init(project="my-project") + +# train/loss 以 train/epoch 作为 X 轴 +swanlab.define_metric("train/loss", x_axis="train/epoch") + +for epoch in range(num_epochs): + # 先记录 X 轴指标 + swanlab.log({"train/epoch": epoch}) + # ... 训练 ... + swanlab.log({"train/loss": loss}) +``` + +X 轴指标与 Y 轴指标可以分开记录,SDK 会自动为 Y 值补上最近一次的 X 值;`key` 也支持 glob 批量匹配(如 `train/*`),方便对一组指标统一定义 X 轴。 + +自定义 X 轴的详细参数说明与注意事项,请参阅 [define_metric API 文档](../../api/py-define_metric.md)。 diff --git a/zh/guide_cloud/general/changelog.md b/zh/guide_cloud/general/changelog.md index 7c9e7d6f..fc8c7b94 100644 --- a/zh/guide_cloud/general/changelog.md +++ b/zh/guide_cloud/general/changelog.md @@ -5,6 +5,17 @@ Github: https://github.com/SwanHubX/SwanLab ::: +## v0.10.1 - 2026.09.22 + +**🚀 新增** + +- `OpenAPI/CLI` 实验指标查询时支持自定义 X 轴参数 + +**🔧修复** + +- 修复在 FUSE 等网络文件系统下,可写探针可能触发的IO异常的问题 +- 修复 `offline` 模式下通过 `swanlab sync` 无法在前端图表看到实验指标的问题 + ## v0.10.0 - 2026.09.01 **🚀 新增**