ML and software engineer: AI agents, generative models, reinforcement learning.
I build AI agents and machine learning models, and the evaluation that tells me whether they actually work. Most of what I make runs end to end: the model, the data pipeline around it, and the backend that puts it in front of people. I work mostly in Python and PyTorch, with Java, Node.js, Docker and AWS on the service side.
Until July 2026 I was a research engineer at Indiana University, most recently benchmarking image and video generation models for autonomous driving on an Astemo-sponsored project. Before my master's I wrote Java services for HDFC Bank at TCS.
Computer-Use Automation System
An AI agent (Claude, driving a real browser through Playwright) learns a task in an old web ERP once. That run is compiled into a typed file a person reviews and signs off on, and from then on a plain interpreter replays it with no model in the loop, so repeat runs cost nothing in model calls. The task posts payments, so it is built to fail safe: a SQLite ledger records intent before every click and never posts a payment twice, a lost response goes to a person instead of being retried, the model never sees real credentials, and anything off the approved action list is blocked. An operator can take over the same live browser mid-run. Tested against Dolibarr with injected network faults, with Dolibarr's own API as the referee: 33 of 33 lookup runs and 5 of 5 payment cases passed, backed by 850+ automated tests.
A voice agent you can talk to about driving footage. You speak, it answers about what is on screen or finds the moment you describe, and it stops talking about a quarter second after you cut in. A zero-temperature router sends frame, video, comparison and search questions straight to the right tool; everything else goes to Qwen3-8B with six tools it can call. Vision questions go to Cosmos-Reason2, which keeps frames out of the chat context. Scene search runs over a FalkorDB knowledge graph of nuScenes scenes (559 nodes, 1,790 edges) built straight from the raw dataset tables. Questions about whether the car is turning are answered from its recorded motion data, because a front camera can't see its own car turn.
Next-Item Recommendation (RePrior-Rec)
Given a shopper's history, predict the first new item they will touch in the next week, ranking all 42,250 items in the catalog with no sampled shortcuts. I compared 18 models on 2.8 million RetailRocket events, from popularity counts and session kNN to SASRec, EASE and transformers with RL heads, each scored once on a held-out week with bootstrap error bars. My hybrid, RePrior-Rec, is a transformer that learns a correction to a simpler EASE recommender, with a copy head for repeat visits. It beat the strongest baseline by 14%, and an XGBoost reranker on top scored best overall. The breakdown taught me more than the headline: about 62% of the new model's score came from the 9% of shoppers returning to something they had already viewed, and swapping RL objectives moved results by less than the error bars.
LedgerBench
A small benchmark for LLM agents, built so I could trust its scores. 40 ledger tasks, each gold answer computed twice by separate code, plus an LLM judge that grades one rubric item per call. Fake models went through first: a perfect answer had to score full marks, and empty, hedged or prompt-injection answers had to score zero. Scores cover pass@1, pass@k and pass^k with Wilson, bootstrap and task-clustered intervals, and a power analysis showed 40 tasks can only catch gaps of about 15 points. Claude Haiku and Sonnet both solved all 40, Haiku at under half the cost per solved task, so the next version needs harder tasks.
A 254M-parameter latent Diffusion Transformer written from scratch: attention, AdaLN-Zero conditioning, patchify and the rectified-flow math by hand, with only the VAE and CLIP text encoder pretrained. Run on about 2 million LAION-Aesthetics images with DDP and DeepSpeed. Profiling showed the data pipeline was never the problem (757 images/s against a model using about 26) and hand-written fp32 attention was. Swapping in fused attention gave 2.2× throughput and half the peak memory.
A team class project with researchers at NICC Brussels, who were coding interview transcripts by hand. The pipeline turns transcripts into a knowledge graph in Neo4j with LlamaIndex, and an OpenAI model suggests codes for passages that a researcher then reviews.
A small, readable diffusion repo that starts from a vanilla DDPM ε-prediction model and moves toward modern diffusion in minimal additive steps. U-Net with timestep embeddings and selective self-attention on CIFAR-10, EMA, checkpointing, and FID reporting every 10k steps, built to be instrumented and legible rather than a heavy framework.
Unsupervised Industrial Anomaly Detection
A Vision Transformer autoencoder with capsule layers and a 10-component Gaussian mixture density model for finding and locating defects in industrial images, adapted from VT-ADL. On the BeanTech (BTAD) dataset it reached 0.94 AUROC, against 0.78 for a ResNet-50 baseline.
Goal-conditioned reinforcement learning combining Soft Actor-Critic, Hindsight Experience Replay, and Stein Variational Goal Generation for curriculum-style goal sampling in sparse-reward robotics environments like FetchReach. Hydra-configured, W&B-tracked.
A model-based RL algorithm inspired by Deep Value-and-Predictive-Model Control: learned dynamics, value approximation, and Cross-Entropy Method planning over a prediction horizon for continuous control. Effective in dense-reward settings, with sparse rewards analyzed as the open challenge.
Mar 2026 – Jul 2026
SMART Lab, Indiana University (sponsored by Astemo Americas)
Benchmarked 8+ image-editing and video-generation models on nuScenes and Argoverse, and wrote the PyTorch pipeline behind it: data prep, inference across several GPUs with vLLM-Omni, and automatic scoring. Designed the geometry and realism metrics from Grounding DINO and FoundationGeo estimates, and checked them on real frames against LiDAR depth and 3D boxes before scoring any generated one. They became the benchmark's main comparison. Wrote up the metrics and failure cases for the sponsor and contributed experiments to a paper now under review.
Jan 2026 – Apr 2026
Heartland Community Network (CHOMP)
Joined a small team before launch and built Node.js and Express services on AWS for recommendations, event-driven analytics and scheduled jobs. After go-live, added logging and monitoring and tracked production issues down to their root cause.
Jan 2025 – Jun 2025
Indiana University
Built custom PointMaze tasks in MuJoCo for goal-conditioned RL. Adding hindsight experience replay to Soft Actor-Critic raised task success from 15% to 55%. Ran 100+ multi-seed experiments with Hydra, MLflow and W&B.
Apr 2024 – Dec 2025
Leung Research Group, Indiana University
Trained U-Net surrogates for Lumerical FDTD optical simulations on one metasurface family, cutting a roughly three-minute solve to under a second while holding SSIM above 0.85, using 5,000+ simulations run on a Slurm cluster. Also built a pipeline that turns time-series OCT videos of tissue into histology-equivalent images.
Jan 2022 – Jan 2023
Tata Consultancy Services (client: HDFC Bank)
Wrote Java and Spring Boot microservices, REST APIs and the SQL behind HDFC Bank's transaction processing, automated reconciliation in batch jobs, and worked with QA and infrastructure teams on releases and incidents.