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.
Files changed (321) hide show
  1. nuboard-0.20.0/.github/workflows/ci.yml +71 -0
  2. nuboard-0.20.0/.github/workflows/docs.yml +41 -0
  3. nuboard-0.20.0/.github/workflows/release.yml +52 -0
  4. nuboard-0.20.0/.github/workflows/windows.yml +35 -0
  5. nuboard-0.20.0/.gitignore +15 -0
  6. nuboard-0.20.0/LICENSE +21 -0
  7. nuboard-0.20.0/PKG-INFO +144 -0
  8. nuboard-0.20.0/README.md +111 -0
  9. nuboard-0.20.0/benchmarks/bench.py +121 -0
  10. nuboard-0.20.0/docs/api/add_artifact.md +134 -0
  11. nuboard-0.20.0/docs/api/add_audio.md +60 -0
  12. nuboard-0.20.0/docs/api/add_figure.md +289 -0
  13. nuboard-0.20.0/docs/api/add_file.md +28 -0
  14. nuboard-0.20.0/docs/api/add_histogram.md +69 -0
  15. nuboard-0.20.0/docs/api/add_html.md +55 -0
  16. nuboard-0.20.0/docs/api/add_image.md +68 -0
  17. nuboard-0.20.0/docs/api/add_point_cloud.md +65 -0
  18. nuboard-0.20.0/docs/api/add_pr_curve.md +60 -0
  19. nuboard-0.20.0/docs/api/add_scalar.md +82 -0
  20. nuboard-0.20.0/docs/api/add_scalar_baseline.md +60 -0
  21. nuboard-0.20.0/docs/api/add_table.md +76 -0
  22. nuboard-0.20.0/docs/api/add_text.md +44 -0
  23. nuboard-0.20.0/docs/api/add_video.md +75 -0
  24. nuboard-0.20.0/docs/api/finish.md +38 -0
  25. nuboard-0.20.0/docs/api/index.md +102 -0
  26. nuboard-0.20.0/docs/api/init.md +247 -0
  27. nuboard-0.20.0/docs/api/tensorboard.md +34 -0
  28. nuboard-0.20.0/docs/assets/api/audio.png +0 -0
  29. nuboard-0.20.0/docs/assets/api/figure.png +0 -0
  30. nuboard-0.20.0/docs/assets/api/histogram.png +0 -0
  31. nuboard-0.20.0/docs/assets/api/html.png +0 -0
  32. nuboard-0.20.0/docs/assets/api/image.png +0 -0
  33. nuboard-0.20.0/docs/assets/api/point_cloud.png +0 -0
  34. nuboard-0.20.0/docs/assets/api/pr_curve.png +0 -0
  35. nuboard-0.20.0/docs/assets/api/scalars.png +0 -0
  36. nuboard-0.20.0/docs/assets/api/table.png +0 -0
  37. nuboard-0.20.0/docs/assets/api/text.png +0 -0
  38. nuboard-0.20.0/docs/assets/api/video.png +0 -0
  39. nuboard-0.20.0/docs/assets/api/waveform.png +0 -0
  40. nuboard-0.20.0/docs/assets/artifacts-light.png +0 -0
  41. nuboard-0.20.0/docs/assets/charts-dark.png +0 -0
  42. nuboard-0.20.0/docs/assets/charts-light.png +0 -0
  43. nuboard-0.20.0/docs/assets/get-started/charts.png +0 -0
  44. nuboard-0.20.0/docs/assets/get-started/decision.png +0 -0
  45. nuboard-0.20.0/docs/assets/get-started/histogram.png +0 -0
  46. nuboard-0.20.0/docs/assets/get-started/points.png +0 -0
  47. nuboard-0.20.0/docs/assets/get-started/pr.png +0 -0
  48. nuboard-0.20.0/docs/assets/get-started/runs.png +0 -0
  49. nuboard-0.20.0/docs/assets/get-started/table.png +0 -0
  50. nuboard-0.20.0/docs/assets/logo.svg +1 -0
  51. nuboard-0.20.0/docs/assets/runs-dark.png +0 -0
  52. nuboard-0.20.0/docs/assets/runs-light.png +0 -0
  53. nuboard-0.20.0/docs/assets/sweeps-light.png +0 -0
  54. nuboard-0.20.0/docs/assets/timeline-light.png +0 -0
  55. nuboard-0.20.0/docs/assets/vendor/mermaid/LICENSE +21 -0
  56. nuboard-0.20.0/docs/assets/vendor/mermaid/mermaid.min.js +2314 -0
  57. nuboard-0.20.0/docs/changelog.md +1035 -0
  58. nuboard-0.20.0/docs/get-started.md +388 -0
  59. nuboard-0.20.0/docs/guide/alerts.md +54 -0
  60. nuboard-0.20.0/docs/guide/analysis.md +76 -0
  61. nuboard-0.20.0/docs/guide/artifacts.md +271 -0
  62. nuboard-0.20.0/docs/guide/distributed.md +63 -0
  63. nuboard-0.20.0/docs/guide/jobs.md +126 -0
  64. nuboard-0.20.0/docs/guide/logging.md +198 -0
  65. nuboard-0.20.0/docs/guide/machines.md +70 -0
  66. nuboard-0.20.0/docs/guide/reports.md +210 -0
  67. nuboard-0.20.0/docs/guide/reproducibility.md +136 -0
  68. nuboard-0.20.0/docs/guide/sweeps.md +149 -0
  69. nuboard-0.20.0/docs/guide/tensorboard.md +81 -0
  70. nuboard-0.20.0/docs/guide/viewer.md +611 -0
  71. nuboard-0.20.0/docs/index.md +131 -0
  72. nuboard-0.20.0/docs/installation.md +116 -0
  73. nuboard-0.20.0/docs/license.md +27 -0
  74. nuboard-0.20.0/docs/quickstart.md +99 -0
  75. nuboard-0.20.0/docs/reference/architecture.md +152 -0
  76. nuboard-0.20.0/docs/reference/cli.md +190 -0
  77. nuboard-0.20.0/docs/reference/development.md +158 -0
  78. nuboard-0.20.0/docs/reference/format.md +519 -0
  79. nuboard-0.20.0/docs/reference/limitations.md +13 -0
  80. nuboard-0.20.0/docs/reference/query.md +68 -0
  81. nuboard-0.20.0/docs/stylesheets/extra.css +94 -0
  82. nuboard-0.20.0/examples/get_started.py +156 -0
  83. nuboard-0.20.0/examples/quickstart.py +23 -0
  84. nuboard-0.20.0/examples/train_numpy.py +116 -0
  85. nuboard-0.20.0/frontend/.gitignore +4 -0
  86. nuboard-0.20.0/frontend/.prettierrc +6 -0
  87. nuboard-0.20.0/frontend/audio.html +86 -0
  88. nuboard-0.20.0/frontend/e2e/viewer.spec.ts +1913 -0
  89. nuboard-0.20.0/frontend/eslint.config.js +23 -0
  90. nuboard-0.20.0/frontend/figure.html +30 -0
  91. nuboard-0.20.0/frontend/index.html +19 -0
  92. nuboard-0.20.0/frontend/package.json +47 -0
  93. nuboard-0.20.0/frontend/playwright.config.ts +23 -0
  94. nuboard-0.20.0/frontend/pnpm-lock.yaml +3428 -0
  95. nuboard-0.20.0/frontend/pnpm-workspace.yaml +8 -0
  96. nuboard-0.20.0/frontend/public/logo.svg +1 -0
  97. nuboard-0.20.0/frontend/src/App.svelte +312 -0
  98. nuboard-0.20.0/frontend/src/app.css +403 -0
  99. nuboard-0.20.0/frontend/src/audio/main.ts +16 -0
  100. nuboard-0.20.0/frontend/src/audio/player.css +384 -0
  101. nuboard-0.20.0/frontend/src/audio/player.js +1742 -0
  102. nuboard-0.20.0/frontend/src/components/About.svelte +87 -0
  103. nuboard-0.20.0/frontend/src/components/ArtifactForm.svelte +471 -0
  104. nuboard-0.20.0/frontend/src/components/AttachmentEmbed.svelte +96 -0
  105. nuboard-0.20.0/frontend/src/components/AudioEmbed.svelte +45 -0
  106. nuboard-0.20.0/frontend/src/components/AudioFrame.svelte +126 -0
  107. nuboard-0.20.0/frontend/src/components/ChartEmbed.svelte +285 -0
  108. nuboard-0.20.0/frontend/src/components/ComboBox.svelte +211 -0
  109. nuboard-0.20.0/frontend/src/components/ComparePanel.svelte +722 -0
  110. nuboard-0.20.0/frontend/src/components/Dialog.svelte +230 -0
  111. nuboard-0.20.0/frontend/src/components/FigureFrame.svelte +71 -0
  112. nuboard-0.20.0/frontend/src/components/FilesView.svelte +1061 -0
  113. nuboard-0.20.0/frontend/src/components/HistChart.svelte +149 -0
  114. nuboard-0.20.0/frontend/src/components/HistView.svelte +186 -0
  115. nuboard-0.20.0/frontend/src/components/Icon.svelte +63 -0
  116. nuboard-0.20.0/frontend/src/components/JobChips.svelte +61 -0
  117. nuboard-0.20.0/frontend/src/components/LineChart.svelte +712 -0
  118. nuboard-0.20.0/frontend/src/components/Markdown.svelte +164 -0
  119. nuboard-0.20.0/frontend/src/components/Marker.svelte +17 -0
  120. nuboard-0.20.0/frontend/src/components/MediaCard.svelte +204 -0
  121. nuboard-0.20.0/frontend/src/components/MediaEmbed.svelte +65 -0
  122. nuboard-0.20.0/frontend/src/components/MediaView.svelte +251 -0
  123. nuboard-0.20.0/frontend/src/components/NotesEditor.svelte +114 -0
  124. nuboard-0.20.0/frontend/src/components/OverlayEmbed.svelte +91 -0
  125. nuboard-0.20.0/frontend/src/components/ParamPicker.svelte +459 -0
  126. nuboard-0.20.0/frontend/src/components/PointsView.svelte +125 -0
  127. nuboard-0.20.0/frontend/src/components/PrChart.svelte +153 -0
  128. nuboard-0.20.0/frontend/src/components/PropertiesEditor.svelte +360 -0
  129. nuboard-0.20.0/frontend/src/components/QueryBar.svelte +161 -0
  130. nuboard-0.20.0/frontend/src/components/ReportEditor.svelte +773 -0
  131. nuboard-0.20.0/frontend/src/components/ReportToast.svelte +38 -0
  132. nuboard-0.20.0/frontend/src/components/RunTable.svelte +1128 -0
  133. nuboard-0.20.0/frontend/src/components/SelectionBanner.svelte +45 -0
  134. nuboard-0.20.0/frontend/src/components/SmallChart.svelte +273 -0
  135. nuboard-0.20.0/frontend/src/components/Status.svelte +62 -0
  136. nuboard-0.20.0/frontend/src/components/StorageDialog.svelte +512 -0
  137. nuboard-0.20.0/frontend/src/components/TableView.svelte +620 -0
  138. nuboard-0.20.0/frontend/src/components/TagEditor.svelte +101 -0
  139. nuboard-0.20.0/frontend/src/components/TagPills.svelte +25 -0
  140. nuboard-0.20.0/frontend/src/components/Terminal.svelte +38 -0
  141. nuboard-0.20.0/frontend/src/components/VideoView.svelte +125 -0
  142. nuboard-0.20.0/frontend/src/components/ViewEmbed.svelte +130 -0
  143. nuboard-0.20.0/frontend/src/components/WaveformPlot.svelte +122 -0
  144. nuboard-0.20.0/frontend/src/figure.ts +118 -0
  145. nuboard-0.20.0/frontend/src/lib/ansi.ts +145 -0
  146. nuboard-0.20.0/frontend/src/lib/api.ts +580 -0
  147. nuboard-0.20.0/frontend/src/lib/apng.ts +123 -0
  148. nuboard-0.20.0/frontend/src/lib/baselines.ts +45 -0
  149. nuboard-0.20.0/frontend/src/lib/brand.ts +14 -0
  150. nuboard-0.20.0/frontend/src/lib/chartspec.ts +75 -0
  151. nuboard-0.20.0/frontend/src/lib/colors.ts +32 -0
  152. nuboard-0.20.0/frontend/src/lib/combo.ts +25 -0
  153. nuboard-0.20.0/frontend/src/lib/dialog.svelte.ts +85 -0
  154. nuboard-0.20.0/frontend/src/lib/diff.ts +84 -0
  155. nuboard-0.20.0/frontend/src/lib/export-hover.js +240 -0
  156. nuboard-0.20.0/frontend/src/lib/exporthtml.ts +842 -0
  157. nuboard-0.20.0/frontend/src/lib/fields.ts +68 -0
  158. nuboard-0.20.0/frontend/src/lib/fold.svelte.ts +24 -0
  159. nuboard-0.20.0/frontend/src/lib/format.ts +80 -0
  160. nuboard-0.20.0/frontend/src/lib/fullscreen.svelte.ts +33 -0
  161. nuboard-0.20.0/frontend/src/lib/hist.ts +196 -0
  162. nuboard-0.20.0/frontend/src/lib/keyfilter.ts +96 -0
  163. nuboard-0.20.0/frontend/src/lib/live.ts +21 -0
  164. nuboard-0.20.0/frontend/src/lib/markdown.ts +71 -0
  165. nuboard-0.20.0/frontend/src/lib/mdedit.ts +318 -0
  166. nuboard-0.20.0/frontend/src/lib/measure.svelte.ts +43 -0
  167. nuboard-0.20.0/frontend/src/lib/media.ts +93 -0
  168. nuboard-0.20.0/frontend/src/lib/overlay.ts +44 -0
  169. nuboard-0.20.0/frontend/src/lib/pattern.ts +29 -0
  170. nuboard-0.20.0/frontend/src/lib/pins.svelte.ts +30 -0
  171. nuboard-0.20.0/frontend/src/lib/points.ts +350 -0
  172. nuboard-0.20.0/frontend/src/lib/pr.ts +71 -0
  173. nuboard-0.20.0/frontend/src/lib/properties.ts +95 -0
  174. nuboard-0.20.0/frontend/src/lib/reportfiles.ts +166 -0
  175. nuboard-0.20.0/frontend/src/lib/reports.svelte.ts +95 -0
  176. nuboard-0.20.0/frontend/src/lib/router.svelte.ts +83 -0
  177. nuboard-0.20.0/frontend/src/lib/smooth.ts +55 -0
  178. nuboard-0.20.0/frontend/src/lib/snapshot.ts +206 -0
  179. nuboard-0.20.0/frontend/src/lib/state.svelte.ts +110 -0
  180. nuboard-0.20.0/frontend/src/lib/storage.svelte.ts +2 -0
  181. nuboard-0.20.0/frontend/src/lib/svgcards.ts +68 -0
  182. nuboard-0.20.0/frontend/src/lib/sweep.ts +295 -0
  183. nuboard-0.20.0/frontend/src/lib/tables.ts +167 -0
  184. nuboard-0.20.0/frontend/src/lib/tags.ts +38 -0
  185. nuboard-0.20.0/frontend/src/lib/waveform.ts +339 -0
  186. nuboard-0.20.0/frontend/src/lib/waveplot.css +300 -0
  187. nuboard-0.20.0/frontend/src/lib/waveplot.ts +883 -0
  188. nuboard-0.20.0/frontend/src/main.ts +10 -0
  189. nuboard-0.20.0/frontend/src/pages/ArtifactsPage.svelte +849 -0
  190. nuboard-0.20.0/frontend/src/pages/ChartsPage.svelte +1662 -0
  191. nuboard-0.20.0/frontend/src/pages/MediaPage.svelte +1010 -0
  192. nuboard-0.20.0/frontend/src/pages/ReportsPage.svelte +452 -0
  193. nuboard-0.20.0/frontend/src/pages/RunsPage.svelte +289 -0
  194. nuboard-0.20.0/frontend/src/pages/SweepsPage.svelte +921 -0
  195. nuboard-0.20.0/frontend/src/pages/TimelinePage.svelte +648 -0
  196. nuboard-0.20.0/frontend/src/plotly.d.ts +6 -0
  197. nuboard-0.20.0/frontend/svelte.config.js +3 -0
  198. nuboard-0.20.0/frontend/tests/ansi.test.ts +27 -0
  199. nuboard-0.20.0/frontend/tests/baselines.test.ts +28 -0
  200. nuboard-0.20.0/frontend/tests/chartspec.test.ts +35 -0
  201. nuboard-0.20.0/frontend/tests/combo.test.ts +36 -0
  202. nuboard-0.20.0/frontend/tests/keyfilter.test.ts +57 -0
  203. nuboard-0.20.0/frontend/tests/mdedit.test.ts +105 -0
  204. nuboard-0.20.0/frontend/tests/pattern.test.ts +20 -0
  205. nuboard-0.20.0/frontend/tests/reportfiles.test.ts +34 -0
  206. nuboard-0.20.0/frontend/tests/smooth.test.ts +35 -0
  207. nuboard-0.20.0/frontend/tests/sweep.test.ts +151 -0
  208. nuboard-0.20.0/frontend/tests/waveform.test.ts +157 -0
  209. nuboard-0.20.0/frontend/tsconfig.json +16 -0
  210. nuboard-0.20.0/frontend/vite.config.ts +24 -0
  211. nuboard-0.20.0/hatch_build.py +57 -0
  212. nuboard-0.20.0/mkdocs.yml +103 -0
  213. nuboard-0.20.0/pyproject.toml +95 -0
  214. nuboard-0.20.0/scripts/blank_lines.py +119 -0
  215. nuboard-0.20.0/scripts/docs_examples.py +64 -0
  216. nuboard-0.20.0/src/nuboard/__init__.py +64 -0
  217. nuboard-0.20.0/src/nuboard/__main__.py +5 -0
  218. nuboard-0.20.0/src/nuboard/_artifact_cli.py +893 -0
  219. nuboard-0.20.0/src/nuboard/_console.py +121 -0
  220. nuboard-0.20.0/src/nuboard/_env.py +644 -0
  221. nuboard-0.20.0/src/nuboard/_format.py +269 -0
  222. nuboard-0.20.0/src/nuboard/_fs.py +168 -0
  223. nuboard-0.20.0/src/nuboard/_media.py +1270 -0
  224. nuboard-0.20.0/src/nuboard/_meta.py +20 -0
  225. nuboard-0.20.0/src/nuboard/_system.py +449 -0
  226. nuboard-0.20.0/src/nuboard/_waveform.py +241 -0
  227. nuboard-0.20.0/src/nuboard/_writer.py +430 -0
  228. nuboard-0.20.0/src/nuboard/alerts.py +250 -0
  229. nuboard-0.20.0/src/nuboard/analysis.py +434 -0
  230. nuboard-0.20.0/src/nuboard/artifacts.py +518 -0
  231. nuboard-0.20.0/src/nuboard/catalog.py +464 -0
  232. nuboard-0.20.0/src/nuboard/cells.py +42 -0
  233. nuboard-0.20.0/src/nuboard/cli.py +481 -0
  234. nuboard-0.20.0/src/nuboard/collection.py +167 -0
  235. nuboard-0.20.0/src/nuboard/compact.py +123 -0
  236. nuboard-0.20.0/src/nuboard/demo.py +1483 -0
  237. nuboard-0.20.0/src/nuboard/figures.py +93 -0
  238. nuboard-0.20.0/src/nuboard/jobs.py +112 -0
  239. nuboard-0.20.0/src/nuboard/merge.py +1027 -0
  240. nuboard-0.20.0/src/nuboard/query.py +597 -0
  241. nuboard-0.20.0/src/nuboard/reader.py +591 -0
  242. nuboard-0.20.0/src/nuboard/remove.py +254 -0
  243. nuboard-0.20.0/src/nuboard/reports.py +672 -0
  244. nuboard-0.20.0/src/nuboard/run.py +1911 -0
  245. nuboard-0.20.0/src/nuboard/series.py +210 -0
  246. nuboard-0.20.0/src/nuboard/server/__init__.py +5 -0
  247. nuboard-0.20.0/src/nuboard/server/app.py +2007 -0
  248. nuboard-0.20.0/src/nuboard/server/auth.py +248 -0
  249. nuboard-0.20.0/src/nuboard/server/data.py +598 -0
  250. nuboard-0.20.0/src/nuboard/server/runfiles.py +185 -0
  251. nuboard-0.20.0/src/nuboard/server/storage.py +273 -0
  252. nuboard-0.20.0/src/nuboard/server/tensorfiles.py +581 -0
  253. nuboard-0.20.0/src/nuboard/static/assets/audio-DY6dO1gB.css +1 -0
  254. nuboard-0.20.0/src/nuboard/static/assets/audio-zfRL7l-7.js +147 -0
  255. nuboard-0.20.0/src/nuboard/static/assets/embed-TtLqwdzi.js +209 -0
  256. nuboard-0.20.0/src/nuboard/static/assets/figure-C2BhteK6.js +1 -0
  257. nuboard-0.20.0/src/nuboard/static/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  258. nuboard-0.20.0/src/nuboard/static/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  259. nuboard-0.20.0/src/nuboard/static/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  260. nuboard-0.20.0/src/nuboard/static/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  261. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  262. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  263. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  264. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-latin-wght-normal-DacJn9Pl.js +1 -0
  265. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  266. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  267. nuboard-0.20.0/src/nuboard/static/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  268. nuboard-0.20.0/src/nuboard/static/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  269. nuboard-0.20.0/src/nuboard/static/assets/hover.min-Cmh-xNZ4.js +1 -0
  270. nuboard-0.20.0/src/nuboard/static/assets/index-DyqX6lRK.css +1 -0
  271. nuboard-0.20.0/src/nuboard/static/assets/main-Cl0qC-Nb.css +1 -0
  272. nuboard-0.20.0/src/nuboard/static/assets/main-uubCGpj4.js +1355 -0
  273. nuboard-0.20.0/src/nuboard/static/assets/minimap.min-rdO4gIdQ.js +1 -0
  274. nuboard-0.20.0/src/nuboard/static/assets/player-81LsU0fu.js +2 -0
  275. nuboard-0.20.0/src/nuboard/static/assets/player-SBz5j5aK.js +1743 -0
  276. nuboard-0.20.0/src/nuboard/static/assets/plotly.min-DtrrpdmF.js +3596 -0
  277. nuboard-0.20.0/src/nuboard/static/assets/plotly.min-_WaezbE4.js +3620 -0
  278. nuboard-0.20.0/src/nuboard/static/assets/preload-helper-mg6Z-sIv.js +1 -0
  279. nuboard-0.20.0/src/nuboard/static/assets/regions.min-BGHYlkZ8.js +1 -0
  280. nuboard-0.20.0/src/nuboard/static/assets/uPlot.iife.min-BFDyfR1Q.js +1 -0
  281. nuboard-0.20.0/src/nuboard/static/assets/vega-embed.min-OLQt4Rq9.js +1 -0
  282. nuboard-0.20.0/src/nuboard/static/assets/vega-lite.min-Dm-nMFQY.js +1 -0
  283. nuboard-0.20.0/src/nuboard/static/assets/vega.min-B1f_1nHC.js +1 -0
  284. nuboard-0.20.0/src/nuboard/static/assets/wavesurfer.min-DboikoeH.js +1 -0
  285. nuboard-0.20.0/src/nuboard/static/audio.html +89 -0
  286. nuboard-0.20.0/src/nuboard/static/figure.html +31 -0
  287. nuboard-0.20.0/src/nuboard/static/index.html +22 -0
  288. nuboard-0.20.0/src/nuboard/static/logo.svg +1 -0
  289. nuboard-0.20.0/src/nuboard/tensorboard.py +750 -0
  290. nuboard-0.20.0/tests/conftest.py +24 -0
  291. nuboard-0.20.0/tests/data/make_tensorboard_logs.py +70 -0
  292. nuboard-0.20.0/tests/data/tensorboard/tbx/exp1/events.out.tfevents.1792088314.vm +0 -0
  293. nuboard-0.20.0/tests/data/tensorboard/tf2/lr0.01/train/events.out.tfevents.1792088304.vm.672.0.v2 +0 -0
  294. nuboard-0.20.0/tests/data/tensorboard/tf2/lr0.01/train/events.out.tfevents.1792088305.vm.672.2.v2 +0 -0
  295. nuboard-0.20.0/tests/data/tensorboard/tf2/lr0.01/validation/events.out.tfevents.1792088305.vm.672.1.v2 +0 -0
  296. nuboard-0.20.0/tests/data/tensorboard/torch/run_a/1792088311.6331112/events.out.tfevents.1792088311.vm.687.3 +0 -0
  297. nuboard-0.20.0/tests/data/tensorboard/torch/run_a/cmp_a/events.out.tfevents.1792088311.vm.687.1 +0 -0
  298. nuboard-0.20.0/tests/data/tensorboard/torch/run_a/cmp_b/events.out.tfevents.1792088311.vm.687.2 +0 -0
  299. nuboard-0.20.0/tests/data/tensorboard/torch/run_a/events.out.tfevents.1792088311.vm.687.0 +0 -0
  300. nuboard-0.20.0/tests/test_alerts.py +49 -0
  301. nuboard-0.20.0/tests/test_analysis.py +45 -0
  302. nuboard-0.20.0/tests/test_artifact_cli.py +188 -0
  303. nuboard-0.20.0/tests/test_catalog.py +147 -0
  304. nuboard-0.20.0/tests/test_compact.py +89 -0
  305. nuboard-0.20.0/tests/test_demo.py +23 -0
  306. nuboard-0.20.0/tests/test_docs.py +62 -0
  307. nuboard-0.20.0/tests/test_env.py +471 -0
  308. nuboard-0.20.0/tests/test_format.py +100 -0
  309. nuboard-0.20.0/tests/test_merge.py +279 -0
  310. nuboard-0.20.0/tests/test_query.py +75 -0
  311. nuboard-0.20.0/tests/test_release.py +27 -0
  312. nuboard-0.20.0/tests/test_remove.py +99 -0
  313. nuboard-0.20.0/tests/test_reports.py +133 -0
  314. nuboard-0.20.0/tests/test_run.py +821 -0
  315. nuboard-0.20.0/tests/test_server.py +1012 -0
  316. nuboard-0.20.0/tests/test_style.py +38 -0
  317. nuboard-0.20.0/tests/test_system.py +277 -0
  318. nuboard-0.20.0/tests/test_tensorboard.py +258 -0
  319. nuboard-0.20.0/tests/test_tensorfiles.py +340 -0
  320. nuboard-0.20.0/tests/test_waveform.py +188 -0
  321. 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.
@@ -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
+ ![Charts page: a learning-rate sweep grouped by lr, mean ± std over three seeds](https://raw.githubusercontent.com/eagomez2/nuboard/main/docs/assets/charts-light.png)
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.
@@ -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
+ ![Charts page: a learning-rate sweep grouped by lr, mean ± std over three seeds](https://raw.githubusercontent.com/eagomez2/nuboard/main/docs/assets/charts-light.png)
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()