auto: 2026-09-02T22:56:02Z [skip ci]

This commit is contained in:
Levi Neuwirth 2026-09-03 00:56:02 +02:00
parent 3fe113c94b
commit 3244d0b660
No known key found for this signature in database
9 changed files with 184 additions and 128 deletions

View File

@ -1,43 +0,0 @@
import sys
import csv
import numpy as np
sys.path.insert(0, 'tools')
from viz_theme import apply_monochrome, save_svg
apply_monochrome()
import matplotlib.pyplot as plt
def read_data(filepath):
ops = []
matrix = []
with open(filepath, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
ops.append(row['op'])
matrix.append([float(row['m512']), float(row['m768']), float(row['m1024'])])
return ops, np.array(matrix)
filepath = "content/essays/where-does-simd-help-post-quantum-cryptography/figures/data/cliffs_delta.csv"
ops, matrix = read_data(filepath)
labels = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']
fig, ax = plt.subplots(figsize=(6, 5))
im = ax.imshow(matrix, cmap='Greys', vmin=0.9, vmax=1.0)
ax.set_xticks(np.arange(len(labels)))
ax.set_yticks(np.arange(len(ops)))
ax.set_xticklabels(labels)
display_ops = [op.replace('gena', 'gen_a') for op in ops]
ax.set_yticklabels(display_ops)
plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
for i in range(len(ops)):
for j in range(len(labels)):
val = matrix[i, j]
text_color = "white" if val > 0.95 else "black"
ax.text(j, i, f"{val:.3f}", ha="center", va="center", color=text_color)
ax.set_title("Cliff's delta (ref vs. avx2)")
save_svg(fig)

View File

@ -0,0 +1,47 @@
{
"files": {
"cliffs_delta.csv": {
"bytes": 248,
"rows": 9,
"sha256": "ce773a41b4b12f87471cad081071430db2d56dee214e1158d041d1c9c0970218",
"source": "TODO: the command or run that produced this"
},
"cross_param.csv": {
"bytes": 559,
"rows": 4,
"sha256": "752b4919e479d7e4ce732e9bb2a0c502c1df4ea9ed5152d33724ebcc0288b9a3",
"source": "TODO: the command or run that produced this"
},
"decomp_mlkem1024.csv": {
"bytes": 1556,
"rows": 9,
"sha256": "9ae19fbadca2f10c5d62829c7123f1b2e85675ac53770772be9bf26c6c5cc37f",
"source": "TODO: the command or run that produced this"
},
"decomp_mlkem512.csv": {
"bytes": 1505,
"rows": 9,
"sha256": "412d920bac2dad2425eedb2b5a7e731c380bc0365404c143f0009c91062a1644",
"source": "TODO: the command or run that produced this"
},
"decomp_mlkem768.csv": {
"bytes": 1529,
"rows": 9,
"sha256": "b3f9ee1b1416dbd36a32bc94ade6b638084142ecba059ca2c8eee1ac4b88d70e",
"source": "TODO: the command or run that produced this"
},
"hand_simd.csv": {
"bytes": 1440,
"rows": 9,
"sha256": "4b250c2529a93d9ef0a00a3f7588f6334ff479910b9a2be7cecf67a883b3e69b",
"source": "TODO: the command or run that produced this"
},
"kem_level.csv": {
"bytes": 654,
"rows": 3,
"sha256": "23578e0e763061a4e5db2f8180d8d178298f58829dc8d4ceca5e57de9b90137c",
"source": "TODO: the command or run that produced this"
}
},
"generated_by": "tools/viz-provenance.py"
}

View File

@ -1,21 +1,18 @@
import sys
import csv
import numpy as np
sys.path.insert(0, 'tools')
from viz_theme import apply_monochrome, save_svg
from viz_theme import apply_monochrome, save_svg, load_csv
apply_monochrome()
import matplotlib.pyplot as plt
def read_data(filepath):
def read_data(rows):
ops = []
m512 = []; m512_err = []
m768 = []; m768_err = []
m1024 = []; m1024_err = []
with open(filepath, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
for row in rows:
ops.append(row['op'])
m512.append(float(row['m512_sp']))
m512_err.append([float(row['m512_elo']), float(row['m512_ehi'])])
@ -29,8 +26,8 @@ def read_data(filepath):
m1024_err = np.array(m1024_err).T
return ops, m512, m512_err, m768, m768_err, m1024, m1024_err
filepath = "content/essays/where-does-simd-help-post-quantum-cryptography/figures/data/cross_param.csv"
ops, m512, m512_err, m768, m768_err, m1024, m1024_err = read_data(filepath)
DATA = "cross_param.csv"
ops, m512, m512_err, m768, m768_err, m1024, m1024_err = read_data(load_csv(DATA))
fig, ax = plt.subplots(figsize=(8, 4))
bar_width = 0.25
@ -50,4 +47,18 @@ ax.set_ylim(bottom=0, top=70)
ax.legend(loc='upper right', frameon=False, fontsize='small')
save_svg(fig)
save_svg(
fig,
alt=(
"Grouped bar chart comparing AVX2 speedup for four per-polynomial "
"ML-KEM operations across the three parameter sets."
),
desc=(
"The four operations -- frommsg, INVNTT, basemul and NTT -- all "
"work on 256-coefficient polynomials, so their speedups would be "
"expected to be independent of the parameter set. They are close "
"but not identical: frommsg rises from about 46 to 55 times as the "
"parameter set grows, while basemul falls from about 52 to 42 "
"times."
),
)

View File

@ -1,22 +1,19 @@
import sys
import os
import csv
import numpy as np
sys.path.insert(0, 'tools')
from viz_theme import apply_monochrome, save_svg
from viz_theme import apply_monochrome, save_svg, load_csv
apply_monochrome()
import matplotlib.pyplot as plt
def read_data(filepath):
def read_data(rows):
ops = []
refnv = []; refnv_err = []
ref = []; ref_err = []
avx2 = []; avx2_err = []
with open(filepath, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
for row in rows:
ops.append(row['op'])
refnv.append(float(row['refnv_sp']))
refnv_err.append([float(row['refnv_elo']), float(row['refnv_ehi'])])
@ -30,10 +27,9 @@ def read_data(filepath):
avx2_err = np.array(avx2_err).T
return ops, refnv, refnv_err, ref, ref_err, avx2, avx2_err
base_path = "content/essays/where-does-simd-help-post-quantum-cryptography/figures/data"
params = [("ML-KEM-512", f"{base_path}/decomp_mlkem512.csv"),
("ML-KEM-768", f"{base_path}/decomp_mlkem768.csv"),
("ML-KEM-1024", f"{base_path}/decomp_mlkem1024.csv")]
params = [("ML-KEM-512", "decomp_mlkem512.csv"),
("ML-KEM-768", "decomp_mlkem768.csv"),
("ML-KEM-1024", "decomp_mlkem1024.csv")]
fig, axes = plt.subplots(1, 3, figsize=(12, 4), sharey=True)
@ -42,7 +38,7 @@ colors = ['#333333', '#777777', '#bbbbbb']
labels = ['O3 (no auto-vec)', 'O3 + auto-vec', 'O3 + hand SIMD']
for i, (title, filepath) in enumerate(params):
ops, refnv, refnv_err, ref, ref_err, avx2, avx2_err = read_data(filepath)
ops, refnv, refnv_err, ref, ref_err, avx2, avx2_err = read_data(load_csv(filepath))
ax = axes[i]
x = np.arange(len(ops))
@ -59,7 +55,7 @@ for i, (title, filepath) in enumerate(params):
ax.set_yscale('log')
if i == 0:
ax.set_ylabel("Speedup over -O0 ($\times$)")
ax.set_ylabel("Speedup over -O0 ($\\times$)")
# Tick formatting
ax.set_ylim(bottom=1, top=500)
@ -67,4 +63,21 @@ for i, (title, filepath) in enumerate(params):
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda y, pos: f"${int(y)}\\times$"))
axes[-1].legend(loc='upper right', frameon=False, fontsize='small')
save_svg(fig)
save_svg(
fig,
alt=(
"Grouped bar chart of cumulative speedup over unoptimized reference "
"code, for nine ML-KEM operations at each of the three parameter "
"sets."
),
desc=(
"Three panels, one per parameter set. Each operation has three bars "
"on a logarithmic axis: compiler O3 without auto-vectorization, O3 "
"with it, and hand-written AVX2. The first two bars are nearly the "
"same height everywhere -- around 3 to 4 times -- so auto- "
"vectorization adds almost nothing. The third bar is far taller for "
"the polynomial operations, reaching roughly 200 times for INVNTT, "
"and the gap narrows for the sampling operations at the right of "
"each panel."
),
)

View File

@ -1,21 +1,18 @@
import sys
import csv
import numpy as np
sys.path.insert(0, 'tools')
from viz_theme import apply_monochrome, save_svg
from viz_theme import apply_monochrome, save_svg, load_csv
apply_monochrome()
import matplotlib.pyplot as plt
def read_data(filepath):
def read_data(rows):
ops = []
m512 = []; m512_err = []
m768 = []; m768_err = []
m1024 = []; m1024_err = []
with open(filepath, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
for row in rows:
ops.append(row['op'])
m512.append(float(row['m512_sp']))
m512_err.append([float(row['m512_elo']), float(row['m512_ehi'])])
@ -29,8 +26,8 @@ def read_data(filepath):
m1024_err = np.array(m1024_err).T
return ops, m512, m512_err, m768, m768_err, m1024, m1024_err
filepath = "content/essays/where-does-simd-help-post-quantum-cryptography/figures/data/hand_simd.csv"
ops, m512, m512_err, m768, m768_err, m1024, m1024_err = read_data(filepath)
DATA = "hand_simd.csv"
ops, m512, m512_err, m768, m768_err, m1024, m1024_err = read_data(load_csv(DATA))
fig, ax = plt.subplots(figsize=(10, 4))
bar_width = 0.25
@ -54,4 +51,19 @@ ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda y, pos: f"${int(y)}\\ti
ax.legend(loc='upper left', frameon=False, fontsize='small')
save_svg(fig)
save_svg(
fig,
alt=(
"Grouped bar chart of hand-written AVX2 speedup over scalar "
"reference code, for nine ML-KEM operations at three parameter "
"sets."
),
desc=(
"Logarithmic axis, operations sorted by their ML-KEM-512 speedup. "
"The range runs from about 56 times for INVNTT and 52 times for "
"basemul down to about 1.4 times for noise sampling. The three "
"parameter sets track each other closely for every operation. "
"Confidence intervals are present but mostly narrower than the bar "
"edges."
),
)

View File

@ -1,21 +1,18 @@
import sys
import csv
import numpy as np
sys.path.insert(0, 'tools')
from viz_theme import apply_monochrome, save_svg
from viz_theme import apply_monochrome, save_svg, load_csv
apply_monochrome()
import matplotlib.pyplot as plt
def read_data(filepath):
def read_data(rows):
ops = []
m512 = []; m512_err = []
m768 = []; m768_err = []
m1024 = []; m1024_err = []
with open(filepath, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
for row in rows:
ops.append(row['op'])
m512.append(float(row['m512_sp']))
m512_err.append([float(row['m512_elo']), float(row['m512_ehi'])])
@ -29,8 +26,8 @@ def read_data(filepath):
m1024_err = np.array(m1024_err).T
return ops, m512, m512_err, m768, m768_err, m1024, m1024_err
filepath = "content/essays/where-does-simd-help-post-quantum-cryptography/figures/data/kem_level.csv"
ops, m512, m512_err, m768, m768_err, m1024, m1024_err = read_data(filepath)
DATA = "kem_level.csv"
ops, m512, m512_err, m768, m768_err, m1024, m1024_err = read_data(load_csv(DATA))
fig, ax = plt.subplots(figsize=(8, 4))
bar_width = 0.25
@ -50,4 +47,18 @@ ax.set_ylim(bottom=0, top=9)
ax.legend(loc='upper left', frameon=False, fontsize='small')
save_svg(fig)
save_svg(
fig,
alt=(
"Grouped bar chart of end-to-end AVX2 speedup for the three ML-KEM "
"operations, at three parameter sets."
),
desc=(
"Key generation, encapsulation and decapsulation all land between "
"roughly 5.4 and 7.1 times faster than the scalar reference, a much "
"narrower band and a much smaller factor than the per-operation "
"speedups elsewhere in the essay, because the arithmetic AVX2 "
"accelerates is only part of the whole operation. Confidence "
"intervals are too small to see at this scale."
),
)

View File

@ -3,6 +3,7 @@ title: "Where Does SIMD Help Post-Quantum Cryptography? A Micro-Architectural St
date: 2026-04-04
abstract: >
We systematically decompose the sources of SIMD speedup for ML-KEM (Kyber) on Intel x86-64 AVX2. By benchmarking four compilation variants, we demonstrate that GCC's auto-vectorizer provides negligible benefit, and that hand-written AVX2 assembly delivers a $35\times$$56\times$ performance increase for core arithmetic operations. This drives an end-to-end KEM speedup of $5.4\times$$7.1\times$.
figure-numbering: true
tags:
- research
- research/cryptography
@ -138,7 +139,7 @@ All benchmarks were conducted on Brown University's [OSCAR HPC cluster](https://
### Statistical Methodology
Cycle count distributions are right-skewed with occasional outliers from OS interrupts and cache-cold starts (the figure). We therefore use nonparametric statistics throughout:
Cycle count distributions are right-skewed with occasional outliers from OS interrupts and cache-cold starts ([](#fig-distributions)). We therefore use nonparametric statistics throughout:
- **Speedup**: ratio of group medians, $\hat{s} = \text{median}(X_\text{baseline}) / \text{median}(X_\text{variant})$.
- **Confidence interval**: 95% bootstrap CI on $\hat{s}$, computed by resampling both groups independently $B = 5{,}000$ times with replacement.
@ -161,7 +162,7 @@ The figure shows the cycle count distributions for three representative operatio
The separation between `ref` and `avx2` is qualitatively different across operation types: for `INVNTT` the distributions do not overlap at all (disjoint spikes separated by two orders of magnitude on the log scale); for `gen_a` there is partial overlap; for noise sampling the distributions are nearly coincident.
![Cycle count distributions for three representative ML-KEM-512 operations. Log $x$-axis. Dashed lines mark medians. Right-skew and outlier structure motivate nonparametric statistics.](figures/distributions.pdf)
![Cycle count distributions for three representative ML-KEM-512 operations. Log $x$-axis. Dashed lines mark medians. Right-skew and outlier structure motivate nonparametric statistics.](figures/distributions.pdf){#fig-distributions}
### Speedup Decomposition
@ -173,7 +174,7 @@ Several structural features are immediately apparent:
- The `avx2` bars are 12 orders of magnitude taller than the `ref` bars for arithmetic operations, indicating that hand-written SIMD dominates the speedup.
- For SHAKE-heavy operations (gen_a, noise), all three bars are much closer together, reflecting the memory-bandwidth bottleneck that limits SIMD benefit.
::: {.figure script="figures/fig_decomp.py" caption="Cumulative speedup at each optimization stage, normalized to `refo0` (1×). Three bars per operation: O3 no auto-vec, O3 + auto-vec, O3 + hand SIMD (AVX2). Log $y$-axis; 95% bootstrap CI shown on `avx2` bars. Sorted by `avx2` speedup."}
::: {.figure #fig-decomp script="figures/fig_decomp.py" caption="Cumulative speedup at each optimization stage, normalized to `refo0` (1×). Three bars per operation: O3 no auto-vec, O3 + auto-vec, O3 + hand SIMD (AVX2). Log $y$-axis; 95% bootstrap CI shown on `avx2` bars. Sorted by `avx2` speedup."}
:::
### Hand-Written SIMD Speedup
@ -187,7 +188,7 @@ Key observations:
- **Noise sampling** achieves only $1.2\times$$1.4\times$, the smallest SIMD benefit. The centered binomial distribution (CBD) sampler is bit-manipulation-heavy with sequential bitstream reads that do not parallelise well.
- Speedups are broadly consistent across parameter sets for per-polynomial operations, as expected (the corresponding section).
::: {.figure script="figures/fig_hand_simd.py" caption="Hand-written SIMD speedup (`ref` $\to$ `avx2`) per operation, across all three ML-KEM parameter sets. Log $y$-axis. 95% bootstrap CI error bars (often sub-pixel). Sorted by ML-KEM-512 speedup."}
::: {.figure #fig-hand-simd script="figures/fig_hand_simd.py" caption="Hand-written SIMD speedup (`ref` $\to$ `avx2`) per operation, across all three ML-KEM parameter sets. Log $y$-axis. 95% bootstrap CI error bars (often sub-pixel). Sorted by ML-KEM-512 speedup."}
:::
| Operation | ML-KEM-512 | ML-KEM-768 | ML-KEM-1024 |
@ -206,12 +207,9 @@ Key observations:
### Statistical Significance
All `ref` vs. `avx2` comparisons pass the Mann-Whitney U test at $p < 10^{-300}$. Cliff's $\delta = +1.000$ for all operations except `NTT` at ML-KEM-512 and ML-KEM-1024 ($\delta = +0.999$), meaning AVX2 achieves a strictly smaller cycle count than `ref` in effectively every observation pair.
All `ref` vs. `avx2` comparisons pass the Mann-Whitney U test at $p < 10^{-300}$. Cliff's $\delta = +1.000$ for every operation at every parameter set except `noise` at ML-KEM-1024 ($\delta = +0.999$), meaning AVX2 achieves a strictly smaller cycle count than `ref` in effectively every observation pair.
The figure shows the heatmap of Cliff's $\delta$ values across all operations and parameter sets.
::: {.figure script="figures/cliffs_delta_heatmap.py" caption="Cliff's $\delta$ (`ref` vs. `avx2`) for all operations and parameter sets. $\delta = +1$: AVX2 is faster in every observation pair. Nearly all cells are at $+1.000$."}
:::
The per-cell values are in [`cliffs_delta.csv`](figures/data/cliffs_delta.csv).
### Cross-Parameter Consistency
@ -219,7 +217,7 @@ The figure shows the `avx2` speedup for the four per-polynomial operations acros
`NTT` shows a more pronounced variation ($35.5\times$ at ML-KEM-512, $39.4\times$ at ML-KEM-768, $34.6\times$ at ML-KEM-1024) that is statistically real (non-overlapping 95% CIs). We attribute this to *cache state effects*: the surrounding polyvec loops that precede each NTT call have a footprint that varies with $k$, leaving different cache residency patterns that affect NTT latency in the scalar `ref` path. The AVX2 path is less sensitive because its smaller register footprint keeps more state in vector registers.
::: {.figure script="figures/fig_cross_param.py" caption="Per-polynomial operation speedup (`ref` $\to$ `avx2`) across security parameters. Polynomial dimension is 256 for all; variation reflects cache-state differences in the calling context."}
::: {.figure #fig-cross-param script="figures/fig_cross_param.py" caption="Per-polynomial operation speedup (`ref` $\to$ `avx2`) across security parameters. Polynomial dimension is 256 for all; variation reflects cache-state differences in the calling context."}
:::
### Hardware Counter Breakdown
@ -271,7 +269,7 @@ The $13\%$ variation in NTT speedup across parameter sets (the corresponding sec
### Implications for Deployment
The end-to-end KEM speedups of $5.4\times$$7.1\times$ (Supplementary, the figure) represent the practical deployment benefit. Deployments that cannot use hand-written SIMD (e.g., some constrained environments, or languages without inline assembly support) should expect performance within a factor of $5$$7$ of the AVX2 reference. Auto-vectorization provides essentially no shortcut: the gap between compiler-optimized C and hand-written SIMD is the full $5$$7\times$, not a fraction of it.
The end-to-end KEM speedups of $5.4\times$$7.1\times$ (Supplementary, [](#fig-kem-level)) represent the practical deployment benefit. Deployments that cannot use hand-written SIMD (e.g., some constrained environments, or languages without inline assembly support) should expect performance within a factor of $5$$7$ of the AVX2 reference. Auto-vectorization provides essentially no shortcut: the gap between compiler-optimized C and hand-written SIMD is the full $5$$7\times$, not a fraction of it.
### Limitations
@ -329,7 +327,7 @@ The figure shows the hand-written SIMD speedup for the top-level KEM operations:
Decapsulation achieves the highest speedup ($6.9\times$$7.1\times$) because it involves the largest share of arithmetic operations (two additional NTT and INVNTT calls for re-encryption verification). Key generation achieves the lowest ($5.3\times$$5.9\times$) because it involves one fewer polynomial multiplication step relative to encapsulation.
::: {.figure script="figures/fig_kem_level.py" caption="End-to-end KEM speedup (`ref` $\to$ `avx2`) for `kyber_keypair`, `kyber_encaps`, and `kyber_decaps`. Intel Xeon Platinum 8268; 95% bootstrap CI."}
::: {.figure #fig-kem-level script="figures/fig_kem_level.py" caption="End-to-end KEM speedup (`ref` $\to$ `avx2`) for `kyber_keypair`, `kyber_encaps`, and `kyber_decaps`. Intel Xeon Platinum 8268; 95% bootstrap CI."}
:::
### Full Operation Set

View File

@ -22,7 +22,7 @@ For as long as I can remember, I have believed that the deepest understanding co
You have found the working library of a mind that takes that spirit seriously. Here live research papers and living essays, compositions and scores, poetry and prose, and the countless smaller investigations that refuse to fit neatly into any one category. The documents here are far from immutable; they grow, are revised, accumulate footnotes and second thoughts. I welcome you to all of it.
This website is *not* an academic homepage, nor a blog, nor a portfolio — though it borrows from each. It is something I built because no existing format could hold what I wanted to make. I carry a copy of *The Brothers Karamazov* everywhere; I compose symphonies and concerti for orchestras; I am currently a MARS V AI safety research fellow with CAISH and FLI, an independent contractor doing work on frontier LLMs, and a graduate student in computer science and engineering at DTU. These facts coexist in one life, and this is the place where they coexist on one shelf.
This website is *not* an academic homepage, nor a blog, nor a portfolio — though it borrows from each. It is something I built because no existing format could hold what I wanted to make. I carry a copy of *The Brothers Karamazov* everywhere; I compose symphonies and concerti for orchestras; I am an independent researcher, working chiefly on cryptographic verification of AI systems, and at present a MARS V fellow with the Cambridge AI Safety Hub and the Future of Life Institute. These facts coexist in one life, and this is the place where they coexist on one shelf.
::: {.hp-latin lang="la"}
*Te accipio, hospes benignus.*

View File

@ -54,12 +54,19 @@ With this said, there is one major exception, and that is my favorite book: *The
### University
I graduated from **Brown University** in May 2026 with degrees in Mathematics and Computer Science. This autumn I begin my graduate studies in Computer Science at the Technical University of Denmark. I chose these areas because their generality and broad interaction with abstraction captivated me in a notable way. This fact is still true to this day - I have never felt significant burnout, nor felt that I had exhausted some finite supply of interest and curiosity in my chosen fields.
I graduated from **Brown University** in May 2026 with degrees in Mathematics and Computer Science. I chose these areas because their generality and broad interaction with abstraction captivated me in a notable way. This fact is still true to this day - I have never felt significant burnout, nor felt that I had exhausted some finite supply of interest and curiosity in my chosen fields.
### Autodidacticism
The bulk of what I have learned has been on an individual basis rather than in affiliation with some institution. This is merely a personal preference; I do not think that autodidactic learning is uniformly intrinsically better, nor do I believe that is necessarily more efficient or otherwise superior to learning through an institution. It is simply what I have always known works for me, and my intuition in this regard has been substantiated by years of empirical evidence.^[Read: progressing through the formalisms of various educational institutions. My grievances are primarily with the public school system that I endured for 13 years of my life, in which autodidacticism was actively perceived as contrary to the goals of the institution, whereas autodidacticism is essentially implied at the University level, or, at a minimum, at a University as rigorous at Brown.]
### Independence
For a long time, autodidacticism was an essential fact about how I learned, becoming axiomatic in severity, but little more. This is no longer the case: it has become a fundamental fact about how I work. The research on this website is largely carried out independently, in the sense that no institution sets its direction. This is a broad preference of mine rather than a circumstance, and thus something that I choose voluntarily, with exceptions: the chief current exception is MARS V with the Cambridge AI Safety Hub and the Future of Life institute. My institutional attachments are now incredibly deliberate: I work with collaborators whose problems I deeply wish to work on, with preprint servers and journals the eventual venues for much of it. The connecting bridge between autodidacticism and independence is that my questions and curiosity remain my own, as I feel this is the only way it can be for me.
I am able to sustain this model by work that is clearly separate: I am an independent contractor working on frontier LLMs, spanning RL, failure analysis, evaluation, red teaming, and more at various points. This work serves the dual purpose of supporting my inquiry on the questions that I decide I would like to pursue, and also providing me an environment in which I can continually do work that I learn a great deal from. That learning has transferred well so far to my research and I expect as LLMs continue to scale and improve that this trend will only continue.
I am certainly not against institutions in the abstract, nor do I think that independence is intrinsically the best model. Let it be known that the record of my work is here, in public, and that this record is what I hope to be judged by, rather than any affilitations past or present (as it is highly likely more will come in the future).
### Study Habits
A core element of my autodidacticism and one that I write about with frequency is what I call *metalearning* - the notion that frequent study of *how* to study itself is a worthy, if not necessary, undertaking. To this end, I try to keep my own study habits somewhere at the midpoint between the relevent cognitive psychology literature and my own intuition of what works best for me.