<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>DGX Lab Blog</title>
        <link>https://jxtngx.github.io/dgx-lab/blog</link>
        <description>DGX Lab Blog</description>
        <lastBuildDate>Fri, 10 Apr 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Remote access: LAN, Tailscale, SSH tunnel]]></title>
            <link>https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh</link>
            <guid>https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh</guid>
            <pubDate>Fri, 10 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How to reach DGX Lab from a Mac or another machine — same ports for dev vs Docker, plus Tailscale and SSH when you are off the LAN.]]></description>
            <content:encoded><![CDATA[<p>The app always runs <strong>on the Spark</strong>. Your browser can be on the Spark, on a laptop on the same Wi‑Fi, or on a machine joined to a tailnet. The only thing that changes is the URL and whether you need a tunnel.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ports">Ports<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh#ports" class="hash-link" aria-label="Direct link to Ports" title="Direct link to Ports" translate="no">​</a></h2>
<table><thead><tr><th>Mode</th><th>URL on the Spark</th><th>From another host</th></tr></thead><tbody><tr><td><code>make dev</code></td><td><code>http://localhost:3000</code></td><td><code>http://&lt;spark-ip&gt;:3000</code></td></tr><tr><td>Docker (<code>make up</code>)</td><td><code>http://localhost</code> (port 80)</td><td><code>http://&lt;spark-ip&gt;</code></td></tr></tbody></table>
<p>nginx in Docker terminates port 80 and proxies to the frontend and <code>/api/</code> to FastAPI. Dev mode skips nginx and exposes Next directly on <strong>3000</strong> and the API on <strong>8000</strong> (proxied by Next for browser calls).</p>
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">Spark-side TCP exposure (planning firewalls)</div><div class="recharts-responsive-container" style="width:100%;height:240px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;text-align:center;margin-top:0.25rem">Counts are a firewall checklist, not a performance metric.</div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="same-lan">Same LAN<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh#same-lan" class="hash-link" aria-label="Direct link to Same LAN" title="Direct link to Same LAN" translate="no">​</a></h2>
<p>On the Spark:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">hostname</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-I</span><br></div></code></pre></div></div>
<p>Use the relevant address from your Mac or other client:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">http://&lt;spark-ip&gt;:3000    # development</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">http://&lt;spark-ip&gt;         # Docker / nginx on :80</span><br></div></code></pre></div></div>
<p>No extra software if routing and firewalls allow it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tailscale">Tailscale<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh#tailscale" class="hash-link" aria-label="Direct link to Tailscale" title="Direct link to Tailscale" translate="no">​</a></h2>
<p>Install Tailscale on the Spark and on the client, authenticate both to the same tailnet, then use the Spark’s Tailscale hostname or IP from <code>tailscale status</code>:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">http://&lt;spark-tailscale-hostname&gt;:3000   # dev</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">http://&lt;spark-tailscale-hostname&gt;        # production/docker</span><br></div></code></pre></div></div>
<p>The README also describes <code>tailscale serve</code> for HTTPS-style URLs on your tailnet and <code>tailscale ssh</code> for shell access — useful when you need to restart <code>make dev</code> or inspect logs without physical access.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ssh-local-forward">SSH local forward<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh#ssh-local-forward" class="hash-link" aria-label="Direct link to SSH local forward" title="Direct link to SSH local forward" translate="no">​</a></h2>
<p>If Tailscale is not an option and you can SSH to the Spark:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># On your Mac or laptop</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">ssh</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-L</span><span class="token plain"> </span><span class="token number">3000</span><span class="token plain">:localhost:3000 </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-L</span><span class="token plain"> </span><span class="token number">8000</span><span class="token plain">:localhost:8000 </span><span class="token operator">&lt;</span><span class="token plain">user</span><span class="token operator">&gt;</span><span class="token plain">@</span><span class="token operator">&lt;</span><span class="token plain">spark-ip</span><span class="token operator">&gt;</span><br></div></code></pre></div></div>
<p>Then open <code>http://localhost:3000</code> locally. Keep the session open; when it drops, the tunnel drops.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="security-posture-stated-plainly">Security posture (stated plainly)<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh#security-posture-stated-plainly" class="hash-link" aria-label="Direct link to Security posture (stated plainly)" title="Direct link to Security posture (stated plainly)" translate="no">​</a></h2>
<p>DGX Lab is meant for <strong>private networks</strong>. The backend uses permissive CORS because the expected clients are your own devices, not arbitrary internet origins. Do not expose port 80 or 3000 to the public internet without putting something in front that you trust.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="further-reading">Further reading<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading" translate="no">​</a></h2>
<ul>
<li class="">Repo guide: <code>docs/remote-access.md</code> (systemd example, same content family).</li>
<li class="">Architecture diagram and stack: <a class="" href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab">Introducing DGX Lab</a>.</li>
<li class="">First-time setup: <a class="" href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark">First run on your Spark</a>.</li>
</ul>]]></content:encoded>
            <category>Spark</category>
            <category>DevEx</category>
            <category>Architecture</category>
        </item>
        <item>
            <title><![CDATA[Paths, memory constants, and config]]></title>
            <link>https://jxtngx.github.io/dgx-lab/blog/2026-04-09-paths-memory-and-config</link>
            <guid>https://jxtngx.github.io/dgx-lab/blog/2026-04-09-paths-memory-and-config</guid>
            <pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Every default directory and env var DGX Lab uses for models, experiments, traces, agent index, and LangSmith exports — plus the two knobs that size the 128 GB story.]]></description>
            <content:encoded><![CDATA[<p>Tools in DGX Lab assume <strong>local disk</strong> and <strong>Spark-class memory</strong>. Defaults match a stock DGX Spark layout; everything below can be overridden with environment variables read in <code>backend/app/config.py</code>.</p>
<!-- -->
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">Config surface in config.py</div><div class="recharts-responsive-container" style="width:100%;height:200px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;text-align:center;margin-top:0.25rem">14 env-backed knobs total · same file you grep for `DGX_LAB_` and `DATA_DESIGNER_HOME`</div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="model-and-experiment-data">Model and experiment data<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-09-paths-memory-and-config#model-and-experiment-data" class="hash-link" aria-label="Direct link to Model and experiment data" title="Direct link to Model and experiment data" translate="no">​</a></h2>
<table><thead><tr><th>Default path</th><th>Env var</th><th>Consumers</th></tr></thead><tbody><tr><td><code>~/.cache/huggingface/hub</code></td><td><code>DGX_LAB_MODELS_DIR</code></td><td>Control — cache scan, Hub pull, memory fit</td></tr><tr><td><code>~/.dgx-lab/experiments</code></td><td><code>DGX_LAB_EXPERIMENTS_DIR</code></td><td>Logger — SQLite / Parquet / JSONL metrics</td></tr><tr><td><code>~/.dgx-lab/traces</code></td><td><code>DGX_LAB_TRACES_DIR</code></td><td>Traces tool — JSONL agent traces</td></tr><tr><td><code>~/.dgx-lab/designer</code></td><td><code>DGX_LAB_DESIGNER_DIR</code></td><td>Designer — generated output</td></tr><tr><td><code>~/.data-designer</code></td><td><code>DATA_DESIGNER_HOME</code></td><td>Designer library config (<code>model_providers.yaml</code>, <code>model_configs.yaml</code>; owned by <code>data-designer</code>)</td></tr><tr><td><code>~/.dgx-lab/curator</code></td><td><code>DGX_LAB_CURATOR_DIR</code></td><td>Curator pipelines and job state</td></tr><tr><td><code>~/.dgx-lab/datasets</code></td><td><code>DGX_LAB_DATASETS_DIR</code></td><td>Datasets browser — local staging</td></tr></tbody></table>
<p>If a directory does not exist yet, create it or run the tool that populates it — the backend does not magically scaffold all of these on first boot.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="agent-transcripts-and-langsmith">Agent, transcripts, and LangSmith<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-09-paths-memory-and-config#agent-transcripts-and-langsmith" class="hash-link" aria-label="Direct link to Agent, transcripts, and LangSmith" title="Direct link to Agent, transcripts, and LangSmith" translate="no">​</a></h2>
<p>These paths support the in-dashboard agent, RAG index, and trace export — they are easy to miss if you only read the “eight tools” table.</p>
<table><thead><tr><th>Default path</th><th>Env var</th><th>Role</th></tr></thead><tbody><tr><td><code>~/.cursor/projects/&lt;slug&gt;/agent-transcripts</code> (when present) else <code>~/.dgx-lab/agent-transcripts</code></td><td><code>DGX_LAB_AGENT_TRANSCRIPTS_DIR</code></td><td>Cursor agent transcript ingestion</td></tr><tr><td><code>~/.claude/projects</code></td><td><code>DGX_LAB_CLAUDE_TRANSCRIPTS_DIR</code></td><td>Claude project transcripts</td></tr><tr><td><code>~/.dgx-lab/langsmith-traces</code></td><td><code>DGX_LAB_LANGSMITH_TRACES_DIR</code></td><td>LangSmith trace JSONL landing zone</td></tr><tr><td><code>~/.dgx-lab/agent</code></td><td><code>DGX_LAB_AGENT_INDEX_DIR</code></td><td>Embeddings / vector index backing RAG</td></tr><tr><td>Current working directory of the process</td><td><code>DGX_LAB_CODEBASE_ROOT</code></td><td>Codebase root for indexing and context</td></tr></tbody></table>
<p>Set these explicitly when you run multiple clones, store caches on another volume, or keep transcripts in a non-default Cursor layout.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="memory-display-constants">Memory display constants<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-09-paths-memory-and-config#memory-display-constants" class="hash-link" aria-label="Direct link to Memory display constants" title="Direct link to Memory display constants" translate="no">​</a></h2>
<p>Unified memory on the Spark is <strong>128 GB</strong> with a <strong>~273 GB/s</strong> bandwidth ceiling in product messaging. DGX Lab uses those numbers for gauges and “fit” math unless you override:</p>
<table><thead><tr><th>Env var</th><th>Default</th><th>Purpose</th></tr></thead><tbody><tr><td><code>DGX_LAB_MEMORY_TOTAL_GB</code></td><td><code>128</code></td><td>Total pool for UI bars and estimates</td></tr><tr><td><code>DGX_LAB_MEMORY_BW_MAX_GBS</code></td><td><code>273</code></td><td>Upper bound for bandwidth visualization</td></tr></tbody></table>
<p>If you run the same codebase on different hardware (not the intended case, but possible), adjust these so the UI does not lie about headroom.</p>
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">Memory UI defaults (overridable)</div><div style="background:#0f0f12;border:1px solid #222230;border-radius:8px;padding:0.75rem 1rem"><div style="margin-bottom:1rem"><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;margin-bottom:4px">Unified pool size (gauges, fit math)</div><div class="recharts-responsive-container" style="width:100%;height:96px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868">Spark default 128 GB — change if you point the UI at different hardware.</div></div><div style="margin-bottom:1rem"><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;margin-bottom:4px">Bandwidth ceiling (visualization cap)</div><div class="recharts-responsive-container" style="width:100%;height:96px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868">Default 273 GB/s — axis cap set to 320 for headroom in the chart.</div></div></div></div>
<p>The same constants feed the <strong>memory fit</strong> story in Control: a typical 70B Q4 load against the 128 GB pool looks like the breakdown below (illustrative segments — your cache and workload will differ).</p>
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">128 GB Unified Memory Budget</div><div class="recharts-responsive-container" style="width:100%;height:320px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;text-align:center;margin-top:0.25rem">DGX Spark GB10 · 128 GB LPDDR5X · ~273 GB/s</div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-this-matters">Why this matters<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-09-paths-memory-and-config#why-this-matters" class="hash-link" aria-label="Direct link to Why this matters" title="Direct link to Why this matters" translate="no">​</a></h2>
<ul>
<li class=""><strong>Control</strong> and <strong>Monitor</strong> tie directly to GPU visibility and cache paths — wrong <code>DGX_LAB_MODELS_DIR</code> means an empty library or wrong sizes.</li>
<li class=""><strong>Logger</strong> / <strong>Traces</strong> / <strong>Datasets</strong> are pure filesystem contracts — if the path is wrong, the UI is empty, not “broken.”</li>
<li class=""><strong>Agent</strong> behavior depends on <code>DGX_LAB_CODEBASE_ROOT</code> and index dir — a mismatched root indexes the wrong tree.</li>
</ul>
<p>Link related reading: <a class="" href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab">Introducing DGX Lab</a> for architecture context; repo <code>README.md</code> duplicates the high-level table for quick grep.</p>]]></content:encoded>
            <category>Spark</category>
            <category>GPU</category>
            <category>Backend</category>
        </item>
        <item>
            <title><![CDATA[First run on your Spark]]></title>
            <link>https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark</link>
            <guid>https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark</guid>
            <pubDate>Wed, 08 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Clone, install with uv and Bun, run `make dev`, and know what to check when something breaks — without expecting a support queue.]]></description>
            <content:encoded><![CDATA[<p>DGX Lab expects to run <strong>on</strong> the DGX Spark (or at least on a box where <code>nvidia-smi</code> and your model cache match how the tools query the system). This is not a hosted product: you clone, you run, you own the outcome.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h2>
<table><thead><tr><th>Requirement</th><th>Notes</th></tr></thead><tbody><tr><td>Python 3.12+</td><td>Backend is pinned to a modern CPython; use <code>uv</code> to match lockfile.</td></tr><tr><td><a href="https://docs.astral.sh/uv/" target="_blank" rel="noopener noreferrer" class="">uv</a></td><td>Installs and syncs <code>backend/pyproject.toml</code> + <code>uv.lock</code>.</td></tr><tr><td><a href="https://bun.sh/" target="_blank" rel="noopener noreferrer" class="">Bun</a> 1.3+</td><td>Frontend monorepo and <code>make dev</code> use Bun workspaces.</td></tr><tr><td>Docker + Compose</td><td>Only for <code>make build</code> / <code>make up</code> production-style runs.</td></tr></tbody></table>
<p>If you are following along from a laptop that is <strong>not</strong> the Spark, you still need the repo <strong>on the Spark</strong> for GPU-backed tools and local paths. SSH in, clone there, open the UI from the Spark browser or from your Mac via LAN/Tailscale (see the <a class="" href="https://jxtngx.github.io/dgx-lab/blog/2026-04-10-remote-access-lan-tailscale-ssh">remote access</a> post).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="install">Install<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark#install" class="hash-link" aria-label="Direct link to Install" title="Direct link to Install" translate="no">​</a></h2>
<p>From the repo root on the machine that will host the app:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> clone https://github.com/jxtngx/dgx-lab.git ~/dgx-lab</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> ~/dgx-lab</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> backend </span><span class="token operator">&amp;&amp;</span><span class="token plain"> uv </span><span class="token function" style="color:rgb(80, 250, 123)">sync</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">..</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> frontend </span><span class="token operator">&amp;&amp;</span><span class="token plain"> bun </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">..</span><br></div></code></pre></div></div>
<p><code>uv sync</code> respects <code>backend/uv.lock</code>. <code>bun install</code> uses the workspace <code>package.json</code> under <code>frontend/</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="development">Development<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark#development" class="hash-link" aria-label="Direct link to Development" title="Direct link to Development" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">make</span><span class="token plain"> dev</span><br></div></code></pre></div></div>
<p>That brings up <strong>FastAPI on port 8000</strong> and <strong>Next.js on port 3000</strong>. The dev frontend proxies <code>/api/*</code> to the backend, so you usually open:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">http://localhost:3000</span><br></div></code></pre></div></div>
<p>From another device on the same LAN, use the Spark’s IP: <code>http://&lt;spark-ip&gt;:3000</code>.</p>
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">TCP listeners (local dev vs Docker)</div><div class="recharts-responsive-container" style="width:100%;height:260px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;text-align:center;margin-top:0.25rem">Dev: open Next on 3000; browser calls `/api/*` via Next proxy. Docker: nginx :80 → frontend + `/api/` → FastAPI.</div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="production-style-docker">Production-style Docker<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark#production-style-docker" class="hash-link" aria-label="Direct link to Production-style Docker" title="Direct link to Production-style Docker" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">make</span><span class="token plain"> build</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">make</span><span class="token plain"> up</span><br></div></code></pre></div></div>
<p>nginx listens on <strong>port 80</strong> and routes <code>/</code> to the frontend container and <code>/api/</code> to FastAPI. Use <code>make down</code>, <code>make rebuild</code>, and <code>make logs</code> as needed; the README summarizes each target.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-something-fails">When something fails<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark#when-something-fails" class="hash-link" aria-label="Direct link to When something fails" title="Direct link to When something fails" translate="no">​</a></h2>
<table><thead><tr><th>Symptom</th><th>Likely check</th></tr></thead><tbody><tr><td>Backend import errors</td><td>Re-run <code>cd backend &amp;&amp; uv sync</code> after pulls; lockfile drift is the usual cause.</td></tr><tr><td>Frontend won’t start</td><td><code>cd frontend &amp;&amp; bun install</code>; ensure Bun meets the minimum version.</td></tr><tr><td>Monitor shows no GPU</td><td>Confirm <code>nvidia-smi</code> on the <strong>host</strong>. If you use Docker, the compose file must grant GPU to the backend container.</td></tr><tr><td>Empty Control model list</td><td>Default model dir is <code>~/.cache/huggingface/hub</code>. Pull a model or set <code>DGX_LAB_MODELS_DIR</code>.</td></tr></tbody></table>
<p>The <a class="" href="https://jxtngx.github.io/dgx-lab/docs/setup">setup guide</a> mirrors these steps. The codebase and <code>docs/</code> are the source of truth — there is no ticket queue.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="expectations">Expectations<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-08-first-run-on-your-spark#expectations" class="hash-link" aria-label="Direct link to Expectations" title="Direct link to Expectations" translate="no">​</a></h2>
<p>Per <code>CONTRIBUTING.md</code>, this repo is a <strong>personal project</strong>: issues and PRs are not triaged. Forks are encouraged if you need different defaults or tools. The modular layout (one router per tool under <code>backend/app/routers/</code>, one route under <code>frontend/apps/web/app/(tools)/</code>) exists so you can adapt without waiting on a maintainer.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">make</span><span class="token plain"> dev</span><br></div></code></pre></div></div>
<p>If that command succeeds and <code>http://localhost:3000</code> loads, you are past the hardest part.</p>]]></content:encoded>
            <category>DevEx</category>
            <category>Spark</category>
            <category>Backend</category>
        </item>
        <item>
            <title><![CDATA[Introducing DGX Lab]]></title>
            <link>https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab</link>
            <guid>https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab</guid>
            <pubDate>Tue, 07 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Architecture overview of DGX Lab: a local-first developer dashboard for the NVIDIA DGX Spark, built for people who run open models on their own hardware.]]></description>
            <content:encoded><![CDATA[<p>DGX Lab is a local-first developer dashboard for the NVIDIA DGX Spark. Eight tools for model management, experiment tracking, agent observability, GPU profiling, training recipes, synthetic data, data curation, and dataset browsing -- all memory-aware against 128 GB of unified LPDDR5X.</p>
<p>This post walks through what it is, what it runs on, and how it fits together.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-hardware">The hardware<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#the-hardware" class="hash-link" aria-label="Direct link to The hardware" title="Direct link to The hardware" translate="no">​</a></h2>
<p>The DGX Spark is a desktop with a GB10 Grace Blackwell SoC: an Arm-based Grace CPU and a Blackwell GPU sharing 128 GB of unified memory at roughly 273 GB/s. FP4, FP8, and FP16 precision. No discrete VRAM -- the memory pool is shared between CPU and GPU, which changes how you think about model loading and inference budgets.</p>
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">DGX Spark System Architecture</div><div style="width:100%;height:360px;background:#0f0f12;border-radius:8px;border:1px solid #222230;overflow:hidden"><div style="position:relative;width:100%;height:100%;overflow:hidden;pointer-events:auto"><div style="width:100%;height:100%"><canvas style="display:block"></canvas></div></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;text-align:center;margin-top:0.5rem">NVIDIA DGX Spark · GB10 Grace Blackwell · Desktop AI</div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="memory-budget">Memory budget<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#memory-budget" class="hash-link" aria-label="Direct link to Memory budget" title="Direct link to Memory budget" translate="no">​</a></h2>
<p>128 GB sounds like a lot until you load a 70B model. Quantization helps -- a 70B at Q4 fits in around 38 GB, leaving room for KV cache, activations, and the system overhead. DGX Lab's Control tool shows this breakdown for every model in your HuggingFace cache.</p>
<div style="width:100%;max-width:720px;margin:1.5rem auto"><div style="font-family:'Instrument Sans', sans-serif;font-size:0.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;opacity:0.4;margin-bottom:0.5rem">128 GB Unified Memory Budget</div><div class="recharts-responsive-container" style="width:100%;height:320px;min-width:0"><div style="width:0;overflow-x:visible"></div></div><div style="font-family:'JetBrains Mono', monospace;font-size:10px;color:#5a5868;text-align:center;margin-top:0.25rem">DGX Spark GB10 · 128 GB LPDDR5X · ~273 GB/s</div></div>
<p>The chart above shows a typical allocation when serving a 70B Q4 model. The "Available" segment is what's left for additional workloads, experiments, or a second model.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-tools">The tools<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#the-tools" class="hash-link" aria-label="Direct link to The tools" title="Direct link to The tools" translate="no">​</a></h2>
<p>DGX Lab ships eight tools, each backed by a FastAPI router and rendered by a Next.js page:</p>
<table><thead><tr><th>Tool</th><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><strong>Control</strong></td><td><code>/control</code></td><td>Model library -- scan HF cache, search Hub, pull models, memory fit estimates</td></tr><tr><td><strong>Logger</strong></td><td><code>/logger</code></td><td>Experiment tracker -- run metrics from SQLite, Parquet, JSONL</td></tr><tr><td><strong>Traces</strong></td><td><code>/traces</code></td><td>Agent trace viewer -- span waterfall, cost/token aggregation</td></tr><tr><td><strong>Monitor</strong></td><td><code>/monitor</code></td><td>GPU dashboard -- gauges, system timeline, process table</td></tr><tr><td><strong>AutoModel</strong></td><td><code>/automodel</code></td><td>NeMo training recipes -- SFT, LoRA, pretraining, distillation, QAT</td></tr><tr><td><strong>Designer</strong></td><td><code>/designer</code></td><td>Synthetic data generation with provider/model config</td></tr><tr><td><strong>Curator</strong></td><td><code>/curator</code></td><td>NeMo Curator data curation pipelines and stage browser</td></tr><tr><td><strong>Datasets</strong></td><td><code>/datasets</code></td><td>Local and HuggingFace dataset browser with row preview</td></tr></tbody></table>
<p>Every tool that touches model loading or training reasons about the 128 GB budget. Control shows memory fit bars. Monitor tracks GPU utilization in real time. AutoModel validates that a training recipe will fit before launching.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-stack">The stack<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#the-stack" class="hash-link" aria-label="Direct link to The stack" title="Direct link to The stack" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">Frontend:   Next.js 16  ·  React 19  ·  Tailwind CSS 4  ·  shadcn v4</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">Backend:    FastAPI  ·  Python 3.12  ·  uv</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">Deploy:     Docker Compose  ·  nginx  ·  Tailscale</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">Hardware:   DGX Spark  ·  GB10 Grace Blackwell  ·  128 GB LPDDR5X</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">Agent:      LangChain  ·  Claude 3.5 Haiku (Bedrock)  ·  FAISS + cuVS  ·  LangSmith</span><br></div></code></pre></div></div>
<p>The frontend is a Turborepo monorepo with Bun workspaces. <code>apps/web</code> is the Next.js app; <code>packages/ui</code> holds shared shadcn components. The backend runs on the Spark itself -- FastAPI with async routers, one per tool. Docker Compose bundles frontend, backend, and an nginx reverse proxy. Tailscale provides remote access from a Mac or any device on the tailnet.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="architecture">Architecture<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#architecture" class="hash-link" aria-label="Direct link to Architecture" title="Direct link to Architecture" translate="no">​</a></h2>
<!-- -->
<p>The DGX Lab Agent is a RAG-backed assistant that treats the entire codebase as its knowledge base. It uses <code>nvidia/llama-embed-nemotron-8b</code> for embeddings, FAISS with cuVS GPU acceleration for vector search, and <code>nvidia/llama-nemotron-rerank-1b-v2</code> for reranking. The LLM is Claude 3.5 Haiku via AWS Bedrock. All interactions are traced with LangSmith.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="design-language">Design language<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#design-language" class="hash-link" aria-label="Direct link to Design language" title="Direct link to Design language" translate="no">​</a></h2>
<p>Dark base. Cyan is earned -- active states, live-status dots, critical metrics only. Monospace for machine data, sans for navigation and prose. Density over decoration. The dashboard should feel like it was built by someone who runs large models at 2am, not a marketing team.</p>
<table><thead><tr><th>Token</th><th>Value</th><th>Use</th></tr></thead><tbody><tr><td><code>--background</code></td><td><code>#09090b</code></td><td>Page base</td></tr><tr><td><code>--surface</code></td><td><code>#0f0f12</code></td><td>Sidebar, panels</td></tr><tr><td><code>--elevated</code></td><td><code>#161619</code></td><td>Cards, inputs</td></tr><tr><td><code>--color-cyan</code></td><td><code>#22d3ee</code></td><td>Primary accent -- scarce</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-next">What's next<a href="https://jxtngx.github.io/dgx-lab/blog/2026-04-07-introducing-dgx-lab#whats-next" class="hash-link" aria-label="Direct link to What's next" title="Direct link to What's next" translate="no">​</a></h2>
<p>DGX Lab is open source under Apache 2.0. Clone it, fork it, adapt it for your hardware. The architecture is modular: adding a tool means one FastAPI router, one Next.js page, one sidebar entry.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> clone https://github.com/jxtngx/dgx-lab.git</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> dgx-lab</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">make</span><span class="token plain"> dev</span><br></div></code></pre></div></div>
<p>The <a class="" href="https://jxtngx.github.io/dgx-lab/docs/intro">docs</a> cover setup, tool guides, and API reference. The codebase is the documentation.</p>]]></content:encoded>
            <category>Architecture</category>
            <category>Spark</category>
            <category>GPU</category>
        </item>
    </channel>
</rss>