Chat-Vorlagen als Teil des Modellvertrags: Rollen, Sonder-Tokens und doppelte Tokenisierung
Eine Chat-Vorlage definiert die exakte Token-Sequenz, die ein Chat-Modell erwartet, einschließlich Rollen-Steuer-Tokens und spezieller Begrenzungs-Tokens. Die Behandlung als Vertragsdaten verhindert stille Qualitätsverluste durch falsch formatierte Eingaben und duplizierte Sonder-Tokens.
Auf dieser Seite
Die kurze Antwort
Behandeln Sie die Chat-Vorlage als deklarierten Teil des Modellvertrags: Erfassen Sie die unterstützten Rollen (System, Benutzer, Assistent), die Steuer-Tokens, denen jede Rolle zugeordnet ist, die Sonder-Tokens des Tokenizers und die genauen Flags bei der Formatierung. Erstellen Sie Prompts mit tokenizer.apply_chat_template, wobei tokenize=True bevorzugt wird, damit nur die eigenen Sonder-Tokens der Vorlage ausgegeben werden. Wenn Sie zuerst zu einem String formatieren, übergeben Sie add_special_tokens=False beim späteren Tokenisieren, da die Vorlage bereits die notwendigen Begrenzungs-Tokens enthält. Verwenden Sie add_generation_prompt=True nur beim Start einer neuen Assistent-Antwort, continue_final_message nur beim Vorfüllen der letzten Nachricht und niemals beide zusammen. Überprüfen Sie den Vertrag mit einem kurzen Generierungstest für jede Modellvariante, da sich Vorlagen selbst zwischen Modellen unterscheiden, die auf derselben Basis feinabgestimmt wurden.
Warum eine Chat-Vorlage in einen Modellvertrag gehört
Ein kausales Sprachmodell erhält nie eine Konversation als solche. Es erhält eine flache Token-Sequenz und sagt das Nächste voraus. Die Chat-Vorlage ist die Komponente, die eine Liste von Wörterbüchern mit Rolle und Inhalt in die präzise Sequenz umwandelt, die das Modell während des Chat-Fine-Tunings encountered hat, einschließlich Steuer-Tokens wie <|user|>, <|assistant|> und Ende-der-Nachricht-Marker, die dem Modell die Struktur des Austauschs sichtbar machen.
Da zwei Modelle, die auf derselben Basis feinabgestimmt wurden, völlig unterschiedliche Formate verwenden können, ist die Vorlage verhaltensbezogene Vertragsdaten und nicht nur Darstellung. Eine Diskrepanz löst normalerweise keine Ausnahme aus; sie degradiert die Antwortqualität stillschweigend, weshalb der Vertrag die Vorlage und ihre Tokens explizit benennen muss.
Praktischer Tipp
Speichern Sie den gerenderten Prompt-String zusammen mit der Modellrevision in Ihrer Evaluationsumgebung. Wenn die Ausgabequalität nach einem Modell- oder Bibliotheks-Upgrade abfällt, decodieren Sie den gespeicherten Prompt und vergleichen Sie ihn mit einem frischen Render; dies isoliert Vorlagen-Drift vom Modellverhalten, bevor Sie Generierungseinstellungen untersuchen.
Standard-Rollen und ihre Semantik
Drei Rollen decken die häufigen Fälle ab. system trägt Anweisungen darüber, wie das Modell handeln soll, und erscheint normalerweise zuerst. user trägt die menschliche Abfrage. assistant trägt die Antwort des Modells. Die Vorlage ordnet jeder Rolle Steuer-Tokens zu, und diese Zuordnung ist modellspezifisch: Mistral-7B-Instruct umschließt Benutzer-Turns mit [INST] und [/INST], während Zephyr-7B Marker im Stil von <|user|> und <|assistant|> mit Ende-der-Sequenz-Separatoren verwendet.
Der Vertrag sollte daher Rollen und ihre konkreten Token-Schreibweisen zusammen angeben. Das bloße Nennen der Rollen reicht nicht aus, da derselbe Rollenname über Checkpoints hinweg unterschiedlich gerendert wird und ein falscher Token-Satz genau der Fehlermodus ist, den die Vorlage verhindern soll.
Definition von Sonder-Tokens im Tokenizer
Die Tokenizer-Konfiguration legt die Teile offen, die die Vorlage konsumiert. Relevante Attribute sind chat_template, eine Jinja-Vorlagenzeichenkette, die Nachrichtenlisten formatiert, sowie Sonder-Tokens wie bos_token, eos_token, unk_token, sep_token, pad_token, cls_token und mask_token. Die Vorlage liest diese Attribute, anstatt ihre Schreibweisen hart zu kodieren, sodass der Tokenizer und die Vorlage aus derselben Modellrevision geladen werden müssen.
Voraussetzung: Der Tokenizer muss tatsächlich ein chat_template-Attribut tragen. Wenn er es nicht tut, hat apply_chat_template nichts zu rendern, und Sie müssen eine Vorlage explizit bereitstellen oder einen anderen Checkpoint wählen. Dies ist eine Umgebungs- und Versionsangelegenheit, keine Garantie dafür, dass eine gegebene Vorlage zum Trainingsformat eines gegebenen Modells passt.
Anwendung der Vorlage mit apply_chat_template
Die funktionierende Sequenz ist: Erstellen Sie eine Liste von Wörterbüchern mit role- und content-Schlüsseln, rufen Sie apply_chat_template auf und wählen Sie tokenize=True, wenn Sie Token-IDs für generate() benötigen, oder tokenize=False, wenn Sie den formatierten String zur Inspektion oder Protokollierung brauchen. Setzen Sie add_special_tokens=False nur, wenn Sie beabsichtigen, Sonder-Tokens später selbst hinzuzufügen.
Das folgende Beispiel lädt einen Tokenizer mit einer Chat-Vorlage, formatiert eine System- und eine Benutzernachricht und fordert eine Generierungs-Eingabeaufforderung an. Die gedruckte Zeile ist illustrative Ausgabe: Exakte Abstände hängen von der Tokenizer-Version und der Vorlagenrevision ab.
Illustrative Ausgabe (Form, kein aufgezeichneter Lauf):
<|system|> You are a helpful assistant </s><|user|> What is 2+2? </s><|assistant|>
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('HuggingFaceH4/zephyr-7b-beta')
messages = [
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "What is 2+2?"}
]
ids = tokenizer.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_tensors='pt'
)
print(tokenizer.decode(ids['input_ids'][0]))Vermeidung doppelter Tokenisierung
Chat-Vorlagen geben bereits die Sonder-Tokens aus, die das Modell benötigt. Wenn Sie mit tokenize=False rendern und dann den resultierenden String durch den normalen Aufruf des Tokenizers laufen lassen, kann der Standardpfad add_special_tokens=True bos- oder eos-Tokens ein zweites Mal einfügen. Das Duplikat schlägt nicht laut fehl; es ändert die Sequenz, die das Modell erwartet hat.
Das sichere Muster ist apply_chat_template(tokenize=True), was IDs einschließlich Steuer-Tokens zurückgibt. Wenn ein String-Zwischenschritt unvermeidbar ist, tokenisieren Sie ihn mit add_special_tokens=False. Diese Unterscheidung ist am wichtigsten in Pipelines, in denen Formatierung und Kodierung in separaten Diensten stattfinden.
Generierungs-Prompts und Handhabung der letzten Nachricht
add_generation_prompt=True fügt die Tokens hinzu, die den Start einer Assistent-Antwort ankündigen, sodass das Modell antwortet, anstatt den Text des Benutzers fortzusetzen. Es hat keine Wirkung auf Modelle wie Llama, die kein spezielles Assistent-Start-Token haben, daher muss der Vertrag erfassen, ob das Zielmodell eines verwendet.
continue_final_message tut das Gegenteil: Es entfernt Ende-der-Sequenz-Tokens, sodass die Generierung innerhalb der letzten Nachricht weiterläuft, was nützlich ist, um einen bekannten Antwort-Präfix oder ein Reasoning-Feld wie reasoning_content vorzufüllen. Die beiden Flags sind exklusiv, und ihre Kombination löst einen Fehler aus. Verwenden Sie während des Trainings add_generation_prompt=False, da Assistent-Start-Tokens in der Trainingssequenz nicht hilfreich sind.
Testen des Vertrags gegen Modellvarianten
Syntax allein beweist keine Korrektheit. Für jede Modellvariante rendern Sie eine feste Zwei-Turn-Konversation, decodieren Sie sie und bestätigen Sie, dass die Steuer-Tokens und Begrenzungs-Tokens dem Format entsprechen, mit dem dieses Modell trainiert wurde. Führen Sie dann eine kurze Generierung durch und prüfen Sie, ob das Modell als Assistent antwortet, anstatt die Benutzernachricht zu erweitern.
Führen Sie diesen Check immer dann durch, wenn sich die Modellrevision, die transformers-Version oder die Tokenizer-Quelle ändern. Gleich aussehende Rollennamen implizieren nicht gleiche Token-Sequenzen, und eine Vorlage, die für einen Fine-Tune funktioniert, kann bei einem anderen, der auf derselben Basis beruht, stillschweigend fehlschlagen.
Dokumentation der Vorlage in einem Vertrag
Ein reproduzierbarer Vertrag erfasst die Rollen, erforderlichen Steuer-Tokens, das Verhalten der Generierungs-Eingabeaufforderung und die exakte Vorlagenzeichenkette oder ihre unveränderliche Quellrevision. Das folgende Snippet ist ein Schemafragment für Ihr Dokumentationssystem, keine lauffähige Konfiguration: Es erfordert Ihre Modell-ID und das Ausfüllen des Vorlagentextes.
Erfassen Sie die Vorlagenquelle (Tokenizer-Attribut oder explizite Zeichenkette) anstelle nur ihrer Ausgabe, da sich die Ausgabe ändern kann, wenn sich die Version der Tokenizer-Bibliothek ändert.
model_contract:
model_id: <hugging-face-model-id>
tokenizer_revision: <revision-or-commit>
roles:
system: <role-token-or-pattern>
user: <role-token-or-pattern>
assistant: <role-token-or-pattern>
special_tokens:
bos: <token>
eos: <token>
add_generation_prompt_on_inference: true
add_generation_prompt_on_training: false
continue_final_message: prefill-only
chat_template_source: tokenizer.chat_template
chat_template_text: <exact-jinja-template>Was Sie prüfen sollten
- Bestätigen Sie, dass der Tokenizer ein nicht-leeres chat_template-Attribut für die exakt verwendete Modellrevision offenlegt.
- Decodieren Sie einen gerenderten Prompt und überprüfen Sie, ob die Steuer-Tokens jeder Rolle dem Trainingsformat des Modells entsprechen.
- Stellen Sie sicher, dass pro Nachrichten-Grenze nach der Tokenisierung nur eine bos/eos-Grenze erscheint.
- Wenn Sie zuerst zu einem String formatieren, bestätigen Sie, dass der spätere Tokenizer-Aufruf add_special_tokens=False verwendet.
- Bestätigen Sie, dass add_generation_prompt und continue_final_message niemals zusammen übergeben werden.
- Erfassen Sie, ob add_generation_prompt für das Zielmodell irgendeine Wirkung hat, da einige Modelle kein Assistent-Start-Token besitzen.
- Führen Sie einen kurzen Generierungstest pro Modellvariante durch und prüfen Sie, ob das Modell antwortet, anstatt den Benutzer-Turn zu erweitern.
- Fixieren Sie die transformers-Version und die Tokenizer-Revision zusammen mit dem gespeicherten Vorlagentext.
Geltungsbereich
Vorlagen sind modellspezifisch: Ein Vertrag, der für einen Checkpoint geschrieben wurde, gilt möglicherweise nicht für einen anderen, selbst wenn beide von derselben Basis abstammen. add_generation_prompt ist wirkungslos für Modelle wie Llama, die kein explizites Assistent-Start-Token haben, und seine Kombination mit continue_final_message löst einen Fehler aus. Die Beispiele gehen von einem Hugging Face Tokenizer mit einem chat_template-Attribut und installierter transformers-Bibliothek aus; exakte gerenderte Abstände und Token-IDs hängen von Tokenizer und Bibliotheksversion ab, sodass der hier gezeigte decodierte String illustrativ und kein aufgezeichnetes Ergebnis ist. Dieser Artikel behandelt nur die Prompt-Formatierung und macht keine Aussagen über Generierungsqualität, Latenz oder Task-Genauigkeit.