# Manuel Cárdenas Prieto (Manu, manoletre) > MS at Stanford. I fine-tune small models and build AI for learning. Previously Computer Science at TUM, math teacher, and EdTech founder. Hi there! I'm Manu (Manuel Cárdenas Prieto), currently finishing an MS @ Stanford in Learning Design & Technology. Did every elective in AI/ML. Previously: Math teacher, EdTech founder (raised $100k), Computer Science at TUM and part of CDTM Spring 21 class. ## What I studied at Stanford I mostly wanted to learn about the intersection of AI and learning. I studied the science of learning, education entrepreneurship and hardware prototyping. Some of the things I worked on: - CS229 (Machine Learning). [My project](https://www.manoletre.com/projects.md#cs229) predicted when a small LLM hallucinates from its activations and token probabilities. - CS231n (Computer Vision). I [fine-tuned vision transformers on satellite images](https://www.manoletre.com/projects.md#cs231n) of every high school in Colombia. - CS234 (Reinforcement Learning). I [trained a 3B model with SFT and DPO to write Manim animations](https://www.manoletre.com/projects.md#cs234), and ran into reward hacking. - CME295 (Transformers & Large Language Models) and CME296 (Diffusion & Large Vision Models). My master's project is [Coversatio](https://www.manoletre.com/projects.md#coversatio), an AI interview simulator. I'm also working on [a paper on when AI helps learning](https://www.manoletre.com/projects.md#ai-and-learning). ## Why small models I got into small language models during my master's because of one question: what would a local tutor look like with no internet connection and little compute? A model that runs on the device you already have. Since then I've been teaching small models to [play chess](https://www.manoletre.com/projects.md#chessllm), to [write math animations](https://www.manoletre.com/projects.md#cs234), and to [answer questions over a government's documents that can't leave the country](https://www.manoletre.com/projects.md#drc-explorer). ## Math teacher To 11-year-olds and 16–17-year-olds. [What it taught me](https://www.manoletre.com/projects.md#teaching). While I was teaching, I coded [Hablo.pro](https://www.manoletre.com/projects.md#hablopro) on my evenings and nights, a tutor you learn languages with by talking. ## Founder I co-founded [Educo](https://www.manoletre.com/projects.md#educo) as ChatGPT came out. As the technical founder I built generative AI tools for schools, and we raised $100k from Platanus Ventures. ## From Colombia I'm inspired by what I see in Colombia and by the many opportunities I got. That's why I work on education: I want more people to get those chances. It's behind projects like [funding tech courses for young Colombians](https://www.manoletre.com/projects.md#techdalo) and [predicting how well Colombian schools do from satellite images](https://www.manoletre.com/projects.md#cs231n). ## Languages I speak Spanish, English and German fluently, and French pretty well. I'm learning Japanese, which is part of why I built [Hablo.pro](https://www.manoletre.com/projects.md#hablopro). My German was good enough to [teach math in it](https://www.manoletre.com/projects.md#teaching). ## Projects Full write-ups: [https://www.manoletre.com/projects.md](https://www.manoletre.com/projects.md) ### Now - [Coversatio: an AI interview simulator](https://www.manoletre.com/projects.md#coversatio) - [DRC Explorer: a fully local AI agent (LFM 2.5 2.6b)](https://www.manoletre.com/projects.md#drc-explorer) - [How AI assistance affects learning across Bloom's taxonomy](https://www.manoletre.com/projects.md#ai-and-learning) - [ChessLLM: teaching small models to play chess](https://www.manoletre.com/projects.md#chessllm) - [brief: a shared memory that keeps you accountable](https://www.manoletre.com/projects.md#brief) - [explainer-video: A Claude Code skill that turns a paper into a narrated explainer video.](https://www.manoletre.com/projects.md#explainer-video) ### Stanford coursework - [Teaching a small model to make math animations](https://www.manoletre.com/projects.md#cs234) - [Predicting school performance from satellite imagery](https://www.manoletre.com/projects.md#cs231n) - [Predicting when a small LLM hallucinates](https://www.manoletre.com/projects.md#cs229) ### Before Stanford - [Hablo.pro: a voice-first language tutor](https://www.manoletre.com/projects.md#hablopro) - [Educo: generative AI for teachers](https://www.manoletre.com/projects.md#educo) - [Math teacher](https://www.manoletre.com/projects.md#teaching) - [Techdalo: financing technical education for Colombian youth](https://www.manoletre.com/projects.md#techdalo) ## Contact - Email: [hi@manoletre.com](mailto:hi@manoletre.com) - CV (PDF): [https://www.manoletre.com/cv.pdf](https://www.manoletre.com/cv.pdf) - GitHub: [github.com/manoletre](https://github.com/manoletre) - Hugging Face: [huggingface.co/manoletre](https://huggingface.co/manoletre) - LinkedIn: [linkedin.com/in/manoletre](https://www.linkedin.com/in/manoletre) - X: [@manoletre_](https://x.com/manoletre_) --- # Projects by Manuel Cárdenas Prieto > Small-model fine-tuning, AI agents, and research on AI and learning at Stanford. Previously an EdTech founder and math teacher. ## Now ### Coversatio: an AI interview simulator I benchmarked speech-to-text, text-to-speech, and LLM combinations to find the best balance of quality, latency, and cost. I also built the harness the interview agent runs on: an interviewer LLM paired with a validator LLM that keeps the interview on track. [Try a behavioral interview](https://coversatio.com/demo/behavioral). ### DRC Explorer: a fully local AI agent (LFM 2.5 2.6b) With [Prof. Jef Caers](https://profiles.stanford.edu/jef-caers), I'm building an agent that helps the government of the Democratic Republic of Congo (DRC) navigate 505 mining contracts and 4,618 ministerial legal acts. The documents can't leave the country's own hardware, so every model runs locally. I first built a 150-question benchmark to compare models on accuracy and speed, which led us to LFM-2.5-2.6B. Liquid's d1-ultra decision model grades the answers, with a code check on citations. I built the harness loop and created custom tools for this small model to navigate the full corpus. It answers about a third of the benchmark: around 60% of the simpler questions (finding a contract, reading one document), but almost none of the questions that combine several documents. I'm now fine-tuning it on exactly those. ### How AI assistance affects learning across Bloom's taxonomy I'm working on a paper with [Prof. Hari Subramonyam](https://profiles.stanford.edu/hariharan-subramonyam) that analyzes when generative AI supports learning and when it replaces the thinking you need to learn. We compare people working with and without AI at three levels of Bloom's taxonomy: understand, analyze, and create. Afterwards we test everyone without AI: how much they remember, whether they understood the causes, and whether they can apply what they learned to new problems. Our hypothesis: AI boosts learning on creative tasks, but hurts it on typical school tasks like summarizing or analyzing a system. I built the research platform the study runs on and developed the study materials, ready for up to 480 participants. ### ChessLLM: teaching small models to play chess My playground for learning post-training by doing it. I started with LFM2.5-1.2B solving puzzles: SFT, then GRPO with a curriculum and a process reward from a tagger I trained to fact-check its reasoning ([try the tagger](https://www.manoletre.com/chess/tagger)). Every version topped out near 15% of puzzles (and RL learned to game the reward), so I switched to Liquid's d1 decision models, trained with DAgger and with SFT on millions of Stockfish-labelled positions. The best so far, d1-omni-600M, beats Stockfish at 1700 Elo 62.5% of the time with a small search, and solves 60% of my puzzle benchmark. [Play chess against it](https://www.manoletre.com/chess/d1) in your browser. I wrote up [everything I tried and what worked](https://www.manoletre.com/chess.md). The models are on Hugging Face ([chess model](https://huggingface.co/manoletre/d1-omni-600M-chess), [tagger](https://huggingface.co/manoletre/chess-move-tagger)) and the code on GitHub ([chessLLM](https://github.com/manoletre/chessLLM), [tagger](https://github.com/manoletre/chess-moves-from-text)). ### brief: a shared memory that keeps you accountable I run several agents a day (grok bot, claude code, “normal” claude, etc.). Brief is a local MCP server they all write to: what I decided, built, got stuck on or learned. Every morning, Brief starts an agent using my local claude CLI and compares that log with my objectives and writes me a blunt brief: what to do more of, less of, or stop, plus what to do today and some paper or article recommendations based on my work + objectives. Everything stays on my Mac. [It's open source](https://github.com/manoletre/brief). ### explainer-video: A Claude Code skill that turns a paper into a narrated explainer video. It researches the paper or source that I mention, writes the script, animates it with ManimGX and voices it offline with LFM2.5-Audio, keeping the take whose transcript best matches the script. I use it to learn and understand the methods I try in my projects. [Get the skill on GitHub](https://github.com/manoletre/explainer-video), or watch two videos it made: [DAgger](https://github.com/manoletre/explainer-video/releases/download/v0.1.0/DAggerExplainer.mp4) and [Self-Evolving Curriculum](https://github.com/manoletre/explainer-video/releases/download/v0.1.0/SECExplainer.mp4). ## Stanford coursework ### Teaching a small model to make math animations *CS234 · Reinforcement Learning* I trained Qwen2.5-Coder-3B to turn a plain-language brief into [Manim](https://www.manim.community/) code, the library behind 3Blue1Brown's videos. Out of the box, only 2.5% of its code rendered into a video. I built the instruction dataset, then generated examples with gemini-3-flash to improve the model manim generation via SFT, then ran DPO on preference pairs sampled from the SFT model. Together, SFT and DPO raised the share of code that actually renders into a video 10×, from 2.5% to 25%. More in [the poster](https://www.manoletre.com/CS234_-_Poster.pdf) and [the code](https://github.com/manoletre/cs234). ### Predicting school performance from satellite imagery *CS231n · Deep Learning for Computer Vision* I collected close-up and wide-area satellite imagery for every high school in Colombia, fixing wrong official coordinates along the way. Then I fine-tuned two vision transformers, combined by a stacking model, to predict whether a school scores above average on Colombia's national exam. It's right 75% of the time, and 66% when comparing only schools with similar socioeconomic backgrounds. More in [the poster](https://www.manoletre.com/cs231n-final-poster.pdf) and [the code](https://github.com/manoletre/cs231n). ### Predicting when a small LLM hallucinates *CS229 · Machine Learning* With Carl Liu, I trained classifiers that predict when Liquid AI's LFM2-1.2B hallucinates. We quizzed it on [TriviaQA](https://huggingface.co/datasets/mandarjoshi/trivia_qa) and recorded its attention activations, final-layer signals and token probabilities for every answer. Token probabilities were the most accurate signal. We also looked at which of these signals are still available when the model is quantized, which matters if you want to use the classifier in deployment. More in [the poster](https://www.manoletre.com/CS229_poster_4x3_final.pdf) and [the code](https://github.com/manoletre/cs229-project). ## Before Stanford ### Hablo.pro: a voice-first language tutor My mom wanted to practice English, I wanted to practice Japanese, and OpenAI had just released its first realtime voice model. So I built a tutor you learn languages by talking. [Open hablo.pro](https://hablo.pro/) to try it. It launched as the [#1 education product of the week on Product Hunt](https://www.producthunt.com/products/hablo-pro) and won its first paying subscribers. I paused the project when I started at Stanford. It taught me how to ship a consumer product, listen to users, and build software that actually teaches. [The code is on GitHub](https://github.com/manoletre/hablopro-speak). ### Educo: generative AI for teachers As the technical founder I built generative AI tools for schools, from a lesson-planning assistant for teachers to a WhatsApp tutor for students that gained early traction. We raised $100k from [Platanus Ventures](https://platan.us), a Chilean accelerator that backs ~1% of applicants. After a year and a half I moved on, with a hard-earned lesson in selling to schools, where the buyer (the principal) isn't the user (teachers and students). ### Math teacher I learned how to hold the attention of an audience that will do anything but listen. I loved teaching and seeing the impact of my work first hand. ### Techdalo: financing technical education for Colombian youth Alongside my CS degree, I co-founded Techdalo. We raised $15k to fund technical courses for young Colombians, then helped them land jobs afterwards. I led an international team of 11 volunteers: 3 in Colombia and 8 in Germany. --- # Teaching chess to small language models > Teaching small models to play chess: SFT, GRPO with a curriculum and a process reward, then Liquid's d1-omni-600M, which beats Stockfish 1700 62.5% of the time with a small search. - [./play](https://www.manoletre.com/chess/d1): play against a finetuned d1-omni-600M - [./tagger](https://www.manoletre.com/chess/tagger): extract chess data out of plain text - [puzzles](https://huggingface.co/datasets/manoletre/chess-puzzles-1k): my benchmark: 1,000 Lichess puzzles, balanced by theme and difficulty - [model](https://huggingface.co/manoletre/d1-omni-600M-chess): d1-omni-600M-chess on Hugging Face - [tagger](https://huggingface.co/manoletre/chess-move-tagger): chess-move-tagger on Hugging Face ## tl;dr I've been teaching small models to play chess. I started with an LLM that reasons before every move (SFT, then GRPO with a curriculum and a process reward), hit a ceiling on my [puzzle benchmark](https://huggingface.co/datasets/manoletre/chess-puzzles-1k), and switched to training Liquid's d1 decision models, where I needed less data and compute to get good results. How my finetuned d1-omni-600M [performs](https://www.manoletre.com/chess/d1): | mode | puzzles | vs sf-1320 | sf-1500 | sf-1700 | sf-2000 | | --- | --- | --- | --- | --- | --- | | one forward pass | 40.9% | 61.3% | 18.8% | 12.5% | 5.0% | | 4-ply search (~0.3 s/move) | 58.9% | 87.5% | 78.8% | 62.5% | 35.0% | Puzzles: share of the 1,000 puzzles in [my benchmark](https://huggingface.co/datasets/manoletre/chess-puzzles-1k) solved to the end. Games: score over 40 games per opponent from balanced positions after move 5; sf-N is Stockfish limited to N Elo. The search keeps the model's top 3 moves at each of 4 plies and scores the leaves with its own value head. ## every model I finetuned, on the [puzzles benchmark](https://huggingface.co/datasets/manoletre/chess-puzzles-1k) I built the benchmark from the [Lichess puzzle database](https://database.lichess.org/#puzzles): 1,000 puzzles, 20 for each of 50 themes (mating patterns, tactics, endgames, mates in 3 to 5), spread evenly over five difficulty bands from a 399 to a 2792 rating. None of them comes from a game I trained on, so every model faces positions it has never seen. It's [on Hugging Face](https://huggingface.co/datasets/manoletre/chess-puzzles-1k). ``` LFM2.5-1.2B, prompted 1.5% █ + SFT 6.7% ███ + GRPO 13.0% █████ + curriculum GRPO 15.4% ██████ d1-3B, LoRA SFT 16.2% ██████ d1-omni-600M, DAgger 28.2% ███████████ d1-omni-600M, fresh SFT 40.9% ████████████████ + 3-ply search 60.2% ████████████████████████ ``` ## part 1: an LLM that reasons before it moves The first model I trained was LFM2.5-1.2B-Instruct, playing through tools: it asks for the board and the legal moves, writes a short reflection, then makes a move. SFT on 24k full puzzle conversations taught it that protocol (0% → 100% valid tool calls) and took puzzles from 1.5% to 6.7%. Then GRPO: +1 for the right move, 0 for a wrong one, −0.5 for an illegal one. Puzzles doubled to 13.0% and illegal moves almost disappeared. After ~300 steps it plateaued, and the model stopped exploring: 8 samples of the same position gave 1.7 different moves. I thought the model was getting to hard positions too soon, so I tried a curriculum: four stages, from easy to hard. It reached 15.4%, my best number with an LLM. But when I read the reflections, they had collapsed into one template: 91% claimed a mate, in puzzles where 6% had one. Since it had stopped exploring, I raised the temperature. The reflections turned into garbage (at the temperature that scored best, 87% were garbled text) and a move still came out at the end. That's when I understood the reflections had never meant much: the model picked a move, and the reflection didn't match the choice. So I tried rewarding reflections that are true. I trained a [tagger](https://www.manoletre.com/chess/tagger), LFM2.5-Encoder-230M as a token classifier, that finds every move, square and claim in a reflection, and checked each claim with python-chess. False facts fell from 53% to 24% and self-contradictions from 39% to 5%, but puzzles stayed at 13.4%. And RL kept finding ways around the reward. I closed one hole and it found the next: the last one dismissed every alternative with lines like “lets White consolidate”, true of any wrong move. It became a cat-and-mouse game, and I don't have the compute to play it. ## part 2: a decision model In October Liquid released d1, models that score a list of options instead of writing text. A d1 question over the legal moves is a policy; a question over ten win-chance bins is a value head. So I could train on Stockfish's full ranking of moves for millions of positions. First, the dumb baseline. d1-3B solved 36.5% of puzzles out of the box, which looked amazing until a rule that only reads the + and # marks in the move names scored 36%. With plain UCI moves it was at chance. SFT with LoRA on 120k Stockfish-labelled positions (KL to the engine's move distribution) got d1-3B to 16.2%. RL from games on top stayed flat for 28 iterations. DAgger worked: play games, have Stockfish label the positions the model actually reaches, train on them, repeat. Four rounds cut the win chance lost per move by 30% (4.63 → 3.26 points). d1-omni-600M trains about 5× faster, so a night fits 11 DAgger rounds: 2.86 points lost per move and 28.2% of puzzles. A small search on top more than tripled its score against Stockfish 1320 (21% → 69%). Then fresh data beat more DAgger. The last run trained 9 rounds on ~1.6M positions it had never seen, from Lichess's evaluation database plus new games Stockfish labelled on the VM's CPUs while the GPU trained. Loss per move fell from 2.86 to 2.23, puzzles from 28.2% to 40.9% without search, and it was still improving when time ran out. [Play against it](https://www.manoletre.com/chess/d1). ## what I learned - Read the samples, not only the metrics. A temperature that looked best wrote garbled text 87% of the time. - Always compare with the dumbest baseline you can think of. - RL optimizes the scorer, not what you meant. Never reward a fact that is trivially true. - Fresh data beats clever rewards and extra epochs at this scale. - Search on top of a decent policy is cheap strength. I made narrated explainers of two methods I used, with my [explainer-video](https://www.manoletre.com/projects?open=explainer-video) skill: [DAgger](https://github.com/manoletre/explainer-video/releases/download/v0.1.0/DAggerExplainer.mp4) and [Self-Evolving Curriculum](https://github.com/manoletre/explainer-video/releases/download/v0.1.0/SECExplainer.mp4).