Was das neuronale Modul von rspamd tatsächlich lernt
Was das neuronale Modul verbraucht, was es nicht verbraucht und warum die meisten Installationen stillschweigend mit einem gelernten Multiplikator auf Bayes enden.
Diese Seite wurde maschinell aus dem English-Original übersetzt. What rspamd's neural module is actually learning (EN).
Wenn Sie das neural Modul von rspamd eingeschaltet haben, es ein Vierteljahr lang beobachtet haben und festgestellt haben, dass das Netzwerk so gut wie nichts Nützliches beiträgt - NEURAL_HAM feuert auf den größten Teil des eingehenden Datenstroms und bewegt die Punktzahl nie in irgendeine Richtung, die von Bedeutung ist - ist die Erklärung normalerweise kein Fehler. Das Modul tut das, was die Konfiguration ihm vorgibt. Das mentale Modell in Ihrem Kopf stimmt nicht überein.
Zuerst muss man sich verinnerlichen, was das Netz tatsächlich liest. Der Hauptteil der Nachricht erreicht es nie. Es gibt keinen Tokenisierer, keine Einbettung, keine Repräsentation von “wie Spam aussieht”, die aus Bytes auf der Leitung gelernt wurde. Die Eingaben sind das Feuerungsmuster jedes anderen aktivierten rspamd-Symbols für die zu bewertende Nachricht: BAYES_SPAM DKIM_REJECT , Ihr verrauschtes RBL_FOO, der von MULTIMAP abgeleitete Greylist-Hinweis, das Spamtrap-Signal und was immer Sie sonst noch verdrahtet haben. Dieser Fließkomma-Vektor durchläuft ein kleines Feedforward-Netzwerk - eine versteckte Schicht auf Vorrat, zwei, wenn jemand sie angepasst hat, tanh-Aktivierung, klein genug, um in Mikrosekunden auf demselben Kern ausgewertet zu werden, der den Regex-Durchlauf gemacht hat - und das Netzwerk gibt einen Skalar aus, der den Beitrag eines weiteren Symbols (NEURAL_SPAM oder NEURAL_HAM) zur endgültigen Bewertung darstellt.
Die darunter liegende Bibliothek ist KANN , von Heng Li. Das Ganze besteht aus ein paar tausend Zeilen C. Wenn Sie noch nie Quellen für neuronale Netze gelesen haben, ist dies ein ungewöhnlich einfacher Einstieg.
Woher die Etiketten kommen
Der Teil, der den Leuten auffällt: auto-train bezieht seine Labels nicht aus einem Orakel. Es verwendet den aktuellen rspamd-Score. Alles, was über spam_score (Standardwert 8.0) liegt, wird zu einem Spam-Trainingsbeispiel, alles unter ham_score (Standardwert -2.0) wird zu Schinken, der Mittelwert wird verworfen. Der Klassifikator lernt, die Entscheidungen der Maschine vorherzusagen, die er verbessern soll.
Sobald es klickt, hört das Verhalten auf, mysteriös zu sein. Im Laufe von ein paar Tausend Stichproben konvergiert das Netzwerk zu einer gelernten gewichteten Summe der Symbole, die bereits die Bewertung beeinflussen. Bei den meisten Installationen bedeutet dies, dass es ziemlich schnell zu einer geglätteten Annäherung an BAYES_SPAM konvergiert, da Bayes der lauteste Klassifikator in der Kette ist. An einem stark frequentierten Standort, den ich vor kurzem gemessen habe, korrelierte die Ausgabe des trainierten Netzes nach einem Vierteljahr ununterbrochenen automatischen Trainings mit BAYES_SPAM allein mit 0,94. An diesem Punkt könnte man das gesamte Modul durch NEURAL_SPAM = 0.4 * BAYES_SPAM ersetzen und niemand würde es bemerken.
Das ist eine Rückkopplungsschleife, kein Zufall. Grenzwertige Botschaften werden etwas sicherer bewertet, weil das neuronale System das Symbol verstärkt, das sie bereits beeinflusst hat. Diese Bewertungen qualifizieren sich dann als Trainingsetiketten für den nächsten Zyklus, die Schleife wird enger, das Netzwerk driftet weiter in Richtung seiner bestehenden dominanten Eingabe. Das ist keine Pathologie, sondern das Ergebnis, wenn die Verlustfunktion lautet: “Sagen Sie Ihre eigenen Ergebnisse voraus”
Nichts davon ist ein Grund, sie abzuschalten. Es ist ein Grund, zu wissen, was man eingeschaltet hat, und die Fehlerform zu erkennen, wenn man sie sieht. Die Diagnose für Bayes-Mimikry besteht aus einer Konfigurationsänderung und einem Testdurchlauf: Setzen Sie BAYES_SPAM weight in local.d/groups.conf auf Null, lassen Sie einen repräsentativen Korpus durch den Controller laufen und schauen Sie, was mit der neuronalen Diskriminierung passiert. Wenn sie mit Bayes zusammenbricht, haben Sie eine gelernte Bayes-Neuformulierung. Bleibt sie bestehen, findet das neuronale System irgendwo anders ein Signal und verdient sich seinen Platz.
Es gibt einen leiseren Fehler, den man erkennen sollte. Eine Nachricht kommt während eines teilweisen Neuladens der Konfiguration oder in den wenigen Sekunden nach dem Start von ann_expire und vor dem Ende des nächsten Trainingszyklus an, wobei die meisten Symbole noch nicht abgefeuert wurden. Undefinierte Symbole werden als Null in das Netz eingespeist. Die meisten trainierten Netze haben einen geringen Anteil an Amateurnachrichten, da die durchschnittliche Amateurnachricht weniger Symbole abfeuert als die durchschnittliche Spamnachricht. Das sichtbare Ergebnis ist eine Population von Nachrichten mit anomal konsistenten NEURAL_HAM Scores in etwa der gleichen Größenordnung. Das sieht wie ein Modellfehler aus. Es handelt sich um ein Artefakt der Population, und die Abhilfe besteht darin, das Training zu überspringen (und auf die neuronale Bewertung zu verzichten), wenn weniger als eine bestimmte Anzahl von Symbolen abgefeuert wird. Bei den Konfigurationen, die ich mir angesehen habe, funktioniert Ten.
Zwei weitere Formen sind wissenswert. Die gemeinsame Nutzung einer Regel für ein- und ausgehende Post trainiert ein Netzwerk, das in beiden Bereichen schlecht ist, weil die Verteilungen über die Symbole zu unterschiedlich sind - eingehende Post überträgt nie die Signale des authentifizierten Benutzers, ausgehende Post feuert nie die eingehenden RBLs. Eine Regel pro Richtung, mit unterschiedlichen symbol_spam / symbol_ham Namen, damit sie separat in /symbols auftauchen. Und eine Site hinter aggressiver Upstream-Filterung (typisch für einen sekundären MX hinter etwas wie Microsoft Defender) sieht fast keinen echten Spam, der rspamd erreicht. Die Spam-Seite des Auto-Train-Puffers füllt sich nur langsam mit Beispielen, die mit geringer Wahrscheinlichkeit den Schwellenwert überschreiten, und das Netzwerk trägt monatelang nichts Nützliches bei. Die Signatur lautet NEURAL_SPAM und wird nur selten und über Wochen hinweg mit aussagekräftigem Gewicht abgefeuert. Die Lösung besteht entweder darin, den Trainer manuell zu füttern oder zuzugeben, dass das neuronale System seine CPU auf dieser Website nicht verdient und es zu deaktivieren.
Konfiguration, kurz
Trainierte Netze befinden sich in Redis unter Schlüsseln mit dem Präfix rn_$rulename. Die Identität eines Netzes ist (rule name, symbol-set hash); der Hash wird zur Trainingszeit aus den aktivierten Symbolen berechnet. Die praktische Konsequenz ist, dass jede Änderung an Ihrem Symbolsatz das bestehende Modell ungültig macht und im nächsten Trainingszyklus ein neues Training von Null beginnt. Wenn Sie am Montagmorgen ein neues Modul einsetzen, müssen Sie damit rechnen, dass die Auswertung bis zum Abschluss des Trainingslaufs am Dienstag etwas unruhig ist. Das sollte man wissen, bevor jemand ein Ticket deswegen einreicht.
Ein Minimum local.d/neural.conf:
enabled = true;
rules {
default {
train {
max_trains = 1000;
max_usages = 20;
spam_score = 8;
ham_score = -2;
learning_rate = 0.01;
max_iterations = 25;
train_prob = 1.0;
}
symbol_spam = "NEURAL_SPAM";
symbol_ham = "NEURAL_HAM";
ann_expire = 86400;
}
}Die beiden wichtigsten Einstellungen für Auto-Train sind die Schwellenwerte für die Beschriftung und train.train_prob. Die Voreinstellung 8 / -2 ist vernünftig; eine Verschärfung auf 12 / -4 reduziert das Etikettenrauschen auf Kosten einer langsameren Konvergenz. Auf Systemen mit hohem Verkehrsaufkommen bedeutet train_prob bei 1,0, dass Ihr rollendes Fenster überraschend schnell aufhört, eine repräsentative Stichprobe des aktuellen Verkehrs zu sein - senken Sie es auf 0,1 oder 0,05 und der Puffer spiegelt einen längeren Abschnitt wider.
Lesen, was es tut
Der schnellste Weg, um herauszufinden, welche neuralen Elemente zu einer bestimmten Nachricht beitragen, ist der /symbols Endpunkt des Controllers:
curl -s -X POST --data-binary @suspect.eml \
-H "Password: $RSPAMD_PASSWORD" \
-H "Content-Type: message/rfc822" \
http://127.0.0.1:11334/symbols \
| jq '.[] | {symbol, score, options}'Die nützliche Frage ist, ob Neural mit Bayes übereinstimmt oder nicht. Zustimmung bringt nichts - wenn BAYES_SPAM bei +4 und NEURAL_SPAM bei +3 für dieselbe Nachricht steht, gibt neural Bayes mit einem gelernten Multiplikator wieder. Bei Nichtübereinstimmung verdient das Modul entweder seinen Platz oder verschwendet ihn. Das sind die Nachrichten, die es wert sind, von Hand geöffnet zu werden.
Sie können quantifizieren, wie oft das passiert. Halten Sie eine Woche lang Nachrichten zurück, lassen Sie sie durchlaufen, wobei die Gewichte der Neuronen in groups.conf auf Null gesetzt werden, lassen Sie sie erneut durchlaufen, wobei die Gewichte wiederhergestellt werden, und zählen Sie die Nachrichten, deren Summe eine Klassifizierungsgrenze überschreitet. Die gesündeste Installation, die ich kürzlich gemessen habe, wies eine Flip-Rate von 1,7 % auf. Die am wenigsten gesunde Installation hatte eine Rate von 0,2 %, wovon etwa zwei Drittel in die falsche Richtung gingen; nach der Deaktivierung von neural sank die Zahl der falsch-positiven Beschwerden auf dieser Website im folgenden Quartal um etwa ein Zehntel.
Manuelles Training
Es gibt keine saubere, versionsstabile CLI für “trainiere dieses Netzwerk aus diesen mbox-Dateien” Was über alle Versionen hinweg überlebt, ist eine separate rspamd-Instanz einzurichten, eine neural.conf mit train_prob = 1.0 zu schreiben und die Schwellenwerte für die Kennzeichnung zu verschärfen, damit die Kennzeichnungen eindeutig sind, und eine kuratierte Mailbox mit rspamc scan durchzuleiten. Sobald der Puffer gefüllt ist und der Trainingszyklus läuft, kann das resultierende Netzwerk aus diesem Redis exportiert und in die Produktion importiert werden, oder beide Instanzen können in ein gemeinsames Redis schreiben, wenn Ihre Topologie dies zulässt. Das ist nicht elegant. Es ist das, was funktioniert.
Der Korpus muss nicht riesig sein. Ein paar tausend Beispiele auf jeder Seite, die von jemandem beschriftet werden, der die Nachrichten tatsächlich gelesen hat, sind besser als monatelanges automatisches Training auf einem ausgelasteten Produktionsknoten. Die Form des Spams ändert sich, so dass der Korpus aktualisiert werden muss - vierteljährlich reicht auf den Websites, auf denen ich das System eingesetzt habe; eine jährliche Aktualisierung reicht aus, um in der zweiten Jahreshälfte sichtbar veraltet zu sein.
Wann man sich nicht anstrengen sollte
Wenn Ihr Symbolsatz klein ist (eine Handvoll RBLs, Bayes, nicht viel mehr), hat das Netzwerk zu wenig zu kombinieren und wird Bayes widerspiegeln. Wenn Ihre Upstream-Filterung den eindeutigen Spam entfernt, bevor rspamd ihn sieht, sieht der Trainer nie genug Spam, um daraus zu lernen. Und wenn niemand auf der Ops-Seite sich /symbols ansieht und überprüft, ob das Modul nützliche Arbeit leistet, zahlen Sie CPU und Redis für eine Zahl, die niemand liest.
Bei den Installationen, bei denen es seinen Platz verdient - breiter Symbolsatz, echter Spam, der den Filter erreicht, jemand, der beobachtet, was es tut - ist es eine lohnende Ergänzung. Aktivieren Sie es nur nicht, weil das Wort “ML” in einer Sitzung gefallen ist.
Weitere Lektüre: Die Upstream-Dokumente unter rspamd.com/doc/modules/neural.html sind knapp und meist korrekt. Die [KANN-Quelle] (https://github.com/attractivechaos/kann
) ist kurz und angenehm, wenn Sie wissen wollen, was tanh tatsächlich kompiliert. Und src/plugins/lua/neural.lua im rspamd-Baum ist die Integrationsschicht; sie ist die kanonische Referenz für die Version, die Sie gerade benutzen