AI/ML Research Engineer
M.Sc. Student Statistics & Data Science, LMU Munich · Munich, Germany
I’m an AI/ML research engineer and M.Sc. Statistics & Data Science student at LMU Munich (expected graduation: spring 2027). I build and evaluate multimodal models for surgical video in collaboration with ZEISS, and self-supervised systems for archaeological LiDAR. My work combines scalable model training with careful benchmarking and reproducible engineering.
I’m interested in reliable medical AI: how models generalize across patients and domains, how uncertainty should shape predictions and human review, and how statistical decision theory can guide model development. My master thesis, supervised by Dr. Philipp Keyl, is on generating synthetic clinical data. I’m looking to pursue these questions through PhD research. I also study agentic systems, with a focus on tool use, evaluation, and failure modes.
Built and ran a self-supervised pretraining benchmark on an ImageNet-init ViT-B/16 backbone, comparing DINO v1 against LeJEPA, then measuring zero-shot calibration and accuracy on HyperKvasir before vs. after in-domain SSL. Designed a checkpoint-resumable streaming pipeline that reads the full ~4.9M-image GastroNet-5M corpus (all 506 source archives) directly off the remote portal with no local pre-curation, handling truncated images and archive-host outages without breaking exact step-count reproducibility across SLURM resubmits.
Selected the winning setting against a pre-registered rule (no regression on accuracy, balanced-accuracy, AUROC or segmentation Dice vs. the pre-SSL baseline): DINO/ImageNet passes cleanly across all 5 HyperKvasir tasks, while LeJEPA/ImageNet regresses on every classification task and on segmentation. 4.9M images × 3 epochs = 113,064 optimizer steps per setting, trained single-GPU on LRZ H100/A100. The winning checkpoint is promoted as a foundation model for downstream fine-tuning.
Repository public — research collaboration. Happy to walk through the work.
An autoencoder pipeline that segments aerial LiDAR point clouds spanning more than ten hectares and automatically flags anomalies for targeted expert review, replacing full-site manual inspection and sharply cutting survey time.
Second author on a paper in preparation for the ISPRS Journal of Photogrammetry and Remote Sensing (not yet submitted).
Code private while the paper is in preparation.
Demand-forecasting models for daily sales across all stores, built around feature engineering on 1.5 years of historical sales and store attributes, and delivered and explained to the retail partner.
24% WAPE on 14-day-ahead forecasts.
Repository private pending a data-sharing check.
A reproducible analysis of a cleaned field survey on compensation applications, agricultural losses, policy support and tolerance toward wild boars in two Chinese counties. The project turns the full questionnaire into an auditable evidence trail, from exploratory data analysis and measurement validation through ordinal models, Bayesian checks, PLS-SEM, mediation, prediction and stress testing.
The public artifact explains every analysis script line by line and reports the limits of causal interpretation, including county-period confounding, measurement overlap, structural missingness and unmeasured confounding.
Led exercise sessions and graded exams for two undergraduate courses of 100+ students each — routine practice at making abstract technical material land with a non-expert audience.
First author · in preparation · target CVPR 2027
Second author · in preparation for the ISPRS Journal of Photogrammetry and Remote Sensing (not yet submitted)
gnhf runs a coding agent in an unattended loop against an objective. Its --max-tokens
safety cap was undercounting spend by 183x: the provider adapters report four token buckets,
the orchestrator stored only two, and the budget check silently dropped cache reads and cache
writes. One reported run believed it was at 22% of a 1,000,000-token budget while it had
already billed 41.1M tokens and $48.64. The cap never fired.
I widened orchestrator state to carry all four buckets and normalized the adapter boundary so
they stay mutually exclusive — Claude was folding cache reads into inputTokens,
and Codex nests cached tokens inside OpenAI's input_tokens — then threaded the
corrected total through the renderer, exit summary and CLI help so the displayed numbers agree
with the enforced cap. Merged through the maintainer's no-mistakes review gate
after three AI review rounds, with 760 tests and 6 CI checks green.
MONAI's EmbeddingCollapseMetric is meant to warn when a model's embeddings lose their
diversity, but its summary score ignored the one indicator that can see collapse confined to a
single class: per-class rank was computed, returned, and then left out of every reduction. With
reduction="max", documented as the worst-case score, a class could be fully collapsed
(per_class_rank = 1.0) while the aggregate reported a healthy embedding space.
Folded the worst per-class score into the reduction as a single term, so max is the
true worst case and mean keeps one vote per indicator. Four regression tests use a
healthy 200-sample majority class and a collapsed 8-sample minority class, including one showing
that the global indicators alone miss it. 2 files, +78 / −4 lines; closes issue #9116.
Each agent runs a farm for a 720-turn season — hiring hands, planting, raising animals, buying land and selling into a market whose prices react to both players — and whoever banks the most wins. Agents are ranked on a live ladder against everyone else's submissions. I started with my own hierarchical heuristic (perception, pathfinding, an economic value model, task assignment), then learned from public replays that the top of the ladder was running replayed action routes, and moved to route-based agents with my own market-timing layers on top.
Most of the work was measurement. I built a paired-seed, both-seats evaluation harness and a validation gate that packages each agent exactly as Kaggle receives it and replays full games through the real loader. I fixed a module-caching bug that had made two "different" agents run identical code, and a tuning script that optimised money when the ladder scores only win or loss. To see what strong opponents actually ran, I crawled the live matchmaking graph and matched their recorded games against local candidates step by step.
Climbed from rank 5,852 to 754 in two days in early September, and reached a peak live rating of 2751.5 (silver range at the time, on the live ladder's own scale). Single-constant changes carried most of the gains: one selling order tweak beat its parent 94–26, and a sale-lookahead change beat the strongest public agent 36–4 on fresh seeds. I also showed that a live rating is not a stable measure: byte-identical code scored 2751 one week and 1847 the next, so I stopped comparing ratings across days. Final standing: rank 1,162 of 10,148 teams, score 4371.7 on the final scale.
Python harnesses and prompt suites that drive tool-using agents (GPT-OSS, Gemma) through adversarial multi-step scenarios. The deliverable is not a clever one-off jailbreak: it is a reproducible failure — one that survives a rerun, has an isolated cause in the tool-calling or context-handling path, and can be turned into a regression test.
Public leaderboard rank 461 of 4,187 teams.
Describe a circuit in plain English and an agent designs it, checks its own electrical and design rules against live component stock, repairs what it gets wrong, and exports Gerbers a factory can build. Every view — schematic, PCB, 3D, BOM, fab files — derives from one Circuit JSON, so they cannot disagree with each other.
Built in one 20-hour window. I owned the distributor-availability layer: the Mouser integration for lifecycle, stock depth and minimum order quantity, plus a web-scraping sub-agent layer so the design loop never depended on a single stock source.
Role-played AWS Account Manager and Solutions Architects, designing and presenting an AWS architecture for a fictional Formula 1 team across five challenge areas: generative AI for race strategy, sovereign cloud/data security, fan engagement, global broadcasting and real-time telemetry.
Delivered as a scored case-study report — an architecture proposal, not a production deployment.
Case-study report (PDF) →
Interactive demo (synthetic data) →
Registered participant — event upcoming. No project outcome to report yet.
A chat assistant that answers from this portfolio, cites the section it used and scrolls the page to it, books calls on my calendar and passes on messages. A LangGraph pipeline routes each question; complex ones are split by a planner, searched in parallel and searched again where evidence is missing, with every step shown in the chat. Model calls go through a router across Gemini (EU region) and open models on Groq. Any action that changes something, a booking or a message, pauses for an explicit yes.
Evaluation: on 12 multi-hop questions research mode raised evidence recall over plain RAG by +0.125 in one run and +0.049 in a repeat (that interval just touches zero), since plain RAG's own recall varies from run to run. It costs about twice as much, so it only runs on complex questions. A claim-verification step I built showed no benefit and is switched off. A 36-case adversarial suite, including poisoned retrieved documents, passed when last run, and five incidents are written up, among them an evaluation I discarded after provider rate limits contaminated it.
An enterprise service desk where a front router receives a request, retrieves policy evidence with citations, and delegates to a bounded ERP, CRM, HR or scheduling specialist. The model classifies and drafts; trusted Python code validates its output, picks the only permitted tools, and holds every protected write behind an IT approval step.
The model never sees raw records, never chooses an arbitrary tool and never executes a mutation. Unavailable, malformed, unsafe or low-confidence output falls through to human review by design, not by accident.
A bronze → silver → quarantine → gold pipeline behind versioned JSON-Schema contracts, running locally via Python/uv or on GCP via a Beam/Dataflow adapter — carrying over Service Desk AI's approval-gate discipline: records failing validation are quarantined with a logged reason rather than silently dropped.
A PaliGemma2-3B model fine-tuned with LoRA/PEFT on ScienceQA, wrapped in a full production stack: DVC data versioning, Hydra configs, cloud training, a FastAPI service with hot-swappable adapters, drift monitoring and CI/CD.
72.2% exact-match. A prompt-ordering fix found by systematic ablation was worth +16 points on its own; int4 quantization cut GPU memory by 51%.
Coursework repository — not mine to publish.
RSNA Knee Abnormality Detection (final rank 1,467 of 6,299; private score 0.942, from ensembles of public notebooks with my own ConvNeXt model as a blend arm); NVIDIA Nemotron Model Reasoning Challenge; BirdCLEF+26 (03/2026). Social Data Science: PLS-SEM analysis of a wildlife-compensation policy in Giant Panda National Park (R² = 0.30), supporting the partner's publication.
A Python library that takes a clinical dataset, one row per patient, and generates millions of synthetic patients. Each column should match the real column's distribution, for up to 500 mixed-type features (binary, categorical, continuous). The first version is cross-sectional; longitudinal data comes later.
Plan: compare generator families (copula, tree-based, GAN, diffusion, autoregressive) and evaluate fidelity, downstream utility (including survival outcomes) and privacy, always against a real-to-real reference. Work in progress; no results yet.
Designed a new decision-theoretic acquisition policy for Bayesian optimization and benchmarked it against standard test functions.
The whole path a model takes to reach an IoT device: synthetic building telemetry, a trainer with a fixed seed, a checksummed JSON artifact, C firmware constants generated from it, and dependency-free inference running on the device. The cloud is a fleet-management and observability layer — it never needs the raw samples to know a device found a problem.
The same inference contract implemented twice, in Python and in C, with the artifact checksum verified before use. Telemetry ingestion is idempotent and deployments are audited.
neetcode-gpt — a GPT built from scratch · NN-from-scratch · InstaSHAP benchmarks
Vietnamese (native), German (C1), English (C1), Italian (B1), Chinese (HSK 2), Arabic (beginner), Thai (beginner)
Python, SQL, C++/CUDA, R, Bash, LaTeX
PyTorch, Hugging Face Transformers, PEFT/LoRA, scikit-learn, LightGBM, Optuna
Tool calling, MCP, structured outputs, RAG and vector search, prompt and context engineering, quantization and pruning
Eval harnesses, confidence intervals, per-class error analysis, benchmarking against published baselines, Weights & Biases sweeps
FastAPI, REST APIs, Docker, GitHub Actions CI/CD, DVC, Hydra, Evidently, Prometheus, pytest
GCP (Vertex AI, Cloud Run, Cloud Build), AWS (S3, EC2/SageMaker, Terraform), Linux, SLURM GPU clusters
Time-series forecasting, self-supervised learning, domain adaptation, explainable AI (SHAP), PLS-SEM, Bayesian optimization
LMU Munich · 2025 – present · expected graduation: spring 2027
Master thesis (ongoing), supervisor Dr. Philipp Keyl: synthetic clinical data generation
LMU Munich · 2021 – 2025 · final grade 1.8
Guitarist and vocalist in jam sessions
Long runs; marathon personal best 4:20:07 (unofficial)