 Command

Sam Foreman's personal site. Vim-style keybinds for navigation; theme + font pickers below.

Theme
 Font Body Code
Reader
Keybinds
Navigation
j / ↓ Next item k / ↑ Previous item g First item in region G Last item in region zz Center focused item h / l Move left/right region ] / [ Next/previous heading } / { Next/previous block d / u Half-page down/up
Layout
<zh> / <zl> Toggle left/right sidebar <zr> Toggle reader view <zj> / <zk> Focus main/navbar <S-h/j/k/l> Focus left/main/navbar/right ⌃H / ⌃L Focus left/right sidebar ⌃J / ⌃K Focus main/navbar ⇧C / ⇧E Collapse / expand all sections
Dialogs
⌃P / : Command palette ⌃X Theme picker / Search ? Show keybinds Esc / ⌃C Close dialog
History
n Next document b Previous document ⌃O History back ⌃I History forward
 Search
about/more: 🪪 More about: Sam Foreman docs/test: Docs Test ideas: 💡 Ideas more: ➕ More now: Now projects: 📚 Projects webtui: Style posts: 📬 Posts talks: 🎙️ Talks posts/2025: 📆 2025 posts/auroragpt: 🤖 AuroraGPT posts/ai-for-physics: ⚛️ AI for Physics posts/ezpz-v1: 📝 ezpz-v1 posts/dope-slides: 💅 How to Make Dope Slides posts/ezpz-at-alcf: 🍋 ezpz @ ALCF posts/jupyter: 📗 Jupyter posts/resume: 🧑🏻‍💻 Sam Foreman’s Résumé posts/svgbob: 🫥 svgbob posts/torchtune-aurora: 🪛 Torchtune on Aurora posts/torchtune-patch-aurora: 🚑 Torchtune Patch on Aurora webtui/components/accordion: Accordion webtui/components/badge: Badge webtui/components/button: Button webtui/components/checkbox: Checkbox webtui/components/dialog: Dialog webtui/components/input: Input webtui/components/pre: Pre webtui/components/popover: Popover webtui/components/progress: Progress webtui/components/radio: Radio webtui/components/range: Range webtui/components/separator: Separator webtui/components/spinner: Spinner webtui/components/switch: Switch webtui/components/table: Table webtui/components/textarea: Textarea webtui/components/tooltip: Popover webtui/components/typography: Typography webtui/components/view: View webtui/installation/astro: Astro webtui/installation/astro: ## Scoping webtui/installation/astro: ### Frontmatter Imports webtui/installation/astro: ### ‹style› tag webtui/installation/astro: ### Full Library Import webtui/installation/nextjs: Next.js webtui/installation/vite: Vite webtui/plugins/plugin-dev: Developing Plugins webtui/plugins/plugin-dev: ### Style Layers webtui/plugins/plugin-nf: Nerd Font Plugin webtui/plugins/theme-custom: Custom Theme webtui/plugins/theme-everforest: Everforest Theme webtui/plugins/theme-catppuccin: Catppuccin Theme webtui/plugins/theme-gruvbox: Gruvbox Theme webtui/plugins/theme-nord: Nord Theme webtui/plugins/theme-vitesse: Vitesse Theme webtui/start/ascii-boxes: ASCII Boxes webtui/start/changelog: Changelog webtui/start/installation: Installation webtui/start/installation: ## Installation webtui/start/installation: ## Using CSS webtui/start/installation: ## Using ESM webtui/start/installation: ## Using a CDN webtui/start/installation: ## Full Library Import webtui/start/installation: ### CSS webtui/start/installation: ### ESM webtui/start/installation: ### CDN webtui/start/intro: Introduction webtui/start/intro: ## Features webtui/start/plugins: Plugins webtui/start/plugins: ## Official Plugins webtui/start/plugins: ### Themes webtui/start/plugins: ## Community Plugins webtui/start/theming: Theming webtui/start/theming: ## CSS Variables webtui/start/theming: ### Font Styles webtui/start/theming: ### Colors webtui/start/theming: ### Light & Dark webtui/start/theming: ## Theme Plugins webtui/start/theming: ### Using Multiple Theme Accents webtui/start/tuis-vs-guis: TUIs vs GUIs webtui/start/tuis-vs-guis: ## Monospace Fonts webtui/start/tuis-vs-guis: ## Character Cells webtui/contributing/contributing: Contributing webtui/contributing/contributing: ## Local Development webtui/contributing/contributing: ## Issues webtui/contributing/contributing: ## Pull Requests webtui/contributing/style-guide: Style Guide webtui/contributing/style-guide: ## CSS Units webtui/contributing/style-guide: ## Selectors webtui/contributing/style-guide: ## Documentation talks/auroragpt-siam25: AuroraGPT talks/ai-for-science-2024: Parallel Training Methods talks/aurora-gpt-fm-for-electric-grid/auroragpt-fm-for-electric-grid: AuroraGPT: Foundation Models for Science talks/hpc-user-forum/auroragpt: AuroraGPT talks/demo-slides: AuroraGPT: Training Foundation Models on Supercomputers talks/alcf-hpc-workshop-2024/alcf-hpc-workshop-2024: Deep Learning and Foundation Models at Scale talks/incite-hackathon-2025: ALCF Incite Hackathon 2025 talks/llms-at-scale: Training LLMs at Scale talks/llms-on-polaris: Training LLMs on Polaris talks/openskai25: Open SkAI2025 posts/2025/06: 06 posts/auroragpt/aurora-gpt: 🏎️ Megatron-DeepSpeed on Intel XPU posts/auroragpt/checkpoints: 💾 Converting Checkpoints posts/auroragpt/flash-attn-sunspot: 📸 `flash-attn` on Sunspot posts/auroragpt/determinstic-flash-attn/deterministic-flash-attn: 🎰 Deterministic `flash-attn` posts/auroragpt/long-sequences: 🚂 Loooooooong Sequence Lengths posts/auroragpt/mpi4py-reproducer: 🐛 `mpi4py` bug on Sunspot posts/auroragpt/spike-skipper: 🏔️ Spike Skipper posts/auroragpt/startup-times: 🐢 Starting Up Distributed Training on Aurora posts/auroragpt/startup-times: ## Response posts/auroragpt/startup-times: ### Measuring / Calculating Startup Time posts/auroragpt/startup-times: ## Minimal Working Example posts/ai-for-physics/diffusion: 🎲 MCMC + Diffusion Sampling posts/ai-for-physics/l2hmc-qcd: 🎢 L2HMC for LQCD posts/jupyter/l2hmc-4dsu3: 🔳 `l2hmc-qcd` Example: 4D SU(3) posts/jupyter/test: 🏁 `l2hmc` Example: 2D $U(1)$ talks/incite-hackathon-2025/ezpz: LLMs on Aurora: Hands-On talks/incite-hackathon-2025/auroragpt: LLMs on Aurora: Overview talks/openskai25/ai4science: Scientific AI at Scale: AuroraGPT talks/auroragpt/alcf-hpc-workshop-2024/auroragpt-alcf-hands-on-hpc-workshop-2024: AuroraGPT: ANL's General Purpose Scientific LLM talks/openskai25/training: Scientific AI at Scale: Distributed Training posts/2025/04/28: 🔥 Building PyTorch 2.6 from Source on Aurora posts/2025/09/12: 🍹 BlendCorpus + TorchTitan @ ALCF posts/2025/09/17: 📊 `pbs-tui`: TUI for PBS Job Scheduler Monitoring posts/2025/06/01: 📰 Nice Headings posts/2025/06/02: 🧜‍♀️ Mermaid posts/2025/06/14: 🏗️ Building PyTorch 2.8 from Source on Aurora posts/2025/10/06: 🎨 Mixing Between Distributions While Training posts/2025/11/12: 🧊 Cooling Down Checkpoints: Best Practices for Model Evaluation posts/2025/05/03: 🚧 Frameworks Issue with numpy \› 2 posts/2026/02/28: ⏱️ Comparing Launchers on Aurora posts/2026/02/28: ## torchrun posts/2026/02/28: ## ezpz posts/2026/04/27: Pre-Training AuroraGPT with TorchTitan posts/2026/04/27: ## Two-Week Summary (Apr 12–27, 2026) posts/2026/04/27: ## Detailed Breakdown posts/2026/04/27: ### Week 1: Apr 12–18 — Benchmarking, LR Finder, XPU Fixes posts/2026/04/27: #### Benchmarking (Apr 12–15) posts/2026/04/27: #### LR Finder (Apr 12–14) posts/2026/04/27: #### Scaling Study (Apr 12) posts/2026/04/27: #### Upstream Syncs (Apr 12–18, syncs 6–14) posts/2026/04/27: #### XPU Bug Fixes (Apr 18) posts/2026/04/27: #### RL Experiment (Apr 18) posts/2026/04/27: ### Week 1.5: Apr 18–25 — Production Readiness posts/2026/04/27: #### Torch 2.12 Benchmarks (Apr 18) posts/2026/04/27: #### LR Finder Extensions (Apr 20–21) posts/2026/04/27: #### XPU Fixes (Apr 23) posts/2026/04/27: #### Torch 2.13 Environment (Apr 25) posts/2026/04/27: #### 2B Scaling Study on Torch 2.13 (Apr 25) posts/2026/04/27: #### Production Training (Apr 25) posts/2026/04/27: ### Week 2: Apr 26–27 — Optimizer Competition posts/2026/04/27: #### RL Multi-Task Refactor (Apr 26) posts/2026/04/27: #### Docs Reorganization (Apr 26) posts/2026/04/27: #### Generic HF Dataset Streaming (Apr 26) posts/2026/04/27: #### New Optimizers (Apr 26) posts/2026/04/27: #### Architecture Tweaks (Apr 26–27) posts/2026/04/27: ## Competition Results posts/2026/04/27: ### Round 1–3: Speedrun — 2N, GBS=48, 1000 steps posts/2026/04/27: ### 10B Full Training — 8N, GBS=384, ~3,178 steps posts/2026/04/27: ### Round 4: Reproducible Speedrun — 2N, GAS=8, GBS=384, 1000 steps posts/2026/04/27: ## Key Discoveries posts/2026/04/27: ## Infrastructure Built posts/2026/04/27: ## High-Level posts/2026/04/27: ## Detailed Breakdown posts/2026/04/27: ### Week 1: Apr 12–18 — Benchmarking, LR Finder, XPU Fixes posts/2026/04/27: #### Benchmarking (Apr 12–15) posts/2026/04/27: #### LR Finder (Apr 12–14) posts/2026/04/27: #### Scaling Study (Apr 12) posts/2026/04/27: #### Upstream Syncs (Apr 12–18, syncs 6–14) posts/2026/04/27: #### XPU Bug Fixes (Apr 18) posts/2026/04/27: #### RL Experiment (Apr 18) posts/2026/04/27: ### Week 1.5: Apr 18–25 — Production Readiness posts/2026/04/27: #### Torch 2.12 Benchmarks (Apr 18) posts/2026/04/27: #### LR Finder Extensions (Apr 20–21) posts/2026/04/27: #### XPU Fixes (Apr 23) posts/2026/04/27: #### Torch 2.13 Environment (Apr 25) posts/2026/04/27: #### 2B Scaling Study on Torch 2.13 (Apr 25) posts/2026/04/27: #### Production Training (Apr 25) posts/2026/04/27: ### Week 2: Apr 26–27 — Optimizer Competition posts/2026/04/27: #### RL Multi-Task Refactor (Apr 26) posts/2026/04/27: #### Docs Reorganization (Apr 26) posts/2026/04/27: #### Generic HF Dataset Streaming (Apr 26) posts/2026/04/27: #### New Optimizers (Apr 26) posts/2026/04/27: #### Architecture Tweaks (Apr 26–27) posts/2026/04/27: ## Competition Results posts/2026/04/27: ### Round 1–3: 1000-step speedruns, 2 nodes, GBS=48 (17 configs) posts/2026/04/27: ### Round 4 (10B full training, 8 nodes, GBS=384, 5 configs) posts/2026/04/27: ### Round 5 (2 nodes, GAS=8, GBS=384, local dataset, 8 configs — in progress) posts/2026/04/27: ## Key Discoveries posts/2026/04/27: ## Infrastructure Built posts/2026/05/01: Running 50k Python Processes on Aurora with ezpz yeet posts/2026/06/28: Migrating from Quarto to Astro: samforeman.me → samf.sh posts/2026/06/27: Local AI Apps on ALCF: Argo, Inference Endpoints, and One Gateway posts/ai-for-physics/l2hmc-qcd/2du1: 🎢 l2hmc-qcd Example: 2D U(1) posts/2026/01/07: 🎉 Happy New Year! posts/2026/01/10: 🍋 ezpz: distributed PyTorch across any hardware posts/jupyter/l2hmc/4dsu3: 🔳 l2hmc-qcd Example: 4D SU(3) posts/ai-for-physics/l2hmc-qcd/4dsu3nb/index-broken: 🕸️ l2hmc-qcd Example: 4D SU(3) talks/2025/09/24: Training Foundation Models on Supercomputers talks/2025/10/08: AERIS: Argonne's Earth Systems Model talks/2025/10/15: Training Foundation Models on Supercomputers talks/2025/10/24: Training Foundation Models on Supercomputers posts/drafts/2025/09/22: 📝 2025 Annual Report talks/2026/06/03: Production Pre-Training at Scale: The Good, the Bad, and the Restarts talks/2025/12/16: AuroraGPT: Training Foundation Models on Supercomputers
 Theme Current: Light j/k or ↑/↓ + Enter

Migrating from Quarto to Astro: samforeman.me → samf.sh

Why I moved my personal site off Quarto and onto Astro, with measured before/after comparisons of Lighthouse scores, build time, and site size.

For about three years my personal site lived at samforeman.me, built with Quarto. Quarto was a great fit at the time: I write a lot of computational notebooks, and it renders .qmd and .ipynb straight to a website with executed output baked in. But the site grew to hundreds of source documents, and the friction grew with it: builds took minutes, the output directory ballooned past 800 MB, and customizing anything past the theme meant fighting the framework.

So I rebuilt it on Astro at samf.sh. This post is the honest accounting: what got better, what is just different, and the numbers behind both.

What carried over

The rebuild was not a rewrite from zero. The parts I actually liked about the old site came along:

  • Math, via KaTeX (was MathJax).
  • Diagrams, via Mermaid, tree-shaken down to only the diagram types I use.
  • ASCII diagrams, rendered to SVG with svgbob at build time.
  • Syntax highlighting, via Shiki (was highlight.js), with a couple of custom Neovim-derived themes.
  • Self-hosted fonts (Iosevka and friends), subset to the glyphs the site actually uses.

The content itself is Markdown/MDX now instead of Quarto Markdown. For prose-first posts that is a clean port. For notebook-heavy posts it is more work, since Astro does not execute notebooks: where the old site re-ran a .ipynb on every render, the new site treats committed output (charts as static SVG/PNG, tables as MDX) as the source of truth. That is a real tradeoff, covered below.

Lighthouse

Rather than cherry-pick one page, I took the 52 routes that exist on both sites and measured 8 of them at random, each on desktop and mobile, against the live production sites in the same session. The eight: /posts/dope-slides, /posts/jupyter/test, /posts/svgbob, /projects, /talks/2025/10/15, /talks/llms-at-scale, /talks/llms-on-polaris, /talks/openskai25/ai4science. The home page (/) is listed first as a reference; it is not part of the random sample, so it is excluded from the mean.

Performance scores (green ≥ 90, amber 50-89, red < 50, Lighthouse’s own bands):

PageDesktop oldDesktop newMobile oldMobile new
/ (home)84965184
/posts/dope-slides84953877
/posts/jupyter/test72952867
/posts/svgbob67995781
/projects69685187
/talks/2025/10/158599n/a67
/talks/llms-at-scale86995267
/talks/llms-on-polaris83994863
/talks/openskai25/ai4science71754975
Mean77914673

The new site is faster on every page on mobile, and on all but one on desktop (/projects is a statistical tie). The mean lift is +14 on desktop and +27 on mobile, where the old Quarto pages were routinely in the red.

A few honest caveats:

  • Mobile is the throttled profile (slow 4G + a 4× CPU slowdown), which is why even the new site sits in amber there. The point is the relative jump, not the absolute mobile number.
  • Lighthouse is point-in-time, sensitive to CPU/network contention at the moment of the run (these ran on a busy shared machine). Treat single-digit gaps as noise; the durable signal is the consistent old → new lift across a random sample, not any one cell. (/talks/2025/10/15 old-mobile is n/a: that one run failed to produce a score.)
  • This table is performance only. On the full category sweep the new site also scores 100 on Best Practices and SEO across the board (up from the low 90s and, on posts, the 70s), driven by structured metadata, correct caching headers, and no third-party console noise.

Build time

CommandTime
Quartoquarto render --no-clean7 min 49 s
Astrobun run build (cold, caches cleared)99 s

This is not a pure apples-to-apples race: Quarto’s time includes executing notebooks, which Astro does not do. Quarto caches executed output (its freeze mechanism), so warm rebuilds are faster than the cold number above. But for my actual workflow (edit prose, rebuild, preview) the Astro loop is the one that feels instant, and the dev server’s hot reload makes most rebuilds unnecessary anyway.

Site size

Built siteHTML pagesFramework assetsCSSJS
Quarto (docs/)851 MB100site_libs 152 MB128 MB8.5 MB
Astro (dist/)523 MB145_astro 17 MB0.3 MB4.8 MB

Two things deserve a caveat so the numbers are not misleading:

  1. Most of both totals is images. The old docs/ carried roughly 500 MB of figures; the new site is smaller mostly because I have not migrated every image yet, not because Astro magically shrinks media. The fairer comparison is the framework overhead, where the gap is real and large.
  2. That CSS column is the real story. Quarto ships full framework CSS (Bootstrap and friends) per page library, which is how 947 CSS files add up to 128 MB on disk. Astro emits one small scoped bundle: 0.3 MB total. That is a ~400× reduction in stylesheet weight on disk, and it shows up in what the browser downloads.

Per-page transfer

What a visitor actually downloads for the HTML document (the new site serves Brotli/gzip from Cloudflare):

PageQuarto (raw / gzip)Astro (raw / gzip)
Home288 KB / 56 KB255 KB / 33 KB
Post182 KB / 34 KB305 KB / 31 KB

The home page compresses to about 60% of the old size. The post’s raw HTML is actually larger on the new site (more inline content), but it still gzips a touch smaller, and it loads against a fraction of the old CSS/JS payload.

What I gave up

To keep this honest, the migration was not free:

  • No notebook execution. Quarto re-runs .qmd/.ipynb and embeds fresh output. Astro does not, so posts that relied on that now commit their output as static assets. For reproducible-by-rebuild posts that is a downgrade; for everything else it removed a slow, fragile step.
  • More manual wiring. Quarto gives you a themed site for free. On Astro I own the layout, the components, and the build config. That is the whole point (it is why customizing is finally pleasant), but it was real up-front work.
  • A port, not a copy. Hundreds of documents had to move from Quarto Markdown to MDX. Most were mechanical; some were not.

Was it worth it

For me, yes. The site is faster on every measured axis, the build loop went from minutes to seconds, the framework overhead dropped by more than an order of magnitude, and I can finally change things without arguing with the toolchain. If you live in notebooks and want execution-on-render, Quarto is still excellent and I would not talk you out of it. But if your site is mostly prose and components, and you have outgrown the theme, Astro is a very comfortable place to land.

 samf.sh / posts / 2026 / 06 / 28 · Top 1:1