<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kavyansh wadhwa</title>
    <description>The latest articles on DEV Community by kavyansh wadhwa (@kavyansh_wadhwa_204108db8).</description>
    <link>https://dev.to/kavyansh_wadhwa_204108db8</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4132036%2F2b2b2107-4fbb-4e7a-890e-ece9c18a360c.png</url>
      <title>DEV Community: kavyansh wadhwa</title>
      <link>https://dev.to/kavyansh_wadhwa_204108db8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kavyansh_wadhwa_204108db8"/>
    <language>en</language>
    <item>
      <title>Birdjournal: Identify Birds by Sound, Offline, with Open-Source AI</title>
      <dc:creator>kavyansh wadhwa</dc:creator>
      <pubDate>Sun, 11 Oct 2026 17:33:43 +0000</pubDate>
      <link>https://dev.to/kavyansh_wadhwa_204108db8/birdjournal-identify-birds-by-sound-offline-with-open-source-ai-246e</link>
      <guid>https://dev.to/kavyansh_wadhwa_204108db8/birdjournal-identify-birds-by-sound-offline-with-open-source-ai-246e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;birdjournal&lt;/strong&gt; is an offline bird-call field journal. You record birds on a walk with your phone, put the phone away, and listen. Later it names the species from sound and writes a short journal entry about the walk.&lt;/p&gt;

&lt;p&gt;The screen is the shortest part of the experience: record, go outside, look up, and check the journal afterwards. It's for beginner birdwatchers and anyone who hears a bird and wants to know what it is, with or without a signal. It can write the journal in English, Hindi or Punjabi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;I tested it on a 46-second recording of a Coppersmith Barbet from Sikar, Rajasthan, taken from Xeno-canto (recordist: Dipendra Maharshi, &lt;a href="https://xeno-canto.org/123456" rel="noopener noreferrer"&gt;XC123456&lt;/a&gt;, licensed &lt;a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;CC BY-NC-SA 4.0&lt;/a&gt;; used unmodified as a test input, not redistributed). Real output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Species heard: 1
  Coppersmith Barbet           x16  best 100%  first at 0s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;BirdNET detected the barbet at 100% confidence in all 16 of its 3-second windows, with the location filter set to Sikar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmlgmvoobo0ua6cnlep73.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmlgmvoobo0ua6cnlep73.jpeg" alt=" " width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outdoor test:&lt;/strong&gt; I haven't done a full field walk yet. The next step is a sunrise recording near Patiala to see how it handles real background noise.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/kavyansh-1" rel="noopener noreferrer"&gt;
        kavyansh-1
      &lt;/a&gt; / &lt;a href="https://github.com/kavyansh-1/Bird-Journal" rel="noopener noreferrer"&gt;
        Bird-Journal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🐦 birdjournal&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;An offline bird-call field journal.&lt;/strong&gt; Record birds on a walk, put the phone away, and let open-source AI tell you who was singing, with no internet, no account and no cloud.&lt;/p&gt;

&lt;p&gt;Built for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge, Week 1: Touch Grass&lt;/a&gt;.&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ python main.py barbet.wav --place "Sikar, Rajasthan" --lat 27.6 --lon 75.14 --out test.md
Species heard: 1
  Coppersmith Barbet           x16  best 100%  first at 0s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt; phone recording (.wav/.mp3)
          |
          v
   BirdNET (open source)  ---- geo filter (lat/lon) removes species that don't live nearby
          |
          v
   species list + confidence
          |
          v
   local LLM via Ollama (open weights)
          |
          v
   short field-journal entry (English / Hindi / Punjabi ...)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The idea is that the screen is the shortest part of the experience. You go outside, record, and listen. The tool does its work afterwards.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Open-source pieces&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table&gt;

&lt;thead&gt;

&lt;tr&gt;

&lt;th&gt;Piece&lt;/th&gt;

&lt;th&gt;Role&lt;/th&gt;

&lt;/tr&gt;

&lt;/thead&gt;

&lt;tbody&gt;

&lt;tr&gt;

&lt;td&gt;&lt;a href="https://github.com/birdnet-team/BirdNET-Analyzer" rel="noopener noreferrer"&gt;BirdNET&lt;/a&gt;&lt;/td&gt;

&lt;td&gt;Identifies species from sound. Runs&lt;/td&gt;

&lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;&lt;/div&gt;…&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/kavyansh-1/Bird-Journal" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Released under the MIT License.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BirdNET&lt;/strong&gt; is an open-source bird-sound classifier. I used its &lt;code&gt;litert&lt;/code&gt; backend, so TensorFlow isn't needed and it can run on a Raspberry Pi. Its geo model takes your latitude and longitude and drops species that don't live near you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An open-weight LLM through Ollama&lt;/strong&gt; writes the journal. The default is Qwen2.5 3B, and &lt;code&gt;--model&lt;/code&gt; swaps it for any other local model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python glue&lt;/strong&gt;: &lt;code&gt;detector.py&lt;/code&gt; runs BirdNET and groups detections by species, &lt;code&gt;journal.py&lt;/code&gt; prompts the local LLM, and &lt;code&gt;main.py&lt;/code&gt; is the command-line tool. If Ollama isn't running, it still prints the species list and a plain summary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What went wrong:&lt;/strong&gt; My first prompt let the small model invent facts that weren't in the detections, such as calling the barbet "colorful and melodious" (its call is closer to a steady "tuk-tuk-tuk"). It also said "heard 16 times" when it meant 16 three-second windows. I tightened the prompt to three first-person sentences using only the listed facts.&lt;/p&gt;

&lt;p&gt;I also ran the whole pipeline with &lt;strong&gt;Gemma 3 4B&lt;/strong&gt; locally through Ollama, using the same code and one flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py barbet.wav &lt;span class="nt"&gt;--place&lt;/span&gt; &lt;span class="s2"&gt;"Sikar, Rajasthan"&lt;/span&gt; &lt;span class="nt"&gt;--lat&lt;/span&gt; 27.6 &lt;span class="nt"&gt;--lon&lt;/span&gt; 75.14 &lt;span class="nt"&gt;--model&lt;/span&gt; gemma3:4b &lt;span class="nt"&gt;--out&lt;/span&gt; test_gemma.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3gzc3lfeu79vmqsp1jw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3gzc3lfeu79vmqsp1jw4.png" alt=" " width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first Gemma run had two bugs: it wrote a literal "N" instead of a number, and it called a 100% detection "uncertain". I moved the confident/uncertain decision into code and tightened the prompt. The second run was clean, with one slip: it says "16 Coppersmith Barbets" when it means 16 three-second windows of audio. A 4B model can follow rules but still blurs this kind of detail, which is why I treat the journal as a rewrite of BirdNET's output and not as the source of truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Works with no signal.&lt;/strong&gt; The models are about 77 MB and 46 MB, downloaded once and cached. After that, the trail needs no internet. A cloud bird-ID app can't do that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your recordings stay on your machine.&lt;/strong&gt; No audio is uploaded anywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free to run.&lt;/strong&gt; There are no per-call API fees, so you can record all morning without worrying about cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could fix it myself.&lt;/strong&gt; When the journal model started making things up, I changed the prompt and could swap the model with one flag. With a closed API, I'd be stuck with whatever it gave me.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limits:&lt;/strong&gt; BirdNET is trained on more data from Europe and North America than South Asia, so expect misses. One loud, clean clip is an easy test, not a measure of accuracy. The journal only rewrites BirdNET's output, so check it against what you actually saw.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;Best Use of Gemma&lt;/p&gt;

</description>
      <category>ai</category>
      <category>hacktoberfest</category>
      <category>machinelearning</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
