Riyaz with a machine
I wanted an AI practice companion for surbahar and sitar, and the model kept making things up about raags it barely knew. Fixing that meant giving it a library of 1,385 Wikipedia articles to look things up in before it answers, and nobody had built one for this music before.
The short version is this. I built a practice companion for Hindustani classical music that runs on my own computer, and I gave it a library of 1,385 Wikipedia articles about raags, talas, instruments and gharanas to look things up in before it answers, so that it would stop making up the grammar of raags. Nothing about it leaves the house, it knows the Dagarvani bani and the Etawah gharana, and it says where its answers came from. As far as the literature goes, nobody had done this before.
Table of contents
- The practice context
- The model that made things up
- Why the music has always been hard to digitise
- What I built
- Getting retrieval right
- Two models, two voices
- Before and after
- Nobody had done this
- What it isn’t
- Five in the morning
- Source code
The practice context
I play surbahar and sitar. The surbahar is the bass version of the sitar (a larger instrument, a lower register, and much slower music), built for the kind of unhurried aalap, the opening of a raag with no beat under it, that can take an hour to reach the middle octave. I practise in the Dagarvani bani, the tradition associated with the Dagar family, which treats that unmeasured opening as the heart of the music rather than a preamble to it. On the khayal side (the more common Hindustani vocal form, adapted here for instrumental playing), I practise in the Etawah gharana, also called the Imdadkhani gharana, whose lineage descends from Imdad Khan and his son Inayat Khan and runs through Vilayat Khan and Imrat Khan. A gharana is a school, a line of teachers and students with its own way of doing things, and a bani is the dhrupad word for the same idea.
The instrument, the bani and the gharana are the grammar of how I approach a raag, which is why they matter for what follows. None of them is an interchangeable detail, and the same raag treated in the Dagarvani way has a different character and different priorities from the same raag treated in the way two other schools, Kirana or Agra, would treat it. When I practise Bhimpalasi on the surbahar, I’m exploring the personality of that raag through the particular lens of a tradition that has been passed from teacher to student, by ear, for several generations, which is a different thing from practising a scale with some ornamentation guidelines.
A practice companion needs to understand this to be useful, since a tool that just knows Bhimpalasi belongs to the Kafi thaat and has komal Ni is a dictionary and not a guide.
The model that made things up
Earlier this year I began experimenting with using a language model as a practice journal. A language model is the kind of program behind the chat assistants everyone now uses, which has read a very large amount of text and answers by predicting what should come next, and this one ran on my own machine rather than on a company’s servers. After a session I wanted somewhere to describe what I’d worked on, what felt right and what slipped, and to have something intelligent to think alongside that would remember previous sessions and ask useful questions. I wasn’t looking for a teacher.
The model I was running was qwen3.6:27b. The name says most of what matters. Twenty-seven billion parameters are the numbers inside the model that its training settled, which makes it a mid-sized model by today’s standards, and it was quantised to four bits, meaning each of those numbers is stored in four bits rather than sixteen, so that the whole model shrinks to a quarter of its size and fits on my graphics card, at a small cost in accuracy. It is capable of remarkable things. But the first serious test produced something disturbing. I asked it to walk me through the grammar of Raag Bhimpalasi, the vadi and samvadi swaras (the note the raag rests on and its partner), the characteristic phrase structure, and the treatment of komal Ni, the flattened seventh, in the Dagarvani approach.
The response was confident and mostly wrong. The aroha it gave me, the way up the scale, belonged to a different raag, the vadi was misidentified, and the guidance on ornaments sounded plausible and was wrong. I asked about Marwa (one of the more demanding raags in the late afternoon repertoire, with its sharpened Ma and flat Re, the careful avoidance of Pa, and the way the raag builds tension through what it withholds) and the response was worse. Darbari Kanada, the late-night raag that tradition traces to Tansen, came back garbled in ways that were internally consistent and factually wrong. This kind of confident invention has a name, hallucination, and it is the standing weakness of these models. They are built to produce fluent text, and fluent text comes out whether or not the facts are there to support it.
In music practice, wrong information is more than an inconvenience - it can actively degrade what you’re trying to build. A model that confidently tells you the vadi is Sa when it is Ma is worse than no model at all. Rather than abandon the experiment, I wanted to fix it.
Why the music has always been hard to digitise
Most of the music hasn’t been digitised. Language models absorb what’s abundant in their training data, and Western music theory is everywhere - textbooks, forums, Wikipedia, software documentation, YouTube transcripts, and millions of blog posts. Hindustani classical music hasn’t been transmitted that way. Its primary mechanism has always been the guru-shishya relationship, where a student learns from a teacher in person over years or decades. The technical vocabulary exists in texts (Vishnu Narayan Bhatkhande’s Kramik Pustak Malika, the Sangit Ratnakar, and numerous Urdu and Hindi treatises), but these are largely untranslated, not digitised, and outside the training corpus. What a model learns about Indian classical music is a thin impression of the broad shape of the tradition, some famous names, and a few raags by title. The grammar of those raags, which is what actually matters for practice, is where the knowledge gets sparse and the model starts generating plausible-sounding, made-up detail.
A paper published in June 2026 did the first systematic evaluation of language models on Hindustani classical theory. It tested thirty-three models on 504 questions covering raag grammar, thaat classification, tala systems, and compositional reasoning. The large cloud-based models from the big labs scored eighty-five to ninety percent, whereas smaller models of the kind that run on one machine scored considerably worse. The paper described the failure precisely and offered no fix. I found it while building the thing described here.
What I built
The approach is called retrieval-augmented generation, and the idea is simple. Before the model answers a question, it searches a library of documents, retrieves the closest passages, and reasons from those rather than from its training alone, the way you would answer a question about a raag by opening the book rather than trusting your memory. If the library has accurate information about a raag’s grammar, the model cites and reasons from that. If the library doesn’t have something, it usually says so, which is better than inventing it.
The critical question was what to put in the library. I was sceptical of Wikipedia at first. But the major Hindustani raags have Wikipedia articles and many of them are surprisingly thorough (vadi and samvadi swaras, aroha and avaroha, pakad phrases, thaat classification, time of day, seasonal associations, characteristic ornamentation, and relationships to other raags). The coverage is uneven - some articles are detailed, others are thin stubs, and a handful of raags I work in have no article at all. But for the core repertoire the information is there and largely accurate. Beyond the raags themselves, Wikipedia covers the thaats, the melakarta system in Carnatic music, talas, instruments, gharanas, and individual musicians. Building a library from this means the model has context for the individual raags and for the web of relationships between them.
So I wrote a script to walk Wikipedia’s category system, starting from root categories like Ragas, Ragas of Hindustani music, Melakarta ragas, Indian musical instruments, Gharanas, Hindustani singers, Carnatic music composers, and twelve others. Wikipedia files every article under categories, and categories under categories, so walking the tree two levels down from each root gathers everything the encyclopaedia has on the subject without anyone listing the articles by hand. The script fetched the plain text of each article through the interface Wikipedia offers to programs, with four fetchers working in parallel and throttled so as not to hammer the servers. The final corpus came to 1,385 articles and roughly 650,000 words of cleaned text.
The whole thing runs on a desktop I built for this purpose (Ryzen 7 9850X3D, 32GB of DDR5, and an RX 9070 XT with 16GB of VRAM). VRAM is the graphics card’s own memory, and it is the number that matters most here, because a model has to fit into it to run at any speed. Ollama is the program that loads a model onto the card and answers requests to it, and Open WebUI is the chat window in front of it. There are two language models in use: qwen3.6:27b (27.8 billion parameters, four-bit quantisation, about 15.6GB on the card) for sessions where I want the model to think carefully, and qwen3:14b (14.8 billion parameters, about 8.6GB on the card) for faster everyday questions. The other thing that has to fit on the card is the context window, which is how much text the model can hold in mind at once, counted in tokens, and a token is a piece of a word, roughly three-quarters of one on average. The smaller model leaves enough room for a 32,768-token window, whereas the larger one is held to 24,576 tokens by storing its working memory of the conversation in fewer bits, so that it fits alongside the model itself. The embedding model runs on the processor rather than the card, kept separate so that neither language model loses memory to it. An embedding model turns a passage of text into a long list of numbers, placed so that passages with similar meanings land near each other, which is what lets a search find a passage by its meaning rather than by its exact words, and the one I use (BAAI/bge-m3) handles English, Devanagari and the Roman spelling of Sanskrit words alike. Embedding a single question on the processor takes about two seconds, which is perfectly acceptable before an answer that takes thirty. The whole thing is a handful of files, most of them configuration, and it’s all at the bottom of this page. It isn’t a package to install, but if you’re thinking of building something like it around your own practice, it’s there to take ideas from. What is there is the stack as it runs now, which has moved on from the build described here in two ways, the models are a newer generation and the raag knowledge reaches the model through a small tool server of its own, doing a plain keyword search over the articles.
Getting retrieval right
The retrieval uses hybrid search, which means two searches run at once. One is the search by meaning that the embedding makes possible. The other is a keyword search of the kind search engines used before any of this existed (BM25 is its name), which scores a passage on how often the exact words of the question appear in it. This matters for Indian classical music specifically, where the word vadi means a particular thing and samvadi means something related but distinct, hence the two aren’t synonyms and can’t be swapped. The search by meaning finds passages that are about the right thing, the keyword search finds passages containing the exact terms, and both are necessary.
Open WebUI rewrites each question as three shorter searches, runs the hybrid search for each, merges the results, and hands the best five passages to the model along with the question. The model reasons from those passages and cites them with numbered references.
During testing I found passages appearing twice in the search results with identical content and different database identifiers, and these exact duplicates were flooding the context window. The library is stored as chunks, the short pieces the articles are cut into for searching, and the process of adding them had run in two phases, an initial phase that partially populated the main collection and a consolidation phase that copied from staging collections without checking for duplicates. Scanning for chunks with identical (source file, character offset) pairs and deleting the redundant ones removed 5,482 duplicates, which brought the collection down from 12,560 to 7,078 unique chunks. At that point the retrieval started behaving cleanly.
Two models, two voices
There are two models in the interface, each with a distinct system prompt and configuration. A system prompt is a standing instruction the model reads before every conversation, which is where it is told who it is talking to and what it is for.
The Dhrupad guide knows the Dagarvani bani and the surbahar. Its system prompt references the tradition’s characteristic aesthetic - the long unhurried aalap, the weight given to the lower octave, and the gravity and patience that distinguish Dagar bani from other dhrupad traditions. It knows I play surbahar, which changes the practical advice, since on a bass instrument the guidance around meend (the glide between notes) and the constraints on gamak (the shake on a note) are different from sitar. This is where I take dhrupad practice sessions.
The Khayal guide knows the Etawah gharana (the lineage of Imdad Khan, Inayat Khan, Vilayat Khan, and their descendants) and understands the gayaki ang, the vocal style adapted for instruments that defines this gharana’s approach to khayal. This is where I take questions about bandish exploration and the characteristic phrasing of the Imdadkhani style.
Each persona runs in two versions. The deep reasoning version uses qwen3.6:27b with its chain-of-thought mode enabled, where the model works through the problem in writing before producing a visible answer, the way you would work a sum on paper before saying the result. That adds time but meaningfully improves accuracy on questions that require musical reasoning rather than simple retrieval. It runs at around 14 tokens per second (a token being a piece of a word, that is faster than you can read) and is best suited to sessions where I want to think carefully about a raag. The fast version uses qwen3:14b with reasoning off and generates at around 38 tokens per second, and it’s better suited to quick questions in the middle of practising. The 14B model also fits comfortably within VRAM at 32,768 tokens of context (about a third more than the 27B can safely hold), and that matters for longer sessions.
Before and after
The practical difference was immediate.
Before the knowledge base, a direct question about Bhimpalasi’s grammar returned something like this:
Without the knowledge base
Raag Bhimpalasi belongs to the Khamaj thaat. Its vadi is Gandhar (Ga) and the samvadi is Nishad (Ni). The aroha follows: Sa Re Ga Ma Pa Dha Ni Sa'. The raga is characterised by its use of shuddha swaras throughout and is performed in the afternoon hours...Most of the grammar in that passage is wrong. Bhimpalasi belongs to the Kafi thaat and not Khamaj, and its vadi is Madhyam (Ma) and not Gandhar. Both Re and Dha are left out on the way up, and Ni is komal and not shuddha, flattened and not natural. The model produces this with complete confidence and no signal that it might be wrong.
After building the knowledge base, the same question pulls from the Bhimpalasi Wikipedia article and the response cites its sources, which I can check. Here’s an edited excerpt from an actual session:
Session — June 2026
YouToday while practising aalap on surbahar on Bhimpalasi raag, I was noticing that I tend to repeat my phrases when I go back and forth between the octaves. While I understand that there are only a few phrases that can take me back or forward, how do I improvise such that it doesn't feel like direct repetition?
GuideIt is good to hear that you are spending time with Bhimpalasi. The observation about repetition during octave movement is a very common hurdle in developing vistar. In the Dagarvani tradition, the alap is not merely about playing notes, but about breathing into them — so that even the same swara feels different when approached with fresh intention.
In Bhimpalasi, whose vadi is Madhyam — Ma [1] — the challenge is that the melodic vocabulary can feel limited if one relies only on standard phrases. Repetition feels jarring because the listener expects an evolution of thought, not transposition.
Vary the gamak and meend application. Even if the swara sequence is identical — say, Ni Sa Ma — the physical execution on the surbahar can differ. A slow meend from Ni to Sa in one phrase can give way to a gamak-touched approach in the next. The note is the same; the texture is different. Shift the point of arrival. Instead of always returning to Sa as your resting point in the mandra saptak, try resting on Pa, or allow Ma to carry the phrase before ascending again...
The knowledge base raises the floor for the raags that are covered, but it doesn’t solve coverage. For Darbari Kanada, which has no recorded misidentification of its vadi now that the knowledge base is populated, the responses are accurate. Marwa is accurate too. For raags with thin or absent Wikipedia coverage (Charukeshi, Kalavati, Nand, Hem Kalyan, and several others), the model falls back on its training data and the old problem recurs.
The journaling function is where the system is most useful in practice. After a session I describe what I worked on (which raag, which passage of the aalap, where the phrasing kept collapsing, and what felt different), and the model connects that to what I’ve described in previous sessions, asks questions, and suggests something specific to focus on. Because the system prompt establishes the instrument, the tradition, and the gharana, the guidance is grounded, which is not a small thing. When it says something about aalap, it means the Dagarvani treatment of aalap. When it asks about meend, it knows the surbahar context.
Nobody had done this
After building it I went looking for prior work, expecting to find something.
Besides the June 2026 evaluation, which precisely described the failure modes I’d observed and offered no fix, there was a December 2025 paper that built a Wikipedia-filtered music retrieval database spanning global music across 163 countries (3.2 million passages from 144,000 articles, deployed on cloud infrastructure). It’s the same architecture in an entirely different domain. Stanford’s WikiChat system won the Wikimedia Research Award of the Year 2024 for using Wikipedia as a grounding corpus to reduce hallucination (97.9% factual accuracy in human-user testing).
For Hindustani or Carnatic music specifically (a Wikipedia corpus, run on one’s own machine, personalised to a specific instrument and gharana, and used as a riyaz journal), there was nothing - no paper, repository, or blog post. I can’t say with confidence whether that’s because the problem didn’t seem worth solving to the people who build these systems, or because the people who care deeply about the music and the people who build these systems rarely sit in the same room. It’s probably some of both.
What it isn’t
There are things this can’t do, and it would be wrong not to say them.
It can’t replace a teacher. The guru-shishya relationship is the mechanism by which this music has survived for as long as it has. It transmits judgment along with information (the ear that has heard thousands of hours of performance, the correction of a phrase that’s technically right but aesthetically wrong, and the sense of when a student needs to sit with something longer). None of that is in a language model, however well it retrieves Wikipedia.
It can’t transmit sruti, the fine placement of pitch below what notation can write down, which distinguishes a great performance of Darbari Kanada from a merely correct one. The tradition holds that sruti is demonstrated rather than described, and a language model can describe it but can’t demonstrate it.
It still hallucinates. When a raag is absent from the knowledge base or its Wikipedia article is thin, the model may produce confident prose that sounds right and isn’t. The response includes source citations when the knowledge base was used, hence the absence of citations is a signal to be more sceptical.
And it’s a text interface, which means it can’t hear me playing and correct my meend or notice that I’ve been avoiding the upper Sa in a raag that calls for it. For a practice companion, these are significant things to be missing.
Five in the morning
At five in the morning, before work, with the surbahar on the stand and a session still fresh, there’s something useful about having a place to be precise about the music. What goes there is a description of what I was trying in this passage, where it held, and where it slipped, rather than a recording or a notation. Putting that in language forces a clarity that helps the next session.
The knowledge base makes the model accurate enough to ask real questions of. The questions I bring to a session (which approach to the upper octave serves this raag better, what the characteristic phrase structure says about where to spend time in the aalap, and what a musician in this tradition has said about approaching the weaker notes) often have factual components. Getting those consistently right was the piece that was missing.
What’s there now is a well-read practice companion that knows the grammar of the music and remembers what I told it last time, which turns out to be a useful thing to have at five in the morning.