Offline AI-Powered Spatial Intelligence for ARM Devices
DreamMeridian is a fully offline spatial query system that runs entirely on ARM-based devices like Raspberry Pi 5. It combines a quantized LLM (xLAM-2-1B) with high-performance graph routing and spatial databases to answer natural language questions about geographic dataโwithout any cloud connectivity.
Built for humanitarian scenarios where internet access is unreliable: refugee camp navigation, disaster response coordination, and field operations planning.
Author: Adam Munawar Rahman
๐ฌ Watch the Demo (3 min) โ See DreamMeridian running on a Raspberry Pi 5
๐ Full Project Writeup โ Technical deep-dive, ARM optimization rationale, benchmarks, and humanitarian context for the ARM AI Developer Challenge 2025
Web dashboard showing isochrone analysis in Cox's Bazar refugee camps
- Key Features
- Architecture
- Pre-Built Datasets
- Requirements
- Installation
- Running DreamMeridian
- Recommended Queries
- Benchmark Results
- Spatial Tools
- Project Structure
- Troubleshooting
- Contributing
- Acknowledgments
- License
- 100% Offline: All AI inference runs locally on ARM CPUโno cloud, no API keys
- Natural Language Queries: Ask questions like "Find hospitals near Camp 6" or "Show 15 minute walkable area from Condado"
- Real Routing: Actual walking routes calculated on road network graphs (not straight-line distances)
- Three Disaster Response Scenarios: Pre-built datasets for Cox's Bazar, San Juan, and Jakarta
- Sub-15 Second Response: Optimized for Raspberry Pi 5 with ARM NEON/dotprod instructions
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Natural Language Query โ
โ "Find nearest hospital to Camp 6" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Geocoding Layer โ
โ Place name โ lat/lon: "Camp 6" โ (21.20, 92.16) โ
โ Modified query: "Find nearest hospital to (21.20, 92.16)" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ xLAM-2-1B (Q5_K_M) โ Tool-calling LLM optimized for ARM โ
โ via llama.cpp โ NEON + dotprod + GBNF grammar โ
โ Selects tool + generates arguments with resolved coordinates โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Spatial Tools โ
โ list_pois โ find_nearest_poi_with_route โ calculate_route โ
โ find_along_route โ generate_isochrone โ geocode_place โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโ
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DuckDB + Spatial โ โ NetworKit Graph Engine โ
โ POI queries, geocoding โ โ Dijkstra routing on road networkโ
โ ~6K-41K POIs per city โ โ ~25K-208K nodes per city โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Three disaster response scenarios with pre-built offline data:
| Location | Context | Nodes | Edges | POIs | Place Names |
|---|---|---|---|---|---|
coxs_bazar |
Rohingya refugee camps, Bangladesh | 27,551 | 71,530 | 6,509 | 464 |
san_juan |
Hurricane response, Puerto Rico | 24,602 | 61,055 | 11,351 | 405 |
jakarta |
Urban flood response, Indonesia | 208,281 | 508,954 | 41,028 | 331 |
Data sourced from OpenStreetMap via OSMnx. Includes hospitals, clinics, pharmacies, schools, shelters, banks, markets, fuel stations, police stations, and places of worship.
- Raspberry Pi 5 (8GB+ RAM recommended) or any ARM64 device
- ~4GB storage for models and data
- Tested on: Pi 5 16GB running DietPi, M3 MacBook Air
# System packages (Debian/Ubuntu/DietPi/Raspberry Pi OS)
sudo apt update
sudo apt install -y build-essential cmake git python3 python3-venv libopenblas-dev
# uv (fast Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc # or restart shellFull instructions including Apple Silicon (macOS) setup are available in INSTALL.md.
git clone https://github.com/msradam/dream-meridian.git
cd dream-meridianuv syncgit clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp && mkdir build && cd build
# Configure for Cortex-A76 (Pi 5)
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-mcpu=cortex-a76 -O3 -ffast-math -fno-finite-math-only" \
-DCMAKE_CXX_FLAGS="-mcpu=cortex-a76 -O3 -ffast-math -fno-finite-math-only" \
-DGGML_NATIVE=ON \
-DGGML_LTO=ON \
-DLLAMA_CURL=OFF
cmake --build . -j4 --config Release
cd ../..mkdir -p models
uv run --with huggingface-hub hf download \
Salesforce/xLAM-2-1b-fc-r-gguf \
xLAM-2-1B-fc-r-Q5_K_M.gguf \
--local-dir ./modelsls -la llama.cpp/build/bin/llama-server # Should exist
ls -la models/*.gguf # Should show ~1.1GB file
ls -la data/ # Should show coxs_bazar, san_juan, jakarta./llama.cpp/build/bin/llama-server \
-m ./models/xLAM-2-1B-fc-r-Q5_K_M.gguf \
--grammar-file tool_grammar.gbnf \
-c 2048 -t 4 --mlock \
--host 0.0.0.0 --port 8080Wait for "server is listening on http://0.0.0.0:8080".
uv run python dream-meridian.py -l <location> "<query>"uv run streamlit run app.py --server.port 8501Open http://[pi-ip-address]:8501 in your browser.
uv run python dream-meridian.py -l coxs_bazar "I need to find the nearest hospital to Camp 6"
uv run python dream-meridian.py -l coxs_bazar "How do I walk from Camp 3 to Camp 8W"
uv run python dream-meridian.py -l coxs_bazar "Show me everywhere I can walk to in 15 minutes from Camp 8W"uv run python dream-meridian.py -l san_juan "Where is the closest hospital to Condado"
uv run python dream-meridian.py -l san_juan "How do I get from Condado to Santurce on foot"
uv run python dream-meridian.py -l san_juan "Show me a 20 minute walking radius from Condado"uv run python dream-meridian.py -l jakarta "Is there a bank near Gelora"
uv run python dream-meridian.py -l jakarta "What is the distance on foot from Pinangsia to Kalianyar"
uv run python dream-meridian.py -l jakarta "What can I reach in 15 minutes walking from Serdang"Full benchmark suite of 57 natural language queries across all three locations.
./benchmark_full.sh| Metric | Value |
|---|---|
| Total queries | 57 |
| Success rate | 94.7% (54/57) |
| Avg response time | 10.87s |
| LLM inference | 8.9 tok/s |
| Location | Queries | Correct | Success Rate |
|---|---|---|---|
| Cox's Bazar | 19 | 19 | 100% |
| San Juan | 19 | 18 | 94.7% |
| Jakarta | 19 | 17 | 89.5% |
See BENCHMARK_RESULTS.md for detailed examples, failure analysis, and improvement pathways.
| Tool | Description | Example |
|---|---|---|
list_pois |
List POIs of a type within radius | "List hospitals within 2km of Camp 6" |
find_nearest_poi_with_route |
Find nearest POI with walking route | "Find nearest clinic to Condado" |
calculate_route |
Walking route between two points | "Route from Camp 6 to Camp 9" |
find_along_route |
Find POIs along a walking path | "Hospitals along route from A to B" |
generate_isochrone |
Walkable area from a point | "15 minute walking radius from Camp 6" |
geocode_place |
Convert place name to coordinates | "Where is Camp 6 located" |
dream-meridian/
โโโ dream-meridian.py # Main query engine
โโโ spatial_tools.py # Spatial query functions
โโโ geocode_layer.py # Place name resolution
โโโ app.py # Streamlit dashboard
โโโ build_location.py # Dataset builder
โโโ tool_grammar.gbnf # GBNF grammar for tool calls
โโโ benchmark_full.sh # Benchmark suite
โโโ BENCHMARK_RESULTS.md # Detailed benchmark analysis
โโโ INSTALL.md # Full installation instructions
โโโ WRITEUP.md # Full project writeup
โโโ pyproject.toml # Python dependencies
โโโ docs/
โ โโโ images/ # Screenshots and diagrams
โโโ static/ # Fonts for Streamlit dashboard
โโโ data/
โ โโโ coxs_bazar/ # Cox's Bazar dataset (27K nodes, 6K POIs)
โ โโโ san_juan/ # San Juan dataset (24K nodes, 11K POIs)
โ โโโ jakarta/ # Jakarta dataset (208K nodes, 41K POIs)
โโโ models/ # LLM models (gitignored)
โโโ llama.cpp/ # Built llama.cpp (gitignored)
lsof -i :8080 # Check if port is in use
pkill -f llama-server # Kill existing process# Reduce context size to 1024
./llama.cpp/build/bin/llama-server \
-m ./models/xLAM-2-1B-fc-r-Q5_K_M.gguf \
-c 1024 -t 4 --host 0.0.0.0 --port 8080# Ensure CPU governor is set to performance
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# Should be "performance" not "powersave"Contributions are welcome! Please open an issue first to discuss proposed changes.
If you'd like to add support for a new location, see build_location.py for the dataset generation pipeline.
- xLAM-2 by Salesforce AI Research - Tool-calling LLM
- llama.cpp by Georgi Gerganov - Efficient inference engine
- NetworKit - High-performance graph algorithms
- DuckDB - Embedded analytical database
- OSMnx by Geoff Boeing - Street network retrieval and analysis
- OpenStreetMap - Geographic data
MIT License - See LICENSE for details.
This project was built for the ARM AI Developer Challenge, demonstrating on-device AI inference for humanitarian applications on ARM-powered devices.
Key Innovation: Natural language spatial queries running entirely offline on a ~$210 single-board computer, enabling field workers in connectivity-constrained environments to access critical geographic intelligence.