<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Tanya Khanna on Medium]]></title>
        <description><![CDATA[Stories by Tanya Khanna on Medium]]></description>
        <link>https://medium.com/@tktanya897?source=rss-10429f82599b------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Stories by Tanya Khanna on Medium</title>
            <link>https://medium.com/@tktanya897?source=rss-10429f82599b------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 03:11:15 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@tktanya897/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[The bug that costs patients blood: building a network that can’t double-promise a unit]]></title>
            <link>https://medium.com/@tktanya897/the-bug-that-costs-patients-blood-building-a-network-that-cant-double-promise-a-unit-791be02e207e?source=rss-10429f82599b------2</link>
            <guid isPermaLink="false">https://medium.com/p/791be02e207e</guid>
            <dc:creator><![CDATA[Tanya Khanna]]></dc:creator>
            <pubDate>Mon, 29 Jun 2026 20:59:00 GMT</pubDate>
            <atom:updated>2026-06-29T20:59:00.534Z</atom:updated>
            <content:encoded><![CDATA[<p>I created this piece for the purposes of entering the H0 Hackathon with Vercel and AWS Databases. #H0Hackathon</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cpIeVjD4_tV0M-ZQrMGgMQ.png" /></figure><p>In January 2026, the American Red Cross declared a severe blood shortage. National supply fell about 35 percent in a single month, and some hospitals were down to less than a two-day reserve.</p><p>That number is scary on its own. But the part that reframed the problem for me was this:</p><p>Sometimes, the right unit already exists somewhere in the network.</p><p>It just gets promised to two hospitals at once.</p><p>Nobody has to be careless for this to happen. A hospital can submit a request. Another hospital can submit a request seconds later. The inventory dashboard may look fresh enough. The unit may appear available in both workflows.</p><p>And then one physical bag of blood has two promises attached to it.</p><p>That is the coordination failure I wanted to build against.</p><p>So I built <strong>Sanguine</strong>, a shared reservation layer for blood centers, hospital supply teams, and regional coordinators. When two facilities request the same scarce unit at the same moment, Sanguine confirms one reservation, reroutes the other request to the next compatible unit, and records every decision in an audit-ready log.</p><h3>Why I made it boring on purpose</h3><p>The flashier version of this project would have been a swarm of agents doing a dozen impressive things.</p><p>I deliberately did the opposite.</p><p>The entire value of Sanguine is one promise:</p><p><strong>A blood unit is never given to two hospitals at once.</strong></p><p>Everything else exists to make that promise true, visible, and testable.</p><p>That is why the headline metric in the app is not an abstract performance score. It is one operational number:</p><p><strong>Double-promised units: 0</strong></p><p>If that number ever rises, the system has failed.</p><h3>Watching the guarantee hold, and break</h3><p>Sanguine ships with two allocation engines and a toggle.</p><p>I fire the exact same surge at both.</p><p>In the legacy engine, two hospitals can end up with a promise for the same unit. The counter climbs.</p><p>Switch to Sanguine, run the same surge again, and the counter stays at zero.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rzLrZ9N2M5PyGHVvgiXAVg.png" /><figcaption>The legacy path double-promising a unit.</figcaption></figure><p>That contrast matters because correctness is hard to trust when it is only described in words.</p><p>It is one thing to say, “This system prevents double allocation.”</p><p>It is much stronger to show the unsafe version failing right next to the safe version holding under the same pressure.</p><p>That became the core of the demo.</p><h3>The choice underneath</h3><p>Sanguine runs on <strong>Amazon Aurora DSQL</strong>, a distributed SQL database with strong consistency.</p><p>That property is not a backend detail here. It is the product.</p><p>When two requests collide over the same scarce unit, the database ensures that exactly one write wins. The other request does not silently create a second promise. It is retried, rerouted, and recorded.</p><p>In other words, the dangerous thing is not handled by hope, timing, or application-layer optimism.</p><p>It is blocked by the infrastructure.</p><h3>The front door is plain English</h3><p>A clinician or coordinator should not have to fill out a complicated form during a shortage.</p><p>So the request interface accepts plain English.</p><p>Someone can type:</p><blockquote><em>half a dozen units of the universal donor type, as soon as possible</em></blockquote><p>Claude on Amazon Bedrock turns that into a structured request, and the allocation engine takes it from there.</p><p>The important part is that the AI is not the source of truth. It helps with intake. The database-backed reservation layer owns the guarantee.</p><h3>What I took away</h3><p>Every blood shortage is partly a supply problem.</p><p>But it is also a coordination problem.</p><p>You do not fix that with a prettier dashboard alone. You fix it by choosing infrastructure that makes the dangerous thing impossible, and then letting people see that guarantee hold under pressure.</p><p>The same pattern applies to any scarce, perishable resource that must never be double-allocated.</p><p>Blood is where it matters most.</p><p>Try it: <a href="https://sanguine-eight.vercel.app/">https://sanguine-eight.vercel.app</a></p><p>Built for the H0 Hackathon with Amazon Aurora DSQL and Vercel. #H0Hackathon</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=791be02e207e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I distilled a 20B model into 0.5B so my résumé could sing]]></title>
            <link>https://medium.com/@tktanya897/i-distilled-a-20b-model-into-0-5b-so-my-r%C3%A9sum%C3%A9-could-sing-4e83c7d2de7d?source=rss-10429f82599b------2</link>
            <guid isPermaLink="false">https://medium.com/p/4e83c7d2de7d</guid>
            <category><![CDATA[hugging-face]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[small-language-model]]></category>
            <category><![CDATA[large-language-models]]></category>
            <category><![CDATA[generative-ai]]></category>
            <dc:creator><![CDATA[Tanya Khanna]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 11:34:47 GMT</pubDate>
            <atom:updated>2026-06-15T12:18:07.631Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Apply like the main character: a résumé-to-music-video machine, all under 32B params. A weekend build for the Build Small Hackathon.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EkEI3v3-Vg4iYdelXmxJ2w.png" /></figure><h3><strong>Chapter Zero — the repetitive void</strong></h3><p>I graduated recently, and like a lot of people right now I’ve spent more hours than I’d like to admit inside the job-hunt loop: same PDF, same cover letter, tweak a bullet, hit <em>Apply</em>, refresh an inbox that doesn’t refresh back. The market is brutal and the feedback loop is mostly silence. It is, to use a technical term, <strong>a void</strong>.</p><p>Then I came across a hackathon whose entire premise made me laugh out loud, in a good way.</p><p>The pitch was basically: <strong>the pace of AI over the last year has been anxiety-inducing; let’s take things back to how they felt in 2021, when models were small enough to tinker with and the vibe was fun and hopeful. </strong>No giant LLM, no B2B SaaS. You get 32 billion parameters, total, and you either solve a real problem for someone you know or you build something whimsical.</p><p>I picked whimsical. <strong>Track 2 — An Adventure in Thousand Token Wood.</strong> The brief: build something delightful that wouldn’t exist without AI, where the AI is doing the fun thing, not just helping you build it. Joyful is the bar.</p><p>So I made the most unserious possible answer to the most serious problem in my life. If applying for jobs is a soul-flattening void, what if you applied like you were the <em>main character of a Broadway musical</em>?</p><h3><strong>The idea: Open to Work: The Musical</strong></h3><p>You drop in your résumé and a job description. You add your photo. Optionally you record ten seconds of your own voice. Then you drag one slider — the <strong>Sendability Slider </strong>— and the app writes you a custom parody song about wanting that exact job, composes the music, sings it (optionally in your voice), and lip-syncs the whole number to your headshot. Out comes a shareable music video.</p><p>The slider is the whole personality of the thing. It goes 1 to 10:</p><blockquote>- <em>1 — Actually Sendable </em>✅<em>:</em> clever, polished, lightly funny. You could genuinely attach it.<br>- <em>5 — LinkedIn Risky </em>⚠️<em>:</em> funny, exaggerated, still makes sense.<br>- <em>10 — HR Has Left the Chat </em>🔥<em>:</em> full unhinged parody. Desperation as an art form.</blockquote><p>Same résumé. One slider. The lyrics, the music, the vocal energy, and the on-screen drama all morph together as you drag it. The tagline I kept coming back to: from “here’s my résumé” to “here’s my application as a music video.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZH8T_rx1IJlw9JhK-9guLA.png" /></figure><h3><strong>The constraint that made it fun</strong></h3><p>Here’s the thing I didn’t expect: the 32B cap made the project better!</p><p>With a powerful API, the obvious instinct is to ask, “How do I write the best prompt?” But with a strict parameter budget, the question becomes much more interesting: what is the smallest model that can do each job, and how do you connect those pieces so the whole thing still feels magical?</p><p>And the timing felt real, not just like a hackathon theme. The industry has been shifting from chasing bigger parameter counts to chasing <em>performance per watt</em>: small, fast, local models that can actually run on everyday machines. NVIDIA researchers have even argued that <a href="https://arxiv.org/abs/2506.02153">small language models are the future of agentic AI</a>, and MarketsandMarkets projects the <a href="https://www.marketsandmarkets.com/Market-Reports/small-language-model-market-4008452.html">small language model market</a> to grow at around 29% CAGR through 2032.</p><p>So building under a hard parameter cap did not feel like building away from where AI is going. It felt like building toward it.</p><p>That gave me one rule: <strong>the entire experience should be able to run tiny.</strong> Not a tiny model bolted onto a big app, but tiny <em>end to end</em>.</p><h3><strong>How it actually works</strong></h3><p>Here’s the full pipeline. Every step runs inside the Hugging Face Space: ZeroGPU for the heavier stages, plain CPU for the tiny lyricist, and no external inference APIs. The final output is not stitched together from outside services. What you render is what the Space made.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G4fWVf65bKWBh6DfOTghEQ.png" /></figure><p>Six models, each picked to be the smallest practical tool for its part of the pipeline:</p><p><strong>🎼 Lyrics / Producer</strong><br><a href="https://huggingface.co/openai/gpt-oss-20b">gpt-oss-20b</a> — 21B parameters</p><p><strong>👀 Photo vibe read</strong><br><a href="https://huggingface.co/vikhyatk/moondream2">moondream2</a>–1.9B parameters</p><p><strong>🎤 Music + sung vocals</strong><br><a href="https://github.com/ace-step/ACE-Step">ACE-Step 1.5 turbo</a> — 2.0B parameters</p><p><strong>🔊 Vocal isolation</strong><br><a href="https://github.com/facebookresearch/demucs">demucs</a> — 0.08B parameters</p><p><strong>🎭 Lip-sync</strong><br><a href="https://github.com/OpenTalker/SadTalker">SadTalker</a> — ~0.2B parameters</p><p><strong>🗣️ Your-voice conversion</strong><br><a href="https://huggingface.co/Plachta/Seed-VC">seed-VC</a> — ~0.1B parameters</p><p>That’s ~25B in Full Mode — comfortably under the 32B cap. But the part I’m proudest of is Tiny Mode, where the same résumé → song → video pipeline runs at ≈2.8B params, every single model ≤4B, with zero calls to the 20B model. More on how that’s possible in a second, because this was the most interesting constraint-solving part of the build.</p><h3><strong>The Agent: a writer that critiques its own drafts</strong></h3><p>The lyrics aren’t one-shotted. The “Producer” (gpt-oss-20b) runs a small reflection loop:</p><blockquote><em>read the materials → set the sendability level → choose a genre → draft the lyrics → critique its own draft against the target tone → revise → pass style tags to the music model</em></blockquote><p>The critique step is the interesting one.</p><p>The model reads its own draft back and scores it against the slider target using a strict rubric: SCORE, KEEP, and FIX. Then it rewrites accordingly. The critic and the writer are the same model, just running under different system prompts.</p><p>So the loop becomes: <em>generate → evaluate → revise.</em></p><p>That loop made the outputs noticeably better. A level-2 draft that came out too zany gets pulled back. A level-9 draft that played it too safe gets pushed further off the rails.</p><p>A couple of unglamorous but essential details will be familiar to anyone who has built with LLMs:</p><p><strong>Structured output, plus a forgiving parser.</strong><br>The model is asked to return a clean GENRE / TITLE / LYRICS format, with [verse] and [chorus] tags. But small models drift. So the parser does not fail dramatically when the format wobbles. It tries to salvage the song, extract the useful parts, and keep the pipeline moving.</p><p><strong>Reasoning-channel handling.</strong><br>gpt-oss uses OpenAI’s <a href="https://github.com/openai/harmony">Harmony format</a>, where the model can produce internal reasoning before the final answer. For this project, I had to separate that from the actual output and keep only the performance. Otherwise, the model’s out-loud deliberation can leak into the lyrics, which is funny once and broken every time after.</p><p>Every loop is logged and shown inside the app under <strong>“Behind the scenes: the Producer’s trace.”</strong> I also published the full set of traces as a Hugging Face Hub dataset, so anyone can inspect how the model moves from draft to critique to revision.</p><h3>The Understudy: how a 0.5B model learned to do the 20B’s job</h3><p>This is the heart of Tiny Mode, and it is the trick I’d most want another builder to steal.</p><p>The 20B Producer writes great lyrics, but it needs a GPU. For <em>instant</em> previews, the kind where you drag the slider and the song rewrites in real time, I did not want to touch GPU quota at all. So I built an understudy: a model <strong>40× smaller</strong> that learned to imitate the Producer.</p><p>The technique is <a href="https://arxiv.org/abs/1503.02531"><strong>knowledge distillation</strong></a>: training a small “student” model to reproduce the outputs of a larger “teacher” model. It has a great lineage. Stanford’s <a href="https://crfm.stanford.edu/2023/03/13/alpaca.html">Alpaca</a> used a related recipe in 2023, fine-tuning LLaMA 7B on synthetic instruction-following data generated by a much larger model. Distillation has since become one of the practical ways teams turn smaller models into high-performing, cost-effective systems, often alongside quantization.</p><p>My version, concretely:</p><ol><li><strong>Synthetic data generation.</strong><br>The training set did not exist, so I had the teacher invent it. gpt-oss-20b wrote around 1,500 parody songs across 60 fictional careers, every genre, and every sendability level: a fully self-bootstrapped corpus.</li><li><strong>The student.</strong><br>Base model: <a href="https://huggingface.co/openbmb/MiniCPM4-0.5B"><strong>MiniCPM4–0.5B</strong></a> from OpenBMB. Half a billion parameters, and <em>not</em> a GPT. People keep assuming the small model is also OpenAI’s. It is not. The OpenAI model is only the teacher whose homework it studied.</li><li><strong>Parameter-efficient fine-tuning.</strong><br>Instead of retraining all 0.5B weights, I trained small <a href="https://arxiv.org/abs/2106.09685"><strong>LoRA</strong></a> adapter matrices, rank 16, on the linear layers and merged them back into the model. One A100, around 30 minutes, eval loss 0.718.</li><li><strong>Quantization + a CPU runtime.</strong><br>I quantized the merged model down to a 4-bit Q4_K_M <strong>GGUF</strong> and serve it through <a href="https://github.com/ggml-org/llama.cpp"><strong>llama.cpp</strong></a> on plain CPU. A few hundred megabytes, zero GPU.</li></ol><p>The payoff: in Tiny Mode, the Understudy replaces the 20B headliner entirely. You drag the fader, and a half-billion-parameter model running on CPU rewrites your song instantly. The whole pipeline drops to about 2.8B parameters.</p><p>One small, very real gotcha worth sharing: a 0.5B model <em>loves</em> to repeat itself. Because mine was trained on the teacher’s calibration examples, it would sometimes parrot memorized lines instead of writing from your résumé. The fix was a mix of decoding controls, including temperature, top-p, repeat penalties, and presence penalties, plus an <strong>anchor-echo detector</strong>. If the output matches a known memorized phrase, the app regenerates with a hotter temperature.</p><p>Tiny models need babysitting. That is part of the craft.</p><h3>The pit orchestra: turning words into a video</h3><p>Once the lyrics exist, four more small models put on the show.</p><p><a href="https://github.com/ace-step/ACE-Step"><strong>ACE-Step</strong></a> turns the lyrics into a full sung track using diffusion-based music generation. In simpler terms, it starts with noisy audio and gradually shapes it into music, guided by the lyrics and the style tags from the Producer. When the slider changes the tags, the <em>music</em> changes with the words.</p><p><a href="https://github.com/facebookresearch/demucs"><strong>demucs</strong></a> handles source separation. It splits the generated song into vocal and instrumental stems, so the lip-sync model can follow the voice alone instead of the entire track.</p><p><a href="https://huggingface.co/Plachta/Seed-VC"><strong>seed-VC</strong></a> is optional, but it is the part that makes the result feel personal. It performs zero-shot voice conversion, mapping the sung vocal onto <em>your</em> vocal timbre from a short sample, without training a new model for each user.</p><p><a href="https://github.com/OpenTalker/SadTalker"><strong>SadTalker</strong></a> animates your headshot using the vocal track, turning the song into a performance instead of just an audio file.</p><p>And off to the side, <a href="https://huggingface.co/vikhyatk/moondream2"><strong>moondream2</strong></a>, a tiny vision-language model, reads your photo and produces the “your headshot radiates…” one-liner.</p><h3>The war stories: because nothing small is actually easy</h3><p>If you only look at the parameter table, the system looks tidy.</p><p>It was not tidy.</p><p>A few scars from the build:</p><p><strong>ZeroGPU and ACE-Step did not get along.</strong><br>ZeroGPU reports torch.cuda.is_available() == True in the main process. ACE-Step then runs real CUDA checks during startup, which triggered an NVML assert and broke the GPU workers. The fix was to hide CUDA during initialization, then re-initialize the model fresh inside each GPU call. Not elegant, but necessary.</p><p><strong>transformers 5 builds models on the </strong><strong>meta device.</strong><br>ACE-Step’s quantizer calls .item() inside __init__, which the meta device does not allow. I had to patch that init path just to get the model to load cleanly.</p><p><strong>Dependency Tetris was very real.</strong><br>I originally wanted OpenBMB’s MiniCPM-V for the photo read, but it pins transformers ~4.44, which could not share an environment with the 4.57 version ACE-Step needed. That was a version conflict, not a model-quality problem. So the photo read moved to moondream2, and MiniCPM stayed where it mattered most: the Understudy.</p><p>This is the part of small-model building that does not fit neatly on a slide. Most of the weekend was not spent on the glamorous part. It was spent making older vision code, a diffusion music model, and a CPU-quantized LLM coexist inside one Gradio Space without setting each other on fire.</p><h3>What I actually took away from it</h3><p>I started this because the job hunt had me feeling like a cog feeding PDFs into a void. I finished it having distilled a 20-billion-parameter model down to something that runs on a laptop CPU and still makes me laugh.</p><p>The hackathon’s whole thesis, <em>take it back to when models were small enough to tinker with and the vibe was hopeful</em>, turned out to be right.</p><p>Working under a tight parameter budget did not feel like a limitation. It was the most fun I have had building in months. It forced sharper design decisions, kept the system inspectable, and produced something I would actually show a friend.</p><p>Also, I now have a level-10 drill song about my own résumé.</p><p>I am going to post it on LinkedIn, because the platform is the punchline.</p><blockquote><em>🎬 </em><strong><em>Try it yourself:</em></strong><em> </em><a href="https://huggingface.co/spaces/build-small-hackathon/open-to-work-musical"><em>Open to Work: The Musical</em></a><em> · 🐜 </em><a href="https://huggingface.co/tanya8997/openwork-understudy-0.5b"><em>the Understudy model</em></a><em> · 📡 </em><a href="https://huggingface.co/datasets/tanya8997/openwork-producer-traces"><em>the Producer’s trace dataset</em></a></blockquote><h3>Thank you</h3><p>Thank you to <strong>Hugging Face</strong> and <strong>Gradio</strong>, the organizers of the Build Small Hackathon, for a prompt that made small models feel exciting again.</p><p>The theme, <em>“take it back to when models were small enough to tinker with,”</em> genuinely shaped the build. Spaces gave the project a home, ZeroGPU made the heavier stages possible without hiding everything behind external APIs, and Gradio made it easy to turn the whole pipeline into something people could actually touch, test, and play with.</p><p><em>Built over a weekend for the Build Small Hackathon, Track 2: Thousand Token Wood. Stack: gpt-oss-20b, MiniCPM4–0.5B, ACE-Step, demucs, SadTalker, seed-VC, and moondream2, all under 32B and running inside one Hugging Face Space.</em></p><h3>Further reading</h3><ul><li><a href="https://arxiv.org/abs/1503.02531">Distilling the Knowledge in a Neural Network</a> — Hinton, Vinyals, and Dean on knowledge distillation</li><li><a href="https://arxiv.org/abs/2106.09685">LoRA: Low-Rank Adaptation of Large Language Models</a> — Hu et al. on parameter-efficient fine-tuning</li><li><a href="https://arxiv.org/abs/2506.02153">Small Language Models are the Future of Agentic AI</a> — Belcak et al. on why SLMs fit agentic systems</li><li><a href="https://crfm.stanford.edu/2023/03/13/alpaca.html">Stanford Alpaca</a> — an early example of fine-tuning a smaller model on synthetic outputs from a larger model</li><li>Project tools: <a href="https://github.com/ggml-org/llama.cpp">llama.cpp</a>, <a href="https://github.com/ace-step/ACE-Step">ACE-Step</a>, <a href="https://github.com/OpenTalker/SadTalker">SadTalker</a>, and <a href="https://github.com/facebookresearch/demucs">demucs</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4e83c7d2de7d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>