Der FireAI-Sicherheitsblog

Von FireAI Security & Research Team · Veröffentlicht

Ein lokales LLM auf Apple Silicon für Sicherheits-Triage betreiben

Ein lokales LLM auf Apple Silicon für Sicherheits-Triage betreiben

Ein Modell, das eine Netzwerkverbindung als prüfenswert oder nicht einstuft und dabei auf demselben Mac läuft, der die Verbindung aufgebaut hat, verändert drei Dinge gleichzeitig: was die Maschine verlässt, was der Betrieb kostet, und ob es weiterläuft, wenn das Netzwerk selbst der Gegenstand des Verdachts ist. Alle drei zählen für ein Sicherheitswerkzeug mehr als für die meisten anderen Anwendungen eines Sprachmodells, weshalb es in diesem Artikel gezielt um den On-Device-Fall geht, nicht um den Aufruf einer API.

Warum On-Device, speziell für Triage

Eine Verbindungs-Logzeile zur Klassifizierung an ein Cloud-Modell zu senden, bedeutet, bei jeder einzelnen Entscheidung zu übertragen, welche App auf Ihrem Mac gerade mit welchem Host über welchen Port spricht. Nichts davon ist geheim wie ein Passwort, aber es ist genau die Art von Metadaten, deren Weitergabe ein sicherheitsbewusstes Setup zu minimieren versucht, und ein Werkzeug, dessen gesamter Zweck darin besteht zu entscheiden, was Ihr Mac anderswohin senden darf, hat einen offensichtlichen Grund, nicht selbst bei jeder Entscheidung davon abhängig zu sein, etwas anderswohin zu senden. Das Modell lokal auszuführen, entfernt diese Abhängigkeit vollständig: Die Logzeile verlässt das Gerät nie, weil im gesamten Entscheidungsweg überhaupt kein Netzwerkaufruf vorkommt.

Der zweite Grund ist Kontinuität. Ein cloud-basierter Triage-Schritt ist nur so verfügbar wie Ihre Internetverbindung und die API des Anbieters — und genau das sind die Dinge, die bei einem echten Vorfall beeinträchtigt oder gezielt gekappt sein könnten. Ein Modell, das im lokalen Speicher läuft, antwortet weiter, auch wenn das Netzwerk ausfällt, das WLAN aus ist oder auf genau der Verbindung, die der API-Aufruf genutzt hätte, gerade eine vermutete Kompromittierung im Gange ist.

MLX: Apples eigenes Array-Framework

MLX ist ein Array-Framework, das Apples Machine-Learning-Forschungsteam gezielt für Apple Silicon gebaut hat, mit APIs für Python, C++, C und Swift. Die eigene Dokumentation beschreibt ein einheitliches Speichermodell als seine prägende Design-Entscheidung: Arrays in MLX liegen in gemeinsam genutztem Speicher, und Operationen darauf können auf jedem unterstützten Gerät laufen — CPU oder GPU —, ohne dass die Gewichte des Modells vorher zwischen getrennten Speicherbereichen kopiert werden müssen. Das ist für einen Laptop konkret relevant: Eine Maschine mit dedizierter GPU muss die Gewichte eines Modells erst über einen Bus in den GPU-Speicher kopieren, bevor sie irgendetwas berechnen kann, was Zeit kostet und den Speicherbedarf verdoppelt; bei der einheitlichen Speicherarchitektur eines Mac teilen sich CPU und GPU bereits denselben physischen Speicher, sodass es nichts zu kopieren gibt.

mlx-lm, das Begleitpaket zum Ausführen von Sprachmodellen auf MLX, installiert sich mit einem einzigen Befehl und liefert von Haus aus ein Standardmodell mit:

MLX-Einrichtung
pip install mlx-lm
# runs the default model (mlx-community/Llama-3.2-3B-Instruct-4bit)
mlx_lm.generate --prompt "How tall is Mt Everest?"
# or name a specific quantized model from the mlx-community hub
mlx_lm.generate --model mlx-community/Mistral-7B-Instruct-v0.3-4bit --prompt "..."
# interactive chat session instead of a single prompt
mlx_lm.chat
# convert and quantize a model yourself
mlx_lm.convert --model mistralai/Mistral-7B-Instruct-v0.3 -q

llama.cpp: die portable Option

llama.cpp ist das ältere, weiter verbreitete der beiden Projekte, geschrieben in C/C++, ohne dass zur Inferenzzeit eine Python-Laufzeit nötig wäre. Die eigene README bringt die Haltung des Projekts zu dieser Hardware direkt auf den Punkt: Apple Silicon wird, in den Worten des Projekts, als „erstklassig behandelt — optimiert über die Frameworks ARM NEON, Accelerate und Metal“, und die Build-Dokumentation bestätigt, dass unter macOS das Metal-GPU-Backend standardmäßig aktiviert ist, mit einem Build-Flag, um es gezielt zu deaktivieren, wenn man reine CPU-Inferenz möchte.

llama.cpp bauen und ausführen
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build
cmake --build build --config Release
# Metal is on by default on macOS; add -DGGML_METAL=OFF to the first
# command above if you need to force CPU-only inference
llama cli -hf ggml-org/Qwen3.5-0.8B-GGUF
# or run it as a local server instead of a one-shot command
llama serve -hf ggml-org/Qwen3.5-0.8B-GGUF

llama.cpp arbeitet mit GGUF-Dateien, einem Einzeldatei-Modellformat, das die quantisierten Gewichte und alles Nötige zu ihrer Ausführung bündelt; der obige Befehl lädt eine davon direkt namentlich aus einem Hugging-Face-Repository. MLX bleibt dagegen näher an einem nativen Python-Workflow und konvertiert und quantisiert Modelle vorab in sein eigenes Format. Keines ist grundsätzlich besser: Zu llama.cpp greift man, wenn man eine einzelne kompilierte Binärdatei ohne Python-Abhängigkeit möchte, zu MLX, wenn man den Rest der eigenen Pipeline ohnehin in Python baut und von dort aus erstklassigen Zugriff auf Apples einheitliches Speichermodell möchte.

Quantisierung: was ein kleineres Modell tatsächlich kostet

Quantisierung speichert jedes Modellgewicht in weniger Bits als den 16 oder 32, in denen das Modell trainiert wurde, wodurch sowohl die Datei auf der Festplatte als auch der zum Ausführen nötige Speicher schrumpfen — auf Kosten der Ausgabequalität. llama.cpps eigene Quantisierungs-Dokumentation listet für jedes unterstützte Schema genaue Bit-pro-Gewicht-Werte auf, was eine präzisere Grundlage für den Kompromiss ist als die übliche Abkürzung „4-Bit“ oder „8-Bit“:

Aus llama.cpps Dokumentation zum Quantisierungswerkzeug.
Schema-FamilieBeispielschemataBits pro Gewicht
Volle Präzision (Referenz)F1616.0
Nahezu verlustfreiQ8_08.50
Höherwertiger MittelbereichQ5_K_S / Q5_K_M5.57 - 5.70
Ausgewogen zwischen Qualität und GrößeQ4_K_S / Q4_K_M4.67 - 4.89
Kleiner, verlustbehafteterQ3_K_S / Q3_K_M / Q3_K_L3.64 - 4.30
Extreme KomprimierungIQ2_XXS ... IQ2_M2.00 - 2.93

Die Parameterzahl eines Modells mit seinem Bit-pro-Gewicht-Wert zu multiplizieren, ergibt eine grobe Speicherschätzung allein für die Gewichte: Ein Modell mit 7 Milliarden Parametern braucht bei Q4_K_Ms 4,89 Bit pro Gewicht ungefähr 7.000.000.000 × 4,89 ÷ 8 Byte, also rund 4,3 GB, noch bevor das Kontextfenster und Zwischenaktivierungen berücksichtigt sind, die je nach eingegebener Textmenge weiteren Bedarf hinzufügen. Das ist eine Berechnung aus dem zitierten Bit-pro-Gewicht-Wert, keine Zahl, die eines der beiden Projekte direkt veröffentlicht, und der tatsächliche Speicherbedarf liegt höher, sobald ein echter Prompt samt Kontext geladen ist. Der praktische Hinweis aus der Tabelle ist einfach: Für eine Aufgabe wie das Klassifizieren jeweils einer einzelnen Verbindungs-Logzeile, bei der die Eingabe kurz ist und die verlangte Ausgabe ein kleines, strukturiertes Urteil, ist ein Modell der Q4_K_M-Klasse sehr oft der richtige Kompromiss — merklich kleiner und schneller als Q8_0 oder F16, ohne in die Stufe der extremen Komprimierung abzurutschen, wo die Ausgabequalität schärfer nachlässt.

Keines der beiden Projekte veröffentlicht einen Speicherbedarf pro Mac-Konfiguration, daher besteht der praktische Ansatz darin, von der obigen Schätzung rückwärts zu rechnen und echten Spielraum zu lassen: macOS selbst, Ihr Browser und was auch sonst läuft, brauchen ebenfalls einheitlichen Speicher, und ein Modell, das gerade so passt, wenn nichts anderes offen ist, wird auslagern oder stocken, sobald Sie zu einer anderen App wechseln. Auf einem Mac mit bescheidenem einheitlichem Speicher spricht das dafür, eher im kleineren Bereich der obigen Tabelle zu bleiben — einige wenige Milliarden Parameter bei Q4_K_M statt eines viel größeren Modells bei derselben Quantisierung — und die größeren, präziseren Optionen Maschinen mit Speicherreserven vorzubehalten. Für eine eng begrenzte Klassifizierungsaufgabe wie die in diesem Artikel behandelte ist ein kleineres Modell mit einer präzisen Frage tendenziell sowohl schneller als auch in der Praxis konsistenter als ein größeres Modell mit einer vagen Frage.

Beide Projekte werden aktiv weiterentwickelt, und der ehrliche Vergleich lautet weniger „was ist besser“ als „was passt zu Ihrer Pipeline“. llama.cpp kompiliert zu einer einzelnen Binärdatei, ohne dass zur Inferenzzeit eine Python-Laufzeit nötig wäre, was zählt, wenn man es in ein anderes Stück Software einbetten will, ohne einen Python-Interpreter mitzuliefern. MLX setzt voraus, dass man bereits in Python arbeitet (oder in Swift, wofür es ebenfalls Bindings mitliefert), und belohnt das mit engerer Integration in Apples eigenen Machine-Learning-Stack und das oben beschriebene einheitliche Speichermodell. Ein Sicherheitswerkzeug, das als eigenständige macOS-Anwendung gebaut ist — die Situation, in der sich FireAI selbst befindet — liegt näher am llama.cpp-Ende dieses Spektrums; ein Forschungs-Notebook, das erkundet, welches Prompt-Muster am besten funktioniert, liegt näher am MLX-Ende.

Ein Prompt-Muster zur Triage einer Verbindung

Je enger die Frage, die man einem kleinen lokalen Modell stellt, desto zuverlässiger antwortet es. Für eine einzelne Verbindung heißt das, ihm genau die Felder zu geben, die auch ein menschlicher Prüfer betrachten würde — nicht mehr, nichts Erschlossenes — und um ein strukturiertes Urteil statt frei formulierter Prosa zu bitten:

Triage-Prompt-Vorlage (illustrativ, an keinem Datensatz getestet)
System: You review one outbound network connection at a time. You are
given only the fields listed below. Do not assume anything not stated.
Respond with exactly two lines: a verdict (allow, ask, or block) and a
one-sentence reason a non-expert could understand.

Connection:
  app: UpdaterHelper.app
  code_signature: unsigned
  destination: 91.203.xxx.xxx:4444
  protocol: TCP
  threat_feed_hit: none
  first_seen: yes (no prior rule for this app)

Verdict:

Die relevanten Felder sind die, die eine Code-Signatur-Prüfung und eine Bedrohungsliste tatsächlich ohne Raten liefern können: ob die Binärdatei signiert ist und von wem, wohin und über welchen Port sie sich zu verbinden versucht, ob dieses Ziel auf einer Bedrohungsliste auftaucht, und ob dies überhaupt der erste Verbindungsversuch dieser App ist. Eine feste zweizeilige Ausgabe statt einer offenen Erklärung zu verlangen, macht das Ergebnis leichter protokollierbar, leichter über Tausende Verbindungen hinweg vergleichbar, und es wird für das Modell viel schwerer, mit vorsichtig klingender Sprache aufzufüllen, die autoritativ wirkt, ohne etwas Überprüfbares zu sagen.

Ein kleines Modell wird das verlangte Format trotzdem gelegentlich ignorieren — drei Zeilen statt zwei, ein zusätzlicher Vorbehalt, ein Urteilswort, das keines der drei angeforderten ist. Behandeln Sie das als technisches Problem, nicht als Modellierungsproblem: Prüfen Sie die Ausgabe gegen die exakte erwartete Form, und wenn sie nicht passt, fragen Sie entweder erneut oder greifen Sie auf das sicherste Urteil zurück (ask, also einem Menschen zeigen), statt zu versuchen, eine lockerere Antwort zu parsen. Ein Triage-Schritt, der bei fehlerhafter Ausgabe sicher versagt, ist weit nützlicher als einer, der gelegentlich eine selbstbewusst wirkende, aber unparsbare Zeile erzeugt und sie stillschweigend verwirft.

Lässt man dieses Muster über einen ganzen Tag an Verbindungsversuchen laufen statt nur über einen, ändert sich die Form der Arbeitslast: Die meisten Verbindungen stammen von Apps mit bestehender Regel und erreichen das Modell überhaupt nicht, eine kleinere Zahl ist wirklich zum ersten Mal zu sehen und erhält ein Urteil, und nur ein Bruchteil dieser Urteile ist etwas anderes als ein routinemäßiges Zulassen. Die eigentliche Aufgabe des Modells ist an dieser Stelle nicht, ein Sicherheitsexperte zu sein; sie besteht darin, eine lange Liste erstmals gesehener Verbindungen auf die kleine Teilmenge zu reduzieren, die eine Person tatsächlich ansehen muss — ein weit erreichbareres Ziel für ein Modell mit wenigen Milliarden Parametern als ein offenes Sicherheitsurteil es wäre.

Wo das schiefgeht

  • Ein kleines lokales Modell kann eine selbstbewusste, gut formulierte, aber völlig falsche Begründung liefern. Nichts am lokalen Betrieb ändert dieses Risiko; es ändert nur, wo der Fehler passiert, nicht ob er passieren kann.
  • Kontextfenster sind endlich, und ein langes, verrauschtes Protokoll passt nicht hinein. Das Zusammenfassen oder Vorfiltern, bevor das Modell die Daten sieht, führt eine eigene Fehlerquelle ein — man kann genau die eine wichtige Zeile verlieren, bevor das Modell überhaupt die Chance hatte, sie anzusehen.
  • Das Modell sieht immer nur das, was in der Logzeile steht. Es kann nicht in verschlüsselten Datenverkehr hineinsehen, es kann nicht überprüfen, ob eine Bedrohungsliste aktuell ist, und es kann Ihre Absicht nicht kennen — eine Verbindung von einem Werkzeug, das Sie gerade absichtlich installiert haben, sieht identisch aus wie eine von einem Werkzeug, von dem Sie noch nie gehört haben.
  • Ein Urteil ist keine Handlung. Nichts hier sollte eine Verbindung von sich aus blockieren, löschen oder stillschweigend zulassen; eine Person muss weiterhin den Grund sehen und bestätigen und die Entscheidung rückgängig machen können, falls das Modell falsch lag.

Dieser letzte Punkt ist keine Einschränkung, die spezifisch für ein kleines, quantisiertes Modell auf einem Laptop gilt — er gilt für jede automatisierte Sicherheitsentscheidung, lokal oder in der Cloud, kleines oder großes Modell. Der Wert des lokalen Betriebs liegt darin, was er aus der Gleichung entfernt (eine Netzwerkabhängigkeit, eine wiederkehrende Rechnung, ein Dritter, der Ihre Verbindungsmetadaten erhält), nicht in der Behauptung, er mache einen Menschen im Entscheidungsprozess überflüssig.

Wo FireAI in dieses Muster passt

FireAI, die Firewall von HisnLabs für den Mac, liefert etwas auf derselben Idee Aufgebautes, mit engerem Umfang als ein allgemeines Chat-Modell: ein optionales lokales Modell, ein zusätzlicher Download von rund 1,5 GB, das vollständig auf dem Mac läuft und Verbindungen von Apps prüft, für die es noch keine Regel gibt. Es setzt macOS 14 oder neuer auf Apple Silicon voraus, wendet öffentliche Bedrohungslisten lokal an, statt sie bei einem entfernten Dienst abzufragen, und zeigt den Grund seiner Entscheidung in derselben Berechtigungsabfrage, mit der es Sie bittet, die Verbindung zuzulassen oder abzulehnen — jede dieser Entscheidungen wird zu einer sichtbaren, bearbeitbaren Regel, und jede davon kann rückgängig gemacht werden. Es lohnt sich, genau zu sein, was das ist und was nicht: Es ist nicht das offene Chat-Modell mit mehreren Milliarden Parametern, das dieser Artikel beschrieben hat, und es ist kein Antivirenprogramm und kein VPN — es erledigt eine eng begrenzte Klassifizierungsaufgabe, lokal, und überlässt die endgültige Entscheidung demjenigen, der die Abfrage liest.

Wo FireAI und HisnLabs ins Spiel kommen

FireAI’s own connection reviewer is this exact bet, made narrower still: an optional, roughly 1.5 GB on-device model, macOS 14 and up, Apple silicon only, reviewing one thing (should this unknown app reach this destination) with a visible reason and an undo button — and, like the triage pattern in this article, it still needs a person to confirm anything consequential.

FireAI ist das eigene Produkt von HisnLabs: eine KI-Firewall für den Mac, die direkt auf dem Gerät läuft. Sie zeigt jede Verbindung Ihrer Apps in verständlicher Sprache und lässt Sie entscheiden, was Ihren Mac verlässt — die KI arbeitet lokal, Ihr Datenverkehr wird also nie an uns oder irgendjemand anderen gesendet. Das Sicherheitsforschungsteam von HisnLabs sorgt dafür, dass diese Entscheidungen verlässlich bleiben: Es katalogisiert, welche Domains gewöhnliche Telemetrie und welche ein echter Dienst sind, verfolgt Land und Netzwerk hinter einer Verbindung und trainiert das lokale Modell (die Autopilot-Funktion) mit echten Verkehrsmustern — ohne dass irgendetwas davon Ihren Mac verlässt.

Die technischen Entscheidungen dahinter können Sie nachlesen — oder FireAI 17 Tage lang ausprobieren — unter FireAI, von HisnLabs.

Quellen