Spaces:
Paused
A newer version of the Gradio SDK is available:
5.23.3
μ΄λ»κ² μ¬μ©μ μ μ νμ΄νλΌμΈμ μμ±νλμ? [[how-to-create-a-custom-pipeline]]
μ΄ κ°μ΄λμμλ μ¬μ©μ μ μ νμ΄νλΌμΈμ μ΄λ»κ² μμ±νκ³ νλΈμ 곡μ νκ±°λ π€ Transformers λΌμ΄λΈλ¬λ¦¬μ μΆκ°νλ λ°©λ²μ μ΄ν΄λ³΄κ² μ΅λλ€.
λ¨Όμ νμ΄νλΌμΈμ΄ μμ©ν μ μλ μμ μ
λ ₯μ κ²°μ ν΄μΌ ν©λλ€.
λ¬Έμμ΄, μμ λ°μ΄νΈ, λμ
λ리 λλ κ°μ₯ μνλ μ
λ ₯μΌ κ°λ₯μ±μ΄ λμ κ²μ΄λ©΄ 무μμ΄λ κ°λ₯ν©λλ€.
μ΄ μ
λ ₯μ κ°λ₯ν ν μμν Python νμμΌλ‘ μ μ§ν΄μΌ (JSONμ ν΅ν΄ λ€λ₯Έ μΈμ΄μλ) νΈνμ±μ΄ μ’μμ§λλ€.
μ΄κ²μ΄ μ μ²λ¦¬(preprocess
) νμ΄νλΌμΈμ μ
λ ₯(inputs
)μ΄ λ κ²μ
λλ€.
κ·Έλ° λ€μ outputs
λ₯Ό μ μνμΈμ.
inputs
μ κ°μ μ μ±
μ λ°λ₯΄κ³ , κ°λ¨ν μλ‘ μ’μ΅λλ€.
μ΄κ²μ΄ νμ²λ¦¬(postprocess
) λ©μλμ μΆλ ₯μ΄ λ κ²μ
λλ€.
λ¨Όμ 4κ°μ λ©μλ(preprocess
, _forward
, postprocess
λ° _sanitize_parameters
)λ₯Ό ꡬννκΈ° μν΄ κΈ°λ³Έ ν΄λμ€ Pipeline
μ μμνμ¬ μμν©λλ€.
from transformers import Pipeline
class MyPipeline(Pipeline):
def _sanitize_parameters(self, **kwargs):
preprocess_kwargs = {}
if "maybe_arg" in kwargs:
preprocess_kwargs["maybe_arg"] = kwargs["maybe_arg"]
return preprocess_kwargs, {}, {}
def preprocess(self, inputs, maybe_arg=2):
model_input = Tensor(inputs["input_ids"])
return {"model_input": model_input}
def _forward(self, model_inputs):
# model_inputs == {"model_input": model_input}
outputs = self.model(**model_inputs)
# Maybe {"logits": Tensor(...)}
return outputs
def postprocess(self, model_outputs):
best_class = model_outputs["logits"].softmax(-1)
return best_class
μ΄ λΆν ꡬ쑰λ CPU/GPUμ λν λΉκ΅μ μνν μ§μμ μ 곡νλ λμμ, λ€λ₯Έ μ€λ λμμ CPUμ λν μ¬μ /μ¬ν μ²λ¦¬λ₯Ό μνν μ μκ² μ§μνλ κ²μ λλ€.
preprocess
λ μλ μ μλ μ
λ ₯μ κ°μ Έμ λͺ¨λΈμ 곡κΈν μ μλ νμμΌλ‘ λ³νν©λλ€.
λ λ§μ μ 보λ₯Ό ν¬ν¨ν μ μμΌλ©° μΌλ°μ μΌλ‘ Dict
ννμ
λλ€.
_forward
λ ꡬν μΈλΆ μ¬νμ΄λ©° μ§μ νΈμΆν μ μμ΅λλ€.
forward
λ μμ μ₯μΉμμ λͺ¨λ κ²μ΄ μλνλμ§ νμΈνκΈ° μν μμ μ₯μΉκ° ν¬ν¨λμ΄ μμ΄ μ νΈλλ νΈμΆ λ©μλμ
λλ€.
μ€μ λͺ¨λΈκ³Ό κ΄λ ¨λ κ²μ _forward
λ©μλμ μνλ©°, λλ¨Έμ§λ μ μ²λ¦¬/νμ²λ¦¬ κ³Όμ μ μμ΅λλ€.
postprocess
λ©μλλ _forward
μ μΆλ ₯μ κ°μ Έμ μ΄μ μ κ²°μ ν μ΅μ’
μΆλ ₯ νμμΌλ‘ λ³νν©λλ€.
_sanitize_parameters
λ μ΄κΈ°ν μκ°μ pipeline(...., maybe_arg=4)
μ΄λ νΈμΆ μκ°μ pipe = pipeline(...); output = pipe(...., maybe_arg=4)
κ³Ό κ°μ΄, μ¬μ©μκ° μνλ κ²½μ° μΈμ λ μ§ λ§€κ°λ³μλ₯Ό μ λ¬ν μ μλλ‘ νμ©ν©λλ€.
_sanitize_parameters
μ λ°ν κ°μ preprocess
, _forward
, postprocess
μ μ§μ μ λ¬λλ 3κ°μ kwargs λμ
λ리μ
λλ€.
νΈμΆμκ° μΆκ° 맀κ°λ³μλ‘ νΈμΆνμ§ μμλ€λ©΄ μ무κ²λ μ±μ°μ§ λ§μμμ€.
μ΄λ κ² νλ©΄ νμ λ "μμ°μ€λ¬μ΄" ν¨μ μ μμ κΈ°λ³Έ μΈμλ₯Ό μ μ§ν μ μμ΅λλ€.
λΆλ₯ μμ
μμ top_k
맀κ°λ³μκ° λνμ μΈ μμ
λλ€.
>>> pipe = pipeline("my-new-task")
>>> pipe("This is a test")
[{"label": "1-star", "score": 0.8}, {"label": "2-star", "score": 0.1}, {"label": "3-star", "score": 0.05}
{"label": "4-star", "score": 0.025}, {"label": "5-star", "score": 0.025}]
>>> pipe("This is a test", top_k=2)
[{"label": "1-star", "score": 0.8}, {"label": "2-star", "score": 0.1}]
μ΄λ₯Ό λ¬μ±νκΈ° μν΄ μ°λ¦¬λ postprocess
λ©μλλ₯Ό κΈ°λ³Έ 맀κ°λ³μμΈ 5
λ‘ μ
λ°μ΄νΈνκ³ _sanitize_parameters
λ₯Ό μμ νμ¬ μ΄ μ 맀κ°λ³μλ₯Ό νμ©ν©λλ€.
def postprocess(self, model_outputs, top_k=5):
best_class = model_outputs["logits"].softmax(-1)
# top_kλ₯Ό μ²λ¦¬νλ λ‘μ§ μΆκ°
return best_class
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
μ /μΆλ ₯μ κ°λ₯ν ν κ°λ¨νκ³ μμ ν JSON μ§λ ¬ν κ°λ₯ν νμμΌλ‘ μ μ§νλ €κ³ λ Έλ ₯νμμμ€. μ΄λ κ² νλ©΄ μ¬μ©μκ° μλ‘μ΄ μ’ λ₯μ κ°μ²΄λ₯Ό μ΄ν΄νμ§ μκ³ λ νμ΄νλΌμΈμ μ½κ² μ¬μ©ν μ μμ΅λλ€. λν μ¬μ© μ©μ΄μ±μ μν΄ μ¬λ¬ κ°μ§ μ νμ μΈμ(μ€λμ€ νμΌμ νμΌ μ΄λ¦, URL λλ μμν λ°μ΄νΈμΌ μ μμ)λ₯Ό μ§μνλ κ²μ΄ λΉκ΅μ μΌλ°μ μ λλ€.
μ§μλλ μμ λͺ©λ‘μ μΆκ°νκΈ° [[adding-it-to-the-list-of-supported-tasks]]
new-task
λ₯Ό μ§μλλ μμ
λͺ©λ‘μ λ±λ‘νλ €λ©΄ PIPELINE_REGISTRY
μ μΆκ°ν΄μΌ ν©λλ€:
from transformers.pipelines import PIPELINE_REGISTRY
PIPELINE_REGISTRY.register_pipeline(
"new-task",
pipeline_class=MyPipeline,
pt_model=AutoModelForSequenceClassification,
)
μνλ κ²½μ° κΈ°λ³Έ λͺ¨λΈμ μ§μ ν μ μμΌλ©°, μ΄ κ²½μ° νΉμ κ°μ (λΆκΈ° μ΄λ¦ λλ μ»€λ° ν΄μμΌ μ μμ, μ¬κΈ°μλ "abcdef")κ³Ό νμ μ ν¨κ» κ°μ ΈμμΌ ν©λλ€:
PIPELINE_REGISTRY.register_pipeline(
"new-task",
pipeline_class=MyPipeline,
pt_model=AutoModelForSequenceClassification,
default={"pt": ("user/awesome_model", "abcdef")},
type="text", # νμ¬ μ§μ μ ν: text, audio, image, multimodal
)
Hubμ νμ΄νλΌμΈ 곡μ νκΈ° [[share-your-pipeline-on-the-hub]]
Hubμ μ¬μ©μ μ μ νμ΄νλΌμΈμ 곡μ νλ €λ©΄ Pipeline
νμ ν΄λμ€μ μ¬μ©μ μ μ μ½λλ₯Ό Python νμΌμ μ μ₯νκΈ°λ§ νλ©΄ λ©λλ€.
μλ₯Ό λ€μ΄, λ€μκ³Ό κ°μ΄ λ¬Έμ₯ μ λΆλ₯λ₯Ό μν μ¬μ©μ μ μ νμ΄νλΌμΈμ μ¬μ©νλ€κ³ κ°μ ν΄ λ³΄κ² μ΅λλ€:
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}
ꡬνμ νλ μμν¬μ ꡬμ λ°μ§ μμΌλ©°, PyTorchμ TensorFlow λͺ¨λΈμ λν΄ μλν©λλ€.
μ΄λ₯Ό 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,
)
μ΄ μμ
μ΄ μλ£λλ©΄ μ¬μ νλ ¨λ λͺ¨λΈκ³Ό ν¨κ» μ¬μ©ν μ μμ΅λλ€.
μλ₯Ό λ€μ΄, sgugger/finetuned-bert-mrpc
μ MRPC λ°μ΄ν° μΈνΈμμ λ―ΈμΈ μ‘°μ λμ΄ λ¬Έμ₯ μμ ν¨λ¬νλ μ΄μ¦μΈμ§ μλμ§λ₯Ό λΆλ₯ν©λλ€.
from transformers import pipeline
classifier = pipeline("pair-classification", model="sgugger/finetuned-bert-mrpc")
κ·Έλ° λ€μ Repository
μ save_pretrained
λ©μλλ₯Ό μ¬μ©νμ¬ νλΈμ 곡μ ν μ μμ΅λλ€:
from huggingface_hub import Repository
repo = Repository("test-dynamic-pipeline", clone_from="{your_username}/test-dynamic-pipeline")
classifier.save_pretrained("test-dynamic-pipeline")
repo.push_to_hub()
μ΄λ κ² νλ©΄ "test-dynamic-pipeline" ν΄λ λ΄μ PairClassificationPipeline
μ μ μν νμΌμ΄ 볡μ¬λλ©°, νμ΄νλΌμΈμ λͺ¨λΈκ³Ό ν ν¬λμ΄μ λ μ μ₯ν ν, {your_username}/test-dynamic-pipeline
μ μ₯μμ μλ λͺ¨λ κ²μ νΈμν©λλ€.
μ΄νμλ trust_remote_code=True
μ΅μ
λ§ μ 곡νλ©΄ λꡬλ μ¬μ©ν μ μμ΅λλ€.
from transformers import pipeline
classifier = pipeline(model="{your_username}/test-dynamic-pipeline", trust_remote_code=True)
π€ Transformersμ νμ΄νλΌμΈ μΆκ°νκΈ° [[add-the-pipeline-to-transformers]]
π€ Transformersμ μ¬μ©μ μ μ νμ΄νλΌμΈμ κΈ°μ¬νλ €λ©΄, pipelines
νμ λͺ¨λμ μ¬μ©μ μ μ νμ΄νλΌμΈ μ½λμ ν¨κ» μ λͺ¨λμ μΆκ°ν λ€μ, pipelines/__init__.py
μμ μ μλ μμ
λͺ©λ‘μ μΆκ°ν΄μΌ ν©λλ€.
κ·Έλ° λ€μ ν
μ€νΈλ₯Ό μΆκ°ν΄μΌ ν©λλ€.
tests/test_pipelines_MY_PIPELINE.py
λΌλ μ νμΌμ λ§λ€κ³ λ€λ₯Έ ν
μ€νΈμ μμ λ₯Ό ν¨κ» μμ±ν©λλ€.
run_pipeline_test
ν¨μλ λ§€μ° μΌλ°μ μ΄λ©°, model_mapping
λ° tf_model_mapping
μμ μ μλ κ°λ₯ν λͺ¨λ μν€ν
μ²μ μμ 무μμ λͺ¨λΈμμ μ€νλ©λλ€.
μ΄λ ν₯ν νΈνμ±μ ν
μ€νΈνλ λ° λ§€μ° μ€μνλ©°, λκ΅°κ° XXXForQuestionAnswering
μ μν μ λͺ¨λΈμ μΆκ°νλ©΄ νμ΄νλΌμΈ ν
μ€νΈκ° ν΄λΉ λͺ¨λΈμμ μ€νμ μλνλ€λ μλ―Έμ
λλ€.
λͺ¨λΈμ΄ 무μμμ΄κΈ° λλ¬Έμ μ€μ κ°μ νμΈνλ κ²μ λΆκ°λ₯νλ―λ‘, λ¨μν νμ΄νλΌμΈ μΆλ ₯ TYPE
κ³Ό μΌμΉμν€κΈ° μν λμ°λ―Έ ANY
κ° μμ΅λλ€.
λν 2κ°(μ΄μμ μΌλ‘λ 4κ°)μ ν μ€νΈλ₯Ό ꡬνν΄μΌ ν©λλ€.
test_small_model_pt
: μ΄ νμ΄νλΌμΈμ λν μμ λͺ¨λΈ 1κ°λ₯Ό μ μ(κ²°κ³Όκ° μλ―Έ μμ΄λ μκ΄μμ)νκ³ νμ΄νλΌμΈ μΆλ ₯μ ν μ€νΈν©λλ€. κ²°κ³Όλtest_small_model_tf
μ λμΌν΄μΌ ν©λλ€.test_small_model_tf
: μ΄ νμ΄νλΌμΈμ λν μμ λͺ¨λΈ 1κ°λ₯Ό μ μ(κ²°κ³Όκ° μλ―Έ μμ΄λ μκ΄μμ)νκ³ νμ΄νλΌμΈ μΆλ ₯μ ν μ€νΈν©λλ€. κ²°κ³Όλtest_small_model_pt
μ λμΌν΄μΌ ν©λλ€.test_large_model_pt
(μ νμ¬ν
): κ²°κ³Όκ° μλ―Έ μμ κ²μΌλ‘ μμλλ μ€μ νμ΄νλΌμΈμμ νμ΄νλΌμΈμ ν μ€νΈν©λλ€. μ΄λ¬ν ν μ€νΈλ μλκ° λ리λ―λ‘ μ΄λ₯Ό νμν΄μΌ ν©λλ€. μ¬κΈ°μμ λͺ©νλ νμ΄νλΌμΈμ 보μ¬μ£Όκ³ ν₯ν 릴리μ¦μμμ λ³νκ° μλμ§ νμΈνλ κ²μ λλ€.test_large_model_tf
(μ νμ¬ν
): κ²°κ³Όκ° μλ―Έ μμ κ²μΌλ‘ μμλλ μ€μ νμ΄νλΌμΈμμ νμ΄νλΌμΈμ ν μ€νΈν©λλ€. μ΄λ¬ν ν μ€νΈλ μλκ° λ리λ―λ‘ μ΄λ₯Ό νμν΄μΌ ν©λλ€. μ¬κΈ°μμ λͺ©νλ νμ΄νλΌμΈμ 보μ¬μ£Όκ³ ν₯ν 릴리μ¦μμμ λ³νκ° μλμ§ νμΈνλ κ²μ λλ€.