I build distributed systems and the machine learning that runs on top of them:
Raft consensus hardened by fault injection, HNSW vector search over embeddings,
transformer-based NLP for crisis triage. USACO Gold, published in a peer-reviewed
journal, and a USA Cricket U19 athlete ranked 31st nationally when I'm away from
the terminal.
abhineeth.tsREADME.md~/portfolio/src
exportconstabhineeth={name:"Abhineeth Duddela",based:"Frisco, TX",school:"Heritage High School",// class of 2027focus:["consensus","NLP","inference"],research:"peer-reviewed · published",computing:"USACO Gold",tutoring:2_500,// students reachedcricket:{squad:"USA U19",rank:31},status:"open for opportunities",}asconst;
main
✓ 0 problemsOpen to workTypeScript · UTF-8 · Ln 13, Col 12
I'm Abhineeth, a rising senior at Heritage High School in Frisco, TX. My work sits
where machine learning meets distributed systems: the models that make a prediction,
and the infrastructure that has to keep serving them when a node dies mid-write.
Most of what's on this page started as a question I couldn't answer by reading
(how does a cluster actually agree under partition, what does an HNSW graph look
like while it's searching) and ended as something I had to implement to find out.
I fine-tune transformer architectures, ship reproducible statistical tooling in R and
Python, and reverse-engineer the messy parts of the internet, from disaster-response
tweet streams to K–8 tutoring logistics. I'm a published researcher in a peer-reviewed
journal, a USACO Gold competitor, a data-science intern under a Harvard preceptor, a
nonprofit co-founder, and a USA Cricket U19 athlete ranked 31st nationally.
My north star is unreasonably simple: build technically elegant systems that
meaningfully compound in the real world. Whether that's an ensemble NLP classifier
triaging emergency signals, a Bayesian pedagogy module deployed to an international
bootcamp, or a lean edtech operation serving 2,500+ students, I optimize for depth,
reproducibility, and reach.
Work
Built from the paper up
Consensus, vector search, distributed training and incompressible flow, implemented
from the primary literature rather than pulled off a shelf. Each card opens on a
drawing of the mechanism it describes; the first three also run live in your browser
further down the page.
R
raft-chaos-testing
Live
Distributed consensus · fault injection
A queued-delivery transport with per-link drop_prob and
delay_ticks, asserting election safety, leader completeness and
state-machine safety per tick across a 600-seed randomized sweep.
TF-IDF over 1–2 grams into L2-regularized logistic regression, chosen so
Shapley values reduce to the closed form φⱼ = wⱼ(xⱼ − E[xⱼ]).
Attributions are exact, not Monte-Carlo sampled.
Hand-written HNSW over 384-dim MiniLM embeddings: M=16,
ef_construction=200, cosine on L2-normalized vectors, built with
SELECT-NEIGHBORS-HEURISTIC. Zero network calls.
Incompressible Navier-Stokes on WebGPU compute shaders, over a MAC staggered grid
so that divergence and gradient are exact negative adjoints and the checkerboard
pressure mode a collocated grid hides cannot form. Pressure projection is solved
five ways (conjugate gradient and an exact FFT solve on CPU; Jacobi, red-black
Gauss-Seidel and a geometric multigrid V-cycle on GPU) so the comparison between
them is measured rather than claimed. Vorticity confinement is a fabricated energy
source, so the solver throws if a validation run asks for it.
Three systems that were already built and tested separately, a Raft consensus
engine, an HNSW index and a training framework, composed into one platform and
driven from outside as read-only dependencies. Each passes its own suite, and none
of those suites says anything about a training worker dying at the instant the
storage cluster splits in half. The first bug the cross-layer harness found was
exactly that shape: Raft behaved correctly, HNSW behaved correctly, and every
replica in the cluster crashed.
Data-parallel SGD with gradients synchronised each step by ring all-reduce or a
parameter server, and six invariants checked on every step against a
single-process reference rebuilt by a route that shares no arithmetic with the
production path. The reduction sums in canonical worker-id order, since float
addition is not associative and without a fixed order bitwise replica agreement
fails intermittently and looks like a race. Four of the six findings published on
the report are defects in this repository's own harness, two of which would have
produced a confidently wrong result.
A compiler for minic with no dependencies and no build step: lexer, parser, type
checker, an SSA intermediate representation, four optimization passes, linear-scan
register allocation and a bytecode VM. Every optimization has to preserve the exact
output bytes, the exact trap and the exact exit status, checked against a reference
interpreter on a corpus and on 100,000 generated programs. Register allocation is
where the win is: 47.5% fewer instructions executed than keeping every value in
a frame slot. The places a pass would have been wrong are written up rather than
quietly fixed.
A tensor compiler from scratch: a static-shape IR, reverse-mode autodiff as a graph
transform, a float64 reference interpreter, and every op lowered to its own WGSL kernel.
Milestones 1 and 2 of 4 are done. The float32 error budget was derived from the WGSL
specification and committed before any kernel ran; direct per-op tests then caught
7 of 7 injected kernel bugs, and the first GPU run's failure is
kept in the record. Training in the browser and the fusion study it exists for are not
built yet.
HNSW built from Malkov & Yashunin rather than from a library: the multi-layer graph,
the greedy layer descent and the bounded best-first search are written in NumPy, with no
FAISS and no hnswlib. The paper's Algorithm 4 neighbour heuristic is the part that is
not optional, and the repository shows why — keeping the M nearest candidates
instead passes every test on uniform random data and then collapses graph connectivity
to 4.8% of nodes on clustered data. Both correctness bugs found on the way are
written up rather than quietly fixed.
Raft implemented from the primary paper: randomized-timeout leader election via
RequestVote, AppendEntries replication with
prevLogIndex/prevLogTerm consistency checking, and
quorum commit advancement restricted to the leader's current term (the Figure 8
constraint). Deterministic discrete-event simulator with injected crashes,
restarts and partitions; 23 tests including live asyncio TCP transport tests that
kill a server mid-write and confirm zero data loss through failover.
Asynchronous Monte Carlo Tree Search for LLM-guided code generation with a modified
UCB1 policy that discounts high-token-cost branches by remaining budget:
Q(s,a) + c·√(ln N(s)/N(s,a)) − λ·(τ(s,a)/B_remaining). Enforces
RLIMIT_AS, RLIMIT_CPU and wall-clock limits on untrusted
generated code, validated against real infinite loops and memory-exhaustion
attempts. A self-reflection loop feeds execution tracebacks back into model context.
17 tests, zero external ML dependencies.
Multi-term university scheduling modelled as a joint CSP/optimization problem, and it is
NP-hard: credit-limit bin-packing combined with precedence-constrained graph
colouring for prerequisites. Dual backends: an OR-Tools CP-SAT integer program doing
two-phase lexicographic optimization (minimize terms-to-graduation, then maximize
course quality under a fairness constraint), and a dependency-free backtracking
search with topological ordering and time-budgeted fallback. Catalogs from five
universities, modelling both semester and quarter calendars.
Co-founded a vertically integrated K–8 tutoring company connecting high-school tutors
with students in Math, Science, Reading and History at below-market rates. Built lean
operations (onboarding, scheduling, payments reconciliation and curriculum logistics)
while serving 2,500+ students and generating roughly $20,000 in revenue.
Students served
2,500+
Revenue
~$20,000
Subjects
Math, Science, Reading, History
OperationsEdTechEntrepreneurshipSystems
Private project
W
Willow Initiative
Active
Nonprofit · research advocacy
Co-founded a nonprofit research and advocacy network on adolescent substance-abuse
awareness. Scaled a 14-person officer corps across 5 states and 3 countries, and
collaborated with 10+ university professors and researchers from Harvard, Yale, USC
and Johns Hopkins to inform research-backed policy advocacy.
Not screenshots and not recordings. Each panel below executes the real
algorithm (the same consensus logic, the same graph search, the same
closed-form attribution) as you scroll to it.
5-node Raft clustertick 0
Starting cluster…
Distributed consensus · Live
Breaking a consensus algorithm on purpose, then proving it still held.
The stock engine ships two transports over the same RaftNode, and
neither can express message delay: the in-memory simulator's
_deliver invokes the recipient's handler synchronously and recurses,
so a RequestVote response can cascade through leadership election and
heartbeat fan-out inside one tick(). An in-flight message has no
state to hold a deadline in, and drop_rate is a single global
probability rather than per-edge.
So I wrote a third transport: a time-ordered priority queue of
(deliver_at, seq, sender, recipient, msg) against the unmodified
node API. Per-link drop_prob is rolled at send time to model packet
loss, while n-way partition membership and liveness are evaluated at
delivery time so a split kills packets already on the wire. Four
invariants are asserted every tick (election safety, leader completeness,
state-machine safety, and acknowledged-read consistency) with commitment
witnessed by quorum match_index advancement rather than by the
proposer's optimism. Cross-validating the queued transport against the engine's
own suite is what makes a reported violation attributable to the consensus
implementation and not to my harness.
The engine ships two transports over the same RaftNode: an in-memory
simulator and an asyncio TCP server. Neither can express message delay.
The simulator's _deliver invokes the recipient's handler synchronously
and recurses, so a vote response can trigger leadership, heartbeats, and their
responses all inside one tick(): an in-flight message has no state,
and “hold this for five ticks” has nowhere to live. Its drop_rate is
also a single global probability, not per-edge.
So I wrote a queued transport against the same node API, which the engine's own
docstring anticipates: a harness may “deliver it, delay it, or drop it.”
RaftNode is used completely unmodified.
Architecture
The capability the original two transports couldn't express: a message held mid-flight, timestamped, and resolved against per-link and partition faults before delivery.
1 tick, nothing resolves inside the tick that produced it
per-link drop
rolled at send time, models packet loss
partition / liveness
evaluated at delivery time, models a split killing in-flight packets
election timeout
randomized 10–20 ticks; heartbeat every 3
Composable faults
Faults are independent objects consulted per message, so composition is structural
rather than special-cased. Partition supports n-way groups and several
simultaneous splits; the engine's own field holds a single two-group tuple.
LinkFault targets one directed edge with drop_prob and
delay_ticks, optionally bidirectional. “Crash a node during an active
partition” is simply two faults being live at once.
Invariants, checked every tick
Election safety: at most one leader per term.
State machine safety: no two nodes apply different commands at the same log index.
Leader completeness: every acknowledged entry is present, unchanged, in the log of every subsequently elected leader. Asserted at election time, which makes it race-free: Raft guarantees a new leader already holds every committed entry, so it needs no waiting on replication.
Acknowledged read consistency: once the leader's last_applied covers an acked write, reading that key from the leader returns that value.
A write counts as acknowledged only once the accepting leader's
commit_index covers it, the instant a real server would answer the
client. An uncommitted entry vanishing is correct Raft behaviour and is
recorded as an overwrite, never a durability violation.
Trusting the results
A queued transport is a different code path from the engine's own 23 tests, so a
violation could in principle be the harness's fault. Every scenario the engine's
suite covers is re-run through the new transport with matching safety outcomes
asserted. That cross-validation is what makes a reported violation attributable to
the engine.
It earned its keep. A 600-seed randomized sweep flagged 50 violations under seed 124,
all false. An entry whose proposer was partitioned is only observed as committed
once that node rejoins, so index 3 was detected at tick 250 after index 4
was detected at tick 248; tracking the newest acked value per key in detection order
regressed the expectation to a value a later write had legitimately superseded.
Expected values are now keyed by log index, and commitment is witnessed by any live
node whose commit_index covers the entry. All three defects this
exercise surfaced were in the harness, and the report documents them rather than
hiding them.
Keyword match vs. the live modelsame sentence, two approaches
Naive keyword matching flags any message containing an urgency word,
with no regard for what the sentence actually means. Type something
and compare it against the real model.
literal keyword match
semantic · live model
The deployed classifiercrisis-nlp-demo.onrender.com
Model explainability · Live
The explanation is the product, not the label.
TF-IDF vectorization over 1–2 grams with sublinear_tf,
min_df=2 and L2 normalization across a 14,758-term vocabulary, into
logistic regression at C=4.0 with class_weight="balanced".
Linear by deliberate choice: for a linear model the Shapley values collapse to the
closed form φⱼ = wⱼ(xⱼ − E[xⱼ]) with base w·E[x] + b, so
base + Σφⱼ ≡ logit(x) holds exactly. No sampling, no KernelSHAP
approximation; a test asserts agreement with shap.LinearExplainer to
within 1e-8, which makes shap a test-only dependency and keeps serving
off any deep-learning stack at 107 MB resident.
The last mile is the harder part: contributions live on vocabulary features but the
highlight has to land on the characters the user actually typed. Tokens are matched
against the vectorizer's own token_pattern over the raw string and
normalized per token rather than per document, so unicode accent-stripping
cannot shift character offsets. Each bigram's φ is split across its two constituent
spans; any feature that fires but cannot be located is excluded from token scores and
reported as a residual, so the additive decomposition still reconciles to the logit.
0.8024Accuracy, held-out split
0.7986Macro F1
0.8705ROC-AUC
1e-8Agreement with shap.LinearExplainer
On the model behind this demo
This runs a stand-in model trained on the public Kaggle "Real or Not? NLP with
Disaster Tweets" dataset, not the model from the NHSJS 2025 paper below,
because that fine-tuned checkpoint was never available. Its accuracy is not comparable
to the figures reported there, and it predicts whether text is disaster-related,
not how urgent it is.
The four numbers above are this stand-in's own, measured on its own held-out split. The
same disclosure is served by the API on every single response, so it travels with the
output rather than living only on this page.
A fine-tuned transformer would score higher and explain worse. For a linear model
the Shapley values have a closed form, so the attribution shown to the user
is the exact contribution rather than a sampled estimate:
SHAP value
φⱼ = wⱼ · (xⱼ − E[xⱼ])
base value
w · E[x] + b
identity
base + Σφⱼ ≡ logit(x), exactly
verified against
shap.LinearExplainer, max abs difference < 1e-8
Two tests hold this in place: one asserts agreement with the reference implementation,
the other asserts the decomposition sums back to the model's logit over the wire. As
a consequence shap is a test-only dependency: serving needs no
deep-learning stack at all, and resident memory measures 107 MB.
The interesting engineering is the last mile. Contributions live on vocabulary
features, but the highlight has to land on characters the user typed. Tokens are
matched on the raw string with the vectorizer's own token_pattern and
normalized per token rather than per document, so accent stripping cannot
shift the character offsets. Each bigram's contribution is then split across its two
constituent spans. Any feature that fires but cannot be located stays out of the
token scores and is reported as a residual, so the additive identity above still
holds exactly.
The last mile: vocabulary-level math mapped back onto the exact characters the user typed, with nothing lost along the way.
The demo runs a stand-in model trained on public Kaggle data, because the
original research checkpoint was unavailable. That disclosure is served by the API
on every response and rendered on the page, so it cannot be quietly dropped by an
embedder. The metrics quoted here are the stand-in's own, and reproducible.
Why the highlighting earns its place
On “This new album is an absolute disaster lol” the token disaster
contributes +0.83 toward disaster-related, and the verdict is still
not disaster-related at 82%, because new (−0.85) and
lol (−0.55) outvote it. The label alone tells you nothing about that.
HNSW graph searchlayer 2
A node's position on screen is its vector, so the highlighted
path is the actual geometry _search_layer navigates.
Click the sparse top layer to drop a query.
Local-first infrastructure · Open source
Memory that outlives the session, and never leaves the machine.
A hand-written hierarchical navigable small-world index: M=16,
M_max0 = 2M at the base layer, ef_construction=200, cosine
distance over L2-normalized 384-dim vectors from an ONNX-exported
all-MiniLM-L6-v2 with attention-masked mean pooling. Because the vectors
are normalized, cosine reduces to a dot product, which is what keeps greedy traversal
cheap. Layer assignment is the paper's exponential decay
(⌊−ln(U) · mL⌋), and search descends greedily at ef=1 per
layer before a bounded best-first SEARCH-LAYER at layer 0.
Insertion uses SELECT-NEIGHBORS-HEURISTIC (Algorithm 4), not the simple
nearest-M rule. A candidate is rejected when it sits closer to an already-selected
neighbor than to the query, which preferentially retains non-redundant candidates and
forces the long-range bridge edges the upper layers depend on for expected
O(log n) search; keepPrunedConnections backfills if the
diversity constraint under-fills the neighbor list. Without it the graph collapses
into per-cluster islands. Deletes are tombstoned rather than excised, since removing
a node can sever connectivity that neighbouring searches traverse through.
Sparse on top for reach, dense at the bottom for precision. That gap is the O(log n).
384Dimension embeddings, on-device
0External API calls
>95%Connectivity with the heuristic, vs ~5% without
Recall is by meaning, not keyword, so it needs real embeddings and a real vector
index. Rather than calling a hosted embedding API, both run on the machine: a
hand-written HNSW (hierarchical navigable small world) graph over vectors
produced by an ONNX-exported MiniLM.
index
HNSW, M=16, ef_construction=200, cosine metric
embedder
all-MiniLM-L6-v2 via ONNX Runtime, 384-dim
pooling
attention-masked mean pool, then L2 normalization
runtime cost
onnxruntime + tokenizers ≈ 90 MB, against ~2 GB for a PyTorch stack
persistence
vectors as .npz, records as JSON, tombstoned deletes
network calls
0
Why the heuristic, not the simple version
Inserting a node means picking up to M neighbors from the candidates
_search_layer found. The paper's simple rule (take the M
closest) sounds sufficient and isn't: for a node deep inside a tight cluster, its
M nearest candidates are almost always from that same cluster, so nothing
ever forces a long-range edge to a different region of the space. The graph
fragments. SELECT-NEIGHBORS-HEURISTIC instead rejects a candidate if it is
farther from the query than it is from a neighbor already picked, which
preferentially keeps candidates that aren't redundant with what's already selected.
On Gaussian-cluster test data this was the difference between ~5% of nodes reachable
from the entry point and >95% connectivity at the same parameters.
Same node, same candidates, same M=3. Only the selection rule changes which edges survive.
Details that actually matter
Masked pooling is not optional. Padding positions still carry real activations, so averaging the final layer without applying the attention mask silently corrupts every embedding of a short text.
Cosine on normalized vectors reduces to a dot product, which is what keeps graph traversal cheap.
Deletes are tombstoned rather than removing nodes, because excising a node from an HNSW graph can sever the connectivity that neighbouring searches depend on.
Durability is the whole point. An index that does not survive a restart is a cache, not a memory.
Local-first is the design constraint, not a limitation: memory contents are exactly
the material you least want to hand to a third-party embedding endpoint.
What this looks like from Claude's side
The visualizer above shows the index's internals; this is the tool interface a session actually calls.
# session one, months agostore_memory(
text="We picked Postgres over MySQL because we need JSONB indexing",
tags=["decision", "db"]
)
# session two, different machine, different daysearch_memory("why did we not use mysql")
→ "We picked Postgres over MySQL because we need JSONB indexing" matched by meaning, not by any shared keyword
Incompressible Navier-Stokes · WebGPU compute512² at 60 fps
Drag inside the panel to push the fluid. Needs WebGPU —
open it
full-screen if the frame is too small to steer.
Computational fluid dynamics · Live
A fluid solver that reports the two places it disagrees with theory.
The incompressible Navier-Stokes equations on WebGPU compute shaders, over a MAC
staggered grid so that divergence and gradient are exact adjoints and the pressure
field cannot develop the checkerboard mode a collocated grid hides. Projection is a
geometric multigrid V-cycle, cross-checked against a conjugate-gradient solve on the
CPU. Advection is implemented twice, semi-Lagrangian and MacCormack, because the
comparison between them turns out to be the most informative result in the project.
The 2D Taylor-Green vortex is an exact solution: its kinetic energy decays as
e^(−4νt), precisely. A simulation decays faster, because the
advection scheme's interpolation removes energy the physics did not. Fitting the
measured decay to e^(−4ν_eff·t) turns
“this scheme is dissipative” into a number in the same units as the real
viscosity. MacCormack invents 2.9% of the physical ν; semi-Lagrangian
invents 104.8%, so the fluid it simulates is roughly twice as viscous as the
one it was asked to simulate.
The turbulence spectrum is where it stops agreeing, and the report leads with that
rather than burying it. Kolmogorov's −5/3 describes three-dimensional
turbulence; 2D has no vortex stretching, so Kraichnan and Batchelor predict a dual
cascade instead — energy upscale at −5/3, enstrophy downscale at
−3. Measured separately against their own predictions, with the fit windows
fixed before the spectrum was looked at, the inverse cascade lands at −1.52
against a predicted −1.67, within 9%. The enstrophy range lands at
−4.53 against −3.00: an extremely clean power law
(r² = 0.999) that is simply the wrong line. Porting the second
advection scheme and re-running the identical study moves it from −6.08 to
−4.53, which is what attributes the steepness to numerical dissipation rather
than leaving it as a guess.
5.79e-4Numerical viscosity invented by MacCormack, 2.9% of the physical ν
3.31e-6GPU against the CPU reference, relative L2 after 10 full steps
26.4×GPU speedup at 512², at equal solution quality
−4.53Enstrophy cascade slope, where theory says −3
A rigid disk immersed in the flow, coupled in both directions: it blocks the
fluid, and the reaction moves it. Two-way is the load-bearing word,
because a static obstacle that deflects flow without ever moving is a boundary
condition and a much easier thing to get right. The method is direct forcing
(Mohd-Yusof, 1997): the solid is a smoothed mask on the existing grid, the fluid
inside it is driven toward the body velocity each step, and the reaction on the
body is the negative of that same integral.
That last clause is Newton's third law, and it is the one thing here that can be
checked exactly rather than approximately: total momentum drifts by
1.15e-14 across a coupling step. Four forcing passes bring the
residual slip inside the body to 9.65e-8, falling by a constant
factor per pass, which is a straight line on a log axis and therefore a property
rather than a coincidence. Below a density ratio of 1.2 the explicit coupling
diverges, which is reported rather than tuned around.
Why the validation is arranged this way
Vorticity confinement is off in every validation run. It restores detail
lost to numerical dissipation by injecting energy, so a spectrum or a decay rate
measured with it on is measuring an artificial energy source rather than the fluid.
The interactive demo has it on; the measurements do not, and the report says which
is which on every plot.
The fit windows were fixed before the spectrum was plotted. Choosing them
afterwards is how almost any curve is made to agree with a power law.
Parseval holds to 4.18e-6, so the spectrum's normalisation is right and
cannot explain the wrong slope; and max |∇·u| reaches
1.54e-13 on the CPU reference, so the field really is solenoidal.
Semi-Lagrangian advection is unconditionally stable, so there is no
advective blow-up boundary to find. Claiming one would have been fabricating a
result; what is measured instead is accuracy degrading while stability holds.
The enstrophy slope is the honest centrepiece. A project that only reported the
Taylor-Green result would look better and would have told you less: the
interesting question was never whether the solver runs, it was how much of the
physics survives a first-order scheme, and the answer is that the inverse cascade
does and the enstrophy cascade does not.
Validation chainrelative agreement
The engine is not checked against itself. Both implementations are compared to a
third that shares no code with either, and the cache is held to exact equality
because caching must not change the arithmetic at all.
Transformer inference · Runs in your browser
A transformer inference engine written from scratch, and honest about losing.
Qwen2.5-0.5B-Instruct on WebGPU, with no PyTorch, no transformers and no
tokenizer library. The safetensors reader, the bfloat16 conversion, the byte-level BPE
tokenizer, the KV cache, the grouped-query attention kernels and the INT8/INT4
quantization are all written in the repository. The weights stream directly from
Hugging Face over HTTP range requests, so nothing is served from the site but code and
the repository holds no weights at all.
Generating plausible text proves nothing, so the checking is per layer rather than at
the output. The ONNX export publishes the post-rotary keys and values for all 24
layers as ordinary graph outputs, which means matching them exercises the embedding,
both norms, all three projections, the rotary embedding and the head grouping
per layer — if layer 7 agrees, everything feeding layer 7 agreed. The
GPU tracks that oracle to 6.4e-5 relative and picks the same next token on all
five test prompts. The KV cache is held to a stricter standard still: incremental
decoding must be bit-identical to full recomputation, because caching is only
correct if it changes nothing.
Against ONNX Runtime on the same laptop's CPU, run alternately in one session, it wins
the generated tokens and still loses the prompt. A decode step takes
53.0 ms against ONNX Runtime's
73.7 ms (both under the
Best performance power mode), so the engine is
1.4× faster there. Prefilling a
52-token prompt takes
964.0 ms against
230.9 ms (Best performance), so
ONNX Runtime is still 4.2× faster at that. The power
mode is named because on this machine it moves the CPU baseline several-fold while
barely moving the GPU, so a ratio only means something within one mode and one session.
Decode used to lose too: half of every step turned out to be the browser creating GPU
objects for each token, and reusing them changed no bit of the output.
Two of the three things I predicted about this engine turned out to be wrong, and the
report keeps both: the outlier activation channel that was supposed to break
quantization has the smallest normalisation gain of all 896, so no projection ever sees
it; and batching roughly 400 GPU submissions per token down to one did not measurably
help, which means submission count was never the bottleneck.
6.4e-5GPU against ONNX Runtime, relative, per layer
0Floats differing between cached and recomputed decode
3,098Tokenizer cases against the reference, zero differences
1.4×Faster than ONNX Runtime at decoding, same session, Best performance
4.2×How much faster ONNX Runtime still is at the prompt, same session, Best performance
The one operation the GPU could not be trusted with
Every kernel agreed with the CPU reference at about 1e-7 except the
rotary embedding, which sat at 2.2e-5. Rather than widen the bound,
I measured this adapter's transcendentals: sin and cos
carry roughly 3.0e-5 of absolute error even for angles inside a
single turn, while pow is fine at 6.5 ULP. WGSL permits relaxed
precision there and this adapter uses the allowance, so about 3e-5 is a floor.
The cosines and sines are now computed once on the CPU in f64 and uploaded as a
table; the kernel does nothing but multiply and add, and went to
9.0e-8 — a factor of 250.
What quantization actually costs at this size
Under a protocol fixed before running — same passage, same positions, full
left context, nothing scored twice — and compared pairwise, since every
scheme scores identical positions. INT8 measured lower perplexity than
f16, and the paired test is what stops that becoming a claim: at 0.3 standard
errors it is noise, so the honest statement is that INT8 does not measurably hurt
this model, not that it helps it. INT4 at 4.5 bits per weight loses 0.42 nats per
token, a 2.5-standard-error effect, and changes the predicted token on two of five
prompts. At 0.5B parameters there is not enough redundancy to absorb 4-bit
rounding.
Things the measurements overturned
The outlier channel was not the problem. Channel 490 grows to 27 times
the RMS of the hidden state, and I predicted it would dominate quantization damage.
It does not: at every layer past the first it has the smallest normalisation gain of
all 896 channels, so the model suppresses the channel it made massive before any
projection reads it. The outlier lives in the residual stream, and weight-only
quantization never touches the residual stream.
Batching the submissions did not help. Half a decode step sat outside the
kernels and the obvious culprit was a command buffer per dispatch, about 400 per
token. Batching the whole forward pass into one changed the throughput by nothing
measurable. The change stayed, because 400 submissions per token is indefensible
either way, but I would have reported it as the fix if I had shipped it without
re-measuring. The missing half was found later: the browser creating GPU objects for
every token, which is what decode's change above came from.
bfloat16 to f16 is nearly free here, which is not obvious: bf16 carries 7
mantissa bits and f16 carries 10, so the mantissa is wider in f16 and only
the narrower exponent range costs anything. Across all 494,032,768 weights, 0.0249%
change and the worst relative change among normally-representable weights is exactly
zero.
The live demo downloads 988 MB of weights and needs about a gigabyte of
GPU-accessible memory. That cost is stated on the page before anything can be
started, and nothing is fetched until you ask for it, which is why the demo is a
button here rather than an embedded frame.
Differential campaign100,000 programs
Three executors, two optimization settings, one comparison. The zero means
something only because the same harness was shown to catch bugs that were put
there deliberately, and then reverted.
Compilers · Differential testing
Every optimization checked against a reference, and the checker checked back.
minic — integers, arrays, functions, loops — through a full pipeline with no
dependencies and no build step: lexer, parser, type checker, an SSA intermediate
representation over a control flow graph, four optimization passes (constant folding,
dead code elimination, common subexpression elimination, copy propagation), linear-scan
register allocation with real spilling, and a register-based bytecode VM. The VM is a
choice with a cost stated plainly: emitted x86-64 could never be assembled, run or
differentially tested on this machine, so it would be an artifact whose correctness is
asserted rather than checked. The target is instead one that keeps every stage
executable, and gives up instruction selection, an ABI, and cycles as the metric.
Every program runs three ways — a reference interpreter written straight from the
semantics, the IR interpreter, and the VM — unoptimized and fully optimized, and
the runs are compared byte for byte on output, trap kind, trap source position and exit
status. The campaign covered 100,000 generated programs at two configurations
each in 530.7 s: zero disagreements, none skipped, none that failed to
compile. A suite that has never reported a failure has not been shown capable of
reporting one, so the optimizer was broken on purpose. Rewriting x + 1 to
x was caught within 4 programs; deleting constant folding's trap
guard was caught within 40 and shrunk automatically from 35 statements to
int main() { int v1 = (11 % 0); return 0; }. Both injections were reverted,
and a permanent test now does the same job without touching src/.
The performance result is narrower than the pipeline implies, and the report leads with
that rather than around it. Register allocation is where the dynamic win actually comes
from: against the same compiler with zero allocatable registers it removes 47.5%
of instructions executed — 594,474 down to 311,815 — and every frame-slot
operation with them. The four passes together cut 15.0% of static code size but
only 0.2% of instructions executed. None of them moves work across an iteration
or a call: no loop-invariant code motion, no strength reduction, no unrolling, no
inlining. So fib runs the identical 219,159 steps and nqueens
the identical 75,785 at every optimization setting, while small straight-line code
gives up as much as 53.7%. Measured alone, three of the four passes change nothing at
all, and the report says so instead of omitting them.
100,000Generated programs compared byte for byte, zero disagreements
47.5%Instructions executed removed by register allocation alone
0.2%What all four optimization passes remove from executed instructions
4 and 40Programs needed to catch two deliberately injected bugs
Verification chainfloat32 budget, fixed in advance
Two executors and one budget, written down before the GPU ran anything. The
direct tests are where the correctness claim rests: the fuzzer has a blind spot
they do not, and the diagram shows it rather than leaving it out.
Compilers · WebGPU · Milestones 1 and 2 of 4
A tensor compiler held to an error budget it wrote down before running anything.
A static-shape tensor IR, reverse-mode autodiff written as a graph-to-graph transform,
a float64 interpreter that defines what every program means, and every op lowered to
its own WGSL kernel, so the gradient graphs run on the GPU as well as the forward ones.
No ML framework in the engine; PyTorch only wrote golden files, offline. Milestones 1
and 2 of 4 are done: the IR, autodiff and the float64 reference, then the kernels
checked against it. Milestone 3, training a model in the browser, and milestone 4, the
fusion study, are not built.
The float32 budget was derived from the WGSL specification's stated accuracy for each
operation and committed before any kernel existed: each element may differ from the
float64 reference by at most 2 times a bound propagated
node by node, with inputs rounded to float32 first so only kernel error is measured.
Direct per-op tests carry the correctness claim, on the inputs most likely to break a
kernel: sizes off the workgroup and tile grid, size-1 dimensions, rank 3 and 4, huge,
tiny and subnormal magnitudes, exact zeros and long reductions. 252 of 252
pass. Differential fuzzing is supporting evidence: 5,318 of 5,318 runs
across 2,000 generated programs, forward and
gradient, every node compared. Kernel bugs were then injected one at a time to test the
tests, and the direct cases caught 7 of 7; a correct change of
summation order was flagged by nothing, which shows the budget is not simply tight.
Two results went against it and stay in the record. The first GPU run passed
251 of 252 direct cases: this adapter's tanh
returns NaN once exp overflows float32, which the specification permits and
my pre-registered derivation had not accounted for. The kernel now clamps its argument,
the budget is unchanged, and the change is logged as revision R2. And the fuzzer missed a
missing bounds check in every one of the 1,954
programs it could affect: with buffers sized exactly to each tensor, the stray writes
changed nothing any comparison could see, and only the direct tests' canary-padded
buffers caught it. Out-of-bounds reads returned zero on the one adapter this ran on
(intel gen-12lp), which explains two lower detection rates; that
behaviour was observed there and nowhere else.
The remaining milestones exist for one question: when does kernel fusion pay off on
an integrated GPU, and when does it lose? Nothing here answers it yet. Milestones 1
and 2 measure correctness only, and no timing has been taken.
252 of 252Direct per-op adversarial cases within the float32 budget
7 of 7Injected kernel bugs the direct tests caught
5,318 of 5,318Fuzz runs, forward and gradient, GPU against CPU
0 of 1,954Programs where fuzzing saw the missing bounds check
Transformer-Based NLP for Real-Time Disaster Response
National High School Journal of Science · Peer-Reviewed
Published
A published, peer-reviewed paper benchmarking modern transformer architectures against
classical statistical baselines for humanitarian crisis intelligence. Mentored by
Dr. Chris Irwin Davis, PhD, at UT Dallas.
01
Fine-tuned a pretrained BERT transformer on 10,000+ disaster-related tweets spanning wildfires, hurricanes and floods, using domain-specific tokenization, subword regularization and class-weighted cross-entropy to combat severe label imbalance.
02
Architected a controlled three-way benchmark (BERT vs. TF-IDF + logistic regression vs. multinomial Naïve Bayes) under identical stratified k-fold cross-validation and held-out test splits, isolating architectural contribution from data leakage.
03
Achieved 89.3% test accuracy and an F1 of 0.88, outperforming the strongest classical baseline by 21% and validating transformer transfer learning as a deployable primitive for real-time humanitarian triage.
04
Conducted independent error analysis exposing a sharp accuracy collapse on sarcastic and semantically ambiguous text; engineered inverse-frequency class weighting and contextualized embedding-space oversampling to lift minority-class recall by 2.1% and F1 by 1.7%.
05
Authored the manuscript end to end, defended it through NHSJS peer review, and published the full methodology and code as an open-source repository for reproducibility.
One split, three arms, one test set, so the gap is architecture, not leakage.
The figures above are those reported in the NHSJS publication. The interactive demo in
Live Systems is a separate model trained on public data so the attribution layer
is explorable without the original checkpoint; it measures 0.8024 accuracy on its own
held-out split. The two are not comparable.
During an active disaster the inbound volume of social posts vastly exceeds what
responders can read, and the messages that matter (trapped persons, structural
collapse, medical need) are diluted by commentary, metaphor and reshares. Framed as
supervised text classification, the difficulty is that the vocabulary of urgency
overlaps heavily with the vocabulary of ordinary hyperbole, so surface keyword
matching fails precisely where accuracy matters most.
Fine-tuning configuration
base model
bert-base-uncased, sequence classification head
max sequence
128 tokens, padded and truncated
optimizer
AdamW, learning rate 2e-5
batch size
16 per device
epochs
5, best checkpoint by eval loss
seed
42
Evaluation
Macro-averaged precision, recall and F1 alongside a confusion matrix and ROC/AUC
over softmax probabilities for the positive class, macro rather than micro because
the urgent class is the minority, and micro-averaging would let majority-class
performance mask exactly the failure mode that matters. The transformer is measured
against a TF-IDF/Naive-Bayes baseline.
Two distinct models appear on this page. The 89.3% / F1 0.88 figures above
are those reported in the NHSJS publication. The interactive demo in section 01 is
a separate model trained on public data so the explanation layer is explorable
without the original checkpoint; its 0.8024 is measured on its own held-out
split and served live from its /metrics endpoint. The two are not
comparable: different models, different data.
Internship
Ivy League internship
Internship
SWE and ML Intern
Harvard University · under Professor David Kane, a Harvard preceptor
Shipping production-grade R infrastructure and Quarto-based curricula used by an
internationally distributed collegiate data-science bootcamp.
01
Engineered production-grade R packages with proper NAMESPACE hygiene, unit tests, roxygen2 documentation and semantic versioning, deployed into a reproducible research toolchain used by students across multiple countries.
02
Authored Quarto-based pedagogical modules integrating literate programming, executable code blocks, LaTeX-rendered math and reproducible HTML/PDF outputs, bridging pedagogy and research reproducibility in a single artifact.
03
Developed Bayesian statistical pipelines (priors, likelihoods, posterior sampling and credible-interval reporting), abstracting the mechanical parts of probabilistic modelling so downstream learners focus on inference intuition.
04
Resolved a critical defect in a shared library that carried no prior documentation or guidance, unblocking the international bootcamp curriculum and demonstrating independent systems-level debugging.
05
Contributed 10+ hours per week to an open, versioned curriculum shipped into a live international bootcamp, with feedback loops from real students informing iterative library refactors.
UT Dallas · NLP with Python · under Dr. Chris Irwin Davis, PhD
An eight-week research immersion building Python NLP pipelines end to end
(tokenization, embedding generation and model fine-tuning) for real-world text
classification across multiple domains. This is the work that became the peer-reviewed
publication above.
PythonNLPEmbeddingsFine-tuning
Athletics
National cricket
Athlete
USA Cricket U19 Athlete
USA Cricket U19 West Conference Team · Captain · 2021–present
Selected for the USA Cricket U19 West Conference Team through multi-stage national
tryouts, ranked 31st nationally among 200,000+ competitive players, 1st in the
Southwest Region and 2nd in the Dallas Region.
01
Selected through multi-stage national tryouts and appointed Captain, leading squad strategy, training and competition execution.
02
Ranked 31st nationally among 200,000+ competitive U19 players, 1st in the Southwest Region and 2nd in the Dallas Region, with a career record of 96 matches, 1,396 runs and 62 wickets.
03
Founded the Coyote Cricket Club at Heritage HS from nothing in a school with no prior program, growing it to 25–30 students and leading it to consecutive top finishes in an 18-school interdistrict tournament: two 2nd-place results and a 3rd.
04
Balanced high-performance athletics with research, USACO Gold, nonprofit leadership and a full academic load; elite sport and elite systems work compounding rather than competing.
Science Olympiad: President, Treasurer and four-year competitor across Entomology,
Dynamic Planet, Remote Sensing and Helicopter, top 3 of 16 teams at Regionals twice ·
Mind4Matter: Global Outreach Representative for a student-run mental-health nonprofit
spanning 10 chapters and 1,500+ volunteers · Karya Siddhi Hanuman Temple: 120+ hours
directing kitchen operations for large-scale community celebrations.
Recognition & Awards
Nationally recognized
From national athletics to USACO Gold, peer-reviewed research, and a top-100 finish
at the Young Investors Society Global Stock Pitch.
USA Cricket U19 · Ranked 31st Nationally
2026 · Athletics · USA Cricket
31stof 200,000+ competitive players
USACO Gold Division
2026 · Olympiad · USA Computing Olympiad
Advanced past Silver on graph-theory and optimization under contest conditions
IT Specialist in Java Certification
2026 · Certification · Certiport / Pearson
Performance-based OOP, data structures, debugging
PSAT/NMSQT Commended Scholar
2026 · National
Top 50Kof 1.5M+ entrants
Coolidge National Declamation
2026 · National
Top 30Honorable Mention, nationally
Published Researcher, NHSJS
2025 · Peer-reviewed · National High School Journal of Science
2025 · Global · advanced to the Global Youth Investment Summit, NYC
Top 100of 1,000+ teams across 24 countries
Java Coding Specialist Certification
2025 · Certification · Knowledge Pillars
AP Scholar with Distinction
2025–26 · Academic · College Board
7Professional certifications
11Awards and honors
2027Graduating: Heritage High School, Frisco TX
› Certifications & academics
Certifications
Aug 2026
Claude in Code, Anthropic Academy. Deploying Claude Code as an autonomous engineering agent: explore-plan-code-commit, context management, project-level instructions and hooks.
Aug 2026
Model Context Protocol: Advanced Topics, Anthropic Academy. Architecting MCP servers and clients across tools, resources and prompts.
Jul 2026
Software Engineer Intern, HackerRank. Timed assessment across problem-solving and SQL.