Projects

A selection of GitHub projects, most recent first.

Three-panel decision boundary comparison: teacher, student without knowledge distillation, and student with knowledge distillation, on the XOR-blobs dataset

A visual knowledge-distillation lab: trains a teacher and a student (with and without distillation) on 2D datasets and compares their decision boundaries, showing what the student actually learns from the teacher beyond accuracy.

Every experiment plots three panels side by side — teacher, student trained on hard labels only, and an architecturally identical student distilled from the teacher — so instead of comparing accuracy numbers you can literally see the boundary each model settled on. On datasets with a real "void" (regions with no training data, like the XOR-blobs case pictured), the no-KD student and the teacher resolve the ambiguity differently, while the KD student — trained on extra teacher-labeled query points sampled from that empty region — reproduces the teacher's exact boundary almost perfectly.

Two further experiments (overlapping blobs, a biased teacher) show the same mechanism from the opposite angle: when there's no void to fill, KD instead transfers the teacher's calibration — including its flaws, like overconfidence or a spurious shortcut feature — which the README argues is structurally the same effect behind why sequence-level distillation works for LLMs, not just a toy analogy.

  • Python
  • PyTorch
  • Knowledge Distillation
  • Visualization
Chart showing how the planner decomposes more subtasks and execution waves as prompt complexity increases
LLM Router
Jul 2026

Decomposes a prompt into subtasks with a single planning call to Claude, routes each one to the cheapest model capable of handling it (Haiku/Sonnet/Opus), and runs the independent ones in parallel.

A single structured-output call to Claude plans the whole job: it breaks a prompt into a dependency graph of subtasks, assigns each one the cheapest model tier that can handle it, and is explicitly told that decomposition isn't free — every extra call has its own overhead — so it only splits work when parallelism or a cheaper tier is actually worth it.

The executor groups subtasks into dependency-respecting "waves" and fires every subtask in a wave concurrently via asyncio, so a wave takes as long as its slowest call rather than the sum of all of them; a final synthesis call stitches independent results back into one answer. Every call — planner, subtasks, synthesis, and a single-model baseline for comparison — logs its own tokens, cost, and latency, so the routed pipeline can be benchmarked against just sending the whole prompt to one large model.

  • Python
  • Claude API
  • asyncio
  • Streamlit
LittleLamb Document Chat — a Streamlit chat interface for querying the fine-tuned model

Local fine-tuning of a small LLM (LittleLamb, 290M parameters) on your own PDFs, with no vector databases or RAG: the knowledge lives in the model weights and runs entirely on CPU.

Most "chat with your PDFs" tools reach for a full RAG stack — a vector database, an embedding model, a chunking/retrieval/reranking pipeline — even for a handful of documents. This project takes the opposite approach for small, stable document sets: extract the text (and describe any embedded images via Claude Vision), turn it into a Q&A training set, and LoRA fine-tune LittleLamb — a 290M-parameter model built by Multiverse Computing by compressing Qwen3-0.6B, state of the art for its size class — directly on the content.

The result runs entirely offline on a laptop CPU: a FastAPI server exposes an OpenAI-compatible endpoint, and a Streamlit chat UI lets you ask questions the model answers straight from what it learned — no retrieval step, no infrastructure.

  • Python
  • LoRA
  • Hugging Face
  • FastAPI
  • Streamlit

Autonomous AI agent that lives on Moltbook, the social network for AI agents. Uses Claude as its reasoning model, deploys on Google Cloud Run, and is triggered every 5 minutes via Cloud Scheduler.

Every 5 minutes, Cloud Scheduler hits a FastAPI heartbeat endpoint on Cloud Run, which asks Claude to decide what the agent should do next, persists its evolving state to Firestore, and posts back to Moltbook through a small API client — a self-registering agent that runs unattended, with no human in the loop.

Secrets never touch the codebase: API keys live in Secret Manager, and the service itself runs with --no-allow-unauthenticated so only Cloud Scheduler's OIDC token can ever trigger it.

  • Python
  • Claude API
  • FastAPI
  • Google Cloud Run
  • Firestore
Tourist Guide
In progress2025 — present

Mobile tourist-guide app that generates AI-personalized points-of-interest information from the user's GPS location, in multiple languages.

A full-stack side project built end to end: a Domain-Driven Design REST API, a PostgreSQL data layer, a React Native/Expo mobile client, and a second Flask/DDD service that calls Gemini to turn raw GPS coordinates into narrated points of interest — historical context, nearby landmarks, recommendations — on demand, in five languages.

It's the oldest project here and the one currently being actively rebuilt: the core AI pipeline and API already work end to end, the mobile app has its navigation shell in place, and the landing page is the next piece to build.

  • Python
  • Flask
  • DDD
  • PostgreSQL
  • React Native
  • Gemini AI
  • Backend

    REST API in Flask with Domain-Driven Design (DDD) architecture for the mobile app.

  • DB Helper

    PostgreSQL schema management scripts: creating and dropping tables, user model.

  • Mobile app

    React Native/Expo app with base navigation already implemented.

  • Agent Backend

    Flask/DDD service that integrates Gemini to generate tourist content and nearby points of interest, with multi-language support (ES/EN/FR/DE/IT).

  • Landing page

    Not started yet.

Coming soon

Projects in the pipeline, not started yet.

LLM Compression to a 16GB Ceiling

Applying the classic Deep Compression pipeline (Han et al., 2015) — magnitude pruning, k-means weight-sharing quantization, and Huffman coding — to a ~7B-parameter LLM sized to sit right at the edge of 16GB of RAM, entirely post-training with no full retraining, then comparing the result against modern quantization methods like GPTQ and AWQ.

AI Assistant for This Site

Adding an AI assistant to this website that can answer visitor questions about me directly — my background, experience, and projects — using this site's own content as context.