Transformers 文件

新增新管道

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

新增新管道

透過繼承並實現幾個方法來定製您的管道。將程式碼分享到Hub社群,並將管道註冊到Transformers,以便所有人都能快速輕鬆地使用它。

本指南將引導您完成向Transformers新增新管道的過程。

設計選擇

至少,您只需要為管道提供適合任務的輸入。這也是您設計管道的起點。

確定管道可以接受的輸入型別。它可以是字串、原始位元組、字典等等。儘可能將輸入保持為純 Python,因為它具有更好的相容性。接下來,確定管道應該返回的輸出。同樣,將輸出保持為 Python 是最簡單和最佳的選擇,因為它更容易處理。

保持輸入和輸出簡單,理想情況下是 JSON 可序列化的,這使得使用者無需學習新的物件型別即可更輕鬆地執行您的管道。支援多種不同的輸入型別以獲得更高的易用性也很常見。例如,接受檔名、URL 或原始位元組的音訊檔案,為使用者提供了提供音訊資料時更大的靈活性。

建立管道

確定輸入和輸出後,您可以開始實現管道。您的管道應該繼承自基礎管道類,幷包含 4 個方法。

from transformers import Pipeline

class MyPipeline(Pipeline):
    def _sanitize_parameters(self, **kwargs):

    def preprocess(self, inputs, args=2):

    def _forward(self, model_inputs):

    def postprocess(self, model_outputs):
  1. `preprocess` 接收輸入並將其轉換為模型合適的輸入格式。
def preprocess(self, inputs, maybe_arg=2):
    model_input = Tensor(inputs["input_ids"])
    return {"model_input": model_input}
  1. `_forward` 不應直接呼叫。`forward` 是首選方法,因為它包含保障措施,以確保所有內容在預期裝置上正常工作。與模型相關的任何內容都屬於 `_forward`,而其他所有內容都屬於 `preprocess` 或 `postprocess`。
def _forward(self, model_inputs):
    outputs = self.model(**model_inputs)
    return outputs
  1. `postprocess` 從 `_forward` 中的模型輸出生成最終輸出。
def postprocess(self, model_outputs, top_k=5):
    best_class = model_outputs["logits"].softmax(-1)
    return best_class
  1. `_sanitize_parameters` 允許使用者將額外引數傳遞給管道。這可以在初始化期間或呼叫管道時進行。`_sanitize_parameters` 返回 3 個額外的關鍵字引數字典,它們直接傳遞給 `preprocess`、`_forward` 和 `postprocess`。如果使用者在呼叫管道時沒有傳遞額外引數,則不要新增任何內容。這會保留函式定義中的預設引數,這總是更自然的。

例如,在 `postprocess` 中新增一個 `top_k` 引數,以返回前 5 個最有可能的類別。然後在 `_sanitize_parameters` 中,檢查使用者是否傳入了 `top_k` 並將其新增到 `postprocess_kwargs`。

def _sanitize_parameters(self, **kwargs):
    preprocess_kwargs = {}
    if "maybe_arg" in kwargs:
        preprocess_kwargs["maybe_arg"] = kwargs["maybe_arg"]

    postprocess_kwargs = {}
    if "top_k" in kwargs:
        postprocess_kwargs["top_k"] = kwargs["top_k"]
    return preprocess_kwargs, {}, postprocess_kwargs

現在,如果使用者選擇,管道可以返回最可能的頂部標籤。

from transformers import pipeline

pipeline = pipeline("my-task")
# returns 3 most likely labels
pipeline("This is the best meal I've ever had", top_k=3)
# returns 5 most likely labels by default
pipeline("This is the best meal I've ever had")

註冊管道

在 `PIPELINE_REGISTRY` 中註冊您的管道支援的新任務。該登錄檔定義:

  • 管道支援的機器學習框架,使用 `pt_model` 或 `tf_model`(兩者都新增以確保它適用於兩種框架)
  • 一個預設模型,它應該來自特定修訂(分支或提交雜湊),其中模型與 `default` 按預期工作
  • 期望的輸入,使用 `type`
from transformers.pipelines import PIPELINE_REGISTRY
from transformers import AutoModelForSequenceClassification, TFAutoModelForSequenceClassification

PIPELINE_REGISTRY.register_pipeline(
    "new-task",
    pipeline_class=MyPipeline,
    pt_model=AutoModelForSequenceClassification,
    tf_model=TFAutoModelForSequenceClassification,
    default={"pt": ("user/awesome-model", "branch-name")},
    type="text",
)

共享您的管道

Hub上與社群分享您的管道,或者您可以直接將其新增到 Transformers。

將您的管道程式碼上傳到 Hub 更快,因為它不需要 Transformers 團隊的審查。將管道新增到 Transformers 可能更慢,因為它需要審查,並且您需要新增測試以確保您的管道正常工作。

上傳到 Hub

將您的管道程式碼以 Python 檔案的形式新增到 Hub。

例如,一個用於句子對分類的自定義管道可能如下面的程式碼所示。該實現適用於 PyTorch 和 TensorFlow 模型。

import numpy as np
from transformers import Pipeline

def softmax(outputs):
    maxes = np.max(outputs, axis=-1, keepdims=True)
    shifted_exp = np.exp(outputs - maxes)
    return shifted_exp / shifted_exp.sum(axis=-1, keepdims=True)

class PairClassificationPipeline(Pipeline):
    def _sanitize_parameters(self, **kwargs):
        preprocess_kwargs = {}
        if "second_text" in kwargs:
            preprocess_kwargs["second_text"] = kwargs["second_text"]
        return preprocess_kwargs, {}, {}

    def preprocess(self, text, second_text=None):
        return self.tokenizer(text, text_pair=second_text, return_tensors=self.framework)

    def _forward(self, model_inputs):
        return self.model(**model_inputs)

    def postprocess(self, model_outputs):
        logits = model_outputs.logits[0].numpy()
        probabilities = softmax(logits)

        best_class = np.argmax(probabilities)
        label = self.model.config.id2label[best_class]
        score = probabilities[best_class].item()
        logits = logits.tolist()
        return {"label": label, "score": score, "logits": logits}

將程式碼儲存到一個名為 `pair_classification.py` 的檔案中,並按照下面所示匯入和註冊它。

from pair_classification import PairClassificationPipeline
from transformers.pipelines import PIPELINE_REGISTRY
from transformers import AutoModelForSequenceClassification, TFAutoModelForSequenceClassification

PIPELINE_REGISTRY.register_pipeline(
    "pair-classification",
    pipeline_class=PairClassificationPipeline,
    pt_model=AutoModelForSequenceClassification,
    tf_model=TFAutoModelForSequenceClassification,
)

register_pipeline 函式將管道詳細資訊(任務型別、管道類、支援的後端)註冊到模型的 `config.json` 檔案中。

  "custom_pipelines": {
    "pair-classification": {
      "impl": "pair_classification.PairClassificationPipeline",
      "pt": [
        "AutoModelForSequenceClassification"
      ],
      "tf": [
        "TFAutoModelForSequenceClassification"
      ],
    }
  },

呼叫 push_to_hub() 將管道推送到 Hub。包含程式碼的 Python 檔案將被複制到 Hub,管道的模型和分詞器也將被儲存並推送到 Hub。您的管道現在應該可以在您的名稱空間下的 Hub 上使用。

from transformers import pipeline

pipeline = pipeline(task="pair-classification", model="sgugger/finetuned-bert-mrpc")
pipeline.push_to_hub("pair-classification-pipeline")

要使用該管道,載入管道時新增 `trust_remote_code=True`。

from transformers import pipeline

pipeline = pipeline(task="pair-classification", trust_remote_code=True)

新增到 Transformers

將自定義管道新增到 Transformers 需要新增測試以確保一切按預期工作,並請求 Transformers 團隊的審查。

將您的管道程式碼作為新模組新增到pipelines子模組,並將其新增到pipelines/__init__.py中定義的任務列表中。

接下來,在 transformers/tests/pipelines 中為管道新增新的測試。您可以檢視其他測試,瞭解如何測試您的管道。

run_pipeline_test 函式應該非常通用,並在 model_mappingtf_model_mapping 中定義的模型上執行。這對於測試與新模型的未來相容性非常重要。

您還會注意到在 run_pipeline_test 函式中使用了 `ANY`。模型是隨機的,所以您無法檢查實際值。使用 `ANY` 允許測試匹配管道型別的輸出。

最後,您還應該實現以下 4 個測試。

  1. test_small_model_pttest_small_model_tf,使用小型模型進行這些管道測試,以確保它們返回正確的輸出。結果不一定有意義。每個管道都應該返回相同的結果。
  2. test_large_model_pttest_large_model_tf,使用真實模型進行這些管道測試,以確保它們返回有意義的結果。這些測試速度較慢,應標記為慢速。
< > 在 GitHub 上更新

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