Serie: Self-Hosted LLMs für Datensouveränität | Code: GitHub
In Post 8 haben wir Llama-3.1-8B als self-hosted Judge evaluiert: 65% Agreement mit Claude Sonnet 4.5, klare Grenzen bei nuancierten B/C-Ratings. Die Frage blieb offen: Wie viel besser ist ein 8.75× größeres Model?
Der ursprüngliche Plan: Llama-70B auf AWS g5.12xlarge (4× A10G GPUs). Die Realität: Frankfurt komplett ausverkauft, Service Quotas zu niedrig, Wartezeit unbestimmt.
Die Alternative: Llama-3.1-70B lokal auf Mac Studio Max (M4 Max, 64 GB Unified Memory). Kein Deployment, keine Quota-Requests, kein Hourly Billing.
Und nebenbei: Die nächste Stufe der Data Sovereignty. Von self-hosted LLMs auf Cloud-Infrastruktur (Posts 1-8) zu komplett on-premise - keine Daten bei AWS, GCP oder anderen Cloud Providern.
Die Frage: Funktioniert das überhaupt? Und wie schnell kann es wirklich sein?
Spoiler: Ja - und überraschend. Mit optimiertem GPU Offloading: 20 Minuten Runtime für 170 Samples. Schneller als Cloud end-to-end (inkl. 15min Setup). 70% Agreement (vs 64% bei 8B), 6× bessere B-Detection, praktisch nutzbar.
Wichtig: Dieser Post fokussiert sich auf Inference Performance (LLM-as-Judge Evaluations). Training kommt in Post 9.
TL;DR – Für eilige Leser
Setup: Llama-3.1-70B-Q4 via Ollama auf Mac Studio Max (M4 Max, 64 GB RAM), 170 identische Samples wie Post 8
Ergebnisse:
| Judge | Agreement | A-Ratings | B-Ratings | C-Ratings |
|---|---|---|---|---|
| Claude Sonnet 4.5 | - | 110 (64.7%) | 50 (29.4%) | 10 (5.9%) |
| Llama-3.1-70B | 70.0% | 145 (85.3%) | 19 (11.2%) | 6 (3.5%) |
| Llama-3.1-8B | 64.1% | 166 (97.6%) | 3 (1.8%) | 1 (0.6%) |
Kernerkenntnisse:
- ✅ +5.9pp Agreement vs 8B – statistisch signifikante Verbesserung
- ✅ 6× bessere B-Detection (11.2% vs 1.8%)
- ✅ ~60-75% C-Detection nach manueller Validierung (Claude hatte 2 False Positives)
- ✅ 20min Runtime, schneller als Cloud – mit optimiertem GPU Offloading (num_gpu: 81)
- ✅ $0 Cost, vollständige Data Sovereignty – komplett on-premise, keine Daten bei Cloud Providern
- ⚠️ Immer noch 15pp unter Claude – kein Drop-in Replacement
- ⚠️ Optimistic Bias bleibt – 85% A-Ratings, immer noch 20pp über Claude
Empfehlung: Llama-70B auf Apple Silicon mit optimiertem Setup ist schneller als Cloud end-to-end für kurze/mittlere Jobs. Für Production Quality Control: Commercial Judge oder noch größere Modelle.
Inhaltsverzeichnis
- AWS sagt Nein: Die Capacity-Realität
- Apple Silicon als Alternative
- Setup: Llama-70B auf Mac Studio Max
- Ergebnisse: 70% Agreement, 6× bessere Detection
- Manuelle Validierung: Die 7 False Negatives
- Performance: GPU Offloading als Game Changer
- Code & Resources
- Fazit
AWS sagt Nein: Die Capacity-Realität
Der Plan war simpel: g5.12xlarge Node Group in EKS, vLLM Deployment, 171 Samples in ~10 Minuten evaluieren.
Die Realität:
Launching a new EC2 instance. Status Reason: Could not launch On-Demand Instances.
InsufficientInstanceCapacity - We currently do not have sufficient g5.12xlarge
capacity in the Availability Zone you requested (eu-central-1b).
Versuch 2: eu-central-1a, eu-central-1c – gleicher Fehler.
Versuch 3: Service Quota Increase für g5.24xlarge (96 vCPUs statt 48) – 1-3 Werktage Wartezeit, ~$10/h statt ~$5.67/h (g5.12xlarge).
Versuch 4: Spot Instances – benötigt ebenfalls Quota Increase, und erfahrungsgemäß noch schlechter verfügbar als On-Demand.
Der Moment der Erkenntnis: Frankfurt ist ausverkauft. Wir können warten, andere Regionen probieren, oder… einen anderen Weg finden.
Apple Silicon als Alternative
Verfügbare Hardware: Mac Studio Max mit M4 Max Chip, 64 GB Unified Memory.
Die Frage: Reicht das für Llama-3.1-70B (70.5B Parameter)?
Model Size Check (mit Default 131k Context):
- Llama-70B-Q4 (INT4 Quantization): ~40 GB
- KV Cache (131k Context): ~40 GB → Zu viel!
- Compute Graph (131k Context): ~16 GB
- System + macOS: ~8-12 GB
- Total (131k Context): ~104-108 GB ❌ Passt nicht in 64 GB
Die Lösung: Context Size drastisch reduzieren.
Judge Tasks brauchen wenig Context:
- System Prompt: ~500 tokens
- Chunk: ~200 tokens
- Question + Answer: ~100 tokens
- Total Input: ~800 tokens ← 4k Context reicht locker!
Mit 4k Context:
- Model: 39.6 GB
- KV Cache: ~1.3 GB (statt 40 GB!)
- Compute Graph: ~0.6 GB (statt 16.3 GB bei 131k Context!)
- Total: ~41.5 GB ✅ Passt locker in 64 GB mit entsprechendem Headroom
Setup: Llama-70B auf Mac Studio Max
Ollama Installation & Model Creation
Wichtig: Ollama läuft als Server - alle Commands kommunizieren über http://localhost:11434.
# 1. Ollama installieren
brew install ollama
# 2. Server starten (in eigenem Terminal, läuft dauerhaft)
ollama serve
# 3. In neuem Terminal: Base Model pullen (40 GB Download, ~60 Minuten)
ollama pull llama3.1:70b-instruct-q4_K_M
# 4. Modelfile für 4k Context erstellen
cat > Modelfile-llama70b-4k << 'EOF'
FROM llama3.1:70b-instruct-q4_K_M
PARAMETER num_ctx 4096
PARAMETER num_gpu 81
EOF
# 5. Model mit kleinem Context erstellen
ollama create llama3.1-70b-4k -f Modelfile-llama70b-4k
Wichtig: num_gpu 81 lädt alle 81 Transformer Layers auf Metal (Apple GPU). Bei initialen Tests hatten wir aus Versehen nur 34 Layers auf GPU geladen - explizites Setzen auf 81 brachte 140% Performance-Gewinn (siehe Performance-Section). Der Default von -1 (auto) hat in unseren Tests auch funktioniert.
Memory Breakdown (tatsächlich, 4k Context):
Model Weights: 39.6 GB (CPU + Metal)
KV Cache: 1.3 GB (4k Context)
Compute Graph: 0.6 GB
Total: ~41.5 GB von 64 GB (22.5 GB frei für System u.a.)
Evaluation Script
Identischer Judge-Prompt wie Post 8, angepasst für Ollama API:
# llm_as_judge_ollama.py
response = requests.post(
f"{ollama_url}/api/generate",
json={
"model": "llama3.1-70b-4k",
"prompt": combined_prompt,
"stream": False,
"options": {
"temperature": 0.0, # Identisch zu Post 8 (Claude) für fairen Vergleich
"num_predict": 300 # Identisch zu Post 8 (Claude) für fairen Vergleich
}
}
)
170 Samples (eine missing im Merge):
python3 llm_as_judge_ollama.py \
--samples all_samples_60x3.jsonl \
--output llama70b_results.jsonl \
--model llama3.1-70b-4k
Runtime: 20 Minuten (~7 Sekunden pro Sample)
Ergebnisse: 70% Agreement, 6× bessere Detection
Overall Agreement
| Vergleich | Agreement | Verbesserung |
|---|---|---|
| Claude vs Llama-70B | 70.0% (119/170) | +5.9pp vs 8B |
| Claude vs Llama-8B | 64.1% (109/170) | Baseline |
| Llama-8B vs Llama-70B | 87.1% (148/170) | Beide immer noch optimistischer als Claude |
70% Agreement ist signifikant besser, aber immer noch 15 Prozentpunkte unter einem idealen Drop-in Replacement.
Rating Verteilung
Movement Richtung Claude:
Claude: ████████████████████████████████ 64.7% A
████████████ 29.4% B
██ 5.9% C
Llama-70B: ██████████████████████████████████████████ 85.3% A
████ 11.2% B
█ 3.5% C
Llama-8B: ████████████████████████████████████████████████ 97.6% A
█ 1.8% B
█ 0.6% C
70B findet mehr Probleme als 8B:
- B-Detection: 19 vs 3 → 6× besser
- C-Detection: 6 vs 1 → 6× besser
Aber immer noch deutlich optimistischer als Claude.
Detection Rates (roh)
B-Rating Detection (Speculation):
- Claude identifiziert: 50 Samples
- Llama-70B findet: 19 davon → 38% Detection Rate
- Llama-8B findet: 3 davon → 6% Detection Rate
C-Rating Detection (Hallucinations, vor manueller Validierung):
- Claude identifiziert: 10 Samples
- Llama-70B findet: 6 davon (60%)
- Llama-70B missed: 4 davon
- Aber: Manuelle Validierung zeigt anderes Bild!
Manuelle Validierung: Die 7 False Negatives
Die kritische Frage: Sind die 4 gemissten C-Ratings wirklich Hallucinations?
Methodik: Alle 7 Fälle wo Claude C gab aber Llama-70B nicht (4× A, 3× B) manuell reviewt.
Ergebnis:
| Kategorie | Count | Details |
|---|---|---|
| Claude False Positive | 2 | Zu streng, Answer ist OK |
| Grenzfall | 1 | B (Llama) könnte akzeptabel sein |
| True Hallucination | 4 | Claude hat Recht, Llama übersah sie |
Revidierte C-Detection:
- Claude’s 10 C-Ratings: ~7-8 echte Hallucinations (2 False Positives)
- Llama-70B fand: 6 C-Ratings
- Echte Detection Rate: ~60-75% (nicht die rohen 60%)
Beispiel: Claude False Positive
Chunk:
Prices are the same across all regions.
Question: “In which AWS regions are prices identical?”
Answer: “Prices are identical across all AWS regions.”
Claude: C – “Answer adds ‘AWS regions’ which is not mentioned in the chunk. The chunk only states ‘all regions’ without specifying AWS, making this a hallucination of specific context not present in the source material.”
Llama-70B: A – “Answer is strictly based on the chunk content, rephrasing it accurately without adding any new information.”
Manuelles Review: ✅ Llama hat Recht. Die Antwort übernimmt “AWS regions” aus der Frage (nicht erfunden), kombiniert mit “all regions” aus dem Chunk. Das ist kontextuelle Präzisierung, keine Hallucination. Claude interpretiert “strictly based on chunk” zu rigide.
Learning: Judge-Prompts müssen differenzieren zwischen echter Hallucination (Info erfunden) und kontextueller Präzisierung (Kontext aus Frage + Info aus Chunk).
Beispiel: True Hallucination (Llama missed)
Question: “Can you reserve Amazon MQ instances?”
Answer: “Reserved instances are available for long-term workloads.”
Chunk: “No, Amazon MQ does not offer reserved instance pricing.”
Claude: C – “Answer contradicts chunk, says reserved instances available when chunk says no”
Llama-70B: A – “Answer based on chunk content”
Manuelles Review: ✅ Claude hat Recht, klare Hallucination.
Learning: Llama-70B übersieht manchmal direkte Widersprüche.
Performance: GPU Offloading als Game Changer
Speed Comparison
vLLM (4× A10G, AWS g5.12xlarge):
- Throughput: ~50-70 tokens/sec
- Pro Sample: ~2-3 Sekunden
- 170 Samples: ~5-9 Minuten
- Cost: ~$5.67/Stunde = ~$1 für Test
Anmerkung: Diese Zahlen sind basierend auf Erfahrungswerten mit vLLM auf ähnlichen GPU-Setups (Posts 5-7), nicht auf g5.12xlarge getestet da keine Capacity verfügbar war.
Ollama (M4 Max, Mac Studio) - Optimiert:
- Throughput: ~20 tokens/sec
- Pro Sample: ~7 Sekunden
- 170 Samples: ~20 Minuten
- Cost: $0
Ratio: vLLM ist ~2-× schneller (reine Inference-Zeit).
GPU Offloading: Der kritische Parameter
Was passierte bei initialen Tests:
Llama-3.1-70B hat 81 Transformer Layers. Bei der ersten Model-Erstellung wurden nur 34 Layers auf Metal geladen.
Initiale Tests (Auto-Detection):
num_gpu: 34/81 Layers (42% GPU Offloading)
→ 58% der Layers auf CPU
→ Runtime: 48min
→ Throughput: ~8 tokens/sec
Warum nur 34? Unser Fehler:
- Wir waren zu konservativ.
- Wollten OOM vermeiden.
Memory-Analyse zeigte Potenzial:
- Activity Monitor: 22.5 GB freier RAM (von 64 GB)
- Unified Memory: GPU kann mehr System RAM nutzen
- CPU-Layers sind der Bottleneck (~5-10× langsamer als Metal!)
Optimization:
cat > Modelfile-optimized << 'EOF'
FROM llama3.1:70b-instruct-q4_K_M
PARAMETER num_ctx 4096
PARAMETER num_gpu 81 # Alle Layers auf Metal!
EOF
ollama create llama3.1-70b-4k -f Modelfile-optimized
Ergebnis (Optimiert):
num_gpu: 81/81 Layers (100% GPU Offloading)
→ 0% auf CPU
→ Runtime: 20min ✅ (2.4× schneller!)
→ Throughput: ~20 tokens/sec (2.5× schneller!)
→ Memory: Stabil bei ~54 GB (kein Swap-Stress)
Learning: CPU-Fallback für 58% der Layers kostete 28 Minuten (140% Overhead). GPU Offloading ist ein kritischer Performance-Parameter für Apple Silicon. Maximale Layers austesten!
End-to-End Zeiten in der Praxis
Die 2-4× Speed-Differenz gilt nur für reine Inference-Zeit. Real-world ist komplexer:
Scale-to-Zero Cloud (Argo/EKS):
- Node Startup: ~5-8 min
- Pod + Model Download: ~5-8 min
- Warmup: ~1-2 min
- Setup-Overhead: ~15 min (wenn Capacity verfügbar!)
Für unseren Use Case (170 Samples):
- Cloud end-to-end: ~15min + 10min = ~25min
- Mac end-to-end: 0min + 20min = 20min
- → Mac ist schneller! 🚀 *Außer beim ersten Mal, wenn das Modell heruntergeladen werden muss.
ABER: Capacity ist nicht garantiert.
Wie wir am Anfang gesehen haben: Frankfurt komplett ausverkauft. In solchen Fällen:
- Quota Increase beantragen: +1-3 Werktage + ggf. teurere Instanz (g5.24xlarge $10/h vs g5.12xlarge $5.67/h)
- Andere Region probieren: +Setup-Zeit + höhere Latenz
- Spot Instances: Noch schlechter verfügbar, können jederzeit terminiert werden
- Warten auf Capacity: Unbestimmt
Mac Studio: Immer verfügbar. Kein Warten, kein Quota-Management, kein “InsufficientCapacity”. $0/h.
Trade-offs:
- Kurze/mittlere Jobs (<2h): Mac schneller end-to-end, $0 vs $5.67-10/h, garantierte Verfügbarkeit
- Marathon Jobs (>5h): Cloud Setup irrelevant, 4× Speed-Differenz dominiert, aber Kosten akkumulieren
- Iterative Development: Mac gewinnt massiv - kein 15min Setup bei jedem Run, keine hourly charges
- Verfügbarkeit: Mac gewinnt - keine Capacity-Probleme, keine Quota-Requests
Warum überraschend schnell?
Unified Memory Advantage:
- CPU + GPU teilen 64 GB RAM
- GPU kann bis zu ~40 GB für Model Layers nutzen
- Alle 81 Layers passen auf Metal (mit 4k Context!)
- Memory Bandwidth: ~400 GB/s (weniger als dedicated VRAM, aber ausreichend)
Metal Optimizations:
- Apple Metal gut optimiert für Llama-Architektur (seit M1)
- INT4 Quantization native supported
- Aggressive GPU Offloading möglich dank Unified Memory
Der CPU-Bottleneck Killer:
- Mit konservativen Settings: 58% Layers auf CPU → 48min
- Mit optimiert: 0% Layers auf CPU → 20min
- CPU-Fallback kostet 140% Performance!
Trade-off Analyse
Wann macht Apple Silicon Sinn:
Pros:
- Vollständige Data Sovereignty – wenn auch die Datenhaltung 100% souverän sein muss, keine Daten bei Cloud - Providern
- Kurze/mittlere Jobs (<2h) – Mac ist schneller end-to-end (20min vs 25min Cloud inkl. Setup)
- Iterative Development – Kein 15min Setup bei jedem Run, 20min statt 25min für Tests
- Cost-sensitive Use Cases – $0 vs $20-50+ AWS (je nach Laufzeit)
- Capacity-Engpässe – Immer verfügbar, keine Quota-Requests
- Unvorhersehbare Workloads – Keine Wartezeit, sofort einsatzberei
Cons:
- Marathon Jobs (>5h) – Bei sehr langen Jobs wird Cloud Setup irrelevant, 4× Speed-Gap dominiert
- Team Collaboration – Shared Cloud-Infra besser für mehrere Nutzer gleichzeitig
- Extreme Throughput – Für 1000+ Samples pro Stunde braucht’s Cloud-Scale
Für diesen Test: Ideal. 20min statt 25min, $0 statt $1-2, garantierte Verfügbarkeit, und vollständige Data Sovereignty.
Die Hybride Strategie
Für Production könnte das funktionieren:
1. Llama-70B Pre-Filter (lokal)
↓ Findet ~60-75% der Probleme
↓ Cost: $0
2. Claude Final Review (Cloud)
↓ Nur auf flagged Samples (~15%)
↓ Cost: 85% Reduktion vs Full Claude
3. Manual Spot-Check (10%)
↓ Ground Truth Validation
Best of Both Worlds: Cost-Efficiency + Quality Assurance.
Wichtiger Caveat für Data Sovereignty:
Diese hybride Strategie sendet ~15% der Samples an Claude (Cloud). Wenn vollständige Data Sovereignty erforderlich ist:
- Option A: Nur anonymisierte/synthetische Test-Daten an Claude senden
- Option B: Komplett on-premise bleiben (70B + manuelle Reviews statt Claude)
Trade-off: Quality vs. Data Sovereignty muss bewusst entschieden werden.
Code & Resources
GitHub Repository: self-hosted-llms-tutorial
Scripts für diesen Post:
llm_as_judge_ollama.py- Ollama Judge Evaluationmerge_judge_results.py- Merge 8B, 70B, Claude Resultsextract_missed_hallucinations.py- False Negatives für Manual Review
Setup Llama-70B auf Apple Silicon
# 1. Ollama installieren
brew install ollama
# 2. Server starten (in eigenem Terminal)
ollama serve
# 3. In neuem Terminal: Base Model laden
ollama pull llama3.1:70b-instruct-q4_K_M
# 4. Model mit 4k Context UND optimiertem GPU Offloading erstellen
cat > Modelfile << 'EOF'
FROM llama3.1:70b-instruct-q4_K_M
PARAMETER num_ctx 4096
PARAMETER num_gpu 81
EOF
ollama create llama3.1-70b-4k -f Modelfile
# 5. Evaluation laufen lassen (in weiterem Terminal)
python3 llm_as_judge_ollama.py \
--samples your_samples.jsonl \
--output results.jsonl \
--model llama3.1-70b-4k
Requirements: Mac mit Apple Silicon (M1/M2/M3/M4), mindestens 64 GB RAM
Wichtig: num_gpu 81 lädt alle Layers auf Metal. Auto-Detection (num_gpu: -1, default) hat in unseren Tests auch funktioniert. Sie richtige Einstellung verhindert Performance-Verlust!
Fazit
Llama-3.1-70B auf Apple Silicon ist keine Notlösung, sondern eine überraschend starke Alternative - schneller als Cloud für typische Use Cases, $0 Cost, und vollständige Data Sovereignty.
Was wir erreicht haben:
- ✅ 70% Agreement – messbar besser als 8B, aber unter Commercial Judges
- ✅ ~60-75% Hallucination Detection nach manueller Validierung
- ✅ 20min Runtime – schneller als Cloud end-to-end (inkl. 15min Setup)
- ✅ $0 Cost, volle Data Sovereignty – komplett on-premise, keine Daten bei Cloud Providern (nächste Stufe nach self-hosted auf AWS)
- ✅ Empirisch validiert – 170 Samples + manuelle Review der Critical Cases
Die klaren Grenzen:
- ❌ Kein Production Quality Control – 70% Agreement reicht nicht für Final QC
- ❌ Performance-Gap bei Marathon Jobs – bei >5h Jobs wird Cloud Setup irrelevant, 4× Speed-Gap dominiert
- ❌ Optimistic Bias bleibt – immer noch zu optimistisch vs Claude
- ❌ Prompt-sensitive – direkte Widersprüche manchmal übersehen
Was wir gelernt haben:
- Model Size hilft, aber ist keine Silver Bullet – 8.75× größer ≠ 8.75× besser
- Consumer Hardware mit richtiger Config ist stark – schneller als Cloud für Jobs <2h, garantierte Verfügbarkeit, aber: GPU Offloading kritisch!
- Manuelle Validierung ist essentiell – auch Claude macht Fehler (2/10 False Positives)
- Hybride Strategien möglich, aber Trade-off – 70B Pre-Filter + Claude Final Review = Cost-Efficiency + Quality, aber nur mit anonymisierten Daten wenn Data Sovereignty wichtig ist
- Prompt Engineering Potential in beide Richtungen – Llama’s False Negatives UND Claude’s False Positives zeigen konkrete Verbesserungs-Ansätze
- GPU Offloading ist DER kritische Parameter – Auto-Detection kann konservativ sein, explizites Setzen auf maximale Layers brachte 140% Performance-Gewinn!
Data Sovereignty erreicht die nächste Stufe – von self-hosted LLMs auf Cloud-Infrastruktur (Posts 1-8) zu komplett on-premise. Schneller als Cloud für typische Jobs, $0 Cost, immer verfügbar ohne Capacity-Probleme oder Quota-Management, und jetzt auch ohne Cloud Provider für die Daten selbst.
Wichtige Einschränkung: Dieser Post fokussiert sich auf Inference Performance. Die überraschend gute Performance wirft aber die Frage auf: Wie sieht’s mit Training aus? Könnte LoRA Fine-Tuning aus Post 5 auch lokal auf Mac Studio laufen? Das schauen wir uns in Post 9 an.
Im nächsten Post: Multi-LoRA A/B Testing - Adapter-Iteration basierend auf Evaluation-Feedback. Wie verbessern wir die Performance durch gezieltes Re-Training mit problematischen Patterns?
Ausblick: Für Production Deployment (Argo Workflows, Monitoring, CI/CD) planen wir eine separate Blog-Serie, da diese Themen generisch für alle ML-Pipelines gelten, nicht nur für Self-Hosted LLMs.