You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`create_superimposed_card(title, tags, run_id)` — helper for superimposed card entries
212
216
213
-
Key parameters of `create_profile` / `set_default_profile` include `pinned_cards`, `run_colors`, `superimposed_cards`, `run_selection`, `selected_runs`, `metric_descriptions`, `tag_filter`, `smoothing`, `y_axis_scale`, `x_axis_scale`, `tag_axis_scales`, `symlog_linear_threshold`, `tag_symlog_linear_thresholds`, `expanded_tag_groups`, and `group_by`. See the docstrings for full details.
217
+
`Profile` properties include `name`, `pinned_cards`, `run_colors` (dict, not list), `group_colors` (dict), `superimposed_cards`, `run_selection`, `metric_descriptions`, `tag_filter`, `smoothing`, `y_axis_scale`, `x_axis_scale`, `tag_axis_scales`, `symlog_linear_threshold`, `tag_symlog_linear_thresholds`, `expanded_tag_groups`, and `group_by`. Convenience methods: `pin_scalar()`, `pin_histogram()`, `pin_image()`, `add_superimposed_card()`, `select_runs()`. See the docstrings for full details.
214
218
215
219
Profile data schema version is tracked via `PROFILE_VERSION = 1`.
216
220
@@ -366,7 +370,11 @@ Key CI details:
366
370
2. Update `createEmptyProfile()` to include the new field's default value
367
371
3. Update `isValidProfile()` to validate the new field
368
372
4. If the change is breaking: bump `PROFILE_VERSION` and add migration logic in `migrateProfile()`
369
-
5. Update `profile_writer.py` (`create_profile` function) to accept the new field
373
+
5. Update `profile_writer.py`:
374
+
- Add the field to the `ProfileData` TypedDict (and `_ProfileDataRequired` if required)
375
+
- Add a property (getter + setter) on the `Profile` class
376
+
- Add the field to `Profile.__init__`, `serialize()`, `from_serialized()`, `update()`, and `__or__`
377
+
- Add the field to the `create_profile()` / `set_default_profile()` signatures
370
378
6. Update `profile_effects.ts` to apply the new field when activating a profile
combined = base | overlay # dicts merged, lists extended, scalars from overlay
231
+
combined.write(logdir)
210
232
```
211
233
212
234
The default profile auto-applies when a user opens TensorBored at this logdir, but only if they don't already have a local profile active. User-created profiles always take priority over the backend default.
213
235
236
+
The one-shot `set_default_profile(logdir, ...)` helper is still available if you don't need the intermediate `Profile` object.
237
+
214
238
### Profile Data Schema
215
239
216
240
A profile contains the following fields:
@@ -258,23 +282,11 @@ Superimposed cards support:
258
282
```python
259
283
from tensorbored.plugins.core import profile_writer
'gradients/global_norm': 'Global L2 norm of all model gradients before clipping.',
312
323
},
313
324
)
325
+
p.write('./logs')
314
326
```
315
327
316
328
Descriptions are set via the `metric_descriptions` parameter in the profile writer. They support Markdown formatting. The descriptions are served by the backend through the `/data/tags` endpoint and displayed as tooltips on scalar, histogram, and image cards.
@@ -527,9 +539,66 @@ The `SummaryWriter` API is identical — only the import changes. You no longer
The core type. Wraps the camelCase JSON the frontend expects behind snake_case properties. Created via `create_profile()`, `Profile(...)`, `Profile.load(logdir)`, or `Profile.from_serialized(dict)`.
545
+
546
+
**Properties** (all have getters and setters):
547
+
548
+
| Property | Type | Default | Description |
549
+
|----------|------|---------|-------------|
550
+
|`name`|`str`|`"Default Profile"`| Display name |
551
+
|`pinned_cards`|`list[dict]`|`[]`| Cards to pin (use `pin_scalar` etc.) |
552
+
|`run_colors`|`dict[str, str]`|`{}`| Run name/ID → hex color |
553
+
|`group_colors`|`dict[str, int]`|`{}`| Group key → color palette index |
Copy file name to clipboardExpand all lines: NEW.md
+11-17Lines changed: 11 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,14 +29,14 @@ Want full control? Set them from your training script:
29
29
```python
30
30
from tensorbored.plugins.core import profile_writer
31
31
32
-
profile_writer.set_default_profile(
33
-
logdir='./logs',
32
+
p = profile_writer.create_profile(
34
33
run_colors={
35
34
'baseline': '#9E9E9E',
36
35
'experiment_v1': '#2196F3',
37
36
'experiment_v2': '#4CAF50',
38
37
},
39
38
)
39
+
p.write('./logs')
40
40
```
41
41
42
42
Or generate perceptually uniform palettes automatically:
@@ -56,15 +56,9 @@ TensorBoard gives you one chart per tag. Want to see `train/loss` and `eval/loss
56
56
TensorBored lets you superimpose any scalar tags onto a single chart. From the UI: click the menu on any card, "Add to superimposed plot", done. Or pre-configure them:
57
57
58
58
```python
59
-
profile_writer.set_default_profile(
60
-
logdir='./logs',
61
-
superimposed_cards=[
62
-
profile_writer.create_superimposed_card(
63
-
title='Train vs Eval Loss',
64
-
tags=['loss/train', 'loss/eval'],
65
-
),
66
-
],
67
-
)
59
+
p = profile_writer.create_profile()
60
+
p.add_superimposed_card('Train vs Eval Loss', ['loss/train', 'loss/eval'])
61
+
p.write('./logs')
68
62
```
69
63
70
64
---
@@ -83,16 +77,16 @@ Pin limit went from ~15 (URL length cap) to **1,000**.
83
77
Set up the dashboard from Python before anyone even opens a browser:
84
78
85
79
```python
86
-
profile_writer.set_default_profile(
87
-
logdir='./logs',
88
-
name='Training Dashboard',
80
+
p = profile_writer.create_profile(
81
+
'Training Dashboard',
89
82
pinned_cards=[
90
83
profile_writer.pin_scalar('loss/train'),
91
84
profile_writer.pin_scalar('accuracy/eval'),
92
85
],
93
86
tag_filter='loss|accuracy',
94
87
smoothing=0.8,
95
88
)
89
+
p.write('./logs')
96
90
```
97
91
98
92
---
@@ -114,14 +108,14 @@ Drag-and-drop to reorder. Arrow buttons for precise positioning. Order persists
114
108
## You have 50 metrics and can't remember what `aux_head_3/nll` means? Add descriptions.
115
109
116
110
```python
117
-
profile_writer.set_default_profile(
118
-
logdir='./logs',
111
+
p = profile_writer.create_profile(
119
112
metric_descriptions={
120
113
'loss/train': 'Cross-entropy loss for backprop.',
121
114
'aux_head_3/nll': 'NLL from the auxiliary prediction head on layer 3.',
122
115
'gradients/global_norm': 'Global L2 norm of all gradients before clipping.',
123
116
},
124
117
)
118
+
p.write('./logs')
125
119
```
126
120
127
121
Hover over any metric card header and the description appears as a tooltip. Set it once in your training harness, every teammate sees it.
@@ -156,7 +150,7 @@ Type a filter, refresh — it's still there. Clear the filter, refresh — it st
156
150
| All runs hidden | Blank dashboard | Auto-reset to visible |
157
151
| Tag filter on refresh | Resets | Remembered |
158
152
| Share config | Long URL | JSON export/import |
159
-
| Configure from Python | No |`profile_writer` API |
153
+
| Configure from Python | No |`Profile` object + `profile_writer` API |
160
154
| Colour palette | Random | OKLCH perceptually uniform |
0 commit comments