Transformers documentation
Thêm một pipeline mới
Thêm một pipeline mới
Tự tạo Pipeline của riêng bạn bằng cách kế thừa lớp này và triển khai một vài phương thức. Chia sẻ mã nguồn với cộng đồng trên Hub và đăng ký pipeline với Transformers để mọi người có thể sử dụng nhanh chóng và dễ dàng.
Hướng dẫn này sẽ giúp bạn thực hiện quy trình thêm một pipeline mới vào Transformers.
Lựa chọn thiết kế
Tối thiểu, bạn chỉ cần cung cấp cho Pipeline một đầu vào phù hợp cho tác vụ. Đây cũng là nơi bạn nên bắt đầu khi thiết kế pipeline của mình.
Xác định các kiểu đầu vào mà Pipeline có thể nhận. Chúng có thể là chuỗi, byte thô, từ điển, v.v. Hãy cố gắng giữ đầu vào ở dạng Python thuần túy khi có thể vì nó tương thích hơn. Tiếp theo, xác định đầu ra mà Pipeline nên trả về. Một lần nữa, giữ đầu ra ở dạng Python là lựa chọn đơn giản và tốt nhất vì dễ làm việc hơn.
Việc giữ cho đầu vào và đầu ra đơn giản, và lý tưởng nhất là có thể serialize thành JSON, giúp người dùng dễ dàng chạy Pipeline của bạn mà không cần phải học các kiểu đối tượng mới. Đồng thời, việc hỗ trợ nhiều kiểu đầu vào khác nhau cũng rất phổ biến để tăng thêm sự tiện lợi. Ví dụ, cho phép nhận tệp âm thanh từ tên tệp, URL hoặc byte thô sẽ mang lại cho người dùng nhiều linh hoạt hơn trong cách cung cấp dữ liệu âm thanh.
Tạo một pipeline
Khi đã xác định được đầu vào và đầu ra, bạn có thể bắt đầu triển khai Pipeline. Pipeline của bạn cần kế thừa từ lớp cơ sở Pipeline và bao gồm 4 phương thức.
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):preprocessnhận các đầu vào và chuyển đổi chúng thành định dạng đầu vào phù hợp cho mô hình.
def preprocess(self, inputs, maybe_arg=2):
model_input = Tensor(inputs["input_ids"])
return {"model_input": model_input}_forwardkhông nên được gọi trực tiếp.forwardlà phương thức được ưu tiên vì nó bao gồm các biện pháp bảo vệ để đảm bảo mọi thứ hoạt động chính xác trên thiết bị mong đợi. Mọi thứ liên quan đến mô hình thuộc về_forwardvà mọi thứ khác thuộc vềpreprocesshoặcpostprocess.
def _forward(self, model_inputs):
outputs = self.model(**model_inputs)
return outputspostprocesstạo ra đầu ra cuối cùng từ đầu ra của mô hình trong_forward.
def postprocess(self, model_outputs, top_k=5):
best_class = model_outputs["logits"].softmax(-1)
return best_class_sanitize_parameterscho phép người dùng truyền thêm các tham số vào Pipeline. Điều này có thể xảy ra trong quá trình khởi tạo hoặc khi Pipeline được gọi._sanitize_parameterstrả về 3 dict chứa các tham số keyword bổ sung, được truyền trực tiếp đếnpreprocess,_forwardvàpostprocess. Không thêm gì nếu người dùng không gọi pipeline với các tham số bổ sung. Điều này giữ nguyên các tham số mặc định trong định nghĩa hàm, vốn luôn tự nhiên hơn.
Ví dụ, thêm tham số top_k vào postprocess để trả về 5 lớp có khả năng cao nhất. Sau đó, trong _sanitize_parameters, kiểm tra xem người dùng có truyền vào top_k không và thêm nó vào 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_kwargsBây giờ pipeline có thể trả về các nhãn có khả năng cao nhất nếu người dùng chọn.
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")Đăng ký một pipeline
Đăng ký tác vụ mới mà pipeline của bạn hỗ trợ trong PIPELINE_REGISTRY. Registry định nghĩa:
- Lớp mô hình Pytorch được hỗ trợ với
pt_model - một mô hình mặc định nên đến từ một revision cụ thể (branch, hoặc commit hash) mà ở đó mô hình hoạt động như mong đợi với
default - đầu vào dự kiến có
type
from transformers.pipelines import PIPELINE_REGISTRY
from transformers import AutoModelForSequenceClassification
PIPELINE_REGISTRY.register_pipeline(
"new-task",
pipeline_class=MyPipeline,
pt_model=AutoModelForSequenceClassification,
default={"pt": ("user/awesome-model", "branch-name")},
type="text",
)Chia sẻ pipeline của bạn
Chia sẻ pipeline của bạn với cộng đồng trên Hub hoặc bạn có thể thêm nó trực tiếp vào Transformers.
Việc tải mã pipeline của bạn lên Hub sẽ nhanh hơn vì không cần sự xem xét từ nhóm Transformers. Việc thêm pipeline vào Transformers có thể chậm hơn vì cần được xem xét và bạn phải thêm các bài kiểm tra để đảm bảo Pipeline của bạn hoạt động.
Tải lên Hub
Thêm mã pipeline của bạn vào Hub trong một tệp Python.
Ví dụ, một pipeline tùy chỉnh cho phân loại cặp câu có thể có dạng như đoạn mã dưới đây.
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}Lưu mã vào một tệp có tên pair_classification.py, sau đó nhập và đăng ký nó như minh họa bên dưới.
from pair_classification import PairClassificationPipeline
from transformers.pipelines import PIPELINE_REGISTRY
from transformers import AutoModelForSequenceClassification
PIPELINE_REGISTRY.register_pipeline(
"pair-classification",
pipeline_class=PairClassificationPipeline,
pt_model=AutoModelForSequenceClassification,
)Hàm register_pipeline đăng ký các chi tiết của pipeline (loại tác vụ, lớp pipeline, các backend được hỗ trợ) vào tệp config.json của mô hình.
"custom_pipelines": {
"pair-classification": {
"impl": "pair_classification.PairClassificationPipeline",
"pt": [
"AutoModelForSequenceClassification"
],
}
},Gọi push_to_hub() để đẩy pipeline lên Hub. Tệp Python chứa mã sẽ được sao chép lên Hub, và mô hình cùng tokenizer của pipeline cũng được lưu và đẩy lên Hub. Pipeline của bạn giờ đã có sẵn trên Hub dưới namespace của bạn.
from transformers import pipeline
pipeline = pipeline(task="pair-classification", model="sgugger/finetuned-bert-mrpc")
pipeline.push_to_hub("pair-classification-pipeline")Để sử dụng pipeline, hãy thêm trust_remote_code=True khi tải pipeline.
from transformers import pipeline
pipeline = pipeline(task="pair-classification", trust_remote_code=True)Thêm vào Transformers
Việc thêm một pipeline tùy chỉnh vào Transformers đòi hỏi phải thêm các bài kiểm tra để đảm bảo mọi thứ hoạt động như mong đợi, đồng thời yêu cầu nhóm Transformers xem xét.
Thêm mã pipeline của bạn như một module mới vào submodule pipelines, và thêm nó vào danh sách các tác vụ được định nghĩa trong pipelines/init.py.
Tiếp theo, thêm một bài kiểm tra mới cho pipeline trong transformers/tests/pipelines. Bạn có thể xem các bài kiểm tra khác làm ví dụ về cách kiểm tra pipeline của mình.
Hàm run_pipeline_test nên rất tổng quát và chạy trên các mô hình được định nghĩa trong model_mapping. Điều này quan trọng để kiểm tra khả năng tương thích trong tương lai với các mô hình mới.
Bạn cũng sẽ nhận thấy ANY được sử dụng xuyên suốt trong hàm run_pipeline_test. Các mô hình là ngẫu nhiên, nên bạn không thể kiểm tra các giá trị thực tế. Việc sử dụng ANY cho phép bài kiểm tra khớp với đầu ra của loại pipeline thay vì giá trị cụ thể.
Cuối cùng, bạn cũng nên triển khai 4 bài kiểm tra sau.
- test_small_model_pt, sử dụng một mô hình nhỏ cho các pipeline này để đảm bảo chúng trả về các kết quả đầu ra chính xác. Kết quả không nhất thiết phải có ý nghĩa. Mỗi pipeline phải trả về cùng một kết quả.
- test_large_model_pt, hãy sử dụng một mô hình thực tế cho các pipeline này để đảm bảo chúng trả về kết quả có ý nghĩa. Các bài kiểm tra này chạy chậm và nên được đánh dấu là chậm.