Tokenizer und Chat-Templates für MLX auf Cloud-Macs prüfen
Wenn MLX nach dem Umzug derselben Unterhaltung auf einen Cloud-Mac plötzlich zusätzliche Rollenbezeichnungen ausgibt, liegt das nicht unbedingt an den Modellgewichten. Auch die Tokenizer-Version, das Chat-Template oder doppelt eingefügte Spezial-Token können die tatsächliche Eingabe verändern. Erst wenn die Umwandlung von Nachrichten in Token feststeht, lassen sich Generierungsergebnisse sinnvoll vergleichen und Eingabeabweichungen von der Zufälligkeit des Samplings trennen.
Zuerst den zu prüfenden Eingabevertrag festlegen
Diese Anleitung prüft ausschließlich die Vorverarbeitung für die Inferenz. Sie lädt keine Modellgewichte und misst keine tokens/s. Benötigt werden eine virtuelle Python-Umgebung und ein geprüftes lokales Modellverzeichnis. Dieses Verzeichnis muss die für das Modell erforderliche Tokenizer-Konfiguration, das Vokabular und das Chat-Template enthalten. Kopieren Sie diese Dateien nicht von einem anderen Modell gleicher Größe.
Eine Abnahme erfasst drei Ebenen: das ursprüngliche Nachrichten-Array, den vom Template gerenderten Text und die vollständige Folge der Token-IDs. Nur die Anzahl der Token zu vergleichen, reicht nicht aus: Zwei gleich lange Sequenzen können unterschiedliche Inhalte ausdrücken. Auch ein identisches reguläres Vokabular bedeutet nicht, dass Rollengrenzen und Endmarkierungen übereinstimmen.
Das Chat-Template ist Teil des Eingabeprotokolls des Modells, keine Darstellungsoption. Eine erfolgreiche Tokenisierung bestätigt nur, dass die Umwandlung abgeschlossen wurde – nicht, dass das Modell die richtige Rollenstruktur erhalten hat.
Speichern Sie das folgende Skript als check_prompt.py und führen Sie es in einer Umgebung aus, in der transformers und die für den Tokenizer benötigten Abhängigkeiten installiert sind. Halten Sie zuvor mit python -m pip freeze > requirements.lock.txt den Stand der Umgebung fest. Diese Liste dokumentiert die Versionen, garantiert aber keine vollständig identischen Installationsergebnisse auf verschiedenen Plattformen.
Lokale Dateien und Nachrichtenbeispiele festlegen
Das Skript unterbindet ausdrücklich sowohl Downloads aus dem Netz als auch die Ausführung benutzerdefinierten Remote-Codes. Falls das Modell eine eigene Implementierung voraussetzt, prüfen Sie diese zuerst und erstellen Sie dafür einen gesonderten Ausführungsplan. Lockern Sie die Ausführungsbeschränkungen nicht kurzfristig, nur um eine Fehlermeldung zu umgehen.
Die Beispiele enthalten chinesischen Text, einen Zeilenumbruch, spitze Klammern und einen mehrstufigen Dialog. Für jedes Beispiel wird sowohl mit als auch ohne Generierungspräfix geprüft. Sie verwenden die übliche abwechselnde Struktur aus user und assistant. Beispiele mit der Rolle system oder mit Tool-Aufrufen sollten erst ergänzt werden, wenn das Modell diese ausdrücklich unterstützt.
import argparse
import json
from pathlib import Path
from transformers import AutoTokenizer
parser = argparse.ArgumentParser()
parser.add_argument("model_dir")
parser.add_argument("baseline")
parser.add_argument("--record", action="store_true")
args = parser.parse_args()
tokenizer = AutoTokenizer.from_pretrained(
args.model_dir,
local_files_only=True,
trust_remote_code=False,
)
cases = [
[{"role": "user", "content": "只回答数字:2+3\n<note>保留原文</note>"}],
[
{"role": "user", "content": "记住代号:实验甲"},
{"role": "assistant", "content": "已记录。"},
{"role": "user", "content": "代号是什么?"},
],
]
rows = []
for messages in cases:
for generation in (False, True):
rendered = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=generation,
)
ids = tokenizer.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=generation,
)
encoded = tokenizer.encode(
rendered, add_special_tokens=False
)
if ids != encoded:
raise SystemExit("Tokenization paths differ")
rows.append({
"messages": messages,
"generation": generation,
"rendered": rendered,
"ids": ids,
})
path = Path(args.baseline)
if args.record:
with path.open("x", encoding="utf-8") as stream:
json.dump(rows, stream, ensure_ascii=False, indent=2)
else:
expected = json.loads(path.read_text(encoding="utf-8"))
if rows != expected:
raise SystemExit("Prompt contract changed")
Eine Referenz erstellen, aber nicht automatisch freigeben
Führen Sie beim ersten Mal python check_prompt.py ./model ./prompt-baseline.json --record aus. Die Aufzeichnung verwendet den exklusiven Erstellungsmodus: Existiert die Datei bereits, schlägt der Vorgang fehl. So werden bei der Fehlersuche keine Belege überschrieben. Lassen Sie bei späteren Prüfungen --record weg. Nur wenn der Befehl keine Ausgabe erzeugt und mit Exit-Code null endet, ist die Prüfung bestanden.
Prüfen Sie die JSON-Datei Punkt für Punkt: Ist der Nutzerinhalt vollständig? Entsprechen die Rollentrenner der Modelldokumentation? Gibt es nach früheren assistant-Antworten eine sinnvolle Abgrenzung? Bereitet der Generierungsmodus die richtige Position für die nächste Antwort vor? Manche Templates ignorieren den Schalter für das Generierungspräfix. Deshalb dürfen unterschiedliche Ergebnisse für die beiden Einstellungen nicht zwingend vorausgesetzt werden.
Nehmen Sie die Referenz, das Skript, die Abhängigkeitsliste und die Prüfsummen der verwendeten Tokenizer-Dateien gemeinsam in die Versionsverwaltung auf. Verwenden Sie ausschließlich synthetische Testdaten. Echte Chats, Zugriffstoken und interne Dokumente gehören nicht in eine Referenz, die eingecheckt werden soll.
Abweichungen entlang der tatsächlichen MLX-Aufrufkette eingrenzen
Auch wenn das Skript erfolgreich durchläuft, müssen Sie prüfen, ob der Anwendungseinstieg dasselbe Template und dieselben Parameter verwendet. Manche Aufrufschichten erwarten ein Nachrichten-Array, andere einen bereits gerenderten String. Wird ein solcher String erneut an einen Chat-Wrapper übergeben, kann das Template zweimal angewendet werden. Erfassen Sie deshalb unmittelbar vor dem Aufruf der Generierungsfunktion die endgültigen Token-IDs des synthetischen Beispiels und vergleichen Sie diese einzeln mit der Referenz.
Spezial-Token nicht doppelt hinzufügen
Templates enthalten häufig bereits Start- oder Endmarkierungen. Deshalb verwendet das Skript beim Kodieren des gerenderten Texts add_special_tokens=False. Fügen Sie kein zusätzliches BOS manuell hinzu. Ein dekodierter Text, der „normal aussieht“, ist ebenfalls kein ausreichender Nachweis: Dekodieroptionen, die Spezial-Token ausblenden, können doppelte Markierungen in der Eingabe verbergen.
Vergleichen Sie bei Abweichungen zuerst rendered und danach ids. Unterscheidet sich der Text, prüfen Sie zunächst das Template und die Nachrichtenvorverarbeitung. Ist der Text identisch, die ID-Folge aber nicht, prüfen Sie das Vokabular, hinzugefügte Token und die Tokenizer-Implementierung. Erst wenn die tatsächliche Eingabe übereinstimmt, sollten Sie die Sampling-Parameter und die Version der Modellgewichte untersuchen.
Fehler in nachvollziehbare Prüfpunkte überführen
Wenn Sie Beispiele mit leerem Inhalt, nachgestellten Leerzeichen, Emojis oder langen chinesischen Texten ergänzen, dokumentieren Sie jeweils den Prüfzweck. Sammeln Sie nicht einfach zufällige Zeichenfolgen. Bei langen Eingaben muss die Anwendung außerdem das Kontextbudget prüfen: Dieses Skript reserviert weder Platz für die Ausgabe der Generierungsaufgabe noch überprüft es die Strategie zum Kürzen der Eingabe.
Bestätigen Sie vor der Übergabe vier Punkte: Im Offline-Betrieb wurden keine Dateien heruntergeladen; eine reguläre Prüfung verändert die Referenz nicht; Abweichungen sowohl beim Template-Text als auch bei den Token stoppen den Vorgang; Aktualisierungen von Abhängigkeiten müssen manuell geprüft werden. Speichern Sie bei einer Aktualisierung der Referenz zunächst eine separate Kandidatendatei und reichen Sie die Änderungen zur Prüfung ein. Zeichnen Sie die Referenz im Fehlerfall nicht automatisch neu auf.
Während der Mietdauer bewahren Sie damit einen erneut ausführbaren Satz von Eingabenachweisen auf, nicht bloß einen Screenshot einer einzelnen Antwort. Beim Wechsel auf einen anderen Cloud-Mac können Sie so zuerst belegen, dass das Modell unveränderte Eingaben erhalten hat – und erst danach untersuchen, warum die Antwort anders ausfällt.
Häufig gestellte Fragen
Müssen dafür Modellgewichte geladen werden?
Nein. Für Template-Rendering und Tokenisierung reichen lokale Tokenizer-Dateien. Die Qualität generierter Antworten wird damit nicht bewertet.
Darf ein Update die Referenz automatisch ersetzen?
Nein. Prüfen Sie zuerst Tokenizer-Dateien, Template und Abhängigkeitsversionen. Eine neue Referenz braucht eine bewusste Freigabe.
Mac passend zur Versuchsdauer mieten
Exklusiver Mac mini M4 mit 16 GB gemeinsamem Arbeitsspeicher und 256 GB SSD. Vorauszahlung für Tage, Wochen, Monate oder Quartale; ohne Verlängerung wird das Gerät nach Ablauf gestoppt. Modelle und Laufzeitumgebung richten Sie selbst ein. Maßgeblich ist der Echtzeitstatus in der Konsole.
Mac tageweise mieten