Skip to content

Commit f22c052

Browse files
committed
Restyle viz to Prime Intellect aesthetic, clean up stack traces
- Background #0E0E0E, IBM Plex Mono / Inter fonts, restrained palette - Filter CPython C internals from stack traces - Shorten paths (strip site-packages/conda prefixes) - Group consecutive frames into collapsible sections (user/torch/C++) - Speed control with [ ] keys, shortcut bar with ?
1 parent c4463a8 commit f22c052

1 file changed

Lines changed: 186 additions & 69 deletions

File tree

transformer_nuggets/utils/memory_viz.py

Lines changed: 186 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,47 @@
11
import json
22

33

4+
_SKIP_NAMES = {
5+
"torch::unwind::unwind()",
6+
"torch::CapturedTraceback::gather(bool, bool, bool)",
7+
}
8+
9+
_CPYTHON_MARKERS = (
10+
"/usr/local/src/conda/python",
11+
"/conda-bld/python",
12+
"/cpython/",
13+
)
14+
15+
16+
def _is_cpython_c_frame(fn: str, name: str) -> bool:
17+
if any(m in fn for m in _CPYTHON_MARKERS):
18+
return True
19+
if fn.endswith(".c") and name.startswith(("_Py", "Py", "pyrun", "pymain", "run_")):
20+
return True
21+
return False
22+
23+
24+
def _shorten_path(path: str) -> str:
25+
markers = ["/site-packages/", "/lib/python"]
26+
for marker in markers:
27+
idx = path.find(marker)
28+
if idx >= 0:
29+
return path[idx + len(marker) :]
30+
return path
31+
32+
433
def _extract_frames(frames: list[dict]) -> list[str]:
534
result = []
635
for f in frames:
736
fn = f.get("filename", "")
837
name = f.get("name", "")
938
line = f.get("line", 0)
10-
if not name or name in (
11-
"torch::unwind::unwind()",
12-
"torch::CapturedTraceback::gather(bool, bool, bool)",
13-
):
39+
if not name or name in _SKIP_NAMES:
40+
continue
41+
if _is_cpython_c_frame(fn, name):
1442
continue
1543
if fn and fn != "??" and fn != "":
16-
result.append(f"{fn}:{line} {name}")
44+
result.append(f"{_shorten_path(fn)}:{line} {name}")
1745
elif name:
1846
result.append(name)
1947
return result
@@ -175,20 +203,21 @@ def generate_memory_html(
175203
<meta charset="utf-8">
176204
<title>__TITLE__</title>
177205
<style>
206+
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500;600&display=swap');
178207
:root {
179-
--bg: #0f1117;
180-
--surface: #1a1d2e;
181-
--border: #2a2d3e;
182-
--text: #e2e4e9;
183-
--text-muted: #8b8fa3;
184-
--accent: #6366f1;
185-
--accent-light: rgba(99, 102, 241, 0.15);
186-
--accent-stroke: rgba(99, 102, 241, 0.8);
187-
--hwm-color: #f59e0b;
188-
--grid: rgba(255, 255, 255, 0.04);
189-
--tooltip-bg: #1e2235;
190-
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
191-
--mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;
208+
--bg: #0E0E0E;
209+
--surface: #1a1a1a;
210+
--border: rgba(255, 255, 255, 0.10);
211+
--text: rgba(255, 255, 255, 0.92);
212+
--text-muted: rgba(255, 255, 255, 0.50);
213+
--accent: #3E93CC;
214+
--accent-light: rgba(62, 147, 204, 0.12);
215+
--accent-stroke: rgba(62, 147, 204, 0.7);
216+
--hwm-color: rgba(255, 255, 255, 0.60);
217+
--grid: rgba(255, 255, 255, 0.03);
218+
--tooltip-bg: #1f1f1f;
219+
--font: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
220+
--mono: 'IBM Plex Mono', 'Fira Mono', monospace;
192221
}
193222
194223
* { margin: 0; padding: 0; box-sizing: border-box; }
@@ -212,7 +241,7 @@ def generate_memory_html(
212241
flex-shrink: 0;
213242
}
214243
215-
#header h1 { font-size: 16px; font-weight: 600; }
244+
#header h1 { font-size: 14px; font-weight: 500; font-family: var(--mono); letter-spacing: 0.03em; text-transform: uppercase; }
216245
217246
#controls {
218247
display: flex;
@@ -240,15 +269,16 @@ def generate_memory_html(
240269
.toggle:hover { color: var(--text); }
241270
242271
.stat {
243-
font-size: 12px;
272+
font-size: 11px;
273+
font-family: var(--mono);
244274
color: var(--text-muted);
245275
padding: 4px 10px;
246-
background: var(--surface);
247-
border-radius: 4px;
276+
background: rgba(255,255,255,0.04);
277+
border-radius: 3px;
248278
border: 1px solid var(--border);
249279
}
250280
251-
.stat strong { color: var(--text); font-weight: 600; }
281+
.stat strong { color: var(--text); font-weight: 500; }
252282
253283
#main {
254284
display: flex;
@@ -277,8 +307,11 @@ def generate_memory_html(
277307
#detail-header {
278308
padding: 12px 16px;
279309
border-bottom: 1px solid var(--border);
280-
font-size: 13px;
281-
font-weight: 600;
310+
font-size: 11px;
311+
font-weight: 500;
312+
font-family: var(--mono);
313+
text-transform: uppercase;
314+
letter-spacing: 0.05em;
282315
display: flex;
283316
justify-content: space-between;
284317
align-items: center;
@@ -301,13 +334,62 @@ def generate_memory_html(
301334
#detail-body::-webkit-scrollbar-track { background: transparent; }
302335
#detail-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
303336
337+
.stack-group {
338+
border-bottom: 1px solid rgba(255,255,255,0.05);
339+
}
340+
341+
.stack-group-header {
342+
display: flex;
343+
align-items: center;
344+
gap: 6px;
345+
padding: 6px 16px;
346+
font-family: var(--mono);
347+
font-size: 10px;
348+
font-weight: 500;
349+
text-transform: uppercase;
350+
letter-spacing: 0.05em;
351+
color: var(--text-muted);
352+
cursor: pointer;
353+
user-select: none;
354+
background: rgba(255,255,255,0.02);
355+
}
356+
357+
.stack-group-header:hover { background: rgba(255,255,255,0.04); }
358+
359+
.stack-group-header .chevron {
360+
display: inline-block;
361+
width: 12px;
362+
font-size: 8px;
363+
transition: transform 0.15s;
364+
color: rgba(255,255,255,0.3);
365+
}
366+
367+
.stack-group.collapsed .chevron { transform: rotate(-90deg); }
368+
.stack-group.collapsed .stack-group-frames { display: none; }
369+
370+
.stack-group-header .group-count {
371+
margin-left: auto;
372+
font-size: 9px;
373+
color: rgba(255,255,255,0.25);
374+
}
375+
376+
.stack-group-header .group-tag {
377+
padding: 1px 6px;
378+
border-radius: 2px;
379+
font-size: 9px;
380+
}
381+
382+
.group-tag.user { background: rgba(73, 201, 99, 0.15); color: #49C963; }
383+
.group-tag.torch { background: rgba(62, 147, 204, 0.15); color: #3E93CC; }
384+
.group-tag.cpp { background: rgba(189, 147, 249, 0.15); color: #bd93f9; }
385+
.group-tag.python { background: rgba(255, 255, 255, 0.06); color: var(--text-muted); }
386+
304387
.stack-frame {
305-
padding: 4px 16px;
388+
padding: 3px 16px 3px 34px;
306389
font-family: var(--mono);
307390
font-size: 11px;
308-
line-height: 1.6;
391+
line-height: 1.5;
309392
color: var(--text-muted);
310-
border-bottom: 1px solid rgba(255,255,255,0.02);
311393
cursor: pointer;
312394
overflow: hidden;
313395
}
@@ -326,16 +408,10 @@ def generate_memory_html(
326408
327409
.stack-frame:hover { background: rgba(255,255,255,0.03); color: var(--text); }
328410
329-
.stack-frame .frame-idx {
330-
display: inline-block; width: 24px;
331-
color: rgba(255,255,255,0.15); text-align: right;
332-
margin-right: 8px; font-size: 10px;
333-
vertical-align: top;
334-
}
335-
336-
.stack-frame .frame-cpp { color: #f97316; }
337-
.stack-frame .frame-file { color: var(--accent); }
338-
.stack-frame .frame-func { color: var(--text); }
411+
.stack-frame .frame-cpp { color: #bd93f9; }
412+
.stack-frame .frame-file { color: #3E93CC; }
413+
.stack-frame .frame-func { color: #49C963; }
414+
.stack-frame .frame-basename { color: var(--text); }
339415
340416
.empty-detail {
341417
padding: 24px 16px;
@@ -349,19 +425,20 @@ def generate_memory_html(
349425
.grid line { stroke: var(--grid); }
350426
.grid path { stroke: none; }
351427
352-
.hwm-line { stroke: var(--hwm-color); stroke-width: 1; stroke-dasharray: 6 4; }
353-
.hwm-label { fill: var(--hwm-color); font-size: 11px; font-family: var(--font); font-weight: 600; }
428+
.hwm-line { stroke: var(--hwm-color); stroke-width: 0.75; stroke-dasharray: 8 4; }
429+
.hwm-label { fill: var(--hwm-color); font-size: 11px; font-family: var(--mono); font-weight: 500; letter-spacing: 0.02em; }
354430
355-
.alloc-poly { stroke: rgba(0,0,0,0.3); stroke-width: 0.5; cursor: pointer; }
356-
.alloc-poly:hover { stroke: white; stroke-width: 1.5; }
431+
.alloc-poly { stroke: rgba(0,0,0,0.5); stroke-width: 0.5; cursor: pointer; transition: opacity 0.1s; }
432+
.alloc-poly:hover { stroke: rgba(255,255,255,0.8); stroke-width: 1; }
357433
358434
#tooltip {
359435
position: fixed; display: none;
360-
background: var(--tooltip-bg); border: 1px solid var(--border);
361-
border-radius: 6px; padding: 10px 12px;
362-
font-size: 12px; line-height: 1.5;
436+
background: #1f1f1f; border: 1px solid rgba(255,255,255,0.08);
437+
border-radius: 4px; padding: 10px 14px;
438+
font-size: 12px; line-height: 1.6;
363439
pointer-events: none; z-index: 100; max-width: 500px;
364-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
440+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
441+
font-family: var(--mono);
365442
}
366443
367444
#tooltip .tt-label { color: var(--text-muted); margin-right: 4px; }
@@ -465,13 +542,12 @@ def generate_memory_html(
465542
document.getElementById('allocs-stat').textContent = META.num_allocs.toLocaleString();
466543
467544
const PALETTE = [
468-
'#6366f1', '#8b5cf6', '#a78bfa', '#c084fc',
469-
'#ec4899', '#f43f5e', '#fb7185', '#f97316',
470-
'#f59e0b', '#eab308', '#84cc16', '#22c55e',
471-
'#14b8a6', '#06b6d4', '#0ea5e9', '#3b82f6',
472-
'#818cf8', '#a5b4fc', '#c4b5fd', '#e879f9',
473-
'#f472b6', '#fb923c', '#fbbf24', '#a3e635',
474-
'#34d399', '#2dd4bf', '#22d3ee', '#38bdf8',
545+
'#3E93CC', '#2E7DB5', '#5BA8D9', '#78BBE3',
546+
'#49C963', '#3AA852', '#6DD883', '#8DE49D',
547+
'#bd93f9', '#a06eed', '#d4b5ff', '#9054e0',
548+
'#CC6B3E', '#E08A5B', '#B55A30', '#F0A478',
549+
'#3ECCC1', '#5BD9D0', '#2EB5AC', '#78E3DC',
550+
'#C9CC3E', '#D9DB5B', '#B5B72E', '#E3E478',
475551
];
476552
477553
function getColor(stackIdx) {
@@ -492,30 +568,71 @@ def generate_memory_html(
492568
493569
function hideTooltip() { tooltipEl.style.display = 'none'; }
494570
571+
function classifyFrame(frame) {
572+
if (!frame.includes(':') && frame.includes('::')) return 'cpp';
573+
if (frame.includes('/site-packages/torch/') || frame.includes('/torch/')) return 'torch';
574+
if (frame.includes('/lib/python') || frame.includes('/conda/') || frame.includes('lib/python')) return 'torch';
575+
return 'user';
576+
}
577+
578+
function renderFrame(frame) {
579+
const hasColon = frame.includes(':');
580+
const isCpp = !hasColon && frame.includes('::');
581+
if (isCpp) {
582+
const parts = frame.split('::');
583+
const funcName = parts[parts.length - 1];
584+
const ns = parts.slice(0, -1).join('::');
585+
return `<span class="frame-cpp">${ns}::</span><span class="frame-basename">${funcName}</span>`;
586+
}
587+
if (hasColon) {
588+
const sp = frame.indexOf(' ', frame.lastIndexOf(':'));
589+
if (sp > 0) {
590+
const filePart = frame.substring(0, sp);
591+
const funcPart = frame.substring(sp + 1);
592+
const lastSlash = filePart.lastIndexOf('/');
593+
const basename = lastSlash >= 0 ? filePart.substring(lastSlash + 1) : filePart;
594+
const dir = lastSlash >= 0 ? filePart.substring(0, lastSlash + 1) : '';
595+
return `<span class="frame-file">${dir}</span><span class="frame-basename">${basename}</span> <span class="frame-func">${funcPart}</span>`;
596+
}
597+
return `<span class="frame-file">${frame}</span>`;
598+
}
599+
return frame;
600+
}
601+
602+
const GROUP_LABELS = { user: 'Your Code', torch: 'PyTorch / Python', cpp: 'C++ Runtime' };
603+
495604
function renderStack(stackIdx, label) {
496605
const stack = STACKS[stackIdx] || [];
497606
detailStats.textContent = label;
498607
if (!stack.length) {
499608
detailBody.innerHTML = '<div class="empty-detail">No frames recorded</div>';
500609
return;
501610
}
502-
detailBody.innerHTML = stack.map((frame, i) => {
503-
const hasColon = frame.includes(':');
504-
const isCpp = !hasColon && frame.includes('::');
505-
let inner;
506-
if (isCpp) {
507-
inner = `<span class="frame-cpp">${frame}</span>`;
508-
} else if (hasColon) {
509-
const sp = frame.indexOf(' ', frame.lastIndexOf(':'));
510-
if (sp > 0) {
511-
inner = `<span class="frame-file">${frame.substring(0, sp)}</span> <span class="frame-func">${frame.substring(sp + 1)}</span>`;
512-
} else {
513-
inner = `<span class="frame-file">${frame}</span>`;
514-
}
515-
} else {
516-
inner = frame;
611+
612+
const groups = [];
613+
let cur = null;
614+
for (const frame of stack) {
615+
const cls = classifyFrame(frame);
616+
if (!cur || cur.cls !== cls) {
617+
cur = { cls, frames: [] };
618+
groups.push(cur);
517619
}
518-
return `<div class="stack-frame" onclick="this.classList.toggle('expanded')"><span class="frame-idx">${i}</span><span class="frame-text">${inner}</span></div>`;
620+
cur.frames.push(frame);
621+
}
622+
623+
detailBody.innerHTML = groups.map(g => {
624+
const collapsed = g.cls !== 'user' ? ' collapsed' : '';
625+
const framesHtml = g.frames.map(f =>
626+
`<div class="stack-frame" onclick="event.stopPropagation();this.classList.toggle('expanded')"><span class="frame-text">${renderFrame(f)}</span></div>`
627+
).join('');
628+
return `<div class="stack-group${collapsed}">
629+
<div class="stack-group-header" onclick="this.parentElement.classList.toggle('collapsed')">
630+
<span class="chevron">▼</span>
631+
<span class="group-tag ${g.cls}">${GROUP_LABELS[g.cls]}</span>
632+
<span class="group-count">${g.frames.length}</span>
633+
</div>
634+
<div class="stack-group-frames">${framesHtml}</div>
635+
</div>`;
519636
}).join('');
520637
}
521638

0 commit comments

Comments
 (0)