Martin Mashalov

Machine learning & AI infrastructure engineer

Martin Mashalov

I train, deploy and scale AI models, and build the agent systems that run on top of them. My MSc thesis put reinforcement learning on diffusion language models. Day to day it is less exotic. A runtime that keeps a few thousand agents alive on one small machine, a document extractor whose accuracy is a measured number rather than a promise, and the workflow platform two insurance agencies run their back office on.

Everything below links to code you can read, and every number on this page comes from a file in the repository it describes.

Martin Mashalov

Selected work

nine, most recent first
2026energy research

Energy Forecast Lab

Forecast the peak. Price the uncertainty. An auditable research system for Texas electricity demand and execution-aware paper trading.

Residual regression, whole-day error scenarios and chronological calibration turn an operator forecast into a distribution for the daily peak. Explore a full year of forecasts, all decision clocks, matched calibration controls and the liquidity screen that found no guaranteed package surplus.

The initial ridge model reduces peak error by 12.37% versus the operator, and 4.04% versus simple bias correction on 357 paired development days. The public extraction has 714 offline tests. Better forecasting is measured; trading profitability remains unproven.

90.30%coverage for a nominal 90% interval at 14:00, after calibration. Matched control: 81.72%. Revised-proxy development results; paper only.
2026research

WeatherPred

A weather signal has to survive the trade. A quantitative research system that follows it through fees, latency, queue position and settlement.

Original NOAA forecasts and NWS report versions, coherent probability models, and a resumable search over momentum, reversals, favorites, longshots and observed-temperature constraints. The paper ledger accounts for partial maker and taker fills, cash reservations and correlated exposure. An independent audit reconstructs 253,227 hypothetical trade calculations across alternative policies from raw market records.

The best-looking backtest is not the conclusion: the monthly strategy selector using only earlier results loses $4.45 on its conditional $100 account. Profitability remains unproven. Every strategy, equation, failed experiment and execution assumption is documented.

1,836registered policy and cost comparisons. 89 tests at the published checkpoint. Historical conditional trades and prospective paper fills are reported separately.
2026open source

gpt2-harness

A training harness built from the parts up: all five parallelism strategies, a roofline, and a tool that tells you why a run is slow.

Data, sharded-data (ZeRO 1 through 3), tensor, pipeline and context parallelism, each written against torch.distributed and each checked against a single-process reference. The per-step wire volume is counted byte for byte and matched to its closed form, so ZeRO-2 and DDP are shown to move identical bytes, which is what you expect once you notice an all-reduce is a reduce-scatter followed by an all-gather. The pipeline bubble is measured against the analytic (p−1)/(m+p−1) for one to sixteen micro-batches. On top of that: a measured roofline, model-FLOPs utilisation, checkpoints that reshard across parallel layouts, a killed rank restarted from its last checkpoint, a resumable streaming loader, and Slurm, Ray and Kubernetes launchers.

The correctness proofs run on gloo because proving a sharded implementation matches a single-process reference does not need a GPU. Throughput and interconnect numbers do, so those are modelled from published bandwidths and labelled as modelled throughout. My thesis training is the other half of this: bfloat16 and FlashAttention-2 on H100s, with a subset of the evaluations on A100 and B200. Underneath it all, the GPT-2 implementation is verified to a worst logit disagreement of 6.1e−5 against HuggingFace across 75 layers, which is what makes the rest of the measurements mean something.

4/4 injected throughput faults the tool found and ranked. A fifth run injects nothing, and it stays quiet. The faults: a dataloader stall at 37.1% of step time, an all-reduce that never overlaps compute, and a batch too small to saturate. Measured MFU 47.7%.
2026production

Sen  papyra.org

Describe a back-office process in plain English and get a workflow you can see, edit and run. Two insurance agencies use it. A person approves anything that leaves the building.

The description compiles into a visual node graph of triggers, tool steps, branches and approval gates, and a durable engine runs it per account across email, cloud storage, and the agency management system, through a registry of 64 tools. A workflow that sends real client mail must never send twice and never silently skip a step. Every state transition passes one chokepoint enforcing four invariants. Each one is traced to the production failure that caused it.

64 tools in the agent registry, with roughly one line of test for every line of application code
2026MSc thesis

Reinforcement learning on diffusion language models

A diffusion language model chooses which position to reveal next. I tested whether post-training should change its weights, its decoding order, or both.

Diffusion language models unmask a sequence instead of writing left to right, so they face a choice autoregressive models never face: which position to reveal next. I ran a grid over three diffusion models, two post-training levers, and two reward designs on HumanEval and MATH-500, with MBPP and GSM8K held out. Carrying a learned ordering policy across to reward-tuned weights unchanged lowered accuracy; re-fitting it on those weights scored highest, though a continuation control means the size of that gain is not attributable to re-adaptation alone. The policy is fitted to a model, not to a task. And a checkpoint that had already been RL-tuned resisted every method: its within-group reward dispersion had collapsed, leaving GRPO almost nothing to learn from.

61.8 HumanEval pass@1 on Dream, up from 46.6 for the same policy on the base model at a matched decoding budget. University of Amsterdam, July 2026
2026production

GridPull

Commercial insurance prospects built from public filings. Every renewal date is either quoted verbatim from a named document or labeled an estimate.

A producer needs to call a business ninety days before its policy renews. A verified renewal date is copied straight from the source registry and marked verified; where none exists the lead carries an estimate, marked as an estimate, and the only date arithmetic anywhere is “is it today or later”. A 150-worker asyncio pool streams document extraction over server-sent events, and the cross-sell engine is deliberately deterministic, with no model in the loop, because a coverage-gap recommendation has to be explainable.

98.9% field accuracy extracting insurance schedules from 100 documents across six schedule types, zero error rows
2026open source

gtm-agent

Finds people describing your problem on Reddit, scores them against an ideal-customer profile, and drafts the outreach. Nothing sends without a human approving it.

Cheap deterministic rules run first; the model only ever sees what survives them, and a test enforces that. Every model call is metered and attributed, so cost per qualified lead is measured end to end on a recorded corpus against a deterministic offline model. Official APIs only, no scraping and no browser automation of LinkedIn. That is the difference between a tool a company can deploy and one that gets its accounts banned.

59% less metered spend than sending every candidate to the model. Rules drop 40 of 65 before the model sees anything. F1 moves by +0.037 ± 0.064 on a paired bootstrap, an interval that includes zero
2026open source

agent-fleet

An agent run spends almost all its time waiting on a model API, so one asyncio supervisor handles thousands. Killing the process mid-run loses none of them.

An agent run is roughly 99% I/O wait on a model API, so the right shape is one asyncio supervisor with a bounded pool rather than a thread per agent. The hard parts come after: an at-least-once queue with leases and idempotency keys, per-step checkpointing so a killed process resumes mid-run, and backpressure that never lets concurrency exceed its cap. Measured in a 1-vCPU, 1 GB container against a deterministic mock provider: 546 agent steps a second.

0 runs lost and zero duplicated when the process is killed mid-flight. The thread-per-agent baseline has nothing to resume from and loses 297. Give it the same commit protocol and it recovers too, so the durability belongs to the protocol rather than to asyncio.
Bar chart: agent-fleet completes 500 of 500 runs after SIGKILL and restart; the thread-per-agent baseline completes 203 and loses 297.
500 runs, SIGKILL at 40% complete, then restart. Measured under --cpus=1 --memory=1g.
2026open source

generative-eval

"My generative model produces good samples" is not one claim. It is four, and they come apart.

Four questions, asked in order: does the metric work at all, does the model match the published marginals, can a classifier tell its samples from real ones, and is the synthetic data any use downstream. Seven families climb the same ladder under one budget: five GAN objectives, denoising diffusion and flow matching, read against a classical GARCH fit and two nulls nothing should lose to. Two testbeds where the answer is known independently: mixtures whose modes are exact, and seventeen years of real intraday equity bars whose stylized facts are a published answer key.

Flow matching is the first family here to beat the classical baseline on real data, and it holds all eight stylized facts down to ten sampling steps. Which families you benchmark decides what your benchmark concludes: over the five GANs alone, ranking by 2D mode coverage anti-correlates with ranking by detectability at Spearman −0.90.

21/39 of this repository’s own conclusions are adequately powered, and it names the other 18. The rank-agreement result cannot be significant at five model families, which is why there are now seven.
Rank of seven model families across four evaluation rungs, with the lines crossing
Rank on each rung. The lines cross, so the metric you pick decides the winner.

Experience

systems other people depend on

Every role below is the same job in a different setting. Somebody needs a system that keeps working when they are not watching it, and I own the part that has to not break.

2026 – Founder & Software Engineer GridPull. I build it and I sell it, which means I hear the complaint and then fix it myself. Commercial insurance prospects assembled from public filings and sold to independent agencies. FastAPI, SQLAlchemy and asyncpg against PostgreSQL behind PgBouncer, with Redis for queues and a 150-worker asyncio pool streaming extraction progress to the browser over server-sent events. Two separate database engines, because schema changes need session semantics that transaction pooling cannot give you. Extraction runs PyMuPDF and Mistral OCR into Anthropic and OpenAI models with a fallback chain; documents live in S3 via boto3; billing is Stripe. The front end is React 18 and TypeScript with TanStack Query, Radix and MapLibre, built by Vite and shipped with Docker Compose behind nginx from GitHub Actions. The cross-sell engine has no model in it by design: a producer has to be able to explain a coverage-gap recommendation to a client. The extractor scores its own output at 98.9% field accuracy across six schedule types with zero error rows.
2025 – Technical Co-Founder Papyra AI (Sen), partnered with Vertafore. Agent infrastructure that two insurance agencies run their back office on. I own the engine: a 64-tool registry behind 338 endpoints, FastAPI with SQLAlchemy 2.0 async and psycopg3 on PostgreSQL behind PgBouncer. Model calls go through litellm across Anthropic, OpenAI, Groq and Gemini so one provider outage does not stop the queue, with DSPy for the eval harness and LightRAG and fastembed behind retrieval. Playwright drives the browser work, sse-starlette streams run progress, Fernet encrypts credentials at rest and Stripe handles billing. The canvas is React Flow and dagre in React 18 and TypeScript, with a Tauri desktop build, deployed on Hetzner under systemd and nginx. The durability work is what makes it safe to let an agent send real client mail: transaction-scoped Postgres advisory locks with a compare-and-set relock, because PgBouncer's transaction pooling makes session locks a trap that only shows up under load, and a pre-send group claim so a redelivered message cannot double-send.
2025 AI Research Assistant Vrije Universiteit Amsterdam, Faculty of Computer Science. Language models driving behaviour-tree control of multi-agent systems in Python: the model writes the policy, the tree keeps it inside behaviour you can inspect and verify. The same question my thesis asks from the other side, which is how much of an agent's competence should live in learned weights and how much in structure around them.
2025 Software Engineer Marubeni American Corporation, freelance. VisionPay: distributed document extraction with a fine-tuned vision-language model, wired into SAP so the output landed in the system the finance team already used rather than in a dashboard nobody opens. I wrote the disaster-recovery runbook for it, which is the part that decides whether a pipeline survives its first bad week.
2024 – 25 Quantitative Modelling Intern ABN AMRO Bank. Six months of quantitative model development inside a European bank, working in Python and R where a model that cannot be explained does not ship. That constraint is why the deterministic, explainable-by-construction components in my own products are deliberate rather than accidental.
2021 – 23 Software Engineer Peek Real Estate. Built and ran their geocoding and points-of-interest service in production: FastAPI and PyMongo over MongoDB 2dSphere indexes with $geoWithin radius queries, Elasticsearch for text search, slowapi for per-client rate limiting, and address parsing with usaddress and NLTK. Eighteen hot paths compiled to C with Cython when the NumPy and pandas versions could not keep up. Containerised with Docker. 341 commits, all mine. I was eighteen when I started it.
Education
2026 MSc Econometrics University of Amsterdam, Data Science track. Thesis on reinforcement learning for diffusion language models, trained multi-node on H100 nodes over NCCL under Slurm on the Dutch national supercomputer, with a fixed compute grant. The write-up is here.
2025 BSc Econometrics & Data Science University of Amsterdam. Thesis on Taylor-rule central-bank rates inside an agent-based macro model, on Eurozone data: at the twelve-quarter horizon the inflation-gap rule cut out-of-sample RMSE by up to 33.9% against an AR(1) baseline and 38.8% against a VAR(1) baseline.

Also

earlier projects
2025 InstructionManualRAG Document-grounded answers with citations back to the source page. LangChain over ChromaDB. Five contributors; I wrote 129 of the 298 commits.
2022 – 23 BisonHFT A quantitative trading stack: BisonHFT predicts directional movement in SPY and feeds indicator data to an execution engine; BisonQ packages the research framework; BisonForecastBacktester scores SARIMAX forecasts out-of-sample. Eight stars, four forks.
2021 Places geocoding API A geocoding and points-of-interest service: FastAPI over MongoDB 2dSphere indexes, with eighteen hot paths compiled to C via Cython. 341 commits, all mine.

Languages Python · TypeScript · JavaScript · SQL · R · Cython · Triton · Metal shading language ML PyTorch · torch.distributed · DTensor · Hugging Face Transformers · PEFT / LoRA · TRL · GRPO · DSPy · scikit-learn · NumPy · pandas · SciPy · FlashAttention-2 · bfloat16 Serving & agents Anthropic · OpenAI · Gemini · Groq · Cerebras · litellm · LangChain · LightRAG · ChromaDB · tool-use loops · MCP-shaped adapters · Playwright · PyWinAuto Backend FastAPI · asyncio · SQLAlchemy 2.0 · asyncpg · psycopg3 · PostgreSQL · PgBouncer · Redis · SQLite · Celery · server-sent events · Pydantic · Stripe Front end React 18 · Vite · Tailwind · Radix · TanStack Query · React Flow · MapLibre · Tauri Infrastructure Docker · Kubernetes · Terraform · AWS · GCP · Hetzner · nginx · systemd · Slurm · Ray · Prometheus · Grafana · GitHub Actions · cgroups · NCCL · InfiniBand

Let’s talk

© 2026 Martin Mashalov Set in Archivo, Instrument Sans & IBM Plex Mono Three static files, no framework