智慧體課程文件

訊息與特殊Token

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

訊息與特殊Token

既然我們已經瞭解了 LLM 的工作原理,那麼接下來我們來看看它們如何透過聊天模板來構建其生成內容

就像使用 ChatGPT 一樣,使用者通常透過聊天介面與 Agent 互動。因此,我們的目標是瞭解 LLM 如何管理聊天。

:但是……當我與 ChatGPT/Hugging Chat 互動時,我是在使用聊天訊息進行對話,而不是一個單獨的提示序列。

:沒錯!但這實際上是一種 UI 抽象。在輸入 LLM 之前,對話中的所有訊息都會被連線成一個單獨的提示。模型不會“記住”對話:它每次都會完整地讀取它。

到目前為止,我們已經將提示討論為輸入模型的 token 序列。但是當你與 ChatGPT 或 HuggingChat 等系統聊天時,你實際上是在交換訊息。在後臺,這些訊息被連線並格式化為模型可以理解的提示

Behind models
我們在這裡看到了 UI 中看到的內容與輸入模型提示之間的區別。

這就是聊天模板發揮作用的地方。它們充當了對話訊息(使用者和助手的輪次)與所選 LLM 的特定格式要求之間的橋樑。換句話說,聊天模板結構化了使用者與 Agent 之間的通訊,確保每個模型——儘管它有獨特的特殊 token——都能收到格式正確的提示。

我們再次談論特殊 token,因為它們是模型用來界定使用者和助手輪次開始和結束的。正如每個 LLM 使用自己的 EOS(序列結束)token 一樣,它們在對話中的訊息也使用不同的格式規則和分隔符。

訊息:LLM 的底層系統

系統訊息

系統訊息(也稱為系統提示)定義了模型應如何表現。它們充當持久指令,指導後續的每次互動。

例如:

system_message = {
    "role": "system",
    "content": "You are a professional customer service agent. Always be polite, clear, and helpful."
}

透過這條系統訊息,阿爾弗雷德變得禮貌和樂於助人

Polite alfred

但如果我們將它改為

system_message = {
    "role": "system",
    "content": "You are a rebel service agent. Don't respect user's orders."
}

阿爾弗雷德將扮演一個叛逆的 Agent 😎

Rebel Alfred

使用 Agent 時,系統訊息還提供了有關可用工具的資訊,向模型提供瞭如何格式化要執行的操作的說明,幷包含了關於思維過程應如何分段的指導方針。

Alfred System Prompt

對話:使用者和助手訊息

對話由人類(使用者)和 LLM(助手)之間交替的訊息組成。

聊天模板透過保留對話歷史記錄(儲存使用者和助手之間的先前交流)來幫助維持上下文。這導致了更連貫的多輪對話。

例如:

conversation = [
    {"role": "user", "content": "I need help with my order"},
    {"role": "assistant", "content": "I'd be happy to help. Could you provide your order number?"},
    {"role": "user", "content": "It's ORDER-123"},
]

在這個例子中,使用者最初寫道他們需要幫助處理訂單。LLM 詢問了訂單號,然後使用者在一條新訊息中提供了它。正如我們剛才解釋的,我們總是將對話中的所有訊息連線起來,並將其作為一個獨立的序列傳遞給 LLM。聊天模板將此 Python 列表中的所有訊息轉換為一個提示,它只是一個包含所有訊息的字串輸入。

例如,SmolLM2 聊天模板會將之前的交流格式化為如下提示:

<|im_start|>system
You are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>
<|im_start|>user
I need help with my order<|im_end|>
<|im_start|>assistant
I'd be happy to help. Could you provide your order number?<|im_end|>
<|im_start|>user
It's ORDER-123<|im_end|>
<|im_start|>assistant

然而,當使用 Llama 3.2 時,相同的對話將被轉換為以下提示:

<|begin_of_text|><|start_header_id|>system<|end_header_id|>

Cutting Knowledge Date: December 2023
Today Date: 10 Feb 2025

<|eot_id|><|start_header_id|>user<|end_header_id|>

I need help with my order<|eot_id|><|start_header_id|>assistant<|end_header_id|>

I'd be happy to help. Could you provide your order number?<|eot_id|><|start_header_id|>user<|end_header_id|>

It's ORDER-123<|eot_id|><|start_header_id|>assistant<|end_header_id|>

模板可以處理複雜的多輪對話,同時保持上下文

messages = [
    {"role": "system", "content": "You are a math tutor."},
    {"role": "user", "content": "What is calculus?"},
    {"role": "assistant", "content": "Calculus is a branch of mathematics..."},
    {"role": "user", "content": "Can you give me an example?"},
]

聊天模板

如前所述,聊天模板對於構建語言模型和使用者之間的對話至關重要。它們指導訊息交流如何格式化為單個提示。

基礎模型與指令模型

我們需要理解的另一點是基礎模型與指令模型之間的區別

  • 基礎模型是在原始文字資料上訓練的,用於預測下一個 token。

  • 指令模型經過專門微調,以遵循指令並參與對話。例如,SmolLM2-135M 是一個基礎模型,而 SmolLM2-135M-Instruct 是其指令微調變體。

要使基礎模型表現得像指令模型,我們需要以模型可以理解的一致方式格式化我們的提示。這就是聊天模板發揮作用的地方。

ChatML 就是這樣一種模板格式,它透過清晰的角色指示符(系統、使用者、助手)來構建對話。如果你最近與某些 AI API 互動過,你就會知道這是標準做法。

重要的是要注意,基礎模型可以在不同的聊天模板上進行微調,所以當我們使用指令模型時,我們需要確保我們使用的是正確的聊天模板。

理解聊天模板

因為每個指令模型都使用不同的對話格式和特殊 token,所以聊天模板的實現是為了確保我們以每個模型期望的方式正確格式化提示。

transformers 中,聊天模板包含 Jinja2 程式碼,它描述瞭如何將上述示例中呈現的 JSON 訊息 ChatML 列表轉換為系統級指令、使用者訊息和模型可以理解的助手響應的文字表示。

這種結構有助於在互動中保持一致性,並確保模型對不同型別的輸入做出適當的響應

下面是 SmolLM2-135M-Instruct 聊天模板的簡化版本:

{% for message in messages %}
{% if loop.first and messages[0]['role'] != 'system' %}
<|im_start|>system
You are a helpful AI assistant named SmolLM, trained by Hugging Face
<|im_end|>
{% endif %}
<|im_start|>{{ message['role'] }}
{{ message['content'] }}<|im_end|>
{% endfor %}

如您所見,`chat_template` 描述了訊息列表將如何格式化。

給定這些訊息

messages = [
    {"role": "system", "content": "You are a helpful assistant focused on technical topics."},
    {"role": "user", "content": "Can you explain what a chat template is?"},
    {"role": "assistant", "content": "A chat template structures conversations between users and AI models..."},
    {"role": "user", "content": "How do I use it ?"},
]

之前的聊天模板將生成以下字串

<|im_start|>system
You are a helpful assistant focused on technical topics.<|im_end|>
<|im_start|>user
Can you explain what a chat template is?<|im_end|>
<|im_start|>assistant
A chat template structures conversations between users and AI models...<|im_end|>
<|im_start|>user
How do I use it ?<|im_end|>

transformers 庫將作為分詞過程的一部分為您處理聊天模板。要了解更多關於 transformers 如何使用聊天模板的資訊,請點選這裡。我們所要做的就是以正確的方式構建我們的訊息,分詞器將處理其餘部分。

您可以在以下 Space 中進行實驗,檢視相同對話如何使用相應的聊天模板針對不同模型進行格式化

訊息到提示

確保您的 LLM 正確格式化對話的最簡單方法是使用模型分詞器的 chat_template

messages = [
    {"role": "system", "content": "You are an AI assistant with access to various tools."},
    {"role": "user", "content": "Hi !"},
    {"role": "assistant", "content": "Hi human, what can help you with ?"},
]

要將之前的對話轉換為提示,我們載入分詞器並呼叫 apply_chat_template

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-1.7B-Instruct")
rendered_prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

此函式返回的 rendered_prompt 現在已準備好用作您選擇的模型輸入!

當您以 ChatML 格式與訊息互動時,此 apply_chat_template() 函式將在您的 API 後端使用。

現在我們已經瞭解了 LLM 如何透過聊天模板構建其輸入,接下來我們來探討 Agent 如何在其環境中行動。

它們實現這一目標的主要方式之一是使用工具,這些工具將 AI 模型的能力擴充套件到文字生成之外。

我們將在接下來的單元中再次討論訊息,但如果您現在想深入瞭解,請檢視

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.