Skip to content

Commit d97fd87

Browse files
heuristicwavewonhyeongseonuatmochoi
authored
🌐 [i18n-KO] Translated add_new_pipeline.md to Korean (#25498)
* dos: ko: add_new_pipeline.mdx * feat: chatgpt draft * fix: manual edits * docs: ko: add_new_pipeline Update _toctree * Update docs/source/ko/add_new_pipeline.md Co-authored-by: Wonhyeong Seo <wonhseo@kakao.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: Wonhyeong Seo <wonhseo@kakao.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: Wonhyeong Seo <wonhseo@kakao.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: Wonhyeong Seo <wonhseo@kakao.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: Wonhyeong Seo <wonhseo@kakao.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com> * Update docs/source/ko/add_new_pipeline.md Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com> --------- Co-authored-by: Wonhyeong Seo <wonhseo@kakao.com> Co-authored-by: SeongWooChoi <46990061+nuatmochoi@users.noreply.github.com>
1 parent a35f889 commit d97fd87

File tree

2 files changed

+251
-3
lines changed

2 files changed

+251
-3
lines changed

docs/source/ko/_toctree.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
- local: perf_infer_gpu_one
133133
title: 하나의 GPU를 활용한 추론
134134
- local: perf_infer_gpu_many
135-
title: 여러 GPU에서 추론
135+
title: 다중 GPU에서 추론
136136
- local: in_translation
137137
title: (번역중) Inference on Specialized Hardware
138138
- local: perf_hardware
@@ -153,8 +153,8 @@
153153
title: 🤗 Transformers에 새로운 모델을 추가하는 방법
154154
- local: add_tensorflow_model
155155
title: 어떻게 🤗 Transformers 모델을 TensorFlow로 변환하나요?
156-
- local: in_translation
157-
title: (번역중) How to add a pipeline to 🤗 Transformers?
156+
- local: add_new_pipeline
157+
title: 어떻게 🤗 Transformers에 파이프라인을 추가하나요?
158158
- local: testing
159159
title: 테스트
160160
- local: pr_checks

docs/source/ko/add_new_pipeline.md

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
<!--Copyright 2020 The HuggingFace Team. All rights reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
4+
the License. You may obtain a copy of the License at
5+
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
8+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
9+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
10+
11+
⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be
12+
rendered properly in your Markdown viewer.
13+
14+
-->
15+
16+
# 어떻게 사용자 정의 파이프라인을 생성하나요? [[how-to-create-a-custom-pipeline]]
17+
18+
이 가이드에서는 사용자 정의 파이프라인을 어떻게 생성하고 [허브](hf.co/models)에 공유하거나 🤗 Transformers 라이브러리에 추가하는 방법을 살펴보겠습니다.
19+
20+
먼저 파이프라인이 수용할 수 있는 원시 입력을 결정해야 합니다.
21+
문자열, 원시 바이트, 딕셔너리 또는 가장 원하는 입력일 가능성이 높은 것이면 무엇이든 가능합니다.
22+
이 입력을 가능한 한 순수한 Python 형식으로 유지해야 (JSON을 통해 다른 언어와도) 호환성이 좋아집니다.
23+
이것이 전처리(`preprocess`) 파이프라인의 입력(`inputs`)이 될 것입니다.
24+
25+
그런 다음 `outputs`를 정의하세요.
26+
`inputs`와 같은 정책을 따르고, 간단할수록 좋습니다.
27+
이것이 후처리(`postprocess`) 메소드의 출력이 될 것입니다.
28+
29+
먼저 4개의 메소드(`preprocess`, `_forward`, `postprocess``_sanitize_parameters`)를 구현하기 위해 기본 클래스 `Pipeline`을 상속하여 시작합니다.
30+
31+
32+
```python
33+
from transformers import Pipeline
34+
35+
36+
class MyPipeline(Pipeline):
37+
def _sanitize_parameters(self, **kwargs):
38+
preprocess_kwargs = {}
39+
if "maybe_arg" in kwargs:
40+
preprocess_kwargs["maybe_arg"] = kwargs["maybe_arg"]
41+
return preprocess_kwargs, {}, {}
42+
43+
def preprocess(self, inputs, maybe_arg=2):
44+
model_input = Tensor(inputs["input_ids"])
45+
return {"model_input": model_input}
46+
47+
def _forward(self, model_inputs):
48+
# model_inputs == {"model_input": model_input}
49+
outputs = self.model(**model_inputs)
50+
# Maybe {"logits": Tensor(...)}
51+
return outputs
52+
53+
def postprocess(self, model_outputs):
54+
best_class = model_outputs["logits"].softmax(-1)
55+
return best_class
56+
```
57+
58+
이 분할 구조는 CPU/GPU에 대한 비교적 원활한 지원을 제공하는 동시에, 다른 스레드에서 CPU에 대한 사전/사후 처리를 수행할 수 있게 지원하는 것입니다.
59+
60+
`preprocess`는 원래 정의된 입력을 가져와 모델에 공급할 수 있는 형식으로 변환합니다.
61+
더 많은 정보를 포함할 수 있으며 일반적으로 `Dict` 형태입니다.
62+
63+
`_forward`는 구현 세부 사항이며 직접 호출할 수 없습니다.
64+
`forward`는 예상 장치에서 모든 것이 작동하는지 확인하기 위한 안전장치가 포함되어 있어 선호되는 호출 메소드입니다.
65+
실제 모델과 관련된 것은 `_forward` 메소드에 속하며, 나머지는 전처리/후처리 과정에 있습니다.
66+
67+
`postprocess` 메소드는 `_forward`의 출력을 가져와 이전에 결정한 최종 출력 형식으로 변환합니다.
68+
69+
`_sanitize_parameters`는 초기화 시간에 `pipeline(...., maybe_arg=4)`이나 호출 시간에 `pipe = pipeline(...); output = pipe(...., maybe_arg=4)`과 같이, 사용자가 원하는 경우 언제든지 매개변수를 전달할 수 있도록 허용합니다.
70+
71+
`_sanitize_parameters`의 반환 값은 `preprocess`, `_forward`, `postprocess`에 직접 전달되는 3개의 kwargs 딕셔너리입니다.
72+
호출자가 추가 매개변수로 호출하지 않았다면 아무것도 채우지 마십시오.
73+
이렇게 하면 항상 더 "자연스러운" 함수 정의의 기본 인수를 유지할 수 있습니다.
74+
75+
분류 작업에서 `top_k` 매개변수가 대표적인 예입니다.
76+
77+
```python
78+
>>> pipe = pipeline("my-new-task")
79+
>>> pipe("This is a test")
80+
[{"label": "1-star", "score": 0.8}, {"label": "2-star", "score": 0.1}, {"label": "3-star", "score": 0.05}
81+
{"label": "4-star", "score": 0.025}, {"label": "5-star", "score": 0.025}]
82+
83+
>>> pipe("This is a test", top_k=2)
84+
[{"label": "1-star", "score": 0.8}, {"label": "2-star", "score": 0.1}]
85+
```
86+
87+
이를 달성하기 위해 우리는 `postprocess` 메소드를 기본 매개변수인 `5`로 업데이트하고 `_sanitize_parameters`를 수정하여 이 새 매개변수를 허용합니다.
88+
89+
90+
```python
91+
def postprocess(self, model_outputs, top_k=5):
92+
best_class = model_outputs["logits"].softmax(-1)
93+
# top_k를 처리하는 로직 추가
94+
return best_class
95+
96+
97+
def _sanitize_parameters(self, **kwargs):
98+
preprocess_kwargs = {}
99+
if "maybe_arg" in kwargs:
100+
preprocess_kwargs["maybe_arg"] = kwargs["maybe_arg"]
101+
102+
postprocess_kwargs = {}
103+
if "top_k" in kwargs:
104+
postprocess_kwargs["top_k"] = kwargs["top_k"]
105+
return preprocess_kwargs, {}, postprocess_kwargs
106+
```
107+
108+
입/출력을 가능한 한 간단하고 완전히 JSON 직렬화 가능한 형식으로 유지하려고 노력하십시오.
109+
이렇게 하면 사용자가 새로운 종류의 개체를 이해하지 않고도 파이프라인을 쉽게 사용할 수 있습니다.
110+
또한 사용 용이성을 위해 여러 가지 유형의 인수(오디오 파일은 파일 이름, URL 또는 순수한 바이트일 수 있음)를 지원하는 것이 비교적 일반적입니다.
111+
112+
113+
114+
## 지원되는 작업 목록에 추가하기 [[adding-it-to-the-list-of-supported-tasks]]
115+
116+
`new-task`를 지원되는 작업 목록에 등록하려면 `PIPELINE_REGISTRY`에 추가해야 합니다:
117+
118+
```python
119+
from transformers.pipelines import PIPELINE_REGISTRY
120+
121+
PIPELINE_REGISTRY.register_pipeline(
122+
"new-task",
123+
pipeline_class=MyPipeline,
124+
pt_model=AutoModelForSequenceClassification,
125+
)
126+
```
127+
128+
원하는 경우 기본 모델을 지정할 수 있으며, 이 경우 특정 개정(분기 이름 또는 커밋 해시일 수 있음, 여기서는 "abcdef")과 타입을 함께 가져와야 합니다:
129+
130+
```python
131+
PIPELINE_REGISTRY.register_pipeline(
132+
"new-task",
133+
pipeline_class=MyPipeline,
134+
pt_model=AutoModelForSequenceClassification,
135+
default={"pt": ("user/awesome_model", "abcdef")},
136+
type="text", # 현재 지원 유형: text, audio, image, multimodal
137+
)
138+
```
139+
140+
## Hub에 파이프라인 공유하기 [[share-your-pipeline-on-the-hub]]
141+
142+
Hub에 사용자 정의 파이프라인을 공유하려면 `Pipeline` 하위 클래스의 사용자 정의 코드를 Python 파일에 저장하기만 하면 됩니다.
143+
예를 들어, 다음과 같이 문장 쌍 분류를 위한 사용자 정의 파이프라인을 사용한다고 가정해 보겠습니다:
144+
145+
```py
146+
import numpy as np
147+
148+
from transformers import Pipeline
149+
150+
151+
def softmax(outputs):
152+
maxes = np.max(outputs, axis=-1, keepdims=True)
153+
shifted_exp = np.exp(outputs - maxes)
154+
return shifted_exp / shifted_exp.sum(axis=-1, keepdims=True)
155+
156+
157+
class PairClassificationPipeline(Pipeline):
158+
def _sanitize_parameters(self, **kwargs):
159+
preprocess_kwargs = {}
160+
if "second_text" in kwargs:
161+
preprocess_kwargs["second_text"] = kwargs["second_text"]
162+
return preprocess_kwargs, {}, {}
163+
164+
def preprocess(self, text, second_text=None):
165+
return self.tokenizer(text, text_pair=second_text, return_tensors=self.framework)
166+
167+
def _forward(self, model_inputs):
168+
return self.model(**model_inputs)
169+
170+
def postprocess(self, model_outputs):
171+
logits = model_outputs.logits[0].numpy()
172+
probabilities = softmax(logits)
173+
174+
best_class = np.argmax(probabilities)
175+
label = self.model.config.id2label[best_class]
176+
score = probabilities[best_class].item()
177+
logits = logits.tolist()
178+
return {"label": label, "score": score, "logits": logits}
179+
```
180+
181+
구현은 프레임워크에 구애받지 않으며, PyTorch와 TensorFlow 모델에 대해 작동합니다.
182+
이를 `pair_classification.py`라는 파일에 저장한 경우, 다음과 같이 가져오고 등록할 수 있습니다:
183+
184+
```py
185+
from pair_classification import PairClassificationPipeline
186+
from transformers.pipelines import PIPELINE_REGISTRY
187+
from transformers import AutoModelForSequenceClassification, TFAutoModelForSequenceClassification
188+
189+
PIPELINE_REGISTRY.register_pipeline(
190+
"pair-classification",
191+
pipeline_class=PairClassificationPipeline,
192+
pt_model=AutoModelForSequenceClassification,
193+
tf_model=TFAutoModelForSequenceClassification,
194+
)
195+
```
196+
197+
이 작업이 완료되면 사전훈련된 모델과 함께 사용할 수 있습니다.
198+
예를 들어, `sgugger/finetuned-bert-mrpc`은 MRPC 데이터 세트에서 미세 조정되어 문장 쌍을 패러프레이즈인지 아닌지를 분류합니다.
199+
200+
```py
201+
from transformers import pipeline
202+
203+
classifier = pipeline("pair-classification", model="sgugger/finetuned-bert-mrpc")
204+
```
205+
206+
그런 다음 `Repository``save_pretrained` 메소드를 사용하여 허브에 공유할 수 있습니다:
207+
208+
```py
209+
from huggingface_hub import Repository
210+
211+
repo = Repository("test-dynamic-pipeline", clone_from="{your_username}/test-dynamic-pipeline")
212+
classifier.save_pretrained("test-dynamic-pipeline")
213+
repo.push_to_hub()
214+
```
215+
216+
이렇게 하면 "test-dynamic-pipeline" 폴더 내에 `PairClassificationPipeline`을 정의한 파일이 복사되며, 파이프라인의 모델과 토크나이저도 저장한 후, `{your_username}/test-dynamic-pipeline` 저장소에 있는 모든 것을 푸시합니다.
217+
이후에는 `trust_remote_code=True` 옵션만 제공하면 누구나 사용할 수 있습니다.
218+
219+
```py
220+
from transformers import pipeline
221+
222+
classifier = pipeline(model="{your_username}/test-dynamic-pipeline", trust_remote_code=True)
223+
```
224+
225+
## 🤗 Transformers에 파이프라인 추가하기 [[add-the-pipeline-to-transformers]]
226+
227+
🤗 Transformers에 사용자 정의 파이프라인을 기여하려면, `pipelines` 하위 모듈에 사용자 정의 파이프라인 코드와 함께 새 모듈을 추가한 다음, `pipelines/__init__.py`에서 정의된 작업 목록에 추가해야 합니다.
228+
229+
그런 다음 테스트를 추가해야 합니다.
230+
`tests/test_pipelines_MY_PIPELINE.py`라는 새 파일을 만들고 다른 테스트와 예제를 함께 작성합니다.
231+
232+
`run_pipeline_test` 함수는 매우 일반적이며, `model_mapping``tf_model_mapping`에서 정의된 가능한 모든 아키텍처의 작은 무작위 모델에서 실행됩니다.
233+
234+
이는 향후 호환성을 테스트하는 데 매우 중요하며, 누군가 `XXXForQuestionAnswering`을 위한 새 모델을 추가하면 파이프라인 테스트가 해당 모델에서 실행을 시도한다는 의미입니다.
235+
모델이 무작위이기 때문에 실제 값을 확인하는 것은 불가능하므로, 단순히 파이프라인 출력 `TYPE`과 일치시키기 위한 도우미 `ANY`가 있습니다.
236+
237+
또한 2개(이상적으로는 4개)의 테스트를 구현해야 합니다.
238+
239+
- `test_small_model_pt`: 이 파이프라인에 대한 작은 모델 1개를 정의(결과가 의미 없어도 상관없음)하고 파이프라인 출력을 테스트합니다.
240+
결과는 `test_small_model_tf`와 동일해야 합니다.
241+
- `test_small_model_tf`: 이 파이프라인에 대한 작은 모델 1개를 정의(결과가 의미 없어도 상관없음)하고 파이프라인 출력을 테스트합니다.
242+
결과는 `test_small_model_pt`와 동일해야 합니다.
243+
- `test_large_model_pt`(`선택사항`): 결과가 의미 있을 것으로 예상되는 실제 파이프라인에서 파이프라인을 테스트합니다.
244+
이러한 테스트는 속도가 느리므로 이를 표시해야 합니다.
245+
여기서의 목표는 파이프라인을 보여주고 향후 릴리즈에서의 변화가 없는지 확인하는 것입니다.
246+
- `test_large_model_tf`(`선택사항`): 결과가 의미 있을 것으로 예상되는 실제 파이프라인에서 파이프라인을 테스트합니다.
247+
이러한 테스트는 속도가 느리므로 이를 표시해야 합니다.
248+
여기서의 목표는 파이프라인을 보여주고 향후 릴리즈에서의 변화가 없는지 확인하는 것입니다.

0 commit comments

Comments
 (0)