Portfolio

ML/LLM engineer focused on the parts that actually decide whether ML works in production — evaluation, calibration, thresholds, drift, serving, and agentic systems. 20+ years, ~50 patents.

Upstream contributions

Bug fixes to production ML/LLM libraries used by millions of developers. All PRs include reproduction case and regression tests.

🟢 Open
vllm-project/vllm · #47662
The Responses API accepted text/image but silently excluded ResponseInputAudioParam from its Pydantic union, rejecting any audio-bearing message at validation time — while the chat completions endpoint accepted identical payloads. Fix: extended the union with an audio-capable TypedDict variant.
🟢 Open
stanfordnlp/dspy · #9979
The gather_examples_from_sets helper filtered for the "augmented" key, which only exists on LLM-bootstrapped demos. Hand-labeled training examples never carry it, so they were dropped silently. The optimizer then generated instructions without ever seeing the user's labeled data.
🟢 Open
567-labs/instructor · #2412
_build_partial_object used isinstance(field_type, type) to decide whether to recurse into a nested model. That guard returns False for Optional[NestedModel] (a generic alias, not a type), so those fields were stored as raw dicts — causing AttributeError mid-stream when code accessed chunk.inner.some_field.
🟢 Open
huggingface/trl · #6297
vLLM emits NaN for near-deterministic tokens. extract_logprobs() converted these to None, then torch.tensor([None]) raised TypeError. Fix: convert None to nan before tensor construction, use torch.where for neutral importance-sampling weights.
🟢 Open
huggingface/peft · #3391
inject_adapter_in_model() returned the bare inner nn.Module, stripping the AdaLoraModel wrapper that holds update_and_allocate. Calling it afterward raised AttributeError, silently breaking AdaLoRA's rank-reallocation schedule.
🟢 Open
BerriAI/litellm · #32205
_update_responses_api_response_id_with_model_id was not idempotent — repeated calls in MCP tool loops applied base64+URL encoding twice, producing ~730-char IDs that are rejected by downstream API calls.
🟢 Open
BerriAI/litellm · #32200
When serving a cached response as a stream, the async path reconstructed chunks from the stored message but never forwarded reasoning_content. Applications relying on chain-of-thought tokens received empty strings silently.
🟢 Open
BerriAI/litellm · #32199
The Responses API proxy hardcoded reasoning_tokens: 0 in the usage block regardless of the actual token count returned by the upstream model. Downstream cost attribution and budget tracking silently received wrong values.
🟢 Open
BerriAI/litellm · #32198
Certain streaming providers emit non-choice chunks (heartbeats, metadata). stream_chunk_builder indexed chunk["choices"] unconditionally, raising KeyError and aborting the entire stream.
🟢 Open
vibrantlabsai/ragas · #2816
Added four standard IR evaluation metrics — NDCG@K, MRR, P@K, R@K — to the ragas retrieval evaluation suite. Ragas previously only supported context precision/recall; these enable proper ranking evaluation for RAG pipelines.
🟢 Open
EleutherAI/lm-evaluation-harness · #3913
Added Expected Calibration Error (ECE) and Root Mean Squared calibration error to lm-evaluation-harness. Previously the harness measured accuracy but had no way to evaluate whether model confidence scores were probabilistically meaningful.
⏳ Pending
langchain-ai/langchain · issue #38679
AIMessageChunk.init_tool_calls treats args="" (stream in progress) identically to args=None (field absent), resolving both to {} and firing the tool call before arguments have arrived. Fix ready; LangChain requires issue assignment before a PR will be accepted.
Writing
fine-tuningLoRARAGprompting

Fine-Tuning vs. Prompting: A Decision Framework That Doesn't Lie to You

The real decision tree — do you have labeled data, is the task format-sensitive or knowledge-sensitive, have you hit the cost crossover? With the breakeven formula, LoRA vs. RAG tradeoffs, and the data requirements teams consistently underestimate.

streamingSSELangChainproduction

Streaming LLMs in Production: The Edge Cases That Break Your App

SSE framing, proxy buffering, backpressure on slow clients, incomplete JSON from tool calls, reconnection replay, TTFT measurement, and the timeout misconfiguration that kills every long generation.

LLMrate limitingcostcaching

Running an LLM Gateway in Production

Token bucket mechanics, full-jitter backoff, prompt caching economics, and a concrete cost model for handling 429s, transient 5xx errors, cost overruns, and cold-start latency spikes at scale.

RAGNDCGMRRIR metrics

RAG Retrieval Isn't a Similarity Problem

Why cosine similarity is the wrong objective for retrieval quality. NDCG, MRR, P@K, R@K explained — and how to actually measure whether your retriever is improving your answers.

calibrationproduction MLfraud

Your Fraud Model's Scores Are Not Probabilities

Most deployed risk models output scores that are monotonically correct but probabilistically wrong. ECE, RMS calibration error, reliability diagrams, Platt scaling, and why your threshold sweep is lying to you.

Open source
Agentic & LLM infrastructure
tool-loopCorrect agentic tool-use loop: parallel dispatch, error isolation, auto-schema from Python functions
mcp-quickserverMCP server template: tools, resources, and prompts with stdio and SSE transports
stream-parseParse streaming LLM output: incremental JSON, markdown blocks, tool-call deltas, SSE events
agent-scratchpadPersistent vector memory for agents: embed, store, retrieve by cosine similarity
prompt-cache-benchBenchmark prompt caching: cache hit rate, latency delta, cost savings with real measurements
llm-eval-liteAssertion-based eval harness for LLM/agent outputs; composite checks (AllOf, AnyOf)
rag-evalRAG pipeline evaluation: chunking strategies, retrieval quality, answer faithfulness
llm-gatewayProduction Anthropic API proxy: token-bucket rate limiting, retry with backoff, cost tracking
rag-demoEnd-to-end RAG demo: BM25 + tool-loop agent + faithfulness eval + persistent memory
ML evaluation & calibration
ml-eval-reportBinary-classifier eval: metrics, ROC/PR + AUC, threshold sweep, Brier score, ECE
calibrate-mlProbability calibration: Platt scaling, isotonic regression, ECE, reliability diagram
thresholdkitPick operating thresholds under precision / FPR / cost / expected-value constraints
rankevalNDCG, MRR, AP@K, P@K, R@K — ranking metrics for search, recommendation, RAG
Production ML & data
featurecheckFeature drift (PSI/KS/chi-squared) + schema/null/dtype validation
idgraphIdentity/entity graphs from shared signals; surface synthetic-identity rings + risk scoring
pii-redactorDetect & redact PII (email, phone, SSN, IP, Luhn-validated cards); custom patterns
capture-qaImage capture-quality gates (sharpness, exposure, resolution)
modelcard-genGenerate Model Card markdown from a JSON config
Systems & infrastructure
tps-benchHTTP throughput & p50/p90/p99 latency benchmark for serving endpoints; warmup + JSON output
cmsketchCount-Min Sketch: approximate counts over high-cardinality streams; merge + serialization