Abhineeth.
Connect

Abhineeth Duddela

Personal portfolio · Est. Frisco, TX

Distributed systems, proven under fire.

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.ts README.md ~/portfolio/src
export const abhineeth = {
  name:      "Abhineeth Duddela",
  based:     "Frisco, TX",
  school:    "Heritage High School",  // class of 2027
  focus:     ["consensus", "NLP", "inference"],

  research:  "peer-reviewed · published",
  computing: "USACO Gold",
  tutoring:  2_500,                  // students reached
  cricket:   { squad: "USA U19", rank: 31 },

  status:    "open for opportunities",
} as const;
main ✓ 0 problems Open to work TypeScript · UTF-8 · Ln 13, Col 12
Scroll to explore
About

The person behind the work

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.

election safety · leader completeness · state machine safety
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.

Safety properties
3, asserted per tick
Seed sweep
600 randomized
Fault model
Per-link drop + delay
PythonRaft LinearizabilityGitHub Actions
pushes away pushes toward
C

crisis-nlp-demo

Live
Model explainability · NLP

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.

Features
TF-IDF, 1–2 grams
Classifier
L2 logistic regression
Attributions
Exact, closed form
FastAPIscikit-learn SHAPDocker
L2L1L0
M

mcp-memory-server

Open source
Vector search · local-first

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.

Index
HNSW, M=16
Embeddings
384-dim MiniLM
Network calls
Zero
PythonMCP HNSWONNX
∇

fluid-sim

Live
Computational physics · GPU compute

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.

Numerical viscosity
ν_num = 5.79e-4, 2.9% of ν
Stability boundary
ν·dt/h² = 0.25 stable, 0.26 not
Inverse cascade
−1.525 vs Kraichnan −5/3
WebGPUWGSL Navier-StokesMultigrid FFT
trainraftindex fault
P

ml-infra-platform

Live
Distributed ML · cross-layer chaos

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.

Engines composed
3, unmodified
Component suites
23 + 28 + 68 tests
Claim under test
The composition, not the parts
PythonRaft HNSWChaos Engineering numpy
Σ nₖ/N · ∇Lₖ 6 invariants, checked every step
D

distributed-training-framework

Live
Distributed training · correctness verification

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.

Checked steps
1,960
Workers killed mid-step
22, no violation
Worst gradient error
8.9e-16, floor ~5e-16
PythonData Parallelism Ring All-ReduceFault Injection numpy
sourceAST SSAbytecode reference interpreter same bytes, same trap, same exit status 100,000 random programs · 0 disagreements
λ

toy-compiler

Live
Compilers · differential testing

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.

Random programs
100,000, 0 disagreements
Allocation
47.5% less executed
Dependencies
None
JavaScriptSSA Register AllocationBytecode VM Differential Testing
IR graphgradient graph float64 referenceWGSL on the GPU every element within a budget fixed before the GPU ran 252 of 252 direct cases · 5,318 of 5,318 fuzz runs
∇

tensor-compiler-webgpu

In progress
Compilers · WebGPU · numerical verification

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.

Direct per-op tests
252 of 252
Fuzz runs, GPU vs CPU
5,318 of 5,318
Injected kernel bugs caught
7 of 7
JavaScriptWGSL WebGPUAutodiff Differential Testing
L2L1L0 recall@10 = 1.000 · 20.1× over brute force at n=8,000
H

vectordb-hnsw

Open source
Vector search · approximate nearest neighbours

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.

Recall@10
1.000 vs exact search
Speedup
1.8× to 20.1×, 500–8,000 vectors
Dependencies
NumPy only
PythonNumPy HNSWANN Search Algorithms
leaderf1f2 commit index
K

Raft KV Store

Shipped
Systems · distributed consensus

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.

Implemented from
The primary paper
Commit rule
Figure 8 constraint
Tests
23, incl. live TCP
Pythonasyncio Distributed ConsensusRaft TCPFault Tolerance
Q + c√(ln N / n) − λ·τ / B
T

MCTS Code Reasoner

Shipped
ML systems · test-time compute

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.

Search policy
Budget-discounted UCB1
Sandbox
RLIMIT_AS / RLIMIT_CPU
ML dependencies
Zero
PythonMCTS UCB1LLM Inference Sandboxing
T1T2 T3T4 credit limit respected per term
F

Flightpath Course Scheduler

Shipped
Optimization · constraint programming

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.

Problem class
NP-hard CSP
Backends
CP-SAT + backtracking
Catalogs
5 universities
OR-ToolsCP-SAT FastAPIReact Constraint Programming
tutorsstudents
S

Simple Tutors

Running
Venture · edtech operations

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
OperationsEdTech EntrepreneurshipSystems
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.

Officer corps
14 across 5 states
Reach
3 countries
Collaborators
10+ university researchers
NonprofitResearch Advocacy
Live Systems

Running live in your browser

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 cluster tick 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.

600Seed randomized sweep
6/6Chaos scenarios verified
0Safety violations in the engine
3Real defects found, all in my own harness
› Implementation notes

Why a third transport

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

Leader RaftNode.tick() Queued Transport ordered by deliver_at = tick + latency LinkFault: drop_prob · delay_ticks (per edge) Partition: sender/recipient same group? Follower handle_append_entries() send deliver at tick T dropped: drop_prob roll, or partitioned
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.

Delivery model

queue entry(deliver_at, seq, sender, recipient, msg), ordered
base latency1 tick, nothing resolves inside the tick that produced it
per-link droprolled at send time, models packet loss
partition / livenessevaluated at delivery time, models a split killing in-flight packets
election timeoutrandomized 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 model same 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 classifier crisis-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.

› Implementation notes

Why linear, deliberately

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 valuew · E[x] + b
identitybase + Σφⱼ ≡ logit(x), exactly
verified againstshap.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.

Pipeline

featuresTF-IDF, 1–2 grams, sublinear_tf, min_df=2, L2-normalized, unicode accent stripping
classifierlogistic regression, C=4.0, class_weight="balanced"
vocabulary14,758 terms
data7,613 labelled examples, stratified 80/20 split
artifact0.55 MB, fits any free tier

Mapping features back onto the raw text

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.

raw text "…absolute disaster lol" TF-IDF row x 14,758-dim, mostly zero φⱼ = wⱼ(xⱼ − E[xⱼ]) exact, closed-form per active feature split across spans bigram → its 2 tokens new disaster lol segments: reconstructed text, per-token φⱼ base + Σφⱼ + absent = logit(x), 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 search layer 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.

layer 2 3 nodes · 2 hops across layer 1 5 nodes · bridge edges layer 0 every node · exact search ef=1 greedy ef=1 greedy
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
~90MBRuntime, vs ~2GB for a PyTorch stack
› Implementation notes

Retrieval

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.

indexHNSW, M=16, ef_construction=200, cosine metric
embedderall-MiniLM-L6-v2 via ONNX Runtime, 384-dim
poolingattention-masked mean pool, then L2 normalization
runtime costonnxruntime + tokenizers ≈ 90 MB, against ~2 GB for a PyTorch stack
persistencevectors as .npz, records as JSON, tombstoned deletes
network calls0

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.

SELECT-NEIGHBORS-SIMPLE new node 3 nearest: all one cluster, no bridge SELECT-NEIGHBORS-HEURISTIC new node 3rd cluster point rejected: bridge kept instead
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 ago
store_memory(
  text="We picked Postgres over MySQL because we need JSONB indexing",
  tags=["decision", "db"]
)

# session two, different machine, different day
search_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 compute 512² 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
› Implementation notes

Two-way fluid-structure interaction

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 chain relative agreement
ONNX Runtime, fp32 an implementation sharing no code with this one 9.1e-5 6.4e-5 CPU reference f32 storage, f64 accumulation WebGPU engine f16 weights, f32 accumulation per layer, across all 24 layers and 48 tensors per prompt incremental decode = full recomputation 0 of 151,936 logits differ — bit-identical, not close
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
› Implementation notes

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 campaign 100,000 programs
generated program well-typed by construction, so a rejection is a bug reference interpreter written from the semantics SSA IR interpreter unoptimized and optimized bytecode VM unoptimized and optimized compared byte for byte output bytes · trap kind and source position · exit status 100,000 programs × 2 configurations 0 disagreements, 0 skipped, 0 failed to compile and the harness itself, checked by breaking the compiler on purpose x + 1 → x — caught in 4 trap guard removed — caught in 40
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 chain float32 budget, fixed in advance
IR program and its gradient graph autodiff is a graph transform, so both lower the same way float64 reference interpreter inputs rounded to float32 first WGSL kernels on the GPU one kernel per op, no fusion every element: |gpu − ref| ≤ 2 · E E propagated from the WGSL spec's per-op accuracy, committed before any kernel ran 252 of 252 direct per-op cases · 5,318 of 5,318 fuzz runs the direct cases carry the claim; the fuzzing is supporting evidence and the checks themselves, tested with kernel bugs put there on purpose direct tests: 7 of 7 caught fuzzer, missing bounds check: 0 of 1,954
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
Research

Peer-reviewed research

Research

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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%.

  5. 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.

10,000 tweets annotated stratified k-fold split BERT, fine-tuned TF-IDF + logreg Naïve Bayes 89.3% held-out accuracy classical baseline classical baseline
One split, three arms, one test set, so the gap is architecture, not leakage.
89.3%Test accuracy
0.88F1 score
+21%Over strongest classical baseline
10,000Annotated disaster-related tweets
BERTPyTorch-style fine-tuning TF-IDFNaïve Bayes scikit-learnStratified K-Fold PandasPython
Two different models on this page

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.

› Method & training configuration

Problem framing

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 modelbert-base-uncased, sequence classification head
max sequence128 tokens, padded and truncated
optimizerAdamW, learning rate 2e-5
batch size16 per device
epochs5, best checkpoint by eval loss
seed42

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

RQuarto Bayesian Inferenceroxygen2 Reproducible ResearchGit
Research internship

Undergraduate Research Intern

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.

PythonNLP EmbeddingsFine-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.

  1. 01

    Selected through multi-stage national tryouts and appointed Captain, leading squad strategy, training and competition execution.

  2. 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.

  3. 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.

  4. 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.

31stNationally, of 200,000+ players
96Matches played
1,396Runs scored
62Wickets taken
LeadershipStrategy Athletic PerformanceTeam Building Competition
Also active in

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
89.3%Reported accuracy

Cybersecurity Fundamentals Credential

2025 · Certification · NOCTI
Cryptography, threat analysis, authentication, digital forensics

BPA Nationals

2025 · National · 2× State Qualifier
8 / 501Meeting & Event Planning · 17 of 665 Payroll Accounting

Young Investors Society Global Stock Pitch

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 2026Claude in Code, Anthropic Academy. Deploying Claude Code as an autonomous engineering agent: explore-plan-code-commit, context management, project-level instructions and hooks.
Aug 2026Model Context Protocol: Advanced Topics, Anthropic Academy. Architecting MCP servers and clients across tools, resources and prompts.
Jul 2026Software Engineer Intern, HackerRank. Timed assessment across problem-solving and SQL.
Jun 2026Frontend Developer (React), HackerRank. Component architecture, state, routing, ES6.
May 2026IT Specialist in Java, Certiport / Pearson. Performance-based OOP, data structures, debugging.
May 2025Cybersecurity Fundamentals, NOCTI. Cryptography, threat analysis, authentication, digital forensics.
Mar 2025Java Coding Specialist, Knowledge Pillars.

Academics: Heritage High School, Frisco TX

graduatingMay 2027
schoolHeritage High School, Frisco TX

Technical proficiency

languagesPython, R, Java, JavaScript, SQL, HTML; C (introductory)
frameworksReact, FastAPI, Angular, NumPy, Pandas, Quarto, Google OR-Tools, asyncio, Go
toolsGit/GitHub, MCP, Claude Code, VS Code, Linux/Unix
Contact

Open a connection.

Listening on three channels. Response time is measured in hours, not weeks.

you abhineeth SYN SYN-ACK ACK ESTABLISHED
Three segments and the socket is open. Same idea here.