Image-Text-to-Text
Transformers
Safetensors
English
gemma4
solar-energy
community-solar
function-calling
multimodal
lora
unsloth
ollama
edge-ai
energy
sustainability
hackathon
conversational
Eval Results (legacy)
Instructions to use Truthseeker87/solarhive-e4b-ollama with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Truthseeker87/solarhive-e4b-ollama with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="Truthseeker87/solarhive-e4b-ollama") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("Truthseeker87/solarhive-e4b-ollama") model = AutoModelForMultimodalLM.from_pretrained("Truthseeker87/solarhive-e4b-ollama", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Truthseeker87/solarhive-e4b-ollama with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Truthseeker87/solarhive-e4b-ollama" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Truthseeker87/solarhive-e4b-ollama", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/Truthseeker87/solarhive-e4b-ollama
- SGLang
How to use Truthseeker87/solarhive-e4b-ollama with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Truthseeker87/solarhive-e4b-ollama" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Truthseeker87/solarhive-e4b-ollama", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Truthseeker87/solarhive-e4b-ollama" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Truthseeker87/solarhive-e4b-ollama", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Unsloth Desktop
- Docker Model Runner
How to use Truthseeker87/solarhive-e4b-ollama with Docker Model Runner:
docker model run hf.co/Truthseeker87/solarhive-e4b-ollama
Add paper title to speculative-decoding citation (arXiv:2211.17192)
Browse files
README.md
CHANGED
|
@@ -1,479 +1,479 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: mit
|
| 3 |
-
base_model: google/gemma-4-e4b-it
|
| 4 |
-
library_name: transformers
|
| 5 |
-
tags:
|
| 6 |
-
- gemma4
|
| 7 |
-
- solar-energy
|
| 8 |
-
- community-solar
|
| 9 |
-
- function-calling
|
| 10 |
-
- multimodal
|
| 11 |
-
- lora
|
| 12 |
-
- unsloth
|
| 13 |
-
- ollama
|
| 14 |
-
- edge-ai
|
| 15 |
-
- energy
|
| 16 |
-
- sustainability
|
| 17 |
-
- hackathon
|
| 18 |
-
datasets:
|
| 19 |
-
- Truthseeker87/solarhive-community-solar-multimodal
|
| 20 |
-
language:
|
| 21 |
-
- en
|
| 22 |
-
pipeline_tag: image-text-to-text
|
| 23 |
-
model-index:
|
| 24 |
-
- name: SolarHive-E4B-Merged
|
| 25 |
-
results:
|
| 26 |
-
- task:
|
| 27 |
-
type: question-answering
|
| 28 |
-
name: Domain Q&A
|
| 29 |
-
metrics:
|
| 30 |
-
- name: Accuracy
|
| 31 |
-
type: accuracy
|
| 32 |
-
value: 1.0
|
| 33 |
-
verified: false
|
| 34 |
-
- task:
|
| 35 |
-
type: text-generation
|
| 36 |
-
name: Tool Calling
|
| 37 |
-
metrics:
|
| 38 |
-
- name: Accuracy
|
| 39 |
-
type: accuracy
|
| 40 |
-
value: 0.8
|
| 41 |
-
verified: false
|
| 42 |
-
---
|
| 43 |
-
|
| 44 |
-

|
| 45 |
-
|
| 46 |
-
# SolarHive E4B — BF16 Merged Safetensors
|
| 47 |
-
|
| 48 |
-
**LoRA fine-tuned Gemma 4 E4B (8B), merged to 16-bit safetensors.** Source artifact for **direct transformers inference** and **llama.cpp `convert_hf_to_gguf.py` → Q4_K_M GGUF conversion** (which powers Ollama + llama.cpp edge deployment via the [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) companion repo).
|
| 49 |
-
|
| 50 |
-
> **For Ollama or llama.cpp edge deployment on a 16 GB CPU laptop, use the [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) repo instead** — it ships the 5.34 GB Q4_K_M GGUF (standard Q6_K-PLE recipe) plus the 992 MB `mmproj-BF16.gguf` companion (vision + audio), with `Modelfile`s ready for `ollama create` and a 10/10 score on the single-pass SolarHive project-held-out 10-prompt parity check.
|
| 51 |
-
>
|
| 52 |
-
> The `--experimental` Ollama path documented previously OOMs `ollama create` on ≤16 GB RAM (the 16 GB BF16 safetensors blob does not fit during ingestion). On hardware ≥24 GB RAM the experimental import works, but the GGUF pipeline (built using **llama.cpp** `convert_hf_to_gguf.py` + `llama-quantize`) is the recommended edge deployment path for everyone else.
|
| 53 |
-
|
| 54 |
-
This repository now serves three roles:
|
| 55 |
-
1. **Source for GGUF conversion** via [llama.cpp](https://github.com/ggerganov/llama.cpp)'s `convert_hf_to_gguf.py` (text tower) and `convert_hf_to_gguf.py --mmproj` (vision + audio projector). See [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) for the produced GGUF artifacts.
|
| 56 |
-
2. **Transformers-native multimodal use** — load with `AutoModelForCausalLM` for full image + audio + text in Python (requires ≥24 GB RAM or A100-class GPU).
|
| 57 |
-
3. **Reference for further fine-tuning** — extend the LoRA on additional data using Unsloth `FastVisionModel`.
|
| 58 |
-
|
| 59 |
-
Built for the [Gemma 4 Good Hackathon](https://kaggle.com/competitions/gemma-4-good-hackathon) (Google DeepMind x Kaggle).
|
| 60 |
-
|
| 61 |
-
| | |
|
| 62 |
-
|---|---|
|
| 63 |
-
| **Base Model** | [google/gemma-4-e4b-it](https://kaggle.com/models/google/gemma-4) |
|
| 64 |
-
| **Architecture** | Dense + PLE — 8B total, 4.5B effective |
|
| 65 |
-
| **Fine-Tuning** | LoRA via [Unsloth](https://unsloth.ai) (BF16) |
|
| 66 |
-
| **Training Data** | 1,727 examples ([solarhive-community-solar-multimodal](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal)) — text-only fine-tune; VQA at inference uses the base [Gemma 4 vision encoder](https://ai.google.dev/gemma/docs/core/model_card_4) (~150M params), unmodified by our LoRA per the [Vertex AI SFT recipe](https://huggingface.co/blog/gemma4) |
|
| 67 |
-
| **Converged Loss** | **0.9218** |
|
| 68 |
-
| **Project-held-out check** | 9/10 (5/5 domain Q&A + 4/5 tool calling) — May 2026 final run, multi-call regression on TQ5 (see Multi-Variant Deployment Validation below) |
|
| 69 |
-
| **Training Time** | 420 seconds (~7 minutes) |
|
| 70 |
-
| **Compute** | Google Colab Pro |
|
| 71 |
-
| **License** | MIT (adapters) / Gemma Terms (base model) |
|
| 72 |
-
|
| 73 |
-
---
|
| 74 |
-
|
| 75 |
-
## Model Overview
|
| 76 |
-
|
| 77 |
-
SolarHive E4B is the **edge companion** to [SolarHive 26B A4B](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora). While the 26B model powers cloud inference with full multimodal VQA, the E4B model is optimized for local deployment via Ollama on consumer hardware.
|
| 78 |
-
|
| 79 |
-
**Privacy-first:** Running Gemma 4 locally means community energy data never leaves the neighborhood. No cloud dependency, no internet requirement, no data privacy concerns. A village in rural India, a suburb in Michigan, and a coastal town recovering from a hurricane all get the same intelligence.
|
| 80 |
-
|
| 81 |
-
This repository contains the **fully merged model** (base + LoRA baked together) — no separate base model download needed.
|
| 82 |
-
|
| 83 |
-
---
|
| 84 |
-
|
| 85 |
-
## Training Details
|
| 86 |
-
|
| 87 |
-
| Parameter | Value |
|
| 88 |
-
|-----------|-------|
|
| 89 |
-
| Method | LoRA via Unsloth `FastVisionModel` (BF16, RTX PRO 6000 96 GB) |
|
| 90 |
-
| LoRA rank | 16 |
|
| 91 |
-
| LoRA alpha | 16 |
|
| 92 |
-
| LoRA dropout | 0 |
|
| 93 |
-
| Target modules | All linear layers |
|
| 94 |
-
| Learning rate | 2e-4 |
|
| 95 |
-
| Optimizer | AdamW 8-bit |
|
| 96 |
-
| Warmup steps | 5 |
|
| 97 |
-
| Epochs | 3 |
|
| 98 |
-
| Max sequence length | 2048 |
|
| 99 |
-
| Precision | BF16 |
|
| 100 |
-
| Seed | 3407 |
|
| 101 |
-
| Trainable parameters | 41.2M / 8.0B (0.51%) |
|
| 102 |
-
|
| 103 |
-
### Training Loss
|
| 104 |
-
|
| 105 |
-
| Metric | Value |
|
| 106 |
-
|--------|-------|
|
| 107 |
-
| Converged loss (last 20 steps) | **0.9218** |
|
| 108 |
-
| Final step loss | 0.0635 |
|
| 109 |
-
| Minimum loss | 0.0635 |
|
| 110 |
-
| Total steps | 324 |
|
| 111 |
-
| Training time | 420 seconds |
|
| 112 |
-
|
| 113 |
-
> **Canonical metric:** the bolded **Converged loss (last 20 steps)** is the only smoothed convergence indicator. *Final step* and *Minimum* are single-batch point statistics — mini-batch loss is noisy step-to-step, so one easy batch can drop a point estimate well below the rolling-average trend.
|
| 114 |
-
|
| 115 |
-
### Training Data
|
| 116 |
-
|
| 117 |
-
Same canonical training corpus as the 26B A4B model — [solarhive-community-solar-multimodal](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal), 1,727 rows:
|
| 118 |
-
|
| 119 |
-
- 413 hand-crafted examples spanning 15+ US cities and 9 energy domains
|
| 120 |
-
- ~1,117 API-grounded examples from live Open-Meteo, PVWatts, OWM, and EIA data
|
| 121 |
-
- 183 tool-calling examples (positive, negative refusals, follow-up clarifications, failure-recovery)
|
| 122 |
-
- 14 image-grounded Q&A turns from 7 manually-labeled Ann Arbor sky photographs
|
| 123 |
-
|
| 124 |
-
### Hardware
|
| 125 |
-
|
| 126 |
-
- **GPU:** NVIDIA RTX PRO 6000 Blackwell Server Edition (102 GB GDDR7 total, 94.97 GB max usable per Unsloth)
|
| 127 |
-
- **Platform:** Google Colab Pro (G4 VM)
|
| 128 |
-
|
| 129 |
-
---
|
| 130 |
-
|
| 131 |
-
## Project-Held-Out Results
|
| 132 |
-
|
| 133 |
-
### Domain Q&A (5/5)
|
| 134 |
-
|
| 135 |
-
| Question | Result |
|
| 136 |
-
|----------|--------|
|
| 137 |
-
| Solar production when humidity exceeds 80%? | Correct |
|
| 138 |
-
| Battery SOC threshold for grid export? | Correct |
|
| 139 |
-
| Home #3 underperforming 22% — diagnostic checklist? | Correct |
|
| 140 |
-
| Winter snow on panels — prioritize actions? | Correct |
|
| 141 |
-
| Grid frequency 59.8 Hz — microgrid implications? | Correct |
|
| 142 |
-
|
| 143 |
-
> **Note on validation history:** the 5/5 Q&A above is from the initial 8-question validation harness used during fine-tune development. The canonical headline number is the May 2026 final-run multi-variant validation (single-pass project-held-out 10-question parity check) — see below.
|
| 144 |
-
|
| 145 |
-
### Tool inventory + inference-time When2Call validation
|
| 146 |
-
|
| 147 |
-
`solarhive_inference.py` exposes **5 tools** to the model — all three keyed APIs (`OWM_API_KEY`, `EIA_API_KEY`, `NREL_API_KEY`) actively wired:
|
| 148 |
-
|
| 149 |
-
| Tool | API | Returns |
|
| 150 |
-
|------|-----|---------|
|
| 151 |
-
| `get_weather(location)` | OpenWeatherMap (`OWM_API_KEY`) | Temperature, clouds %, wind, humidity, sunrise/sunset |
|
| 152 |
-
| `get_solar_production(clouds_pct, temp_f)` | Open-Meteo GHI (keyless) | Production kW, efficiency %, GHI W/m², temp derating |
|
| 153 |
-
| `get_battery_state()` | Community BMS (sim) | State of charge, capacity, charging status |
|
| 154 |
-
| `get_grid_status()` | EIA Open Data (`EIA_API_KEY`) | Pricing period, rate/kWh, renewable %, CO2 intensity |
|
| 155 |
-
| `get_nrel_pvwatts_baseline()` | NREL PVWatts v8 (`NREL_API_KEY`) | Annual + current-month typical kWh + avg kW for the 72 kW array |
|
| 156 |
-
|
| 157 |
-
Tool results feed back as a **2-message sequence** matching the training distribution: `{"role": "assistant", "tool_calls": [...]}` then `{"role": "tool", "name": "<fn>", "content": json.dumps(result)}` per call. Shared across the data-generation pipeline, the fine-tune SFT preprocessing layer, and the inference agentic loop — inference matches training distribution exactly.
|
| 158 |
-
|
| 159 |
-
**When2Call probes.** Three held-out probes validate 3 of the 4 failure-mode categories from [Ross, H., Mahabaleshwarkar, A. S., & Suhara, Y. (2025). *When2Call: When (not) to Call Tools.* arXiv:2504.18851](https://arxiv.org/abs/2504.18851) — the paper documents 9–67% tool-hallucination rates on (c)+(d) in untrained community models:
|
| 160 |
-
|
| 161 |
-
- **(b)** *"What's the current grid rate?"* → expect `get_grid_status` call (well-specified, in-scope)
|
| 162 |
-
- **(c)** *"How much will a 10 kW array produce today?"* → expect follow-up question (does NOT auto-fill location default)
|
| 163 |
-
- **(d)** *"What's the current air quality index in Ann Arbor?"* → expect refusal + redirect (does NOT hallucinate a tool)
|
| 164 |
-
|
| 165 |
-
Models trained without explicit *unable-to-answer* and *follow-up clarification* examples typically fail (c) + (d). The SolarHive corpus includes 16 such examples (10 *unable-to-answer* + 6 *follow-up clarification*) following the When2Call taxonomy.
|
| 166 |
-
|
| 167 |
-
### Multi-Variant Deployment Validation (Final Run, May 2026) — E4B regression on When2Call (c)
|
| 168 |
-
|
| 169 |
-
End-to-end inference run on Colab Pro G4. This E4B BF16 merged variant
|
| 170 |
-
loaded from a local cache (16.9 GB VRAM utilization, ~10 min runtime).
|
| 171 |
-
|
| 172 |
-
**Project-held-out parity check: 5/5 Q&A + 4/5 tool = 9/10** on the 10-question set —
|
| 173 |
-
matches the [A4B family](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora)
|
| 174 |
-
on the 9 deterministic questions; the single FAIL is the lenient
|
| 175 |
-
multi-call probe (TQ5 — *"Compare today's irradiance forecast across
|
| 176 |
-
Ann Arbor, Phoenix, and Seattle"*, `min_calls=2`) where this variant
|
| 177 |
-
emitted only 1 `get_weather` call. Notably, the
|
| 178 |
-
[E4B LoRA + base variant](https://huggingface.co/Truthseeker87/solarhive-e4b-lora)
|
| 179 |
-
(same fine-tune, applied via Unsloth instead of merged) DOES chain
|
| 180 |
-
3 calls on the same probe and scores 10/10 — pattern reproducible
|
| 181 |
-
across runs.
|
| 182 |
-
|
| 183 |
-
**[When2Call](https://arxiv.org/abs/2504.18851) probes — measured 2/3 (final run May 2026):**
|
| 184 |
-
|
| 185 |
-
| Probe | E4B merged behavior | Score |
|
| 186 |
-
|-------|---------------------|:-:|
|
| 187 |
-
| **(b)** *"current grid rate?"* | ✅ Correctly calls `get_grid_status` | PASS |
|
| 188 |
-
| **(c)** *"How much will a 10 kW array produce today?"* | ❌ Auto-fills location and calls `get_solar_production` instead of asking back | FAIL |
|
| 189 |
-
| **(d)** *"current AQI in Ann Arbor?"* | ✅ Genuinely disclaims (no fabrication, no tool call) | PASS |
|
| 190 |
-
|
| 191 |
-
**Cross-variant pattern:** the [E4B LoRA + base variant](https://huggingface.co/Truthseeker87/solarhive-e4b-lora) is inferred to score **2/3** by mathematical lossless equivalence with this merged variant (the merge step is lossless on weights, so the When2Call decision boundary is identical). The +1/3 W2C delta vs the [A4B family](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora) (3/3 directly measured on A4B LoRA, inferred-lossless on A4B merged + NF4) is the empirical signature of size-vs-refusal scaling.
|
| 192 |
-
|
| 193 |
-
**Honest finding — size-vs-refusal scaling is real, and was the pre-stated hypothesis.**
|
| 194 |
-
This E4B fine-tune regresses on (c) compared to the
|
| 195 |
-
[A4B LoRA baseline](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora)
|
| 196 |
-
(which scores 3/3). The smaller model with less reasoning depth more readily
|
| 197 |
-
auto-fills missing parameters when it should ask back — exactly the failure
|
| 198 |
-
mode Ross et al. 2025 document at 9-67% rates in untrained community models.
|
| 199 |
-
The fine-tune closes (b)+(d) at this size but doesn't fully close (c).
|
| 200 |
-
|
| 201 |
-
**This was the expected outcome going in**, per the [official Google Gemma 4 Core docs](https://ai.google.dev/gemma/docs/core) *"Parameter sizes and quantization"*: *"Models with higher parameters and bit counts (higher precision) are generally more capable, but are more expensive to run."* E4B's 8B total / 4.5B effective parameters / ~150M vision encoder vs A4B's 25.2B total / 3.8B active (MoE) / ~550M vision encoder reflect a deliberate ~3× capacity gap on the dimension that drives reasoning-heavy refusal/follow-up behavior. The validation confirms the documented scaling — not a defect, but architecture-aware deployment design.
|
| 202 |
-
|
| 203 |
-
**Quantitative reinforcement** from [Unsloth's published Gemma 4 benchmarks](https://unsloth.ai/docs/models/gemma-4): E4B scores **69.4% on MMLU Pro** (vs 26B A4B's 82.6% — a 13.2 pp gap), **52.6% on MMMU Pro** (vs 73.8% — 21.2 pp gap), and **42.5% on AIME 2026** (vs 88.3% — a 45.8 pp gap). The AIME math-reasoning gap and MMMU Pro multimodal-reasoning gap directly **predict** the (c)/(d) [When2Call](https://arxiv.org/abs/2504.18851) regression we observe here — the smaller model's published reasoning-benchmark deltas scale cleanly into the 2-of-3 behavioral regression vs the [A4B baseline](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora). E4B is the right choice for the volume of well-specified, in-scope queries that dominate everyday community-energy interactions; A4B handles the harder reasoning edge cases.
|
| 204 |
-
|
| 205 |
-
**Deployment recommendation:** Use this E4B variant for the volume of
|
| 206 |
-
**well-specified, in-scope queries** (production estimates, grid pricing,
|
| 207 |
-
maintenance guidance) where (b)-category routing dominates. Route
|
| 208 |
-
**under-specified or out-of-scope queries** to the A4B cloud variant for
|
| 209 |
-
correct refusal + follow-up behavior. A future fine-tune could increase
|
| 210 |
-
the E4B *follow-up clarification* example count (currently 6) and
|
| 211 |
-
*unable-to-answer* count (currently 10) to close the gap.
|
| 212 |
-
|
| 213 |
-
---
|
| 214 |
-
|
| 215 |
-
## How to Use
|
| 216 |
-
|
| 217 |
-
### Loading with transformers
|
| 218 |
-
|
| 219 |
-
```python
|
| 220 |
-
from transformers import AutoModelForCausalLM, AutoProcessor
|
| 221 |
-
import torch
|
| 222 |
-
|
| 223 |
-
model = AutoModelForCausalLM.from_pretrained(
|
| 224 |
-
"Truthseeker87/solarhive-e4b-ollama", # This repo (merged safetensors)
|
| 225 |
-
dtype=torch.bfloat16,
|
| 226 |
-
device_map="auto",
|
| 227 |
-
trust_remote_code=True,
|
| 228 |
-
)
|
| 229 |
-
processor = AutoProcessor.from_pretrained(
|
| 230 |
-
"Truthseeker87/solarhive-e4b-ollama",
|
| 231 |
-
trust_remote_code=True,
|
| 232 |
-
)
|
| 233 |
-
```
|
| 234 |
-
|
| 235 |
-
### Edge Deployment — use the GGUF repo
|
| 236 |
-
|
| 237 |
-
For Ollama or llama.cpp on a 16 GB CPU laptop, **download the GGUF artifacts** instead of trying to import these safetensors:
|
| 238 |
-
|
| 239 |
-
```bash
|
| 240 |
-
hf download Truthseeker87/solarhive-e4b-gguf \
|
| 241 |
-
solarhive-e4b-q4_k_m.gguf Modelfile \
|
| 242 |
-
--local-dir ./solarhive-gguf
|
| 243 |
-
cd ./solarhive-gguf
|
| 244 |
-
ollama create solarhive -f Modelfile
|
| 245 |
-
ollama run solarhive "What's the best time to run my dishwasher today?"
|
| 246 |
-
```
|
| 247 |
-
|
| 248 |
-
The [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) repo ships the Q4_K_M GGUF (standard Q6_K-PLE recipe, 5.34 GB) plus a 992 MB `mmproj-BF16.gguf` for full multimodal via `llama-server --mmproj`.
|
| 249 |
-
|
| 250 |
-
### Edge Deployment via Ollama `--experimental` (≥24 GB RAM only)
|
| 251 |
-
|
| 252 |
-
If you have ≥24 GB system RAM, you can experimentally import these safetensors directly via Ollama:
|
| 253 |
-
|
| 254 |
-
```bash
|
| 255 |
-
git clone https://huggingface.co/Truthseeker87/solarhive-e4b-ollama
|
| 256 |
-
cd solarhive-e4b-ollama
|
| 257 |
-
cat > Modelfile << 'EOF'
|
| 258 |
-
FROM .
|
| 259 |
-
SYSTEM "You are SolarHive, an AI energy advisor for a community of 12 homes with rooftop solar and shared battery storage in Ann Arbor, Michigan. Use the available tools to get real-time data before answering. Be specific, reference actual data, and keep responses concise (3-5 sentences)."
|
| 260 |
-
PARAMETER temperature 1.0
|
| 261 |
-
PARAMETER top_p 0.95
|
| 262 |
-
PARAMETER top_k 64
|
| 263 |
-
PARAMETER num_ctx 4096
|
| 264 |
-
EOF
|
| 265 |
-
ollama create solarhive --experimental -f Modelfile
|
| 266 |
-
ollama run solarhive "What's the best time to run my dishwasher today?"
|
| 267 |
-
```
|
| 268 |
-
|
| 269 |
-
> **OOM warning:** on 16 GB RAM, `ollama create --experimental` crashes around 44% blob processing as Ollama tries to materialize the full 16 GB BF16 model in memory during ingestion. Use the GGUF path above instead.
|
| 270 |
-
>
|
| 271 |
-
> The official base (non-fine-tuned) E4B is also available as a pre-built GGUF on [ollama.com/library/gemma4:e4b](https://ollama.com/library/gemma4:e4b) (9.6 GB, Q4_K_M). Our [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) adds 1,727 examples of community solar domain expertise on top.
|
| 272 |
-
|
| 273 |
-
### GGUF Conversion via llama.cpp (reproducibility recipe)
|
| 274 |
-
|
| 275 |
-
These safetensors are the source artifact for the GGUF deployment. Reproducible via [llama.cpp](https://github.com/ggerganov/llama.cpp) tooling:
|
| 276 |
-
|
| 277 |
-
```bash
|
| 278 |
-
# Text tower → BF16 GGUF (~14 GB intermediate)
|
| 279 |
-
python convert_hf_to_gguf.py --outtype bf16 \
|
| 280 |
-
--outfile solarhive-e4b-bf16.gguf \
|
| 281 |
-
Truthseeker87/solarhive-e4b-ollama/
|
| 282 |
-
|
| 283 |
-
# Quantize text → Q4_K_M (shipped recipe, 5.34 GB; needs ≥30 GB RAM)
|
| 284 |
-
llama-quantize \
|
| 285 |
-
solarhive-e4b-bf16.gguf solarhive-e4b-q4_k_m.gguf Q4_K_M
|
| 286 |
-
|
| 287 |
-
# Multimodal projector (vision SigLIP + audio Conformer, ~992 MB)
|
| 288 |
-
python convert_hf_to_gguf.py --mmproj --outtype bf16 \
|
| 289 |
-
--outfile mmproj-solarhive-e4b-BF16.gguf \
|
| 290 |
-
Truthseeker87/solarhive-e4b-ollama/
|
| 291 |
-
```
|
| 292 |
-
|
| 293 |
-
The shipped 5.34 GB Q4_K_M quant requires ≥30 GB RAM at quantization time (the Q6_K-PLE tensor needs a ~10.7 GB float32 buffer). To quantize on a 16 GB laptop instead, add `--tensor-type per_layer_token_embd.weight=q4_0` — it bypasses that buffer and yields a smaller (~4.6 GB) GGUF, validated quality-safe in development. See the [`solarhive_quantize_e4b.ipynb`](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive) notebook for the high-RAM recipe.
|
| 294 |
-
|
| 295 |
-
---
|
| 296 |
-
|
| 297 |
-
## Core Capabilities
|
| 298 |
-
|
| 299 |
-
### 1. Multimodal Visual Question Answering (3 Modes)
|
| 300 |
-
|
| 301 |
-
Available because the base Gemma 4 E4B vision encoder (~150M params) is preserved unmodified in these merged weights:
|
| 302 |
-
|
| 303 |
-
| Mode | Input | Output |
|
| 304 |
-
|------|-------|--------|
|
| 305 |
-
| Sky Analysis | Sky photograph | Cloud coverage %, production forecast, storage recommendation |
|
| 306 |
-
| Panel Inspection | Panel photograph | Dirt/damage/shading detection, efficiency impact estimate |
|
| 307 |
-
| Neighborhood Assessment | Aerial/satellite image | Panel inventory, expansion priorities, shading analysis |
|
| 308 |
-
|
| 309 |
-
### 2. Native Function Calling (5 Tools — all 3 keyed APIs wired)
|
| 310 |
-
|
| 311 |
-
| Tool | API | Returns |
|
| 312 |
-
|------|-----|---------|
|
| 313 |
-
| `get_weather(location)` | OpenWeatherMap (`OWM_API_KEY`) | Temperature, clouds %, wind, humidity, sunrise/sunset |
|
| 314 |
-
| `get_solar_production(clouds_pct, temp_f)` | Open-Meteo GHI (keyless) | Production kW, efficiency %, GHI W/m², temp derating |
|
| 315 |
-
| `get_battery_state()` | Community BMS (sim) | State of charge, capacity, charging status |
|
| 316 |
-
| `get_grid_status()` | EIA Open Data (`EIA_API_KEY`) | Pricing period, rate/kWh, renewable %, CO2 intensity |
|
| 317 |
-
| `get_nrel_pvwatts_baseline()` | NREL PVWatts v8 (`NREL_API_KEY`) | Annual + current-month typical kWh + avg kW for the 72 kW array |
|
| 318 |
-
|
| 319 |
-
### 3. Selective Tool Reasoning
|
| 320 |
-
|
| 321 |
-
The model decides when to call tools — it does not blindly invoke all of them:
|
| 322 |
-
|
| 323 |
-
```
|
| 324 |
-
"What time does peak pricing start?"
|
| 325 |
-
→ Calls: get_grid_status() only
|
| 326 |
-
|
| 327 |
-
"Should I run my pool heater now?"
|
| 328 |
-
→ Calls: get_weather() + get_solar_production() + get_battery_state() + get_grid_status()
|
| 329 |
-
|
| 330 |
-
"What are general maintenance tips for panels?"
|
| 331 |
-
→ Calls: none (answers from training knowledge)
|
| 332 |
-
```
|
| 333 |
-
|
| 334 |
-
---
|
| 335 |
-
|
| 336 |
-
## Community Model
|
| 337 |
-
|
| 338 |
-
| Parameter | Value |
|
| 339 |
-
|-----------|-------|
|
| 340 |
-
| Location | Ann Arbor, Michigan (42.2808°N, 83.7430°W) |
|
| 341 |
-
| Community size | 12 homes |
|
| 342 |
-
| Total panel capacity | 72 kW |
|
| 343 |
-
| Shared battery storage | 100 kWh |
|
| 344 |
-
| Grid region | MISO (Midcontinent Independent System Operator) |
|
| 345 |
-
|
| 346 |
-
---
|
| 347 |
-
|
| 348 |
-
## Technical Notes
|
| 349 |
-
|
| 350 |
-
- **Merged BF16 safetensors.** Base + LoRA fused via Unsloth `save_pretrained_merged("merged_16bit")`. Loads with plain `transformers.AutoModelForCausalLM.from_pretrained(...)` — no PEFT or Unsloth dependency at inference time.
|
| 351 |
-
- **Vision tower frozen during fine-tune.** VQA at inference uses the base model's pretrained vision encoder unmodified, matching the [Vertex AI SFT recipe](https://huggingface.co/blog/gemma4) which freezes both vision and audio towers during text-focused fine-tuning.
|
| 352 |
-
- **Two-step tokenization at inference.** Single-step `tokenize=True` crashes in transformers 5.5.x on messages without a `content` key (e.g., `tool_calls` messages). Always render text first (`tokenize=False`) then tokenize separately.
|
| 353 |
-
- **Sampling defaults.** `temperature=1.0, top_p=0.95, top_k=64` (Kaggle-recommended Gemma 4 defaults).
|
| 354 |
-
- **Chat template.** `gemma-4` (per Unsloth Tip #1 for E2B/E4B). The `gemma-4-thinking` template is reserved for 26B/31B reasoning-class variants. The simpler template is more robust across downstream Ollama / llama.cpp runtimes that don't expose `enable_thinking=False` at the runtime layer.
|
| 355 |
-
|
| 356 |
-
---
|
| 357 |
-
|
| 358 |
-
## Limitations
|
| 359 |
-
|
| 360 |
-
- **Prototype scope.** Tested on a single community model (12 homes, Ann Arbor, MI). Real-world deployment requires validation across diverse geographies and community sizes.
|
| 361 |
-
- **Smaller model, weaker refusal/follow-up.** When2Call (c) regression vs the A4B baseline (2/3 vs 3/3 — see Multi-Variant Deployment Validation above). Route under-specified or out-of-scope queries to the A4B cloud variant for correct refusal + follow-up behavior.
|
| 362 |
-
- **Occasional capacity hallucination.** The base model's prior occasionally surfaces "60 kW" instead of the correct 72 kW community capacity in direct (no-tool) responses. The tool-calling path (which queries actual capacity from `get_nrel_pvwatts_baseline`) avoids this.
|
| 363 |
-
- **External API dependence.** Tool responses depend on Open-Meteo, OWM, EIA, and PVWatts availability with their respective rate limits.
|
| 364 |
-
- **Battery state is simulated.** `get_battery_state()` is a deterministic in-memory simulator for demonstrations — real deployment requires integration with actual battery management systems.
|
| 365 |
-
- **Single-trial multi-variant validation.** The May 2026 final-run project-held-out numbers are from one inference pass; a multi-trial bootstrap would strengthen the multi-call regression claim against temperature-1.0 stochasticity.
|
| 366 |
-
- **Memory.** ~16 GB BF16 safetensors require ≥24 GB system RAM at load time — does not fit on consumer 16 GB laptops in this format. For 16 GB laptops, use the [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) Q4_K_M variant.
|
| 367 |
-
|
| 368 |
-
---
|
| 369 |
-
|
| 370 |
-
## Future Iteration — Multi-Token Prediction (MTP) Drafters
|
| 371 |
-
|
| 372 |
-
> **Not in the measured numbers above.** Google announced Gemma 4 MTP drafters on **May 5, 2026** ([blog](https://blog.google/innovation-and-ai/technology/developers-tools/multi-token-prediction-gemma-4/), [overview](https://ai.google.dev/gemma/docs/mtp/overview), [HF collection](https://huggingface.co/collections/google/gemma-4), [Kaggle](https://www.kaggle.com/models/google/gemma-4), [@GoogleGemma](https://x.com/googlegemma/status/2051694045869879749)) — after this artifact's final project-held-out check was captured. The numbers above reflect standard autoregressive decoding only. **MTP integration is documented here as future iteration; no measured speedup is claimed in this release.**
|
| 373 |
-
|
| 374 |
-
**Theoretical foundation.** Speculative decoding (Leviathan, Kalman & Matias, ICML 2023, [arXiv:2211.17192](https://arxiv.org/abs/2211.17192)) accelerates generation **without changing the output distribution under argmax decoding**: a smaller drafter proposes γ candidate tokens, the target verifies all γ in a single parallel forward pass, accepted tokens are kept, and any rejection is resampled from a corrected distribution. The output distribution is preserved exactly regardless of drafter quality; only **acceptance rate α**, and therefore walltime speedup, varies.
|
| 375 |
-
|
| 376 |
-
**What Google released on May 5, 2026.** Paired drafter checkpoints for all four IT-tuned Gemma 4 variants — `gemma-4-E2B-it-assistant`, `gemma-4-E4B-it-assistant`, `gemma-4-26B-A4B-it-assistant`, `gemma-4-31B-it-assistant` — discoverable via the [`google/gemma-4` Hugging Face collection](https://huggingface.co/collections/google/gemma-4) and on [Kaggle Models](https://www.kaggle.com/models/google/gemma-4). The drafters share the input embedding table with their paired target and consume the target's last-layer activations (architecture per the [MTP overview](https://ai.google.dev/gemma/docs/mtp/overview)). For the E4B target family the paired drafter is [`google/gemma-4-E4B-it-assistant`](https://huggingface.co/google/gemma-4-E4B-it-assistant) (~78.8 M params). Google reports **up to 3× decode speedup with no quality degradation** on the headline 26B-A4B configuration and **~2.2×** on Apple Silicon at batch sizes 4–8; per-variant E4B numbers were not enumerated in the announcement. Tested runtimes named in the blog: LiteRT-LM, MLX, Hugging Face Transformers, vLLM, SGLang, Ollama.
|
| 377 |
-
|
| 378 |
-
**Integration via Hugging Face Transformers** is a plain-`AutoModelForCausalLM` two-line load plus one extra kwarg:
|
| 379 |
-
|
| 380 |
-
```python
|
| 381 |
-
target = AutoModelForCausalLM.from_pretrained("Truthseeker87/solarhive-e4b-ollama", dtype=torch.bfloat16, ...)
|
| 382 |
-
assistant = AutoModelForCausalLM.from_pretrained("google/gemma-4-E4B-it-assistant", dtype=torch.bfloat16, ...)
|
| 383 |
-
target.generate(**inputs, assistant_model=assistant) # MTP enabled
|
| 384 |
-
```
|
| 385 |
-
|
| 386 |
-
The merged-safetensors load path on this repo is the cleanest E4B integration surface — no PEFT/Unsloth wrapping; the Hugging Face Transformers `assistant_model=` kwarg works directly.
|
| 387 |
-
|
| 388 |
-
**Open question specific to this LoRA-merged BF16 target.** Per the 2023 speculative-sampling guarantee, correctness is invariant to drafter quality — the target's verification step preserves the exact output distribution regardless of what the drafter proposes. What varies is **acceptance rate α**, since Google's released drafter was trained against the base `gemma-4-E4B-it`, not against this LoRA-merged target. Measured α at the edge BF16 tier is the planned post-hackathon contribution; a cloud-tier measurement against the A4B merged target is captured by the gated future-iteration cell in [`solarhive_inference.py`](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive/blob/main/solarhive_inference.py) §14.
|
| 389 |
-
|
| 390 |
-
---
|
| 391 |
-
|
| 392 |
-
## Companion Repositories
|
| 393 |
-
|
| 394 |
-
| Model | Repository | Purpose |
|
| 395 |
-
|-------|-----------|---------|
|
| 396 |
-
| **SolarHive 26B A4B LoRA** | [solarhive-26b-a4b-lora](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora) | Cloud inference with full multimodal + function calling (LoRA adapters) |
|
| 397 |
-
| **SolarHive 26B A4B Merged** | [solarhive-26b-a4b-merged](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-merged) | Full BF16 cloud model (~48 GB) — production inference, no PEFT/Unsloth dep |
|
| 398 |
-
| **SolarHive 26B A4B NF4** | [solarhive-26b-a4b-nf4](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-nf4) | Pre-quantized 4-bit cloud model for HF Spaces / 24 GB+ GPUs |
|
| 399 |
-
| **SolarHive E4B LoRA** | [solarhive-e4b-lora](https://huggingface.co/Truthseeker87/solarhive-e4b-lora) | E4B adapter weights (~200 MB) — apply over base via Unsloth |
|
| 400 |
-
| **SolarHive E4B safetensors** | This repo | Source safetensors for transformers research / GGUF conversion via llama.cpp |
|
| 401 |
-
| **SolarHive E4B GGUF** | [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) | **Edge deployment** — Q4_K_M GGUF + mmproj for Ollama / llama.cpp on 16 GB CPU laptop. **10/10 project-held-out check.** |
|
| 402 |
-
| **SolarHive Dataset** | [solarhive-community-solar-multimodal](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal) | 1,727 training examples (1,713 text + 14 image-grounded) |
|
| 403 |
-
| **LiteRT-LM Python edge runtime** | [`solarhive_e4b_litert_v3.1.ipynb`](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive/blob/main/solarhive_e4b_litert_v3.1.ipynb) | LiteRT Special Tech Track entry — runs upstream base [`litert-community/gemma-4-E4B-it-litert-lm`](https://huggingface.co/litert-community/gemma-4-E4B-it-litert-lm) `.litertlm` (3.66 GB) + SolarHive UX layer + on-device agentic loop with native Gemma 4 function calling. **Q&A 8/8** on Colab Pro CPU + High-RAM. Fine-tuned LiteRT-LM bundle is a planned next iteration once upstream `gemma4` example module lands in `ai_edge_torch.generative.examples/`. |
|
| 404 |
-
| **GitHub** | [the-gemma4-good-hackathon-solarhive](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive) | Full source code, training & quantization notebooks, data principles |
|
| 405 |
-
|
| 406 |
-
---
|
| 407 |
-
|
| 408 |
-
## Fine-Tuning Architecture — Text-Only on the Multimodal-Capable Corpus
|
| 409 |
-
|
| 410 |
-
**The shipped fine-tune is text-only** on the canonical
|
| 411 |
-
[`solarhive-community-solar-multimodal`](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal)
|
| 412 |
-
corpus (1,727 rows = 1,713 text + 14 image-grounded). Image rows are
|
| 413 |
-
skipped at the data-prep layer; the training pipeline pre-renders only
|
| 414 |
-
text rows for TRL's default text collator. Multimodal fine-tuning is
|
| 415 |
-
deferred post-hackathon — a real image corpus and a held-out VQA
|
| 416 |
-
benchmark would be prerequisites; the dataset's image schema is
|
| 417 |
-
preserved so a future multimodal fine-tune can re-enable image rows
|
| 418 |
-
without changing the corpus.
|
| 419 |
-
|
| 420 |
-
**VQA at inference time uses the base Gemma 4 E4B model's pretrained
|
| 421 |
-
vision encoder (~150M params per the [official model card](https://ai.google.dev/gemma/docs/core/model_card_4)).**
|
| 422 |
-
Our LoRA targets only the language-model linear layers
|
| 423 |
-
(`target=all-linear`); the vision tower is not modified. This matches
|
| 424 |
-
the Vertex AI Gemma 4 SFT recipe documented in the
|
| 425 |
-
[Hugging Face blog](https://huggingface.co/blog/gemma4), which
|
| 426 |
-
explicitly freezes both vision and audio towers during text-focused
|
| 427 |
-
fine-tuning.
|
| 428 |
-
|
| 429 |
-
Companion 26B A4B LoRA is published at
|
| 430 |
-
[`Truthseeker87/solarhive-26b-a4b-lora`](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora).
|
| 431 |
-
|
| 432 |
-
The dataset uses the project archive for its 14 image-grounded Q&A
|
| 433 |
-
turns (7 Ann Arbor sky photos × 2 turns). Image-source planning pivoted
|
| 434 |
-
twice: the SWIM corpora (NUS) were rejected for CC BY-NC licensing, and
|
| 435 |
-
NREL SRRL was rejected because the legacy MIDC SkyCam image archive
|
| 436 |
-
ended May 2017 (modern ASI-16 only exposes derived measurements). The
|
| 437 |
-
shipped dataset uses the project archive only — fewer images, but every
|
| 438 |
-
label is human-confirmed and every paired Q&A traces back to the same
|
| 439 |
-
GHI / temperature-derating formula used elsewhere in the dataset.
|
| 440 |
-
|
| 441 |
-
The fine-tune notebook has been pre-aligned with the official Unsloth
|
| 442 |
-
Gemma 4 documentation
|
| 443 |
-
([train guide](https://unsloth.ai/docs/models/gemma-4/train),
|
| 444 |
-
[bug fixes & tips](https://unsloth.ai/docs/models/gemma-4/train#bug-fixes--tips)):
|
| 445 |
-
explicit loader arguments (`max_seq_length`, `dtype`,
|
| 446 |
-
`full_finetuning=False`), explicit `SFTConfig` arguments
|
| 447 |
-
(`weight_decay`, `lr_scheduler_type`, `max_grad_norm`), and
|
| 448 |
-
`chat_template="gemma-4"` per Tip #1 (the simpler template is
|
| 449 |
-
recommended for E2B/E4B; `gemma-4-thinking` is reserved for 26B/31B
|
| 450 |
-
reasoning-class variants). The change makes the embedded chat
|
| 451 |
-
template more robust across downstream Ollama / llama.cpp runtimes
|
| 452 |
-
that don't expose `enable_thinking=False` at the runtime layer.
|
| 453 |
-
|
| 454 |
-
---
|
| 455 |
-
|
| 456 |
-
## Citation
|
| 457 |
-
|
| 458 |
-
```bibtex
|
| 459 |
-
@misc{solarhive2026,
|
| 460 |
-
title={SolarHive: AI-Powered Community Solar Energy Intelligence},
|
| 461 |
-
author={Youshen Lim},
|
| 462 |
-
year={2026},
|
| 463 |
-
url={https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive},
|
| 464 |
-
note={Gemma 4 Good Hackathon submission — Google DeepMind x Kaggle}
|
| 465 |
-
}
|
| 466 |
-
```
|
| 467 |
-
|
| 468 |
-
---
|
| 469 |
-
|
| 470 |
-
## Links
|
| 471 |
-
|
| 472 |
-
- **GitHub:** [youshen-lim/the-gemma4-good-hackathon-solarhive](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive)
|
| 473 |
-
- **Kaggle:** [The Gemma 4 Good Hackathon](https://kaggle.com/competitions/gemma-4-good-hackathon)
|
| 474 |
-
- **Base Model:** [google/gemma-4-e4b-it](https://kaggle.com/models/google/gemma-4)
|
| 475 |
-
- **Unsloth Gemma 4 docs:** [unsloth.ai/docs/models/gemma-4](https://unsloth.ai/docs/models/gemma-4)
|
| 476 |
-
|
| 477 |
-
*Built with Gemma 4 in Ann Arbor, Michigan. May 2026.*
|
| 478 |
-
|
| 479 |
-
*Gemma is a trademark of Google LLC.*
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
base_model: google/gemma-4-e4b-it
|
| 4 |
+
library_name: transformers
|
| 5 |
+
tags:
|
| 6 |
+
- gemma4
|
| 7 |
+
- solar-energy
|
| 8 |
+
- community-solar
|
| 9 |
+
- function-calling
|
| 10 |
+
- multimodal
|
| 11 |
+
- lora
|
| 12 |
+
- unsloth
|
| 13 |
+
- ollama
|
| 14 |
+
- edge-ai
|
| 15 |
+
- energy
|
| 16 |
+
- sustainability
|
| 17 |
+
- hackathon
|
| 18 |
+
datasets:
|
| 19 |
+
- Truthseeker87/solarhive-community-solar-multimodal
|
| 20 |
+
language:
|
| 21 |
+
- en
|
| 22 |
+
pipeline_tag: image-text-to-text
|
| 23 |
+
model-index:
|
| 24 |
+
- name: SolarHive-E4B-Merged
|
| 25 |
+
results:
|
| 26 |
+
- task:
|
| 27 |
+
type: question-answering
|
| 28 |
+
name: Domain Q&A
|
| 29 |
+
metrics:
|
| 30 |
+
- name: Accuracy
|
| 31 |
+
type: accuracy
|
| 32 |
+
value: 1.0
|
| 33 |
+
verified: false
|
| 34 |
+
- task:
|
| 35 |
+
type: text-generation
|
| 36 |
+
name: Tool Calling
|
| 37 |
+
metrics:
|
| 38 |
+
- name: Accuracy
|
| 39 |
+
type: accuracy
|
| 40 |
+
value: 0.8
|
| 41 |
+
verified: false
|
| 42 |
+
---
|
| 43 |
+
|
| 44 |
+

|
| 45 |
+
|
| 46 |
+
# SolarHive E4B — BF16 Merged Safetensors
|
| 47 |
+
|
| 48 |
+
**LoRA fine-tuned Gemma 4 E4B (8B), merged to 16-bit safetensors.** Source artifact for **direct transformers inference** and **llama.cpp `convert_hf_to_gguf.py` → Q4_K_M GGUF conversion** (which powers Ollama + llama.cpp edge deployment via the [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) companion repo).
|
| 49 |
+
|
| 50 |
+
> **For Ollama or llama.cpp edge deployment on a 16 GB CPU laptop, use the [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) repo instead** — it ships the 5.34 GB Q4_K_M GGUF (standard Q6_K-PLE recipe) plus the 992 MB `mmproj-BF16.gguf` companion (vision + audio), with `Modelfile`s ready for `ollama create` and a 10/10 score on the single-pass SolarHive project-held-out 10-prompt parity check.
|
| 51 |
+
>
|
| 52 |
+
> The `--experimental` Ollama path documented previously OOMs `ollama create` on ≤16 GB RAM (the 16 GB BF16 safetensors blob does not fit during ingestion). On hardware ≥24 GB RAM the experimental import works, but the GGUF pipeline (built using **llama.cpp** `convert_hf_to_gguf.py` + `llama-quantize`) is the recommended edge deployment path for everyone else.
|
| 53 |
+
|
| 54 |
+
This repository now serves three roles:
|
| 55 |
+
1. **Source for GGUF conversion** via [llama.cpp](https://github.com/ggerganov/llama.cpp)'s `convert_hf_to_gguf.py` (text tower) and `convert_hf_to_gguf.py --mmproj` (vision + audio projector). See [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) for the produced GGUF artifacts.
|
| 56 |
+
2. **Transformers-native multimodal use** — load with `AutoModelForCausalLM` for full image + audio + text in Python (requires ≥24 GB RAM or A100-class GPU).
|
| 57 |
+
3. **Reference for further fine-tuning** — extend the LoRA on additional data using Unsloth `FastVisionModel`.
|
| 58 |
+
|
| 59 |
+
Built for the [Gemma 4 Good Hackathon](https://kaggle.com/competitions/gemma-4-good-hackathon) (Google DeepMind x Kaggle).
|
| 60 |
+
|
| 61 |
+
| | |
|
| 62 |
+
|---|---|
|
| 63 |
+
| **Base Model** | [google/gemma-4-e4b-it](https://kaggle.com/models/google/gemma-4) |
|
| 64 |
+
| **Architecture** | Dense + PLE — 8B total, 4.5B effective |
|
| 65 |
+
| **Fine-Tuning** | LoRA via [Unsloth](https://unsloth.ai) (BF16) |
|
| 66 |
+
| **Training Data** | 1,727 examples ([solarhive-community-solar-multimodal](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal)) — text-only fine-tune; VQA at inference uses the base [Gemma 4 vision encoder](https://ai.google.dev/gemma/docs/core/model_card_4) (~150M params), unmodified by our LoRA per the [Vertex AI SFT recipe](https://huggingface.co/blog/gemma4) |
|
| 67 |
+
| **Converged Loss** | **0.9218** |
|
| 68 |
+
| **Project-held-out check** | 9/10 (5/5 domain Q&A + 4/5 tool calling) — May 2026 final run, multi-call regression on TQ5 (see Multi-Variant Deployment Validation below) |
|
| 69 |
+
| **Training Time** | 420 seconds (~7 minutes) |
|
| 70 |
+
| **Compute** | Google Colab Pro |
|
| 71 |
+
| **License** | MIT (adapters) / Gemma Terms (base model) |
|
| 72 |
+
|
| 73 |
+
---
|
| 74 |
+
|
| 75 |
+
## Model Overview
|
| 76 |
+
|
| 77 |
+
SolarHive E4B is the **edge companion** to [SolarHive 26B A4B](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora). While the 26B model powers cloud inference with full multimodal VQA, the E4B model is optimized for local deployment via Ollama on consumer hardware.
|
| 78 |
+
|
| 79 |
+
**Privacy-first:** Running Gemma 4 locally means community energy data never leaves the neighborhood. No cloud dependency, no internet requirement, no data privacy concerns. A village in rural India, a suburb in Michigan, and a coastal town recovering from a hurricane all get the same intelligence.
|
| 80 |
+
|
| 81 |
+
This repository contains the **fully merged model** (base + LoRA baked together) — no separate base model download needed.
|
| 82 |
+
|
| 83 |
+
---
|
| 84 |
+
|
| 85 |
+
## Training Details
|
| 86 |
+
|
| 87 |
+
| Parameter | Value |
|
| 88 |
+
|-----------|-------|
|
| 89 |
+
| Method | LoRA via Unsloth `FastVisionModel` (BF16, RTX PRO 6000 96 GB) |
|
| 90 |
+
| LoRA rank | 16 |
|
| 91 |
+
| LoRA alpha | 16 |
|
| 92 |
+
| LoRA dropout | 0 |
|
| 93 |
+
| Target modules | All linear layers |
|
| 94 |
+
| Learning rate | 2e-4 |
|
| 95 |
+
| Optimizer | AdamW 8-bit |
|
| 96 |
+
| Warmup steps | 5 |
|
| 97 |
+
| Epochs | 3 |
|
| 98 |
+
| Max sequence length | 2048 |
|
| 99 |
+
| Precision | BF16 |
|
| 100 |
+
| Seed | 3407 |
|
| 101 |
+
| Trainable parameters | 41.2M / 8.0B (0.51%) |
|
| 102 |
+
|
| 103 |
+
### Training Loss
|
| 104 |
+
|
| 105 |
+
| Metric | Value |
|
| 106 |
+
|--------|-------|
|
| 107 |
+
| Converged loss (last 20 steps) | **0.9218** |
|
| 108 |
+
| Final step loss | 0.0635 |
|
| 109 |
+
| Minimum loss | 0.0635 |
|
| 110 |
+
| Total steps | 324 |
|
| 111 |
+
| Training time | 420 seconds |
|
| 112 |
+
|
| 113 |
+
> **Canonical metric:** the bolded **Converged loss (last 20 steps)** is the only smoothed convergence indicator. *Final step* and *Minimum* are single-batch point statistics — mini-batch loss is noisy step-to-step, so one easy batch can drop a point estimate well below the rolling-average trend.
|
| 114 |
+
|
| 115 |
+
### Training Data
|
| 116 |
+
|
| 117 |
+
Same canonical training corpus as the 26B A4B model — [solarhive-community-solar-multimodal](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal), 1,727 rows:
|
| 118 |
+
|
| 119 |
+
- 413 hand-crafted examples spanning 15+ US cities and 9 energy domains
|
| 120 |
+
- ~1,117 API-grounded examples from live Open-Meteo, PVWatts, OWM, and EIA data
|
| 121 |
+
- 183 tool-calling examples (positive, negative refusals, follow-up clarifications, failure-recovery)
|
| 122 |
+
- 14 image-grounded Q&A turns from 7 manually-labeled Ann Arbor sky photographs
|
| 123 |
+
|
| 124 |
+
### Hardware
|
| 125 |
+
|
| 126 |
+
- **GPU:** NVIDIA RTX PRO 6000 Blackwell Server Edition (102 GB GDDR7 total, 94.97 GB max usable per Unsloth)
|
| 127 |
+
- **Platform:** Google Colab Pro (G4 VM)
|
| 128 |
+
|
| 129 |
+
---
|
| 130 |
+
|
| 131 |
+
## Project-Held-Out Results
|
| 132 |
+
|
| 133 |
+
### Domain Q&A (5/5)
|
| 134 |
+
|
| 135 |
+
| Question | Result |
|
| 136 |
+
|----------|--------|
|
| 137 |
+
| Solar production when humidity exceeds 80%? | Correct |
|
| 138 |
+
| Battery SOC threshold for grid export? | Correct |
|
| 139 |
+
| Home #3 underperforming 22% — diagnostic checklist? | Correct |
|
| 140 |
+
| Winter snow on panels — prioritize actions? | Correct |
|
| 141 |
+
| Grid frequency 59.8 Hz — microgrid implications? | Correct |
|
| 142 |
+
|
| 143 |
+
> **Note on validation history:** the 5/5 Q&A above is from the initial 8-question validation harness used during fine-tune development. The canonical headline number is the May 2026 final-run multi-variant validation (single-pass project-held-out 10-question parity check) — see below.
|
| 144 |
+
|
| 145 |
+
### Tool inventory + inference-time When2Call validation
|
| 146 |
+
|
| 147 |
+
`solarhive_inference.py` exposes **5 tools** to the model — all three keyed APIs (`OWM_API_KEY`, `EIA_API_KEY`, `NREL_API_KEY`) actively wired:
|
| 148 |
+
|
| 149 |
+
| Tool | API | Returns |
|
| 150 |
+
|------|-----|---------|
|
| 151 |
+
| `get_weather(location)` | OpenWeatherMap (`OWM_API_KEY`) | Temperature, clouds %, wind, humidity, sunrise/sunset |
|
| 152 |
+
| `get_solar_production(clouds_pct, temp_f)` | Open-Meteo GHI (keyless) | Production kW, efficiency %, GHI W/m², temp derating |
|
| 153 |
+
| `get_battery_state()` | Community BMS (sim) | State of charge, capacity, charging status |
|
| 154 |
+
| `get_grid_status()` | EIA Open Data (`EIA_API_KEY`) | Pricing period, rate/kWh, renewable %, CO2 intensity |
|
| 155 |
+
| `get_nrel_pvwatts_baseline()` | NREL PVWatts v8 (`NREL_API_KEY`) | Annual + current-month typical kWh + avg kW for the 72 kW array |
|
| 156 |
+
|
| 157 |
+
Tool results feed back as a **2-message sequence** matching the training distribution: `{"role": "assistant", "tool_calls": [...]}` then `{"role": "tool", "name": "<fn>", "content": json.dumps(result)}` per call. Shared across the data-generation pipeline, the fine-tune SFT preprocessing layer, and the inference agentic loop — inference matches training distribution exactly.
|
| 158 |
+
|
| 159 |
+
**When2Call probes.** Three held-out probes validate 3 of the 4 failure-mode categories from [Ross, H., Mahabaleshwarkar, A. S., & Suhara, Y. (2025). *When2Call: When (not) to Call Tools.* arXiv:2504.18851](https://arxiv.org/abs/2504.18851) — the paper documents 9–67% tool-hallucination rates on (c)+(d) in untrained community models:
|
| 160 |
+
|
| 161 |
+
- **(b)** *"What's the current grid rate?"* → expect `get_grid_status` call (well-specified, in-scope)
|
| 162 |
+
- **(c)** *"How much will a 10 kW array produce today?"* → expect follow-up question (does NOT auto-fill location default)
|
| 163 |
+
- **(d)** *"What's the current air quality index in Ann Arbor?"* → expect refusal + redirect (does NOT hallucinate a tool)
|
| 164 |
+
|
| 165 |
+
Models trained without explicit *unable-to-answer* and *follow-up clarification* examples typically fail (c) + (d). The SolarHive corpus includes 16 such examples (10 *unable-to-answer* + 6 *follow-up clarification*) following the When2Call taxonomy.
|
| 166 |
+
|
| 167 |
+
### Multi-Variant Deployment Validation (Final Run, May 2026) — E4B regression on When2Call (c)
|
| 168 |
+
|
| 169 |
+
End-to-end inference run on Colab Pro G4. This E4B BF16 merged variant
|
| 170 |
+
loaded from a local cache (16.9 GB VRAM utilization, ~10 min runtime).
|
| 171 |
+
|
| 172 |
+
**Project-held-out parity check: 5/5 Q&A + 4/5 tool = 9/10** on the 10-question set —
|
| 173 |
+
matches the [A4B family](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora)
|
| 174 |
+
on the 9 deterministic questions; the single FAIL is the lenient
|
| 175 |
+
multi-call probe (TQ5 — *"Compare today's irradiance forecast across
|
| 176 |
+
Ann Arbor, Phoenix, and Seattle"*, `min_calls=2`) where this variant
|
| 177 |
+
emitted only 1 `get_weather` call. Notably, the
|
| 178 |
+
[E4B LoRA + base variant](https://huggingface.co/Truthseeker87/solarhive-e4b-lora)
|
| 179 |
+
(same fine-tune, applied via Unsloth instead of merged) DOES chain
|
| 180 |
+
3 calls on the same probe and scores 10/10 — pattern reproducible
|
| 181 |
+
across runs.
|
| 182 |
+
|
| 183 |
+
**[When2Call](https://arxiv.org/abs/2504.18851) probes — measured 2/3 (final run May 2026):**
|
| 184 |
+
|
| 185 |
+
| Probe | E4B merged behavior | Score |
|
| 186 |
+
|-------|---------------------|:-:|
|
| 187 |
+
| **(b)** *"current grid rate?"* | ✅ Correctly calls `get_grid_status` | PASS |
|
| 188 |
+
| **(c)** *"How much will a 10 kW array produce today?"* | ❌ Auto-fills location and calls `get_solar_production` instead of asking back | FAIL |
|
| 189 |
+
| **(d)** *"current AQI in Ann Arbor?"* | ✅ Genuinely disclaims (no fabrication, no tool call) | PASS |
|
| 190 |
+
|
| 191 |
+
**Cross-variant pattern:** the [E4B LoRA + base variant](https://huggingface.co/Truthseeker87/solarhive-e4b-lora) is inferred to score **2/3** by mathematical lossless equivalence with this merged variant (the merge step is lossless on weights, so the When2Call decision boundary is identical). The +1/3 W2C delta vs the [A4B family](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora) (3/3 directly measured on A4B LoRA, inferred-lossless on A4B merged + NF4) is the empirical signature of size-vs-refusal scaling.
|
| 192 |
+
|
| 193 |
+
**Honest finding — size-vs-refusal scaling is real, and was the pre-stated hypothesis.**
|
| 194 |
+
This E4B fine-tune regresses on (c) compared to the
|
| 195 |
+
[A4B LoRA baseline](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora)
|
| 196 |
+
(which scores 3/3). The smaller model with less reasoning depth more readily
|
| 197 |
+
auto-fills missing parameters when it should ask back — exactly the failure
|
| 198 |
+
mode Ross et al. 2025 document at 9-67% rates in untrained community models.
|
| 199 |
+
The fine-tune closes (b)+(d) at this size but doesn't fully close (c).
|
| 200 |
+
|
| 201 |
+
**This was the expected outcome going in**, per the [official Google Gemma 4 Core docs](https://ai.google.dev/gemma/docs/core) *"Parameter sizes and quantization"*: *"Models with higher parameters and bit counts (higher precision) are generally more capable, but are more expensive to run."* E4B's 8B total / 4.5B effective parameters / ~150M vision encoder vs A4B's 25.2B total / 3.8B active (MoE) / ~550M vision encoder reflect a deliberate ~3× capacity gap on the dimension that drives reasoning-heavy refusal/follow-up behavior. The validation confirms the documented scaling — not a defect, but architecture-aware deployment design.
|
| 202 |
+
|
| 203 |
+
**Quantitative reinforcement** from [Unsloth's published Gemma 4 benchmarks](https://unsloth.ai/docs/models/gemma-4): E4B scores **69.4% on MMLU Pro** (vs 26B A4B's 82.6% — a 13.2 pp gap), **52.6% on MMMU Pro** (vs 73.8% — 21.2 pp gap), and **42.5% on AIME 2026** (vs 88.3% — a 45.8 pp gap). The AIME math-reasoning gap and MMMU Pro multimodal-reasoning gap directly **predict** the (c)/(d) [When2Call](https://arxiv.org/abs/2504.18851) regression we observe here — the smaller model's published reasoning-benchmark deltas scale cleanly into the 2-of-3 behavioral regression vs the [A4B baseline](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora). E4B is the right choice for the volume of well-specified, in-scope queries that dominate everyday community-energy interactions; A4B handles the harder reasoning edge cases.
|
| 204 |
+
|
| 205 |
+
**Deployment recommendation:** Use this E4B variant for the volume of
|
| 206 |
+
**well-specified, in-scope queries** (production estimates, grid pricing,
|
| 207 |
+
maintenance guidance) where (b)-category routing dominates. Route
|
| 208 |
+
**under-specified or out-of-scope queries** to the A4B cloud variant for
|
| 209 |
+
correct refusal + follow-up behavior. A future fine-tune could increase
|
| 210 |
+
the E4B *follow-up clarification* example count (currently 6) and
|
| 211 |
+
*unable-to-answer* count (currently 10) to close the gap.
|
| 212 |
+
|
| 213 |
+
---
|
| 214 |
+
|
| 215 |
+
## How to Use
|
| 216 |
+
|
| 217 |
+
### Loading with transformers
|
| 218 |
+
|
| 219 |
+
```python
|
| 220 |
+
from transformers import AutoModelForCausalLM, AutoProcessor
|
| 221 |
+
import torch
|
| 222 |
+
|
| 223 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 224 |
+
"Truthseeker87/solarhive-e4b-ollama", # This repo (merged safetensors)
|
| 225 |
+
dtype=torch.bfloat16,
|
| 226 |
+
device_map="auto",
|
| 227 |
+
trust_remote_code=True,
|
| 228 |
+
)
|
| 229 |
+
processor = AutoProcessor.from_pretrained(
|
| 230 |
+
"Truthseeker87/solarhive-e4b-ollama",
|
| 231 |
+
trust_remote_code=True,
|
| 232 |
+
)
|
| 233 |
+
```
|
| 234 |
+
|
| 235 |
+
### Edge Deployment — use the GGUF repo
|
| 236 |
+
|
| 237 |
+
For Ollama or llama.cpp on a 16 GB CPU laptop, **download the GGUF artifacts** instead of trying to import these safetensors:
|
| 238 |
+
|
| 239 |
+
```bash
|
| 240 |
+
hf download Truthseeker87/solarhive-e4b-gguf \
|
| 241 |
+
solarhive-e4b-q4_k_m.gguf Modelfile \
|
| 242 |
+
--local-dir ./solarhive-gguf
|
| 243 |
+
cd ./solarhive-gguf
|
| 244 |
+
ollama create solarhive -f Modelfile
|
| 245 |
+
ollama run solarhive "What's the best time to run my dishwasher today?"
|
| 246 |
+
```
|
| 247 |
+
|
| 248 |
+
The [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) repo ships the Q4_K_M GGUF (standard Q6_K-PLE recipe, 5.34 GB) plus a 992 MB `mmproj-BF16.gguf` for full multimodal via `llama-server --mmproj`.
|
| 249 |
+
|
| 250 |
+
### Edge Deployment via Ollama `--experimental` (≥24 GB RAM only)
|
| 251 |
+
|
| 252 |
+
If you have ≥24 GB system RAM, you can experimentally import these safetensors directly via Ollama:
|
| 253 |
+
|
| 254 |
+
```bash
|
| 255 |
+
git clone https://huggingface.co/Truthseeker87/solarhive-e4b-ollama
|
| 256 |
+
cd solarhive-e4b-ollama
|
| 257 |
+
cat > Modelfile << 'EOF'
|
| 258 |
+
FROM .
|
| 259 |
+
SYSTEM "You are SolarHive, an AI energy advisor for a community of 12 homes with rooftop solar and shared battery storage in Ann Arbor, Michigan. Use the available tools to get real-time data before answering. Be specific, reference actual data, and keep responses concise (3-5 sentences)."
|
| 260 |
+
PARAMETER temperature 1.0
|
| 261 |
+
PARAMETER top_p 0.95
|
| 262 |
+
PARAMETER top_k 64
|
| 263 |
+
PARAMETER num_ctx 4096
|
| 264 |
+
EOF
|
| 265 |
+
ollama create solarhive --experimental -f Modelfile
|
| 266 |
+
ollama run solarhive "What's the best time to run my dishwasher today?"
|
| 267 |
+
```
|
| 268 |
+
|
| 269 |
+
> **OOM warning:** on 16 GB RAM, `ollama create --experimental` crashes around 44% blob processing as Ollama tries to materialize the full 16 GB BF16 model in memory during ingestion. Use the GGUF path above instead.
|
| 270 |
+
>
|
| 271 |
+
> The official base (non-fine-tuned) E4B is also available as a pre-built GGUF on [ollama.com/library/gemma4:e4b](https://ollama.com/library/gemma4:e4b) (9.6 GB, Q4_K_M). Our [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) adds 1,727 examples of community solar domain expertise on top.
|
| 272 |
+
|
| 273 |
+
### GGUF Conversion via llama.cpp (reproducibility recipe)
|
| 274 |
+
|
| 275 |
+
These safetensors are the source artifact for the GGUF deployment. Reproducible via [llama.cpp](https://github.com/ggerganov/llama.cpp) tooling:
|
| 276 |
+
|
| 277 |
+
```bash
|
| 278 |
+
# Text tower → BF16 GGUF (~14 GB intermediate)
|
| 279 |
+
python convert_hf_to_gguf.py --outtype bf16 \
|
| 280 |
+
--outfile solarhive-e4b-bf16.gguf \
|
| 281 |
+
Truthseeker87/solarhive-e4b-ollama/
|
| 282 |
+
|
| 283 |
+
# Quantize text → Q4_K_M (shipped recipe, 5.34 GB; needs ≥30 GB RAM)
|
| 284 |
+
llama-quantize \
|
| 285 |
+
solarhive-e4b-bf16.gguf solarhive-e4b-q4_k_m.gguf Q4_K_M
|
| 286 |
+
|
| 287 |
+
# Multimodal projector (vision SigLIP + audio Conformer, ~992 MB)
|
| 288 |
+
python convert_hf_to_gguf.py --mmproj --outtype bf16 \
|
| 289 |
+
--outfile mmproj-solarhive-e4b-BF16.gguf \
|
| 290 |
+
Truthseeker87/solarhive-e4b-ollama/
|
| 291 |
+
```
|
| 292 |
+
|
| 293 |
+
The shipped 5.34 GB Q4_K_M quant requires ≥30 GB RAM at quantization time (the Q6_K-PLE tensor needs a ~10.7 GB float32 buffer). To quantize on a 16 GB laptop instead, add `--tensor-type per_layer_token_embd.weight=q4_0` — it bypasses that buffer and yields a smaller (~4.6 GB) GGUF, validated quality-safe in development. See the [`solarhive_quantize_e4b.ipynb`](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive) notebook for the high-RAM recipe.
|
| 294 |
+
|
| 295 |
+
---
|
| 296 |
+
|
| 297 |
+
## Core Capabilities
|
| 298 |
+
|
| 299 |
+
### 1. Multimodal Visual Question Answering (3 Modes)
|
| 300 |
+
|
| 301 |
+
Available because the base Gemma 4 E4B vision encoder (~150M params) is preserved unmodified in these merged weights:
|
| 302 |
+
|
| 303 |
+
| Mode | Input | Output |
|
| 304 |
+
|------|-------|--------|
|
| 305 |
+
| Sky Analysis | Sky photograph | Cloud coverage %, production forecast, storage recommendation |
|
| 306 |
+
| Panel Inspection | Panel photograph | Dirt/damage/shading detection, efficiency impact estimate |
|
| 307 |
+
| Neighborhood Assessment | Aerial/satellite image | Panel inventory, expansion priorities, shading analysis |
|
| 308 |
+
|
| 309 |
+
### 2. Native Function Calling (5 Tools — all 3 keyed APIs wired)
|
| 310 |
+
|
| 311 |
+
| Tool | API | Returns |
|
| 312 |
+
|------|-----|---------|
|
| 313 |
+
| `get_weather(location)` | OpenWeatherMap (`OWM_API_KEY`) | Temperature, clouds %, wind, humidity, sunrise/sunset |
|
| 314 |
+
| `get_solar_production(clouds_pct, temp_f)` | Open-Meteo GHI (keyless) | Production kW, efficiency %, GHI W/m², temp derating |
|
| 315 |
+
| `get_battery_state()` | Community BMS (sim) | State of charge, capacity, charging status |
|
| 316 |
+
| `get_grid_status()` | EIA Open Data (`EIA_API_KEY`) | Pricing period, rate/kWh, renewable %, CO2 intensity |
|
| 317 |
+
| `get_nrel_pvwatts_baseline()` | NREL PVWatts v8 (`NREL_API_KEY`) | Annual + current-month typical kWh + avg kW for the 72 kW array |
|
| 318 |
+
|
| 319 |
+
### 3. Selective Tool Reasoning
|
| 320 |
+
|
| 321 |
+
The model decides when to call tools — it does not blindly invoke all of them:
|
| 322 |
+
|
| 323 |
+
```
|
| 324 |
+
"What time does peak pricing start?"
|
| 325 |
+
→ Calls: get_grid_status() only
|
| 326 |
+
|
| 327 |
+
"Should I run my pool heater now?"
|
| 328 |
+
→ Calls: get_weather() + get_solar_production() + get_battery_state() + get_grid_status()
|
| 329 |
+
|
| 330 |
+
"What are general maintenance tips for panels?"
|
| 331 |
+
→ Calls: none (answers from training knowledge)
|
| 332 |
+
```
|
| 333 |
+
|
| 334 |
+
---
|
| 335 |
+
|
| 336 |
+
## Community Model
|
| 337 |
+
|
| 338 |
+
| Parameter | Value |
|
| 339 |
+
|-----------|-------|
|
| 340 |
+
| Location | Ann Arbor, Michigan (42.2808°N, 83.7430°W) |
|
| 341 |
+
| Community size | 12 homes |
|
| 342 |
+
| Total panel capacity | 72 kW |
|
| 343 |
+
| Shared battery storage | 100 kWh |
|
| 344 |
+
| Grid region | MISO (Midcontinent Independent System Operator) |
|
| 345 |
+
|
| 346 |
+
---
|
| 347 |
+
|
| 348 |
+
## Technical Notes
|
| 349 |
+
|
| 350 |
+
- **Merged BF16 safetensors.** Base + LoRA fused via Unsloth `save_pretrained_merged("merged_16bit")`. Loads with plain `transformers.AutoModelForCausalLM.from_pretrained(...)` — no PEFT or Unsloth dependency at inference time.
|
| 351 |
+
- **Vision tower frozen during fine-tune.** VQA at inference uses the base model's pretrained vision encoder unmodified, matching the [Vertex AI SFT recipe](https://huggingface.co/blog/gemma4) which freezes both vision and audio towers during text-focused fine-tuning.
|
| 352 |
+
- **Two-step tokenization at inference.** Single-step `tokenize=True` crashes in transformers 5.5.x on messages without a `content` key (e.g., `tool_calls` messages). Always render text first (`tokenize=False`) then tokenize separately.
|
| 353 |
+
- **Sampling defaults.** `temperature=1.0, top_p=0.95, top_k=64` (Kaggle-recommended Gemma 4 defaults).
|
| 354 |
+
- **Chat template.** `gemma-4` (per Unsloth Tip #1 for E2B/E4B). The `gemma-4-thinking` template is reserved for 26B/31B reasoning-class variants. The simpler template is more robust across downstream Ollama / llama.cpp runtimes that don't expose `enable_thinking=False` at the runtime layer.
|
| 355 |
+
|
| 356 |
+
---
|
| 357 |
+
|
| 358 |
+
## Limitations
|
| 359 |
+
|
| 360 |
+
- **Prototype scope.** Tested on a single community model (12 homes, Ann Arbor, MI). Real-world deployment requires validation across diverse geographies and community sizes.
|
| 361 |
+
- **Smaller model, weaker refusal/follow-up.** When2Call (c) regression vs the A4B baseline (2/3 vs 3/3 — see Multi-Variant Deployment Validation above). Route under-specified or out-of-scope queries to the A4B cloud variant for correct refusal + follow-up behavior.
|
| 362 |
+
- **Occasional capacity hallucination.** The base model's prior occasionally surfaces "60 kW" instead of the correct 72 kW community capacity in direct (no-tool) responses. The tool-calling path (which queries actual capacity from `get_nrel_pvwatts_baseline`) avoids this.
|
| 363 |
+
- **External API dependence.** Tool responses depend on Open-Meteo, OWM, EIA, and PVWatts availability with their respective rate limits.
|
| 364 |
+
- **Battery state is simulated.** `get_battery_state()` is a deterministic in-memory simulator for demonstrations — real deployment requires integration with actual battery management systems.
|
| 365 |
+
- **Single-trial multi-variant validation.** The May 2026 final-run project-held-out numbers are from one inference pass; a multi-trial bootstrap would strengthen the multi-call regression claim against temperature-1.0 stochasticity.
|
| 366 |
+
- **Memory.** ~16 GB BF16 safetensors require ≥24 GB system RAM at load time — does not fit on consumer 16 GB laptops in this format. For 16 GB laptops, use the [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) Q4_K_M variant.
|
| 367 |
+
|
| 368 |
+
---
|
| 369 |
+
|
| 370 |
+
## Future Iteration — Multi-Token Prediction (MTP) Drafters
|
| 371 |
+
|
| 372 |
+
> **Not in the measured numbers above.** Google announced Gemma 4 MTP drafters on **May 5, 2026** ([blog](https://blog.google/innovation-and-ai/technology/developers-tools/multi-token-prediction-gemma-4/), [overview](https://ai.google.dev/gemma/docs/mtp/overview), [HF collection](https://huggingface.co/collections/google/gemma-4), [Kaggle](https://www.kaggle.com/models/google/gemma-4), [@GoogleGemma](https://x.com/googlegemma/status/2051694045869879749)) — after this artifact's final project-held-out check was captured. The numbers above reflect standard autoregressive decoding only. **MTP integration is documented here as future iteration; no measured speedup is claimed in this release.**
|
| 373 |
+
|
| 374 |
+
**Theoretical foundation.** Speculative decoding (Leviathan, Kalman & Matias, *Fast Inference from Transformers via Speculative Decoding*, ICML 2023, [arXiv:2211.17192](https://arxiv.org/abs/2211.17192)) accelerates generation **without changing the output distribution under argmax decoding**: a smaller drafter proposes γ candidate tokens, the target verifies all γ in a single parallel forward pass, accepted tokens are kept, and any rejection is resampled from a corrected distribution. The output distribution is preserved exactly regardless of drafter quality; only **acceptance rate α**, and therefore walltime speedup, varies.
|
| 375 |
+
|
| 376 |
+
**What Google released on May 5, 2026.** Paired drafter checkpoints for all four IT-tuned Gemma 4 variants — `gemma-4-E2B-it-assistant`, `gemma-4-E4B-it-assistant`, `gemma-4-26B-A4B-it-assistant`, `gemma-4-31B-it-assistant` — discoverable via the [`google/gemma-4` Hugging Face collection](https://huggingface.co/collections/google/gemma-4) and on [Kaggle Models](https://www.kaggle.com/models/google/gemma-4). The drafters share the input embedding table with their paired target and consume the target's last-layer activations (architecture per the [MTP overview](https://ai.google.dev/gemma/docs/mtp/overview)). For the E4B target family the paired drafter is [`google/gemma-4-E4B-it-assistant`](https://huggingface.co/google/gemma-4-E4B-it-assistant) (~78.8 M params). Google reports **up to 3× decode speedup with no quality degradation** on the headline 26B-A4B configuration and **~2.2×** on Apple Silicon at batch sizes 4–8; per-variant E4B numbers were not enumerated in the announcement. Tested runtimes named in the blog: LiteRT-LM, MLX, Hugging Face Transformers, vLLM, SGLang, Ollama.
|
| 377 |
+
|
| 378 |
+
**Integration via Hugging Face Transformers** is a plain-`AutoModelForCausalLM` two-line load plus one extra kwarg:
|
| 379 |
+
|
| 380 |
+
```python
|
| 381 |
+
target = AutoModelForCausalLM.from_pretrained("Truthseeker87/solarhive-e4b-ollama", dtype=torch.bfloat16, ...)
|
| 382 |
+
assistant = AutoModelForCausalLM.from_pretrained("google/gemma-4-E4B-it-assistant", dtype=torch.bfloat16, ...)
|
| 383 |
+
target.generate(**inputs, assistant_model=assistant) # MTP enabled
|
| 384 |
+
```
|
| 385 |
+
|
| 386 |
+
The merged-safetensors load path on this repo is the cleanest E4B integration surface — no PEFT/Unsloth wrapping; the Hugging Face Transformers `assistant_model=` kwarg works directly.
|
| 387 |
+
|
| 388 |
+
**Open question specific to this LoRA-merged BF16 target.** Per the 2023 speculative-sampling guarantee, correctness is invariant to drafter quality — the target's verification step preserves the exact output distribution regardless of what the drafter proposes. What varies is **acceptance rate α**, since Google's released drafter was trained against the base `gemma-4-E4B-it`, not against this LoRA-merged target. Measured α at the edge BF16 tier is the planned post-hackathon contribution; a cloud-tier measurement against the A4B merged target is captured by the gated future-iteration cell in [`solarhive_inference.py`](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive/blob/main/solarhive_inference.py) §14.
|
| 389 |
+
|
| 390 |
+
---
|
| 391 |
+
|
| 392 |
+
## Companion Repositories
|
| 393 |
+
|
| 394 |
+
| Model | Repository | Purpose |
|
| 395 |
+
|-------|-----------|---------|
|
| 396 |
+
| **SolarHive 26B A4B LoRA** | [solarhive-26b-a4b-lora](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora) | Cloud inference with full multimodal + function calling (LoRA adapters) |
|
| 397 |
+
| **SolarHive 26B A4B Merged** | [solarhive-26b-a4b-merged](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-merged) | Full BF16 cloud model (~48 GB) — production inference, no PEFT/Unsloth dep |
|
| 398 |
+
| **SolarHive 26B A4B NF4** | [solarhive-26b-a4b-nf4](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-nf4) | Pre-quantized 4-bit cloud model for HF Spaces / 24 GB+ GPUs |
|
| 399 |
+
| **SolarHive E4B LoRA** | [solarhive-e4b-lora](https://huggingface.co/Truthseeker87/solarhive-e4b-lora) | E4B adapter weights (~200 MB) — apply over base via Unsloth |
|
| 400 |
+
| **SolarHive E4B safetensors** | This repo | Source safetensors for transformers research / GGUF conversion via llama.cpp |
|
| 401 |
+
| **SolarHive E4B GGUF** | [solarhive-e4b-gguf](https://huggingface.co/Truthseeker87/solarhive-e4b-gguf) | **Edge deployment** — Q4_K_M GGUF + mmproj for Ollama / llama.cpp on 16 GB CPU laptop. **10/10 project-held-out check.** |
|
| 402 |
+
| **SolarHive Dataset** | [solarhive-community-solar-multimodal](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal) | 1,727 training examples (1,713 text + 14 image-grounded) |
|
| 403 |
+
| **LiteRT-LM Python edge runtime** | [`solarhive_e4b_litert_v3.1.ipynb`](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive/blob/main/solarhive_e4b_litert_v3.1.ipynb) | LiteRT Special Tech Track entry — runs upstream base [`litert-community/gemma-4-E4B-it-litert-lm`](https://huggingface.co/litert-community/gemma-4-E4B-it-litert-lm) `.litertlm` (3.66 GB) + SolarHive UX layer + on-device agentic loop with native Gemma 4 function calling. **Q&A 8/8** on Colab Pro CPU + High-RAM. Fine-tuned LiteRT-LM bundle is a planned next iteration once upstream `gemma4` example module lands in `ai_edge_torch.generative.examples/`. |
|
| 404 |
+
| **GitHub** | [the-gemma4-good-hackathon-solarhive](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive) | Full source code, training & quantization notebooks, data principles |
|
| 405 |
+
|
| 406 |
+
---
|
| 407 |
+
|
| 408 |
+
## Fine-Tuning Architecture — Text-Only on the Multimodal-Capable Corpus
|
| 409 |
+
|
| 410 |
+
**The shipped fine-tune is text-only** on the canonical
|
| 411 |
+
[`solarhive-community-solar-multimodal`](https://huggingface.co/datasets/Truthseeker87/solarhive-community-solar-multimodal)
|
| 412 |
+
corpus (1,727 rows = 1,713 text + 14 image-grounded). Image rows are
|
| 413 |
+
skipped at the data-prep layer; the training pipeline pre-renders only
|
| 414 |
+
text rows for TRL's default text collator. Multimodal fine-tuning is
|
| 415 |
+
deferred post-hackathon — a real image corpus and a held-out VQA
|
| 416 |
+
benchmark would be prerequisites; the dataset's image schema is
|
| 417 |
+
preserved so a future multimodal fine-tune can re-enable image rows
|
| 418 |
+
without changing the corpus.
|
| 419 |
+
|
| 420 |
+
**VQA at inference time uses the base Gemma 4 E4B model's pretrained
|
| 421 |
+
vision encoder (~150M params per the [official model card](https://ai.google.dev/gemma/docs/core/model_card_4)).**
|
| 422 |
+
Our LoRA targets only the language-model linear layers
|
| 423 |
+
(`target=all-linear`); the vision tower is not modified. This matches
|
| 424 |
+
the Vertex AI Gemma 4 SFT recipe documented in the
|
| 425 |
+
[Hugging Face blog](https://huggingface.co/blog/gemma4), which
|
| 426 |
+
explicitly freezes both vision and audio towers during text-focused
|
| 427 |
+
fine-tuning.
|
| 428 |
+
|
| 429 |
+
Companion 26B A4B LoRA is published at
|
| 430 |
+
[`Truthseeker87/solarhive-26b-a4b-lora`](https://huggingface.co/Truthseeker87/solarhive-26b-a4b-lora).
|
| 431 |
+
|
| 432 |
+
The dataset uses the project archive for its 14 image-grounded Q&A
|
| 433 |
+
turns (7 Ann Arbor sky photos × 2 turns). Image-source planning pivoted
|
| 434 |
+
twice: the SWIM corpora (NUS) were rejected for CC BY-NC licensing, and
|
| 435 |
+
NREL SRRL was rejected because the legacy MIDC SkyCam image archive
|
| 436 |
+
ended May 2017 (modern ASI-16 only exposes derived measurements). The
|
| 437 |
+
shipped dataset uses the project archive only — fewer images, but every
|
| 438 |
+
label is human-confirmed and every paired Q&A traces back to the same
|
| 439 |
+
GHI / temperature-derating formula used elsewhere in the dataset.
|
| 440 |
+
|
| 441 |
+
The fine-tune notebook has been pre-aligned with the official Unsloth
|
| 442 |
+
Gemma 4 documentation
|
| 443 |
+
([train guide](https://unsloth.ai/docs/models/gemma-4/train),
|
| 444 |
+
[bug fixes & tips](https://unsloth.ai/docs/models/gemma-4/train#bug-fixes--tips)):
|
| 445 |
+
explicit loader arguments (`max_seq_length`, `dtype`,
|
| 446 |
+
`full_finetuning=False`), explicit `SFTConfig` arguments
|
| 447 |
+
(`weight_decay`, `lr_scheduler_type`, `max_grad_norm`), and
|
| 448 |
+
`chat_template="gemma-4"` per Tip #1 (the simpler template is
|
| 449 |
+
recommended for E2B/E4B; `gemma-4-thinking` is reserved for 26B/31B
|
| 450 |
+
reasoning-class variants). The change makes the embedded chat
|
| 451 |
+
template more robust across downstream Ollama / llama.cpp runtimes
|
| 452 |
+
that don't expose `enable_thinking=False` at the runtime layer.
|
| 453 |
+
|
| 454 |
+
---
|
| 455 |
+
|
| 456 |
+
## Citation
|
| 457 |
+
|
| 458 |
+
```bibtex
|
| 459 |
+
@misc{solarhive2026,
|
| 460 |
+
title={SolarHive: AI-Powered Community Solar Energy Intelligence},
|
| 461 |
+
author={Youshen Lim},
|
| 462 |
+
year={2026},
|
| 463 |
+
url={https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive},
|
| 464 |
+
note={Gemma 4 Good Hackathon submission — Google DeepMind x Kaggle}
|
| 465 |
+
}
|
| 466 |
+
```
|
| 467 |
+
|
| 468 |
+
---
|
| 469 |
+
|
| 470 |
+
## Links
|
| 471 |
+
|
| 472 |
+
- **GitHub:** [youshen-lim/the-gemma4-good-hackathon-solarhive](https://github.com/youshen-lim/the-gemma4-good-hackathon-solarhive)
|
| 473 |
+
- **Kaggle:** [The Gemma 4 Good Hackathon](https://kaggle.com/competitions/gemma-4-good-hackathon)
|
| 474 |
+
- **Base Model:** [google/gemma-4-e4b-it](https://kaggle.com/models/google/gemma-4)
|
| 475 |
+
- **Unsloth Gemma 4 docs:** [unsloth.ai/docs/models/gemma-4](https://unsloth.ai/docs/models/gemma-4)
|
| 476 |
+
|
| 477 |
+
*Built with Gemma 4 in Ann Arbor, Michigan. May 2026.*
|
| 478 |
+
|
| 479 |
+
*Gemma is a trademark of Google LLC.*
|