|
| 1 | +# Ollama Gemma 4 Migration Runbook |
| 2 | + |
| 3 | +**Date**: 2026-04-05 |
| 4 | +**Author**: Claude Code |
| 5 | +**Status**: Complete |
| 6 | + |
| 7 | +## Summary |
| 8 | + |
| 9 | +Migrate Ollama models from current stack to Gemma 4 (e2b) after benchmark testing showed decisive performance improvements. |
| 10 | + |
| 11 | +## Context |
| 12 | + |
| 13 | +### Current Model Stack (pre-migration) |
| 14 | +| Use Case | Model | Speed | Notes | |
| 15 | +|----------|-------|-------|-------| |
| 16 | +| Voice PE conversation | qwen3.5:4b | 5.4 tok/s | BELOW 10 tok/s threshold | |
| 17 | +| Camera vision analysis | gemma3:4b | ~15 tok/s | LLM Vision blueprint | |
| 18 | +| Package delivery detection | llava:7b | ~8 tok/s | llmvision.image_analyzer | |
| 19 | + |
| 20 | +### Hardware |
| 21 | +- **GPU**: NVIDIA RTX 3070 (8GB VRAM) |
| 22 | +- **Node**: k3s-vm-pumped-piglet-gpu |
| 23 | +- **Constraints**: OLLAMA_MAX_LOADED_MODELS=1, OLLAMA_GPU_OVERHEAD=1GB |
| 24 | + |
| 25 | +### Benchmark Results (2026-04-05) |
| 26 | + |
| 27 | +**qwen3.5:4b vs gemma4:e2b** across 4 Voice PE scenarios, 3 iterations each: |
| 28 | + |
| 29 | +| Test | qwen3.5:4b | gemma4:e2b | |
| 30 | +|------|-----------|-----------| |
| 31 | +| Quick Q&A | 8.84s / 5.1 t/s | 0.99s / 21.7 t/s | |
| 32 | +| Time parsing | 3.58s / 6.0 t/s | 0.92s / 20.8 t/s | |
| 33 | +| Entity control | 5.89s / 5.3 t/s | 1.31s / 18.3 t/s | |
| 34 | +| Multi-step reasoning | 6.06s / 5.4 t/s | 1.60s / 19.6 t/s | |
| 35 | +| **Overall** | **6.09s / 5.4 t/s** | **1.21s / 20.1 t/s** | |
| 36 | + |
| 37 | +**Result**: gemma4:e2b is 269% faster, 80% less latency. Passes Voice PE threshold (>10 tok/s). Response quality is concise and natural (better for voice). |
| 38 | + |
| 39 | +### Gemma 4 Model Selection |
| 40 | + |
| 41 | +| Variant | Size | VRAM Fit (8GB) | Notes | |
| 42 | +|---------|------|----------------|-------| |
| 43 | +| gemma4:e2b | 7.2GB (q4_K_M) | YES | Best fit for RTX 3070 | |
| 44 | +| gemma4:e4b | 9.6GB (q4_K_M) | NO | Exceeds VRAM with 1GB overhead | |
| 45 | +| gemma4:26b | 18GB | NO | Way too large | |
| 46 | + |
| 47 | +## Migration Steps |
| 48 | + |
| 49 | +### Step 1: Upgrade Ollama (DONE) |
| 50 | +- **File**: `gitops/clusters/homelab/apps/ollama/deployment.yaml` |
| 51 | +- **Change**: `ollama/ollama:0.17.7` -> `ollama/ollama:0.20.2` |
| 52 | +- **Why**: Gemma 4 requires Ollama 0.20.0+ |
| 53 | + |
| 54 | +### Step 2: Update model-update Job |
| 55 | +- **File**: `gitops/clusters/homelab/apps/ollama/job-model-update.yaml` |
| 56 | +- **Change**: NEW_MODEL=`gemma4:e2b`, OLD_MODEL=`qwen3.5:4b` |
| 57 | +- **Why**: Flux-managed model lifecycle |
| 58 | + |
| 59 | +### Step 3: Update HA conversation agent |
| 60 | +- **Script**: `scripts/ollama/set-ha-model.sh gemma4:e2b` |
| 61 | +- **What it does**: Edits HA storage JSON inside HAOS container, reloads Ollama integration |
| 62 | +- **Rollback**: Timestamped backup created automatically |
| 63 | + |
| 64 | +### Step 4: Update vision automations (NOT changing) |
| 65 | +- **LLM Vision** (automations.yaml lines 17, 37): `gemma3:4b` -> keep as-is |
| 66 | +- **Package Detection** (lines 189, 319): `llava:7b` -> keep as-is |
| 67 | +- **Why**: These use the `llmvision.image_analyzer` action with separate provider config. |
| 68 | + gemma4:e2b is multimodal but the LLM Vision integration manages its own model loading. |
| 69 | + Since OLLAMA_MAX_LOADED_MODELS=1, loading gemma4:e2b for vision would evict |
| 70 | + the conversation model. The vision models are loaded on-demand when events trigger. |
| 71 | + Changing these requires testing the LLM Vision integration separately. |
| 72 | + |
| 73 | +### Step 5: Update model selection reference |
| 74 | +- **File**: `scripts/ollama/README.md` |
| 75 | +- **Change**: Add gemma4:e2b to model table, mark as recommended |
| 76 | + |
| 77 | +### Step 6: Clean up old models |
| 78 | +- Old models (qwen3.5:4b, qwen3:4b) removed via model-update Job |
| 79 | +- gemma4:e2b pulled via same Job |
| 80 | + |
| 81 | +## Rollback Plan |
| 82 | + |
| 83 | +1. **Revert deployment image**: `ollama/ollama:0.20.2` -> `ollama/ollama:0.17.7` (only if 0.20.2 unstable) |
| 84 | +2. **Revert conversation model**: `scripts/ollama/set-ha-model.sh qwen3.5:4b` |
| 85 | +3. **Revert model-update Job**: Change NEW_MODEL back to `qwen3.5:4b` |
| 86 | + |
| 87 | +## Verification |
| 88 | + |
| 89 | +After migration: |
| 90 | +```bash |
| 91 | +# Check Ollama version and models |
| 92 | +scripts/ollama/check-ollama.sh |
| 93 | + |
| 94 | +# Test inference speed |
| 95 | +scripts/ollama/test-inference.sh gemma4:e2b "what time is it?" |
| 96 | + |
| 97 | +# Test voice PE end-to-end |
| 98 | +# Say "Hey Nabu, what's the weather like?" and confirm response <3s |
| 99 | +``` |
| 100 | + |
| 101 | +## Future Work |
| 102 | + |
| 103 | +- Test gemma4:e2b with LLM Vision integration for camera analysis (replace gemma3:4b) |
| 104 | +- Test gemma4:e2b with package detection (replace llava:7b) |
| 105 | +- Consider gemma4:e4b if a GPU upgrade happens |
0 commit comments