Inspiration
GreenNet The Offline AI Agronomist for Every African Farmer
Inspiration
Africa has over 36 million smallholder farmers. Most of them have never spoken to an agronomist in their lives.
Not because agronomists don't exist but because one agronomist serves thousands of farmers across vast rural distances, extension services are underfunded, and the advice that does exist is locked behind internet connectivity that most farming communities simply don't have.
I grew up watching this gap. A farmer loses half a cassava harvest to mosaic disease because nobody told them what the yellowing leaves meant. Another plants at the wrong time because there was no one to ask about the season. These aren't knowledge problems they're access problems. The knowledge exists. Getting it to the right person at the right moment doesn't.
That's what GreenNet is about. Not building AI for AI's sake. Building an AI that shows up where the internet doesn't.
What It Does
GreenNet is a fully offline AI agricultural assistant that runs on a \$200 laptop with no GPU, no cloud dependency, and no internet connection. A farmer can:
- Photograph a sick crop leaf and receive an instant disease diagnosis
- Ask questions in plain language English, Pidgin, or local phrasing and get specific, actionable advice
- Check treatment protocols with real costs quoted in Naira, sourced from a local knowledge base
- Query market price trends to make informed selling decisions
The entire system language model, vision classifier, vector database, and knowledge base runs locally and responds in seconds.
How I Built It
GreenNet is built as a four-layer system, each layer solving a problem the previous one can't solve alone.
Layer 1 Language Reasoning
The reasoning core is Qwen2.5 1.5B Instruct, quantized to Q4_K_M GGUF format and served through llama.cpp. This model was chosen specifically because:
- At Q4_K_M quantization, it occupies approximately 1.1 GB of RAM, leaving headroom on the 8 GB benchmark machine
- Qwen2.5 was trained with strong multilingual and instruction-following capability at this parameter count it understands Nigerian English, Pidgin phrasing, and context-switched queries without fine-tuning
- Generation runs at ~5.6 tokens/second on CPU-only hardware, fast enough for a streaming UI that feels responsive
Layer 2 Retrieval-Augmented Generation (RAG)
Raw language model knowledge is general. Nigerian farmers need specific which pesticide is available in Kano markets, how much it costs, what the correct dosage is for a half-hectare plot.
A local ChromaDB vector store holds curated agronomic documents crop guides, pest treatment protocols, fertilizer schedules, and market advisories all embedded offline using nomic-embed-text via Ollama. At query time, the top matching documents are retrieved and injected into the LLM prompt, grounding every answer in verified local knowledge rather than the model's general training.
Layer 3 Computer Vision Disease Classifier
The most technically novel component. When a farmer photographs a sick leaf, an ONNX-format MobileNetV3 classifier trained on the PlantVillage dataset of 54,000 labeled leaf images across 38 disease classes identifies the disease before the language model ever sees the query.
The vision output ("Cassava Mosaic Disease, 87% confidence") is injected into the prompt alongside the RAG context. The LLM's job then becomes translation and costing, not diagnosis. This separation of concerns is critical: vision models are better at visual pattern recognition than language models, and language models are better at communicating findings in natural language than vision models.
Layer 4 Desktop UI
The interface is a native desktop window built with pywebview not a browser-based Gradio app. This matters: Chrome or Firefox running alongside the model would consume 800 MB–1.5 GB of RAM on its own, eating deeply into the 7 GB ceiling. The pywebview window uses Ubuntu's native WebKitGTK renderer at approximately 80–150 MB overhead, leaving maximum RAM available for inference.
Ollama token streaming is consumed directly via requests.post(..., stream=True), with each token dispatched into the UI via evaluate_js as it's generated so the farmer sees words appearing progressively rather than waiting 20 seconds for a complete response.
The Math Behind the Memory Budget
The full system stays within the constraint:
$$ M_{total} = M_{model} + M_{kv} + M_{vision} + M_{rag} + M_{ui} + M_{os} $$
$$ M_{total} \approx 1.1 + 0.3 + 0.6 + 0.5 + 0.15 + 1.8 \approx 4.45 \text{ GB} \ll 7 \text{ GB} $$
Where:
- $M_{model}$ = Qwen2.5 1.5B Q4_K_M weights ≈ 1.1 GB
- $M_{kv}$ = KV cache at
num_ctx=512≈ 0.3 GB - $M_{vision}$ = MobileNetV3 ONNX + ONNX Runtime ≈ 0.6 GB
- $M_{rag}$ = ChromaDB + nomic-embed-text ≈ 0.5 GB
- $M_{ui}$ = pywebview (WebKitGTK) ≈ 0.15 GB
- $M_{os}$ = Ubuntu 22.04 + Python runtime ≈ 1.8 GB
Cross-Disciplinary Integration
GreenNet earns its cross-disciplinary claim through a load-bearing pipeline, not a surface-level combination.
The three disciplines don't just coexist they depend on each other sequentially:
- Computer Vision identifies what disease is present from pixel data alone, without language
- Information Retrieval (RAG) finds what the verified treatment protocol is for that disease from structured local documents
- Natural Language Generation translates both findings into plain-language advice the farmer can act on, in their own phrasing, with costs in Naira
Remove any one layer and the system degrades meaningfully:
- Without vision, the LLM guesses at diagnosis from symptom descriptions less precise
- Without RAG, the LLM answers from general training data not locally grounded, potentially wrong about available products and prices
- Without the LLM, vision and retrieval produce outputs the farmer can't interpret
Challenges
Hardware constraints shaped every decision.
The Intel Pentium Silver N-series the chip in my development machine lacks AVX2 support, which is what most optimized inference paths expect. Getting acceptable generation speed on a 4-core, no-GPU, 8 GB machine without AVX2 meant choosing Qwen2.5 1.5B over larger alternatives, keeping num_ctx tight at 512, and building a streaming UI so latency feels shorter than it is. A 20-second response that streams word by word feels faster than a 10-second response that appears all at once.
Cold start latency was a persistent problem. Ollama's default keep_alive timeout unloads the model from RAM after 5 minutes of inactivity. During a hackathon demo, if a judge pauses between questions, the next query takes 15–20 seconds just to reload the model. The fix setting keep_alive: -1 and sending a silent pre-warm query at app startup made the demo experience dramatically smoother.
The RAG/vision integration required careful prompt engineering. When vision confidence is low (below 30%) and RAG retrieval is weak, the injected context can confuse the model more than help it. Designing the orchestrator to be selective only injecting context when it's actually relevant and high-confidence took more iteration than the component integration itself.
The class imbalance problem in dataset collection encountered while building a parallel rug-pull detection classifier reinforced a lesson that applies here too: the quality and representativeness of your data determines the ceiling of your model's usefulness, regardless of how sophisticated the architecture is.
What I Learned
Building for constrained hardware forces clarity. When you can't throw compute at a problem, every architectural decision has a measurable consequence in RAM, in latency, in user experience. That discipline made GreenNe a better product, not a compromised one.
The most important design insight: the LLM is not the product. The system is the product. Qwen2.5 1.5B alone cannot reliably diagnose cassava mosaic disease from a symptom description and quote the correct treatment cost in Naira. But Qwen2.5 1.5B with a vision classifier telling it what disease is present, and a RAG layer telling it what the local treatment protocol costs that system can. The language model is a communication layer, not an oracle.
That reframe from "what can this model do?" to "what can a system built around this model do?" is the insight I'll carry well beyond this hackathon.
What it does
How we built it
Challenges we ran into
Accomplishments that we're proud of
What we learned
What's next for GreenNet
Built With
- chromadb
- css3
- fastapi
- html5
- javascript
- llama.cpp
- mobilenetv3
- nomic-embed-text
- onnx
- python
- pywebview
- qwen2.5
- sqlite
- webkitgtk
Log in or sign up for Devpost to join the conversation.