返回文章列表

語言模型微調與高效提示工程實踐

本文深入探討語言模型微調與高效提示工程的實踐技巧,涵蓋迭代式提示最佳化、佈署與監控、提示模組組成、高效提示範本建立、多字串提示範本設計、範例選擇器優點、自定義範例選擇器實作以及與提示範本的整合應用。藉由理解這些技術,開發者能有效提升語言模型效能,打造更流暢、更智慧的互動體驗。

機器學習 Web 開發

語言模型微調是提升特定任務效能的有效方法,尤其在提示工程不足以應付複雜場景時。微調過程需要多次迭代、測試和改進提示,並持續監控模型效能變化,以便及時調整。一個完整的提示模組包含提示範本、範例選擇器和輸出解析器。提示範本分為常規和聊天兩種,範例選擇器則負責挑選最相關的資料,而輸出解析器則處理模型輸出,確保其符合預期格式。高效的提示範本設計需考慮指令、少數示例、背景和問題,並可透過 Python 的 Langchain 函式庫建立多字串提示範本,動態填充變數,提升程式碼可讀性和可維護性。範例選擇器則能引導模型理解輸出格式、提高準確性,並實作少數學習。開發者可以根據需求自定義範例選擇器,例如根據輸入詞彙長度選擇最接近的範例,並將其整合至提示範本中,以最佳化模型的學習效果,並應用於翻譯等自然語言處理任務。

精準的語言模型調整

在進行語言模型調整時,尤其是當您需要在特定任務中取得一致的效能,且提示工程無法提供幫助時,模型微調可以成為您的解決方案。

迭代的重要性

不要期望第一次就能達到完美。相反,應該準備好進行多次迭代、測試和改進您的提示。

佈署您的提示

當您對語言模型的回應感到滿意,並且對您的提示品質充滿信心時,就該將其佈署到現實世界中了。

監控和維護

隨著時間的推移,監控其效能變化至關重要。如果您發現任何偏差或不一致性,請積極更新和改進您的提示。

提示的組成部分

提示模組由三個主要組成部分構成:

  1. 提示範本:您可以利用兩種型別的提示範本與語言模型合作:

    • 常規提示範本:適用於直接的文字生成使用案例,例如回答問題、完成句子或任何其他文字生成任務。
    • 聊天提示範本:設計用於更具互動性和對話性的體驗,具有系統訊息和使用者訊息等元件,以引導互動作用。
  2. 示例選擇器:用於從資料集中選擇最相關的示例,以幫助語言模型更好地理解任務需求。

  3. 輸出解析器:負責處理和解釋語言模型的輸出,確保它符合預期的格式和品質。

瞭解這些組成部分可以幫助您建立出色的提示,從而提高語言模型的效能和有效性。透過合理利用這些工具,您可以為使用者打造出更流暢、更智慧的互動體驗。

建立高效的提示範本

要建立一個高效的提示範本,需要考慮以下幾個關鍵因素:指令、少數示例、背景和問題。指令用於提供清晰的方向和期望給語言模型(LLM),而少數示例則幫助 LLM 理解所需的風格、語調和格式。背景和問題有助於 LLM 理解對話的設定和焦點,從而提供更具體的回應。

建立多字串提示範本

建立一個多字串提示範本可以與任何型別的 LLM 一起使用。首先,需要從langchain.prompts函式庫中匯入PromptTemplate類別。然後,建立一個多行字串,稱為template,它類別似於一個 f 字串,但使用 {variable} 而不是 f"{variable}"

from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI

template = """
你是一位資深軟體工程師。
請解釋以下演算法:{algorithm}{language} 中。描述其目的、時間複雜度和一個常見的使用案例。
"""

在這個例子中, {algorithm}{language} 分別被替換為 “機器學習” 和 “法語”。生成的提示將如下所示:

你是一位資深軟體工程師。 請解釋以下演算法:機器學習 在 法語 中。描述其目的、時間複雜度和一個常見的使用案例。

呼叫 LLM 使用提示範本

建立 LLM 物件時,需要指定 API 金鑰和溫度等引數。然後,使用生成的提示字串作為引數,並列印回應。

llm = OpenAI(openai_api_key="你的OpenAI金鑰", temperature=0.7)
chain = LLMChain(llm=llm, prompt=template)
response = chain.run(algorithm="機器學習", language="法語")

圖表翻譯

圖表翻譯:

此圖表展示了建立一個高效的提示範本並使用它呼叫 LLM 的過程。首先,建立一個提示範本,然後指定 API 金鑰和溫度建立 LLM 物件。接下來,使用生成的提示字串作為引數呼叫 LLM,並列印回應。

使用提示範本和示例選擇器的優點

在使用語言模型時,提示範本和示例選擇器是兩種強大的工具,可以幫助您獲得更好的結果。提示範本允許您動態地建立提示,從而使您的程式碼更易於閱讀和維護。示例選擇器則可以幫助您選擇最合適的示例來包含在提示中,從而導致語言模型生成更準確和更合適的回應。

提示範本的優點

  1. 一致性:提示範本確保輸入語言模型的格式和結構的一致性。
  2. 可重用性:提示範本是可重用的,因為它們與呼叫模型的程式碼是分離的。
  3. 自定義:您可以根據需要動態填充提示範本中的相關資訊。
  4. 改進微調:提示範本可以引導語言模型生成與所需格式、風格或內容相符的回應。
  5. 可維護性:將提示範本與程式碼分離可以提高程式碼函式庫的可讀性和可維護性。

示例選擇器的優點

  1. 指導語言模型:示例選擇器可以幫助語言模型瞭解所需的輸出格式和模式。
  2. 提高準確性:透過選擇最合適的示例,示例選擇器可以幫助語言模型生成更準確和更合適的回應。
  3. 少數學習:示例選擇器可以實作少數學習,透過提供少數示例來引導語言模型生成所需的輸出。

示例選擇器的實作

要實作一個示例選擇器,您需要定義一個基礎類別,例如 BaseExampleSelector,它提供了一個介面來選擇示例。然後,您需要實作這個介面,建立一個具體的示例選擇器類別。

from abc import ABC, abstractmethod
from typing import Dict, List

class BaseExampleSelector(ABC):
    """示例選擇器介面"""

    @abstractmethod
    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        """根據輸入變數選擇示例"""

    @abstractmethod
    def add_example(self, example: Dict[str, str]) -> Any:
        """新增新的示例到儲存中"""

透過實作這個介面,您可以建立一個具體的示例選擇器類別,例如 MyExampleSelector,它可以根據輸入變數選擇最合適的示例。

class MyExampleSelector(BaseExampleSelector):
    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        # 實作選擇示例的邏輯
        pass

    def add_example(self, example: Dict[str, str]) -> Any:
        # 實作新增新的示例到儲存中的邏輯
        pass

透過使用提示範本和示例選擇器,您可以提高語言模型的效能和準確性,並使您的程式碼更易於閱讀和維護。

自訂範例選擇器的實作

在這個章節中,我們將實作一個自訂的範例選擇器,該選擇器可以根據輸入詞彙的長度選擇最接近的範例。

範例資料結構

首先,我們定義了一個範例資料結構,該結構包含輸入詞彙和對應的義大利語翻譯:

examples = [
    {"input": "hi", "output": "ciao"},
    {"input": "bye", "output": "arrivaderci"},
    {"input": "soccer", "output": "calcio"},
]

自訂範例選擇器類別

接下來,我們實作了一個自訂範例選擇器類別 CustomExampleSelector,該類別繼承自 BaseExampleSelector

class CustomExampleSelector(BaseExampleSelector):
    def __init__(self, examples):
        self.examples = examples

    def add_example(self, example):
        self.examples.append(example)

    def select_examples(self, input_variables):
        new_word = input_variables["input"]
        new_word_length = len(new_word)
        best_match = None
        smallest_diff = float("inf")
        for example in self.examples:
            current_diff = abs(len(example["input"]) - new_word_length)
            if current_diff < smallest_diff:
                smallest_diff = current_diff
                best_match = example
        return best_match

範例選擇器的工作原理

範例選擇器的 select_examples 方法根據輸入詞彙的長度選擇最接近的範例。它計算每個範例的輸入詞彙長度與輸入詞彙長度之間的差異,並保持最小差異的範例。

內容解密:

def select_examples(self, input_variables):
    # 取得輸入詞彙
    new_word = input_variables["input"]
    # 計算輸入詞彙的長度
    new_word_length = len(new_word)
    # 初始化最佳匹配範例和最小差異
    best_match = None
    smallest_diff = float("inf")
    # 迭代每個範例
    for example in self.examples:
        # 計算範例的輸入詞彙長度與輸入詞彙長度之間的差異
        current_diff = abs(len(example["input"]) - new_word_length)
        # 如果差異小於最小差異,更新最佳匹配範例和最小差異
        if current_diff < smallest_diff:
            smallest_diff = current_diff
            best_match = example
    # 傳回最佳匹配範例
    return best_match

圖表翻譯:

圖表翻譯:

此圖表展示了範例選擇器的工作原理。它首先取得輸入詞彙,然後計算其長度。接下來,它迭代每個範例,計算範例的輸入詞彙長度與輸入詞彙長度之間的差異。如果差異小於最小差異,則更新最佳匹配範例和最小差異。最後,傳回最佳匹配範例。

自定義範例選擇器的應用

在自然語言處理中,選擇最合適的範例以匹配輸入詞彙是一項重要的任務。以下,我們將探討如何實作一個自定義範例選擇器,並將其應用於特定場景中。

實作自定義範例選擇器

首先,我們需要定義一個類別,負責管理範例並根據輸入詞彙選擇最匹配的範例。這個類別可以被命名為 CustomExampleSelector

class CustomExampleSelector:
    def __init__(self, examples):
        self.examples = examples

    def select_examples(self, input_word):
        # 初始化最小差異和最佳匹配範例
        smallest_diff = float('inf')
        best_match = None

        # 遍歷所有範例
        for example in self.examples:
            # 計算當前範例與輸入詞彙之間的差異
            current_diff = self.calculate_diff(input_word, example['input'])

            # 如果當前差異小於最小差異,更新最小差異和最佳匹配範例
            if current_diff < smallest_diff:
                smallest_diff = current_diff
                best_match = example

        return [best_match]

    def add_example(self, new_example):
        # 將新範例新增到現有的範例列表中
        self.examples.append(new_example)

    def calculate_diff(self, input_word, example_input):
        # 這裡可以實作任何合適的差異計算方法,例如Levenshtein距離
        # 為簡單起見,這裡使用了基本的字串比較
        return abs(len(input_word) - len(example_input))

使用自定義範例選擇器

現在,我們可以建立一個 CustomExampleSelector 的例項,並使用它來選擇最匹配的範例。

examples = [
    {'input': 'bye', 'output': 'arrivaderci'},
    # 可以新增更多範例
]

example_selector = CustomExampleSelector(examples)

# 選擇最匹配的範例
result = example_selector.select_examples({"input": "okay"})

print(result)  # 輸出:[{'input': 'bye', 'output': 'arrivaderci'}]

# 新增新範例
example_selector.add_example({"input": "hand", "output": "mano"})

# 再次選擇最匹配的範例
result = example_selector.select_examples({"input": "okay"})

print(result)  # 輸出:[{'input': 'hand', 'output': 'mano'}]

在提示中使用範例選擇器

最後,我們可以將這個自定義範例選擇器整合到一個提示範本中,以便在自然語言生成任務中使用。

from langchain import FewShotPromptTemplate

# 建立一個提示範本
prompt_template = FewShotPromptTemplate(
    input_variables=["input"],
    template="根據輸入'{input}',請生成對應的輸出。",
    few_shot_examples=examples
)

# 使用範例選擇器選擇最匹配的範例並生成提示
def generate_prompt(input_word):
    best_match = example_selector.select_examples({"input": input_word})
    if best_match:
        return prompt_template.format(input=input_word, example=best_match[0])
    else:
        return "沒有找到匹配的範例。"

# 測試生成的提示
print(generate_prompt("okay"))

這樣,我們就實作了一個基本的自定義範例選擇器,並將其應用於特定的自然語言生成任務中。這個選擇器可以根據輸入詞彙選擇最匹配的範例,並生成相應的提示。

自定義範例選擇器和提示範本

在自然語言處理任務中,例如翻譯,自定義範例選擇器和提示範本可以幫助提高模型的效能和相關性。以下是如何建立一個自定義範例選擇器和使用它來生成提示的步驟。

建立自定義範例選擇器

首先,需要定義一個範例選擇器,該選擇器可以根據輸入的長度選擇最相似的範例。這可以透過建立一個函式來實作,該函式計算輸入和可用範例之間的長度相似度。

定義範例提示範本

接下來,需要定義一個範例提示範本,該範本指定了每個範例在提示中的格式。這可以透過 PromptTemplate.from_template 方法來實作,該方法允許你定義輸入和輸出的格式。

example_prompt = PromptTemplate.from_template("Input: {input} -> Output: {output}")

建立 FewShotPromptTemplate

然後,需要建立一個 FewShotPromptTemplate 例項,該例項使用自定義範例選擇器、範例提示範本、字首、字尾和輸入變數。

prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    suffix="Input: {input} -> Output:",
    prefix="Translate the following words from English to Italian:",
    input_variables=["input"],
)

生成提示

最後,需要使用 format 方法來生成一個包含輸入單詞的提示。

print(prompt.format(input="word"))

選擇合適的範例選擇器

有不同型別的範例選擇器可供選擇,包括:

  1. 相似度範例選擇器:根據輸入和可用範例之間的語義相似度選擇最相似的範例。
  2. 長度相似度範例選擇器:根據輸入和可用範例之間的長度相似度選擇最相似的範例。

選擇合適的範例選擇器取決於具體的任務需求和可用資料的特點。

圖表翻譯:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 語言模型微調與高效提示工程實踐

package "提示工程實踐" {
    package "提示模組" {
        component [提示範本] as template
        component [範例選擇器] as selector
        component [輸出解析器] as parser
    }

    package "微調流程" {
        component [迭代最佳化] as iterate
        component [佈署監控] as monitor
        component [效能追蹤] as track
    }

    package "技術實作" {
        component [LangChain] as langchain
        component [少數學習] as fewshot
        component [動態變數] as dynamic
    }
}

template --> selector : 提示組成
iterate --> monitor : 持續改進
langchain --> fewshot : 範例引導

note bottom of selector
  選擇最相關
  範例資料
end note

collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型

note right of feature
  特徵工程包含:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

內容解密:

上述過程描述瞭如何建立一個自定義範例選擇器和使用它來生成提示。這個過程涉及定義一個範例選擇器、建立一個範例提示範本、生成一個 FewShotPromptTemplate 例項和使用 format 方法來生成一個包含輸入單詞的提示。最終,需要根據具體的任務需求選擇合適的範例選擇器。

精準的語言模型調整:結論

從模型微調的迭代過程、提示的組成、高效提示範本的建立,到範例選擇器的優點和自定義實作,本文深入探討瞭如何精準調整語言模型以提升其在特定任務中的效能。觀察產業技術發展趨勢,低程式碼/無程式碼開發平臺興起,伴隨而來的是對客製化語言模型的需求日益增長。精準的模型調整不再只是研究人員的專利,更成為廣大開發者的必備技能。

透過本文的多維度分析,我們可以看到,雖然提示工程能快速提升模型效能,但模型微調在追求一致性和特定領域表現上更具優勢。技術的限制在於微調的成本和複雜度,尤其是在資料量不足或缺乏專業知識的情況下。然而,隨著工具和技術的成熟,這些限制將逐漸被克服。對於追求高效能的企業,投資於模型微調和自定義範例選擇器將是提升商業價值的關鍵策略。技術團隊應著重於理解不同範例選擇器的優缺點,並根據實際應用場景選擇最佳方案,才能最大化模型的潛力。

展望未來,自動化模型微調和更智慧的範例選擇策略將成為重要的發展方向。隨著模型架構的演進和訓練資料的豐富,我們預見更精細、更客製化的語言模型將廣泛應用於各個領域,重新定義人機互動的模式。玄貓認為,掌握精準的語言模型調整技術,將是未來在 AI 驅動的世界中保持競爭力的重要根本。