nuboard 0.20.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nuboard-0.20.0/.github/workflows/ci.yml +71 -0
- nuboard-0.20.0/.github/workflows/docs.yml +41 -0
- nuboard-0.20.0/.github/workflows/release.yml +52 -0
- nuboard-0.20.0/.github/workflows/windows.yml +35 -0
- nuboard-0.20.0/.gitignore +15 -0
- nuboard-0.20.0/LICENSE +21 -0
- nuboard-0.20.0/PKG-INFO +144 -0
- nuboard-0.20.0/README.md +111 -0
- nuboard-0.20.0/benchmarks/bench.py +121 -0
- nuboard-0.20.0/docs/api/add_artifact.md +134 -0
- nuboard-0.20.0/docs/api/add_audio.md +60 -0
- nuboard-0.20.0/docs/api/add_figure.md +289 -0
- nuboard-0.20.0/docs/api/add_file.md +28 -0
- nuboard-0.20.0/docs/api/add_histogram.md +69 -0
- nuboard-0.20.0/docs/api/add_html.md +55 -0
- nuboard-0.20.0/docs/api/add_image.md +68 -0
- nuboard-0.20.0/docs/api/add_point_cloud.md +65 -0
- nuboard-0.20.0/docs/api/add_pr_curve.md +60 -0
- nuboard-0.20.0/docs/api/add_scalar.md +82 -0
- nuboard-0.20.0/docs/api/add_scalar_baseline.md +60 -0
- nuboard-0.20.0/docs/api/add_table.md +76 -0
- nuboard-0.20.0/docs/api/add_text.md +44 -0
- nuboard-0.20.0/docs/api/add_video.md +75 -0
- nuboard-0.20.0/docs/api/finish.md +38 -0
- nuboard-0.20.0/docs/api/index.md +102 -0
- nuboard-0.20.0/docs/api/init.md +247 -0
- nuboard-0.20.0/docs/api/tensorboard.md +34 -0
- nuboard-0.20.0/docs/assets/api/audio.png +0 -0
- nuboard-0.20.0/docs/assets/api/figure.png +0 -0
- nuboard-0.20.0/docs/assets/api/histogram.png +0 -0
- nuboard-0.20.0/docs/assets/api/html.png +0 -0
- nuboard-0.20.0/docs/assets/api/image.png +0 -0
- nuboard-0.20.0/docs/assets/api/point_cloud.png +0 -0
- nuboard-0.20.0/docs/assets/api/pr_curve.png +0 -0
- nuboard-0.20.0/docs/assets/api/scalars.png +0 -0
- nuboard-0.20.0/docs/assets/api/table.png +0 -0
- nuboard-0.20.0/docs/assets/api/text.png +0 -0
- nuboard-0.20.0/docs/assets/api/video.png +0 -0
- nuboard-0.20.0/docs/assets/api/waveform.png +0 -0
- nuboard-0.20.0/docs/assets/artifacts-light.png +0 -0
- nuboard-0.20.0/docs/assets/charts-dark.png +0 -0
- nuboard-0.20.0/docs/assets/charts-light.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/charts.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/decision.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/histogram.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/points.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/pr.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/runs.png +0 -0
- nuboard-0.20.0/docs/assets/get-started/table.png +0 -0
- nuboard-0.20.0/docs/assets/logo.svg +1 -0
- nuboard-0.20.0/docs/assets/runs-dark.png +0 -0
- nuboard-0.20.0/docs/assets/runs-light.png +0 -0
- nuboard-0.20.0/docs/assets/sweeps-light.png +0 -0
- nuboard-0.20.0/docs/assets/timeline-light.png +0 -0
- nuboard-0.20.0/docs/assets/vendor/mermaid/LICENSE +21 -0
- nuboard-0.20.0/docs/assets/vendor/mermaid/mermaid.min.js +2314 -0
- nuboard-0.20.0/docs/changelog.md +1035 -0
- nuboard-0.20.0/docs/get-started.md +388 -0
- nuboard-0.20.0/docs/guide/alerts.md +54 -0
- nuboard-0.20.0/docs/guide/analysis.md +76 -0
- nuboard-0.20.0/docs/guide/artifacts.md +271 -0
- nuboard-0.20.0/docs/guide/distributed.md +63 -0
- nuboard-0.20.0/docs/guide/jobs.md +126 -0
- nuboard-0.20.0/docs/guide/logging.md +198 -0
- nuboard-0.20.0/docs/guide/machines.md +70 -0
- nuboard-0.20.0/docs/guide/reports.md +210 -0
- nuboard-0.20.0/docs/guide/reproducibility.md +136 -0
- nuboard-0.20.0/docs/guide/sweeps.md +149 -0
- nuboard-0.20.0/docs/guide/tensorboard.md +81 -0
- nuboard-0.20.0/docs/guide/viewer.md +611 -0
- nuboard-0.20.0/docs/index.md +131 -0
- nuboard-0.20.0/docs/installation.md +116 -0
- nuboard-0.20.0/docs/license.md +27 -0
- nuboard-0.20.0/docs/quickstart.md +99 -0
- nuboard-0.20.0/docs/reference/architecture.md +152 -0
- nuboard-0.20.0/docs/reference/cli.md +190 -0
- nuboard-0.20.0/docs/reference/development.md +158 -0
- nuboard-0.20.0/docs/reference/format.md +519 -0
- nuboard-0.20.0/docs/reference/limitations.md +13 -0
- nuboard-0.20.0/docs/reference/query.md +68 -0
- nuboard-0.20.0/docs/stylesheets/extra.css +94 -0
- nuboard-0.20.0/examples/get_started.py +156 -0
- nuboard-0.20.0/examples/quickstart.py +23 -0
- nuboard-0.20.0/examples/train_numpy.py +116 -0
- nuboard-0.20.0/frontend/.gitignore +4 -0
- nuboard-0.20.0/frontend/.prettierrc +6 -0
- nuboard-0.20.0/frontend/audio.html +86 -0
- nuboard-0.20.0/frontend/e2e/viewer.spec.ts +1913 -0
- nuboard-0.20.0/frontend/eslint.config.js +23 -0
- nuboard-0.20.0/frontend/figure.html +30 -0
- nuboard-0.20.0/frontend/index.html +19 -0
- nuboard-0.20.0/frontend/package.json +47 -0
- nuboard-0.20.0/frontend/playwright.config.ts +23 -0
- nuboard-0.20.0/frontend/pnpm-lock.yaml +3428 -0
- nuboard-0.20.0/frontend/pnpm-workspace.yaml +8 -0
- nuboard-0.20.0/frontend/public/logo.svg +1 -0
- nuboard-0.20.0/frontend/src/App.svelte +312 -0
- nuboard-0.20.0/frontend/src/app.css +403 -0
- nuboard-0.20.0/frontend/src/audio/main.ts +16 -0
- nuboard-0.20.0/frontend/src/audio/player.css +384 -0
- nuboard-0.20.0/frontend/src/audio/player.js +1742 -0
- nuboard-0.20.0/frontend/src/components/About.svelte +87 -0
- nuboard-0.20.0/frontend/src/components/ArtifactForm.svelte +471 -0
- nuboard-0.20.0/frontend/src/components/AttachmentEmbed.svelte +96 -0
- nuboard-0.20.0/frontend/src/components/AudioEmbed.svelte +45 -0
- nuboard-0.20.0/frontend/src/components/AudioFrame.svelte +126 -0
- nuboard-0.20.0/frontend/src/components/ChartEmbed.svelte +285 -0
- nuboard-0.20.0/frontend/src/components/ComboBox.svelte +211 -0
- nuboard-0.20.0/frontend/src/components/ComparePanel.svelte +722 -0
- nuboard-0.20.0/frontend/src/components/Dialog.svelte +230 -0
- nuboard-0.20.0/frontend/src/components/FigureFrame.svelte +71 -0
- nuboard-0.20.0/frontend/src/components/FilesView.svelte +1061 -0
- nuboard-0.20.0/frontend/src/components/HistChart.svelte +149 -0
- nuboard-0.20.0/frontend/src/components/HistView.svelte +186 -0
- nuboard-0.20.0/frontend/src/components/Icon.svelte +63 -0
- nuboard-0.20.0/frontend/src/components/JobChips.svelte +61 -0
- nuboard-0.20.0/frontend/src/components/LineChart.svelte +712 -0
- nuboard-0.20.0/frontend/src/components/Markdown.svelte +164 -0
- nuboard-0.20.0/frontend/src/components/Marker.svelte +17 -0
- nuboard-0.20.0/frontend/src/components/MediaCard.svelte +204 -0
- nuboard-0.20.0/frontend/src/components/MediaEmbed.svelte +65 -0
- nuboard-0.20.0/frontend/src/components/MediaView.svelte +251 -0
- nuboard-0.20.0/frontend/src/components/NotesEditor.svelte +114 -0
- nuboard-0.20.0/frontend/src/components/OverlayEmbed.svelte +91 -0
- nuboard-0.20.0/frontend/src/components/ParamPicker.svelte +459 -0
- nuboard-0.20.0/frontend/src/components/PointsView.svelte +125 -0
- nuboard-0.20.0/frontend/src/components/PrChart.svelte +153 -0
- nuboard-0.20.0/frontend/src/components/PropertiesEditor.svelte +360 -0
- nuboard-0.20.0/frontend/src/components/QueryBar.svelte +161 -0
- nuboard-0.20.0/frontend/src/components/ReportEditor.svelte +773 -0
- nuboard-0.20.0/frontend/src/components/ReportToast.svelte +38 -0
- nuboard-0.20.0/frontend/src/components/RunTable.svelte +1128 -0
- nuboard-0.20.0/frontend/src/components/SelectionBanner.svelte +45 -0
- nuboard-0.20.0/frontend/src/components/SmallChart.svelte +273 -0
- nuboard-0.20.0/frontend/src/components/Status.svelte +62 -0
- nuboard-0.20.0/frontend/src/components/StorageDialog.svelte +512 -0
- nuboard-0.20.0/frontend/src/components/TableView.svelte +620 -0
- nuboard-0.20.0/frontend/src/components/TagEditor.svelte +101 -0
- nuboard-0.20.0/frontend/src/components/TagPills.svelte +25 -0
- nuboard-0.20.0/frontend/src/components/Terminal.svelte +38 -0
- nuboard-0.20.0/frontend/src/components/VideoView.svelte +125 -0
- nuboard-0.20.0/frontend/src/components/ViewEmbed.svelte +130 -0
- nuboard-0.20.0/frontend/src/components/WaveformPlot.svelte +122 -0
- nuboard-0.20.0/frontend/src/figure.ts +118 -0
- nuboard-0.20.0/frontend/src/lib/ansi.ts +145 -0
- nuboard-0.20.0/frontend/src/lib/api.ts +580 -0
- nuboard-0.20.0/frontend/src/lib/apng.ts +123 -0
- nuboard-0.20.0/frontend/src/lib/baselines.ts +45 -0
- nuboard-0.20.0/frontend/src/lib/brand.ts +14 -0
- nuboard-0.20.0/frontend/src/lib/chartspec.ts +75 -0
- nuboard-0.20.0/frontend/src/lib/colors.ts +32 -0
- nuboard-0.20.0/frontend/src/lib/combo.ts +25 -0
- nuboard-0.20.0/frontend/src/lib/dialog.svelte.ts +85 -0
- nuboard-0.20.0/frontend/src/lib/diff.ts +84 -0
- nuboard-0.20.0/frontend/src/lib/export-hover.js +240 -0
- nuboard-0.20.0/frontend/src/lib/exporthtml.ts +842 -0
- nuboard-0.20.0/frontend/src/lib/fields.ts +68 -0
- nuboard-0.20.0/frontend/src/lib/fold.svelte.ts +24 -0
- nuboard-0.20.0/frontend/src/lib/format.ts +80 -0
- nuboard-0.20.0/frontend/src/lib/fullscreen.svelte.ts +33 -0
- nuboard-0.20.0/frontend/src/lib/hist.ts +196 -0
- nuboard-0.20.0/frontend/src/lib/keyfilter.ts +96 -0
- nuboard-0.20.0/frontend/src/lib/live.ts +21 -0
- nuboard-0.20.0/frontend/src/lib/markdown.ts +71 -0
- nuboard-0.20.0/frontend/src/lib/mdedit.ts +318 -0
- nuboard-0.20.0/frontend/src/lib/measure.svelte.ts +43 -0
- nuboard-0.20.0/frontend/src/lib/media.ts +93 -0
- nuboard-0.20.0/frontend/src/lib/overlay.ts +44 -0
- nuboard-0.20.0/frontend/src/lib/pattern.ts +29 -0
- nuboard-0.20.0/frontend/src/lib/pins.svelte.ts +30 -0
- nuboard-0.20.0/frontend/src/lib/points.ts +350 -0
- nuboard-0.20.0/frontend/src/lib/pr.ts +71 -0
- nuboard-0.20.0/frontend/src/lib/properties.ts +95 -0
- nuboard-0.20.0/frontend/src/lib/reportfiles.ts +166 -0
- nuboard-0.20.0/frontend/src/lib/reports.svelte.ts +95 -0
- nuboard-0.20.0/frontend/src/lib/router.svelte.ts +83 -0
- nuboard-0.20.0/frontend/src/lib/smooth.ts +55 -0
- nuboard-0.20.0/frontend/src/lib/snapshot.ts +206 -0
- nuboard-0.20.0/frontend/src/lib/state.svelte.ts +110 -0
- nuboard-0.20.0/frontend/src/lib/storage.svelte.ts +2 -0
- nuboard-0.20.0/frontend/src/lib/svgcards.ts +68 -0
- nuboard-0.20.0/frontend/src/lib/sweep.ts +295 -0
- nuboard-0.20.0/frontend/src/lib/tables.ts +167 -0
- nuboard-0.20.0/frontend/src/lib/tags.ts +38 -0
- nuboard-0.20.0/frontend/src/lib/waveform.ts +339 -0
- nuboard-0.20.0/frontend/src/lib/waveplot.css +300 -0
- nuboard-0.20.0/frontend/src/lib/waveplot.ts +883 -0
- nuboard-0.20.0/frontend/src/main.ts +10 -0
- nuboard-0.20.0/frontend/src/pages/ArtifactsPage.svelte +849 -0
- nuboard-0.20.0/frontend/src/pages/ChartsPage.svelte +1662 -0
- nuboard-0.20.0/frontend/src/pages/MediaPage.svelte +1010 -0
- nuboard-0.20.0/frontend/src/pages/ReportsPage.svelte +452 -0
- nuboard-0.20.0/frontend/src/pages/RunsPage.svelte +289 -0
- nuboard-0.20.0/frontend/src/pages/SweepsPage.svelte +921 -0
- nuboard-0.20.0/frontend/src/pages/TimelinePage.svelte +648 -0
- nuboard-0.20.0/frontend/src/plotly.d.ts +6 -0
- nuboard-0.20.0/frontend/svelte.config.js +3 -0
- nuboard-0.20.0/frontend/tests/ansi.test.ts +27 -0
- nuboard-0.20.0/frontend/tests/baselines.test.ts +28 -0
- nuboard-0.20.0/frontend/tests/chartspec.test.ts +35 -0
- nuboard-0.20.0/frontend/tests/combo.test.ts +36 -0
- nuboard-0.20.0/frontend/tests/keyfilter.test.ts +57 -0
- nuboard-0.20.0/frontend/tests/mdedit.test.ts +105 -0
- nuboard-0.20.0/frontend/tests/pattern.test.ts +20 -0
- nuboard-0.20.0/frontend/tests/reportfiles.test.ts +34 -0
- nuboard-0.20.0/frontend/tests/smooth.test.ts +35 -0
- nuboard-0.20.0/frontend/tests/sweep.test.ts +151 -0
- nuboard-0.20.0/frontend/tests/waveform.test.ts +157 -0
- nuboard-0.20.0/frontend/tsconfig.json +16 -0
- nuboard-0.20.0/frontend/vite.config.ts +24 -0
- nuboard-0.20.0/hatch_build.py +57 -0
- nuboard-0.20.0/mkdocs.yml +103 -0
- nuboard-0.20.0/pyproject.toml +95 -0
- nuboard-0.20.0/scripts/blank_lines.py +119 -0
- nuboard-0.20.0/scripts/docs_examples.py +64 -0
- nuboard-0.20.0/src/nuboard/__init__.py +64 -0
- nuboard-0.20.0/src/nuboard/__main__.py +5 -0
- nuboard-0.20.0/src/nuboard/_artifact_cli.py +893 -0
- nuboard-0.20.0/src/nuboard/_console.py +121 -0
- nuboard-0.20.0/src/nuboard/_env.py +644 -0
- nuboard-0.20.0/src/nuboard/_format.py +269 -0
- nuboard-0.20.0/src/nuboard/_fs.py +168 -0
- nuboard-0.20.0/src/nuboard/_media.py +1270 -0
- nuboard-0.20.0/src/nuboard/_meta.py +20 -0
- nuboard-0.20.0/src/nuboard/_system.py +449 -0
- nuboard-0.20.0/src/nuboard/_waveform.py +241 -0
- nuboard-0.20.0/src/nuboard/_writer.py +430 -0
- nuboard-0.20.0/src/nuboard/alerts.py +250 -0
- nuboard-0.20.0/src/nuboard/analysis.py +434 -0
- nuboard-0.20.0/src/nuboard/artifacts.py +518 -0
- nuboard-0.20.0/src/nuboard/catalog.py +464 -0
- nuboard-0.20.0/src/nuboard/cells.py +42 -0
- nuboard-0.20.0/src/nuboard/cli.py +481 -0
- nuboard-0.20.0/src/nuboard/collection.py +167 -0
- nuboard-0.20.0/src/nuboard/compact.py +123 -0
- nuboard-0.20.0/src/nuboard/demo.py +1483 -0
- nuboard-0.20.0/src/nuboard/figures.py +93 -0
- nuboard-0.20.0/src/nuboard/jobs.py +112 -0
- nuboard-0.20.0/src/nuboard/merge.py +1027 -0
- nuboard-0.20.0/src/nuboard/query.py +597 -0
- nuboard-0.20.0/src/nuboard/reader.py +591 -0
- nuboard-0.20.0/src/nuboard/remove.py +254 -0
- nuboard-0.20.0/src/nuboard/reports.py +672 -0
- nuboard-0.20.0/src/nuboard/run.py +1911 -0
- nuboard-0.20.0/src/nuboard/series.py +210 -0
- nuboard-0.20.0/src/nuboard/server/__init__.py +5 -0
- nuboard-0.20.0/src/nuboard/server/app.py +2007 -0
- nuboard-0.20.0/src/nuboard/server/auth.py +248 -0
- nuboard-0.20.0/src/nuboard/server/data.py +598 -0
- nuboard-0.20.0/src/nuboard/server/runfiles.py +185 -0
- nuboard-0.20.0/src/nuboard/server/storage.py +273 -0
- nuboard-0.20.0/src/nuboard/server/tensorfiles.py +581 -0
- nuboard-0.20.0/src/nuboard/static/assets/audio-DY6dO1gB.css +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/audio-zfRL7l-7.js +147 -0
- nuboard-0.20.0/src/nuboard/static/assets/embed-TtLqwdzi.js +209 -0
- nuboard-0.20.0/src/nuboard/static/assets/figure-C2BhteK6.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-latin-wght-normal-DacJn9Pl.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- nuboard-0.20.0/src/nuboard/static/assets/hover.min-Cmh-xNZ4.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/index-DyqX6lRK.css +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/main-Cl0qC-Nb.css +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/main-uubCGpj4.js +1355 -0
- nuboard-0.20.0/src/nuboard/static/assets/minimap.min-rdO4gIdQ.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/player-81LsU0fu.js +2 -0
- nuboard-0.20.0/src/nuboard/static/assets/player-SBz5j5aK.js +1743 -0
- nuboard-0.20.0/src/nuboard/static/assets/plotly.min-DtrrpdmF.js +3596 -0
- nuboard-0.20.0/src/nuboard/static/assets/plotly.min-_WaezbE4.js +3620 -0
- nuboard-0.20.0/src/nuboard/static/assets/preload-helper-mg6Z-sIv.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/regions.min-BGHYlkZ8.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/uPlot.iife.min-BFDyfR1Q.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/vega-embed.min-OLQt4Rq9.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/vega-lite.min-Dm-nMFQY.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/vega.min-B1f_1nHC.js +1 -0
- nuboard-0.20.0/src/nuboard/static/assets/wavesurfer.min-DboikoeH.js +1 -0
- nuboard-0.20.0/src/nuboard/static/audio.html +89 -0
- nuboard-0.20.0/src/nuboard/static/figure.html +31 -0
- nuboard-0.20.0/src/nuboard/static/index.html +22 -0
- nuboard-0.20.0/src/nuboard/static/logo.svg +1 -0
- nuboard-0.20.0/src/nuboard/tensorboard.py +750 -0
- nuboard-0.20.0/tests/conftest.py +24 -0
- nuboard-0.20.0/tests/data/make_tensorboard_logs.py +70 -0
- nuboard-0.20.0/tests/data/tensorboard/tbx/exp1/events.out.tfevents.1792088314.vm +0 -0
- nuboard-0.20.0/tests/data/tensorboard/tf2/lr0.01/train/events.out.tfevents.1792088304.vm.672.0.v2 +0 -0
- nuboard-0.20.0/tests/data/tensorboard/tf2/lr0.01/train/events.out.tfevents.1792088305.vm.672.2.v2 +0 -0
- nuboard-0.20.0/tests/data/tensorboard/tf2/lr0.01/validation/events.out.tfevents.1792088305.vm.672.1.v2 +0 -0
- nuboard-0.20.0/tests/data/tensorboard/torch/run_a/1792088311.6331112/events.out.tfevents.1792088311.vm.687.3 +0 -0
- nuboard-0.20.0/tests/data/tensorboard/torch/run_a/cmp_a/events.out.tfevents.1792088311.vm.687.1 +0 -0
- nuboard-0.20.0/tests/data/tensorboard/torch/run_a/cmp_b/events.out.tfevents.1792088311.vm.687.2 +0 -0
- nuboard-0.20.0/tests/data/tensorboard/torch/run_a/events.out.tfevents.1792088311.vm.687.0 +0 -0
- nuboard-0.20.0/tests/test_alerts.py +49 -0
- nuboard-0.20.0/tests/test_analysis.py +45 -0
- nuboard-0.20.0/tests/test_artifact_cli.py +188 -0
- nuboard-0.20.0/tests/test_catalog.py +147 -0
- nuboard-0.20.0/tests/test_compact.py +89 -0
- nuboard-0.20.0/tests/test_demo.py +23 -0
- nuboard-0.20.0/tests/test_docs.py +62 -0
- nuboard-0.20.0/tests/test_env.py +471 -0
- nuboard-0.20.0/tests/test_format.py +100 -0
- nuboard-0.20.0/tests/test_merge.py +279 -0
- nuboard-0.20.0/tests/test_query.py +75 -0
- nuboard-0.20.0/tests/test_release.py +27 -0
- nuboard-0.20.0/tests/test_remove.py +99 -0
- nuboard-0.20.0/tests/test_reports.py +133 -0
- nuboard-0.20.0/tests/test_run.py +821 -0
- nuboard-0.20.0/tests/test_server.py +1012 -0
- nuboard-0.20.0/tests/test_style.py +38 -0
- nuboard-0.20.0/tests/test_system.py +277 -0
- nuboard-0.20.0/tests/test_tensorboard.py +258 -0
- nuboard-0.20.0/tests/test_tensorfiles.py +340 -0
- nuboard-0.20.0/tests/test_waveform.py +188 -0
- nuboard-0.20.0/uv.lock +2213 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
# A new push to a branch or PR cancels its run still going
|
|
12
|
+
concurrency:
|
|
13
|
+
group: tests-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
python:
|
|
18
|
+
name: Python ${{ matrix.python }} on ${{ matrix.os }}
|
|
19
|
+
runs-on: ${{ matrix.os }}
|
|
20
|
+
timeout-minutes: 15
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
os: [ubuntu-latest, macos-latest]
|
|
25
|
+
python: ["3.10", "3.13"]
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: pnpm/action-setup@v4
|
|
29
|
+
with:
|
|
30
|
+
version: 10
|
|
31
|
+
- uses: actions/setup-node@v4
|
|
32
|
+
with:
|
|
33
|
+
node-version: 22
|
|
34
|
+
cache: pnpm
|
|
35
|
+
cache-dependency-path: frontend/pnpm-lock.yaml
|
|
36
|
+
- uses: astral-sh/setup-uv@v6
|
|
37
|
+
with:
|
|
38
|
+
python-version: ${{ matrix.python }}
|
|
39
|
+
- name: Build the frontend
|
|
40
|
+
working-directory: frontend
|
|
41
|
+
run: |
|
|
42
|
+
pnpm install --frozen-lockfile
|
|
43
|
+
pnpm build
|
|
44
|
+
- run: uv sync --locked
|
|
45
|
+
# A test that hangs fails after 2 minutes and is named in the log
|
|
46
|
+
- run: uv run pytest tests -q --timeout=120
|
|
47
|
+
- run: uv run ruff check src tests
|
|
48
|
+
if: matrix.os == 'ubuntu-latest'
|
|
49
|
+
- run: uv run pyright src
|
|
50
|
+
if: matrix.os == 'ubuntu-latest'
|
|
51
|
+
|
|
52
|
+
frontend:
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
timeout-minutes: 10
|
|
55
|
+
defaults:
|
|
56
|
+
run:
|
|
57
|
+
working-directory: frontend
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
- uses: pnpm/action-setup@v4
|
|
61
|
+
with:
|
|
62
|
+
version: 10
|
|
63
|
+
- uses: actions/setup-node@v4
|
|
64
|
+
with:
|
|
65
|
+
node-version: 22
|
|
66
|
+
cache: pnpm
|
|
67
|
+
cache-dependency-path: frontend/pnpm-lock.yaml
|
|
68
|
+
- run: pnpm install --frozen-lockfile
|
|
69
|
+
- run: pnpm check
|
|
70
|
+
- run: pnpm lint
|
|
71
|
+
- run: pnpm test
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 15
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: astral-sh/setup-uv@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
- run: uv sync --locked
|
|
27
|
+
- run: uv run mkdocs build --strict
|
|
28
|
+
- uses: actions/upload-pages-artifact@v3
|
|
29
|
+
with:
|
|
30
|
+
path: site
|
|
31
|
+
|
|
32
|
+
deploy:
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
timeout-minutes: 15
|
|
36
|
+
environment:
|
|
37
|
+
name: github-pages
|
|
38
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
39
|
+
steps:
|
|
40
|
+
- id: deployment
|
|
41
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishing a GitHub release builds the wheel and sdist and uploads them to
|
|
4
|
+
# PyPI through Trusted Publishing, so no PyPI token is stored in the repository.
|
|
5
|
+
on:
|
|
6
|
+
release:
|
|
7
|
+
types: [published]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 15
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: pnpm/action-setup@v4
|
|
19
|
+
with:
|
|
20
|
+
version: 10
|
|
21
|
+
- uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: 22
|
|
24
|
+
- uses: astral-sh/setup-uv@v6
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
- run: uv sync --locked
|
|
28
|
+
- name: Check the release matches the version
|
|
29
|
+
run: |
|
|
30
|
+
uv run pytest tests/test_release.py -q
|
|
31
|
+
test "${GITHUB_REF_NAME#v}" = "$(uv run python -c 'import nuboard; print(nuboard.__version__)')"
|
|
32
|
+
- run: uv build
|
|
33
|
+
- uses: actions/upload-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
|
|
38
|
+
publish:
|
|
39
|
+
needs: build
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
timeout-minutes: 15
|
|
42
|
+
environment:
|
|
43
|
+
name: pypi
|
|
44
|
+
url: https://pypi.org/p/nuboard
|
|
45
|
+
permissions:
|
|
46
|
+
id-token: write
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/download-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: dist
|
|
51
|
+
path: dist/
|
|
52
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Windows
|
|
2
|
+
|
|
3
|
+
# Run by hand from the Actions tab while Windows support is being checked; it
|
|
4
|
+
# never runs on pushes or pull requests, so it cannot mark them as failing.
|
|
5
|
+
on:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
python:
|
|
13
|
+
runs-on: windows-latest
|
|
14
|
+
timeout-minutes: 15
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: pnpm/action-setup@v4
|
|
18
|
+
with:
|
|
19
|
+
version: 10
|
|
20
|
+
- uses: actions/setup-node@v4
|
|
21
|
+
with:
|
|
22
|
+
node-version: 22
|
|
23
|
+
cache: pnpm
|
|
24
|
+
cache-dependency-path: frontend/pnpm-lock.yaml
|
|
25
|
+
- uses: astral-sh/setup-uv@v6
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.13"
|
|
28
|
+
- name: Build the frontend
|
|
29
|
+
working-directory: frontend
|
|
30
|
+
run: |
|
|
31
|
+
pnpm install --frozen-lockfile
|
|
32
|
+
pnpm build
|
|
33
|
+
- run: uv sync --locked
|
|
34
|
+
# A test that hangs fails after 2 minutes and is named in the log
|
|
35
|
+
- run: uv run pytest tests -v --timeout=120
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
.venv/
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
.ruff_cache/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
site/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
# built frontend: produced by `pnpm build`, bundled into wheels by hatch_build.py
|
|
11
|
+
src/nuboard/static/
|
|
12
|
+
# local run data
|
|
13
|
+
experiments/
|
|
14
|
+
demo-runs/
|
|
15
|
+
.DS_Store
|
nuboard-0.20.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Esteban Gómez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
nuboard-0.20.0/PKG-INFO
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: nuboard
|
|
3
|
+
Version: 0.20.0
|
|
4
|
+
Summary: A fast, local, folder-based experiment tracker and viewer for ML training.
|
|
5
|
+
Project-URL: Homepage, https://eagomez2.github.io/nuboard/
|
|
6
|
+
Project-URL: Documentation, https://eagomez2.github.io/nuboard/
|
|
7
|
+
Project-URL: Source, https://github.com/eagomez2/nuboard
|
|
8
|
+
Project-URL: Issues, https://github.com/eagomez2/nuboard/issues
|
|
9
|
+
Project-URL: Changelog, https://eagomez2.github.io/nuboard/changelog/
|
|
10
|
+
Author: Esteban Gómez
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: experiment-tracking,machine-learning,tensorboard,visualization
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Requires-Dist: numpy>=1.23
|
|
28
|
+
Requires-Dist: pyarrow>=14
|
|
29
|
+
Requires-Dist: starlette>=0.37
|
|
30
|
+
Requires-Dist: uvicorn>=0.29
|
|
31
|
+
Provides-Extra: viewer
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
<p align="center"><img src="https://raw.githubusercontent.com/eagomez2/nuboard/main/docs/assets/logo.svg" width="72" alt=""></p>
|
|
35
|
+
|
|
36
|
+
<h1 align="center">NuBoard</h1>
|
|
37
|
+
|
|
38
|
+
<p align="center"><b>Experiment tracking that lives in a folder.</b><br>
|
|
39
|
+
Log from Python with three calls. Every run is a folder. View thousands of runs in your browser.</p>
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import nuboard as nb
|
|
45
|
+
|
|
46
|
+
with nb.init("my-project", run_name="baseline", config={"lr": 3e-4}) as run:
|
|
47
|
+
for step in range(10_000):
|
|
48
|
+
loss = train_step()
|
|
49
|
+
run.add_scalar({"train/loss": loss}, step=step) # ~3 µs, never blocks training
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
nuboard up experiments # http://localhost:6070
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Why
|
|
57
|
+
|
|
58
|
+
- **No setup.** No account, no server, no database. `pip install nuboard` gives
|
|
59
|
+
you logging and the viewer; logging uses only the standard library, so it
|
|
60
|
+
adds nothing to the import time of a training script.
|
|
61
|
+
- **Folder-contained.** Each run is one folder (`run.json`, an append-only
|
|
62
|
+
binary log, a media pack, a Parquet file at the end). Copy it, rsync it, zip
|
|
63
|
+
it, delete it.
|
|
64
|
+
- **Fast.** Logging is a deque append; a background thread writes columnar
|
|
65
|
+
frames. The viewer reads a million points in about a tenth of a second and
|
|
66
|
+
lists thousands of runs instantly.
|
|
67
|
+
- **Records what you forget.** Config, git commit and uncommitted diff,
|
|
68
|
+
installed packages, GPUs, command line, rank, console output and CPU, memory
|
|
69
|
+
and GPU use, automatically.
|
|
70
|
+
- **Crash-safe.** A killed process loses at most the last second of data; torn
|
|
71
|
+
writes are ignored; crashes are marked with their traceback.
|
|
72
|
+
|
|
73
|
+
## Quick start
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install nuboard # or: uv pip install nuboard
|
|
77
|
+
nuboard demo demo-runs --up --open # 4 projects, 31 runs, one live run
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then try `where tags has "sweep" group by config.optim.lr` in the query bar and
|
|
81
|
+
open the Charts page. The [quickstart](https://eagomez2.github.io/nuboard/quickstart/) has a tour, and
|
|
82
|
+
[installation](https://eagomez2.github.io/nuboard/installation/) covers building from source.
|
|
83
|
+
|
|
84
|
+
## What's in 0.13
|
|
85
|
+
|
|
86
|
+
| Area | Included |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| Python API | `init` (+ resume, fork, ranks), `add_scalar`, `add_file`, `add_text`, `add_image`, `add_audio`, `add_video`, `add_figure`, `add_pr_curve`, `add_histogram`, `add_table`, `add_point_cloud`, `add_html`, `add_artifact` (copies or references), `use_artifact` (across projects), `nb.add_artifact`, `nb.get_artifact`, `finish`, context manager; system scalars (CPU, memory, GPU) and console capture |
|
|
89
|
+
| Storage | documented [log format](https://eagomez2.github.io/nuboard/reference/format/), Parquet compaction with zoom levels, versioned artifacts, collections |
|
|
90
|
+
| Analysis | `nb.load("project").scalars("loss", group_by="config.lr")` returns Arrow tables; properties, collections and alerts per run |
|
|
91
|
+
| Runs | query language, stars, Markdown notes, archive, typed properties, tag editing, column chooser, collections, saved views, run details and config/file diffs |
|
|
92
|
+
| Charts | grouped lines with bands, smoothing, zoom, linked crosshair, inspector, live updates, alerts strip, x axis by any scalar (tokens, epochs), solo or show all series |
|
|
93
|
+
| Media | images, video, audio (waveform + spectrogram player with notes, or the browser's player), per-example tables compared across steps, PR curves, distributions over steps, point clouds with axes, text, HTML, interactive Plotly, Vega-Lite and Bokeh figures, and waveforms with signals over them (accurate at every zoom); filter by kind, a step slider per card, best-scalar step, configurable grid |
|
|
94
|
+
| Reports | Markdown reports that embed logged items, live charts and plot snapshots; export as HTML or a zip, print to PDF |
|
|
95
|
+
| Sweeps | parallel coordinates with brushing, scatter per parameter, rank correlation, best runs |
|
|
96
|
+
| Timeline | runs over wall-clock time, packed concurrency view, crash, alert and artifact markers |
|
|
97
|
+
| Artifacts | versions, files, metadata and a lineage graph |
|
|
98
|
+
| Health alerts | NaN/Inf, loss and gradient spikes, throughput drops, per scalar and rank |
|
|
99
|
+
| CLI | `nuboard up`, `demo`, `ls`, `rm`, `compact`, `merge`, `artifact add`/`ls`/`show`, `import-tensorboard` (TensorBoard logs to runs); see the [command line reference](https://eagomez2.github.io/nuboard/reference/cli/) |
|
|
100
|
+
|
|
101
|
+
See the [changelog](https://eagomez2.github.io/nuboard/changelog/) and the
|
|
102
|
+
[known limitations](https://eagomez2.github.io/nuboard/reference/limitations/).
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
The docs are a [MkDocs](https://www.mkdocs.org/) site in `docs/`:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv run mkdocs serve # http://localhost:8000
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- [Installation](https://eagomez2.github.io/nuboard/installation/) and [Quickstart](https://eagomez2.github.io/nuboard/quickstart/)
|
|
113
|
+
- [Logging from Python](https://eagomez2.github.io/nuboard/guide/logging/), [Using the viewer](https://eagomez2.github.io/nuboard/guide/viewer/),
|
|
114
|
+
[Sweeps](https://eagomez2.github.io/nuboard/guide/sweeps/), [Health alerts](https://eagomez2.github.io/nuboard/guide/alerts/),
|
|
115
|
+
[Artifacts and lineage](https://eagomez2.github.io/nuboard/guide/artifacts/), [Analysis API](https://eagomez2.github.io/nuboard/guide/analysis/),
|
|
116
|
+
[Distributed training](https://eagomez2.github.io/nuboard/guide/distributed/),
|
|
117
|
+
[Importing from TensorBoard](https://eagomez2.github.io/nuboard/guide/tensorboard/)
|
|
118
|
+
- Reference: [query language](https://eagomez2.github.io/nuboard/reference/query/), [file format](https://eagomez2.github.io/nuboard/reference/format/),
|
|
119
|
+
[architecture](https://eagomez2.github.io/nuboard/reference/architecture/), [development](https://eagomez2.github.io/nuboard/reference/development/)
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
uv sync # Python + dev tools
|
|
125
|
+
(cd frontend && pnpm install && pnpm build) # builds the viewer into src/nuboard/static/
|
|
126
|
+
uv run pytest && uv run ruff check . && uv run pyright
|
|
127
|
+
(cd frontend && pnpm test && pnpm check && pnpm lint && pnpm e2e)
|
|
128
|
+
uv build # wheel with the frontend bundled
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
See [Development](https://eagomez2.github.io/nuboard/reference/development/) for the repository layout, the rules for
|
|
132
|
+
the logging side, and how to rename the project (the name lives in three
|
|
133
|
+
places).
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
NuBoard is released under the [MIT License](https://github.com/eagomez2/nuboard/blob/main/LICENSE).
|
|
138
|
+
|
|
139
|
+
## Requirements
|
|
140
|
+
|
|
141
|
+
Python 3.10+ on Linux, macOS or Windows. It installs NumPy, PyArrow, Starlette and
|
|
142
|
+
uvicorn for the viewer; logging uses only the standard library. Building the
|
|
143
|
+
frontend from source needs Node 20+ and pnpm (`brew install pnpm` on macOS);
|
|
144
|
+
installing from PyPI does not.
|
nuboard-0.20.0/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<p align="center"><img src="https://raw.githubusercontent.com/eagomez2/nuboard/main/docs/assets/logo.svg" width="72" alt=""></p>
|
|
2
|
+
|
|
3
|
+
<h1 align="center">NuBoard</h1>
|
|
4
|
+
|
|
5
|
+
<p align="center"><b>Experiment tracking that lives in a folder.</b><br>
|
|
6
|
+
Log from Python with three calls. Every run is a folder. View thousands of runs in your browser.</p>
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
import nuboard as nb
|
|
12
|
+
|
|
13
|
+
with nb.init("my-project", run_name="baseline", config={"lr": 3e-4}) as run:
|
|
14
|
+
for step in range(10_000):
|
|
15
|
+
loss = train_step()
|
|
16
|
+
run.add_scalar({"train/loss": loss}, step=step) # ~3 µs, never blocks training
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
nuboard up experiments # http://localhost:6070
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Why
|
|
24
|
+
|
|
25
|
+
- **No setup.** No account, no server, no database. `pip install nuboard` gives
|
|
26
|
+
you logging and the viewer; logging uses only the standard library, so it
|
|
27
|
+
adds nothing to the import time of a training script.
|
|
28
|
+
- **Folder-contained.** Each run is one folder (`run.json`, an append-only
|
|
29
|
+
binary log, a media pack, a Parquet file at the end). Copy it, rsync it, zip
|
|
30
|
+
it, delete it.
|
|
31
|
+
- **Fast.** Logging is a deque append; a background thread writes columnar
|
|
32
|
+
frames. The viewer reads a million points in about a tenth of a second and
|
|
33
|
+
lists thousands of runs instantly.
|
|
34
|
+
- **Records what you forget.** Config, git commit and uncommitted diff,
|
|
35
|
+
installed packages, GPUs, command line, rank, console output and CPU, memory
|
|
36
|
+
and GPU use, automatically.
|
|
37
|
+
- **Crash-safe.** A killed process loses at most the last second of data; torn
|
|
38
|
+
writes are ignored; crashes are marked with their traceback.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install nuboard # or: uv pip install nuboard
|
|
44
|
+
nuboard demo demo-runs --up --open # 4 projects, 31 runs, one live run
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Then try `where tags has "sweep" group by config.optim.lr` in the query bar and
|
|
48
|
+
open the Charts page. The [quickstart](https://eagomez2.github.io/nuboard/quickstart/) has a tour, and
|
|
49
|
+
[installation](https://eagomez2.github.io/nuboard/installation/) covers building from source.
|
|
50
|
+
|
|
51
|
+
## What's in 0.13
|
|
52
|
+
|
|
53
|
+
| Area | Included |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| Python API | `init` (+ resume, fork, ranks), `add_scalar`, `add_file`, `add_text`, `add_image`, `add_audio`, `add_video`, `add_figure`, `add_pr_curve`, `add_histogram`, `add_table`, `add_point_cloud`, `add_html`, `add_artifact` (copies or references), `use_artifact` (across projects), `nb.add_artifact`, `nb.get_artifact`, `finish`, context manager; system scalars (CPU, memory, GPU) and console capture |
|
|
56
|
+
| Storage | documented [log format](https://eagomez2.github.io/nuboard/reference/format/), Parquet compaction with zoom levels, versioned artifacts, collections |
|
|
57
|
+
| Analysis | `nb.load("project").scalars("loss", group_by="config.lr")` returns Arrow tables; properties, collections and alerts per run |
|
|
58
|
+
| Runs | query language, stars, Markdown notes, archive, typed properties, tag editing, column chooser, collections, saved views, run details and config/file diffs |
|
|
59
|
+
| Charts | grouped lines with bands, smoothing, zoom, linked crosshair, inspector, live updates, alerts strip, x axis by any scalar (tokens, epochs), solo or show all series |
|
|
60
|
+
| Media | images, video, audio (waveform + spectrogram player with notes, or the browser's player), per-example tables compared across steps, PR curves, distributions over steps, point clouds with axes, text, HTML, interactive Plotly, Vega-Lite and Bokeh figures, and waveforms with signals over them (accurate at every zoom); filter by kind, a step slider per card, best-scalar step, configurable grid |
|
|
61
|
+
| Reports | Markdown reports that embed logged items, live charts and plot snapshots; export as HTML or a zip, print to PDF |
|
|
62
|
+
| Sweeps | parallel coordinates with brushing, scatter per parameter, rank correlation, best runs |
|
|
63
|
+
| Timeline | runs over wall-clock time, packed concurrency view, crash, alert and artifact markers |
|
|
64
|
+
| Artifacts | versions, files, metadata and a lineage graph |
|
|
65
|
+
| Health alerts | NaN/Inf, loss and gradient spikes, throughput drops, per scalar and rank |
|
|
66
|
+
| CLI | `nuboard up`, `demo`, `ls`, `rm`, `compact`, `merge`, `artifact add`/`ls`/`show`, `import-tensorboard` (TensorBoard logs to runs); see the [command line reference](https://eagomez2.github.io/nuboard/reference/cli/) |
|
|
67
|
+
|
|
68
|
+
See the [changelog](https://eagomez2.github.io/nuboard/changelog/) and the
|
|
69
|
+
[known limitations](https://eagomez2.github.io/nuboard/reference/limitations/).
|
|
70
|
+
|
|
71
|
+
## Documentation
|
|
72
|
+
|
|
73
|
+
The docs are a [MkDocs](https://www.mkdocs.org/) site in `docs/`:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv run mkdocs serve # http://localhost:8000
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- [Installation](https://eagomez2.github.io/nuboard/installation/) and [Quickstart](https://eagomez2.github.io/nuboard/quickstart/)
|
|
80
|
+
- [Logging from Python](https://eagomez2.github.io/nuboard/guide/logging/), [Using the viewer](https://eagomez2.github.io/nuboard/guide/viewer/),
|
|
81
|
+
[Sweeps](https://eagomez2.github.io/nuboard/guide/sweeps/), [Health alerts](https://eagomez2.github.io/nuboard/guide/alerts/),
|
|
82
|
+
[Artifacts and lineage](https://eagomez2.github.io/nuboard/guide/artifacts/), [Analysis API](https://eagomez2.github.io/nuboard/guide/analysis/),
|
|
83
|
+
[Distributed training](https://eagomez2.github.io/nuboard/guide/distributed/),
|
|
84
|
+
[Importing from TensorBoard](https://eagomez2.github.io/nuboard/guide/tensorboard/)
|
|
85
|
+
- Reference: [query language](https://eagomez2.github.io/nuboard/reference/query/), [file format](https://eagomez2.github.io/nuboard/reference/format/),
|
|
86
|
+
[architecture](https://eagomez2.github.io/nuboard/reference/architecture/), [development](https://eagomez2.github.io/nuboard/reference/development/)
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
uv sync # Python + dev tools
|
|
92
|
+
(cd frontend && pnpm install && pnpm build) # builds the viewer into src/nuboard/static/
|
|
93
|
+
uv run pytest && uv run ruff check . && uv run pyright
|
|
94
|
+
(cd frontend && pnpm test && pnpm check && pnpm lint && pnpm e2e)
|
|
95
|
+
uv build # wheel with the frontend bundled
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
See [Development](https://eagomez2.github.io/nuboard/reference/development/) for the repository layout, the rules for
|
|
99
|
+
the logging side, and how to rename the project (the name lives in three
|
|
100
|
+
places).
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
NuBoard is released under the [MIT License](https://github.com/eagomez2/nuboard/blob/main/LICENSE).
|
|
105
|
+
|
|
106
|
+
## Requirements
|
|
107
|
+
|
|
108
|
+
Python 3.10+ on Linux, macOS or Windows. It installs NumPy, PyArrow, Starlette and
|
|
109
|
+
uvicorn for the viewer; logging uses only the standard library. Building the
|
|
110
|
+
frontend from source needs Node 20+ and pnpm (`brew install pnpm` on macOS);
|
|
111
|
+
installing from PyPI does not.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Rough performance checks against the targets in the project brief.
|
|
2
|
+
|
|
3
|
+
uv run python benchmarks/bench.py
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import tempfile
|
|
11
|
+
import time
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
import nuboard as nb
|
|
15
|
+
from nuboard.catalog import Catalog
|
|
16
|
+
from nuboard.reader import RunReader
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main() -> None:
|
|
20
|
+
"""Run the benchmarks and print the timings next to their targets.
|
|
21
|
+
|
|
22
|
+
Measures `Run.log` overhead, reading a live log, compacting to Parquet,
|
|
23
|
+
reading a metric from Parquet, and opening and refreshing a catalog of 5000
|
|
24
|
+
runs. Data goes to a temporary folder, removed afterwards unless `KEEP` is set.
|
|
25
|
+
"""
|
|
26
|
+
root = Path(tempfile.mkdtemp())
|
|
27
|
+
data = {f"metric_{i:02d}": float(i) for i in range(50)}
|
|
28
|
+
|
|
29
|
+
run = nb.init("bench", dir=root, capture_env=False, compact=False)
|
|
30
|
+
n = 20_000
|
|
31
|
+
t0 = time.perf_counter()
|
|
32
|
+
|
|
33
|
+
for step in range(n):
|
|
34
|
+
run.add_scalar(data, step=step)
|
|
35
|
+
|
|
36
|
+
per_call = (time.perf_counter() - t0) / n
|
|
37
|
+
t1 = time.perf_counter()
|
|
38
|
+
run.finish()
|
|
39
|
+
print(f"log() of a 50-metric dict: {per_call * 1e6:6.1f} µs per call (target < 50 µs)")
|
|
40
|
+
print(
|
|
41
|
+
f" final flush of {n * 50 / 1e6:.1f}M points: "
|
|
42
|
+
f"{time.perf_counter() - t1:6.2f} s (background)"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
run = nb.init("bench", run_name="million", dir=root, capture_env=False, compact=False)
|
|
46
|
+
|
|
47
|
+
for step in range(100_000):
|
|
48
|
+
run.add_scalar({f"m{i}": step * 0.5 + i for i in range(10)}, step=step)
|
|
49
|
+
|
|
50
|
+
run.finish()
|
|
51
|
+
size = sum(p.stat().st_size for p in run.path.glob("events.*"))
|
|
52
|
+
t0 = time.perf_counter()
|
|
53
|
+
reader = RunReader(run.path)
|
|
54
|
+
reader.refresh()
|
|
55
|
+
total = sum(len(s[0]) for s in reader.all_scalars().values())
|
|
56
|
+
print(
|
|
57
|
+
f"read {total / 1e6:.0f}M points from the live log: "
|
|
58
|
+
f"{time.perf_counter() - t0:6.3f} s (target < 0.1 s), "
|
|
59
|
+
f"{size / 1e6:.0f} MB on disk"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
from nuboard.compact import compact_run
|
|
63
|
+
|
|
64
|
+
t0 = time.perf_counter()
|
|
65
|
+
compact_run(run.path)
|
|
66
|
+
print(
|
|
67
|
+
f"compact to Parquet: {time.perf_counter() - t0:6.2f} s, "
|
|
68
|
+
f"{(run.path / 'data.parquet').stat().st_size / 1e6:.1f} MB"
|
|
69
|
+
)
|
|
70
|
+
reader = RunReader(run.path)
|
|
71
|
+
assert reader.parquet is not None
|
|
72
|
+
times = []
|
|
73
|
+
|
|
74
|
+
for name in ("m3", "m4", "m3"):
|
|
75
|
+
t0 = time.perf_counter()
|
|
76
|
+
reader.scalars(name)
|
|
77
|
+
times.append((time.perf_counter() - t0) * 1e3)
|
|
78
|
+
|
|
79
|
+
print(
|
|
80
|
+
f"one metric (100k points) from Parquet: first {times[0]:.1f} ms, "
|
|
81
|
+
f"warm {min(times[1:]):.1f} ms"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
many = root / "many" / "proj" / "runs"
|
|
85
|
+
meta = json.dumps(
|
|
86
|
+
{
|
|
87
|
+
"format_version": 1,
|
|
88
|
+
"status": "finished",
|
|
89
|
+
"config": {"lr": 0.1},
|
|
90
|
+
"summary": {
|
|
91
|
+
f"m{i}": {"last": 1.0, "min": 0.5, "max": 2, "count": 1, "step": 0, "nonfinite": 0}
|
|
92
|
+
for i in range(20)
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
for i in range(5000):
|
|
98
|
+
d = many / f"20250101-0000_r{i}_aaaaaa"
|
|
99
|
+
d.mkdir(parents=True)
|
|
100
|
+
(d / "run.json").write_text(meta)
|
|
101
|
+
|
|
102
|
+
cache = root / "cache"
|
|
103
|
+
Catalog(root / "many", cache=cache).refresh() # cold build
|
|
104
|
+
t0 = time.perf_counter()
|
|
105
|
+
cat = Catalog(root / "many", cache=cache)
|
|
106
|
+
print(f"open catalog of 5000 runs (server start): {(time.perf_counter() - t0) * 1e3:5.0f} ms")
|
|
107
|
+
t0 = time.perf_counter()
|
|
108
|
+
cat.refresh()
|
|
109
|
+
print(
|
|
110
|
+
f"refresh + list {len(cat.runs())} runs (per request): "
|
|
111
|
+
f"{(time.perf_counter() - t0) * 1e3:5.0f} ms (target < 200 ms)"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if os.environ.get("KEEP") is None:
|
|
115
|
+
import shutil
|
|
116
|
+
|
|
117
|
+
shutil.rmtree(root, ignore_errors=True)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if __name__ == "__main__":
|
|
121
|
+
main()
|