{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Transformers 설치 방법\n",
"! pip install transformers datasets\n",
"# 마지막 릴리스 대신 소스에서 설치하려면, 위 명령을 주석으로 바꾸고 아래 명령을 해제하세요.\n",
"# ! pip install git+https://github.com/huggingface/transformers.git"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 객관식 문제[[multiple-choice]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"객관식 과제는 문맥과 함께 여러 개의 후보 답변이 제공되고 모델이 정답을 선택하도록 학습된다는 점을 제외하면 질의응답과 유사합니다.\n",
"\n",
"진행하는 방법은 아래와 같습니다:\n",
"\n",
"1. [SWAG](https://huggingface.co/datasets/swag) 데이터 세트의 'regular' 구성으로 [BERT](https://huggingface.co/bert-base-uncased)를 미세 조정하여 여러 옵션과 일부 컨텍스트가 주어졌을 때 가장 적합한 답을 선택합니다.\n",
"2. 추론에 미세 조정된 모델을 사용합니다.\n",
"\n",
"\n",
"이 튜토리얼에서 설명하는 작업은 다음 모델 아키텍처에서 지원됩니다:\n",
"\n",
"\n",
"\n",
"[ALBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/albert), [BERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/bert), [BigBird](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/big_bird), [CamemBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/camembert), [CANINE](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/canine), [ConvBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/convbert), [Data2VecText](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/data2vec-text), [DeBERTa-v2](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/deberta-v2), [DistilBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/distilbert), [ELECTRA](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/electra), [ERNIE](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/ernie), [ErnieM](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/ernie_m), [FlauBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/flaubert), [FNet](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/fnet), [Funnel Transformer](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/funnel), [I-BERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/ibert), [Longformer](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/longformer), [LUKE](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/luke), [MEGA](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/mega), [Megatron-BERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/megatron-bert), [MobileBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/mobilebert), [MPNet](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/mpnet), [Nezha](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/nezha), [Nyströmformer](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/nystromformer), [QDQBert](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/qdqbert), [RemBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/rembert), [RoBERTa](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/roberta), [RoBERTa-PreLayerNorm](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/roberta-prelayernorm), [RoCBert](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/roc_bert), [RoFormer](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/roformer), [SqueezeBERT](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/squeezebert), [XLM](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/xlm), [XLM-RoBERTa](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/xlm-roberta), [XLM-RoBERTa-XL](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/xlm-roberta-xl), [XLNet](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/xlnet), [X-MOD](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/xmod), [YOSO](https://huggingface.co/docs/transformers/main/ko/tasks/../model_doc/yoso)\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"시작하기 전에 필요한 라이브러리가 모두 설치되어 있는지 확인하세요:\n",
"\n",
"```bash\n",
"pip install transformers datasets evaluate\n",
"```\n",
"\n",
"모델을 업로드하고 커뮤니티와 공유할 수 있도록 허깅페이스 계정에 로그인하는 것이 좋습니다. 메시지가 표시되면 토큰을 입력하여 로그인합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from huggingface_hub import notebook_login\n",
"\n",
"notebook_login()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## SWAG 데이터 세트 가져오기[[load-swag-dataset]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"먼저 🤗 Datasets 라이브러리에서 SWAG 데이터셋의 '일반' 구성을 가져옵니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from datasets import load_dataset\n",
"\n",
"swag = load_dataset(\"swag\", \"regular\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 데이터를 살펴봅니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'ending0': 'passes by walking down the street playing their instruments.',\n",
" 'ending1': 'has heard approaching them.',\n",
" 'ending2': \"arrives and they're outside dancing and asleep.\",\n",
" 'ending3': 'turns the lead singer watches the performance.',\n",
" 'fold-ind': '3416',\n",
" 'gold-source': 'gold',\n",
" 'label': 0,\n",
" 'sent1': 'Members of the procession walk down the street holding small horn brass instruments.',\n",
" 'sent2': 'A drum line',\n",
" 'startphrase': 'Members of the procession walk down the street holding small horn brass instruments. A drum line',\n",
" 'video-id': 'anetv_jkn6uvmqwh4'}"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"swag[\"train\"][0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"여기에는 많은 필드가 있는 것처럼 보이지만 실제로는 매우 간단합니다:\n",
"\n",
"- `sent1` 및 `sent2`: 이 필드는 문장이 어떻게 시작되는지 보여주며, 이 두 필드를 합치면 `시작 구절(startphrase)` 필드가 됩니다.\n",
"- `종료 구절(ending)`: 문장이 어떻게 끝날 수 있는지에 대한 가능한 종료 구절를 제시하지만 그 중 하나만 정답입니다.\n",
"- `레이블(label)`: 올바른 문장 종료 구절을 식별합니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 전처리[[preprocess]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"다음 단계는 문장의 시작과 네 가지 가능한 구절을 처리하기 위해 BERT 토크나이저를 불러옵니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import AutoTokenizer\n",
"\n",
"tokenizer = AutoTokenizer.from_pretrained(\"bert-base-uncased\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"생성하려는 전처리 함수는 다음과 같아야 합니다:\n",
"\n",
"1. `sent1` 필드를 네 개 복사한 다음 각각을 `sent2`와 결합하여 문장이 시작되는 방식을 재현합니다.\n",
"2. `sent2`를 네 가지 가능한 문장 구절 각각과 결합합니다.\n",
"3. 이 두 목록을 토큰화할 수 있도록 평탄화(flatten)하고, 각 예제에 해당하는 `input_ids`, `attention_mask` 및 `labels` 필드를 갖도록 다차원화(unflatten) 합니다."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ending_names = [\"ending0\", \"ending1\", \"ending2\", \"ending3\"]\n",
"\n",
"\n",
"def preprocess_function(examples):\n",
" first_sentences = [[context] * 4 for context in examples[\"sent1\"]]\n",
" question_headers = examples[\"sent2\"]\n",
" second_sentences = [\n",
" [f\"{header} {examples[end][i]}\" for end in ending_names] for i, header in enumerate(question_headers)\n",
" ]\n",
"\n",
" first_sentences = sum(first_sentences, [])\n",
" second_sentences = sum(second_sentences, [])\n",
"\n",
" tokenized_examples = tokenizer(first_sentences, second_sentences, truncation=True)\n",
" return {k: [v[i : i + 4] for i in range(0, len(v), 4)] for k, v in tokenized_examples.items()}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"전체 데이터 집합에 전처리 기능을 적용하려면 🤗 Datasets `map` 메소드를 사용합니다. `batched=True`를 설정하여 데이터 집합의 여러 요소를 한 번에 처리하면 `map` 함수의 속도를 높일 수 있습니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tokenized_swag = swag.map(preprocess_function, batched=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"🤗 Transformers에는 객관식용 데이터 콜레이터가 없으므로 예제 배치를 만들려면 `DataCollatorWithPadding`을 조정해야 합니다. 데이터 정렬 중에 전체 데이터 집합을 최대 길이로 패딩하는 대신 배치 중 가장 긴 길이로 문장을 *동적 패딩*하는 것이 더 효율적입니다.\n",
"\n",
"`DataCollatorForMultipleChoice`는 모든 모델 입력을 평탄화하고 패딩을 적용하며 그 결과를 결과를 다차원화합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from dataclasses import dataclass\n",
"from transformers.tokenization_utils_base import PreTrainedTokenizerBase, PaddingStrategy\n",
"from typing import Optional, Union\n",
"import torch\n",
"\n",
"\n",
"@dataclass\n",
"class DataCollatorForMultipleChoice:\n",
" \"\"\"\n",
" Data collator that will dynamically pad the inputs for multiple choice received.\n",
" \"\"\"\n",
"\n",
" tokenizer: PreTrainedTokenizerBase\n",
" padding: Union[bool, str, PaddingStrategy] = True\n",
" max_length: Optional[int] = None\n",
" pad_to_multiple_of: Optional[int] = None\n",
"\n",
" def __call__(self, features):\n",
" label_name = \"label\" if \"label\" in features[0].keys() else \"labels\"\n",
" labels = [feature.pop(label_name) for feature in features]\n",
" batch_size = len(features)\n",
" num_choices = len(features[0][\"input_ids\"])\n",
" flattened_features = [\n",
" [{k: v[i] for k, v in feature.items()} for i in range(num_choices)] for feature in features\n",
" ]\n",
" flattened_features = sum(flattened_features, [])\n",
"\n",
" batch = self.tokenizer.pad(\n",
" flattened_features,\n",
" padding=self.padding,\n",
" max_length=self.max_length,\n",
" pad_to_multiple_of=self.pad_to_multiple_of,\n",
" return_tensors=\"pt\",\n",
" )\n",
"\n",
" batch = {k: v.view(batch_size, num_choices, -1) for k, v in batch.items()}\n",
" batch[\"labels\"] = torch.tensor(labels, dtype=torch.int64)\n",
" return batch"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from dataclasses import dataclass\n",
"from transformers.tokenization_utils_base import PreTrainedTokenizerBase, PaddingStrategy\n",
"from typing import Optional, Union\n",
"import tensorflow as tf\n",
"\n",
"\n",
"@dataclass\n",
"class DataCollatorForMultipleChoice:\n",
" \"\"\"\n",
" Data collator that will dynamically pad the inputs for multiple choice received.\n",
" \"\"\"\n",
"\n",
" tokenizer: PreTrainedTokenizerBase\n",
" padding: Union[bool, str, PaddingStrategy] = True\n",
" max_length: Optional[int] = None\n",
" pad_to_multiple_of: Optional[int] = None\n",
"\n",
" def __call__(self, features):\n",
" label_name = \"label\" if \"label\" in features[0].keys() else \"labels\"\n",
" labels = [feature.pop(label_name) for feature in features]\n",
" batch_size = len(features)\n",
" num_choices = len(features[0][\"input_ids\"])\n",
" flattened_features = [\n",
" [{k: v[i] for k, v in feature.items()} for i in range(num_choices)] for feature in features\n",
" ]\n",
" flattened_features = sum(flattened_features, [])\n",
"\n",
" batch = self.tokenizer.pad(\n",
" flattened_features,\n",
" padding=self.padding,\n",
" max_length=self.max_length,\n",
" pad_to_multiple_of=self.pad_to_multiple_of,\n",
" return_tensors=\"tf\",\n",
" )\n",
"\n",
" batch = {k: tf.reshape(v, (batch_size, num_choices, -1)) for k, v in batch.items()}\n",
" batch[\"labels\"] = tf.convert_to_tensor(labels, dtype=tf.int64)\n",
" return batch"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 평가 하기[[evaluate]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"훈련 중에 메트릭을 포함하면 모델의 성능을 평가하는 데 도움이 되는 경우가 많습니다. 🤗[Evaluate](https://huggingface.co/docs/evaluate/index) 라이브러리를 사용하여 평가 방법을 빠르게 가져올 수 있습니다. 이 작업에서는 [accuracy](https://huggingface.co/spaces/evaluate-metric/accuracy) 지표를 가져옵니다(🤗 Evaluate [둘러보기](https://huggingface.co/docs/evaluate/a_quick_tour)를 참조하여 지표를 가져오고 계산하는 방법에 대해 자세히 알아보세요):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import evaluate\n",
"\n",
"accuracy = evaluate.load(\"accuracy\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"그리고 예측과 레이블을 `compute`에 전달하여 정확도를 계산하는 함수를 만듭니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"\n",
"def compute_metrics(eval_pred):\n",
" predictions, labels = eval_pred\n",
" predictions = np.argmax(predictions, axis=1)\n",
" return accuracy.compute(predictions=predictions, references=labels)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 `compute_metrics` 함수를 사용할 준비가 되었으며, 훈련을 설정할 때 이 함수로 돌아가게 됩니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 훈련 하기[[train]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"`Trainer`로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](https://huggingface.co/docs/transformers/main/ko/tasks/../training#train-with-pytorch-trainer)를 살펴보세요!\n",
"\n",
"\n",
"\n",
"이제 모델 훈련을 시작할 준비가 되었습니다! `AutoModelForMultipleChoice`로 BERT를 로드합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import AutoModelForMultipleChoice, TrainingArguments, Trainer\n",
"\n",
"model = AutoModelForMultipleChoice.from_pretrained(\"bert-base-uncased\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 세 단계만 남았습니다:\n",
"\n",
"1. 훈련 하이퍼파라미터를 `TrainingArguments`에 정의합니다. 유일한 필수 매개변수는 모델을 저장할 위치를 지정하는 `output_dir`입니다. `push_to_hub=True`를 설정하여 이 모델을 허브에 푸시합니다(모델을 업로드하려면 허깅 페이스에 로그인해야 합니다). 각 에폭이 끝날 때마다 `Trainer`가 정확도를 평가하고 훈련 체크포인트를 저장합니다.\n",
"2. 모델, 데이터 세트, 토크나이저, 데이터 콜레이터, `compute_metrics` 함수와 함께 훈련 인자를 `Trainer`에 전달합니다.\n",
"3. `train()`을 사용하여 모델을 미세 조정합니다."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"training_args = TrainingArguments(\n",
" output_dir=\"my_awesome_swag_model\",\n",
" evaluation_strategy=\"epoch\",\n",
" save_strategy=\"epoch\",\n",
" load_best_model_at_end=True,\n",
" learning_rate=5e-5,\n",
" per_device_train_batch_size=16,\n",
" per_device_eval_batch_size=16,\n",
" num_train_epochs=3,\n",
" weight_decay=0.01,\n",
" push_to_hub=True,\n",
")\n",
"\n",
"trainer = Trainer(\n",
" model=model,\n",
" args=training_args,\n",
" train_dataset=tokenized_swag[\"train\"],\n",
" eval_dataset=tokenized_swag[\"validation\"],\n",
" tokenizer=tokenizer,\n",
" data_collator=DataCollatorForMultipleChoice(tokenizer=tokenizer),\n",
" compute_metrics=compute_metrics,\n",
")\n",
"\n",
"trainer.train()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"훈련이 완료되면 모든 사람이 모델을 사용할 수 있도록 `push_to_hub()` 메소드를 사용하여 모델을 허브에 공유하세요:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"trainer.push_to_hub()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"Keras로 모델을 미세 조정하는 데 익숙하지 않다면 기본 튜토리얼 [여기](https://huggingface.co/docs/transformers/main/ko/tasks/../training#train-a-tensorflow-model-with-keras)를 살펴보시기 바랍니다!\n",
"\n",
"\n",
"TensorFlow에서 모델을 미세 조정하려면 최적화 함수, 학습률 스케쥴 및 몇 가지 학습 하이퍼파라미터를 설정하는 것부터 시작하세요:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import create_optimizer\n",
"\n",
"batch_size = 16\n",
"num_train_epochs = 2\n",
"total_train_steps = (len(tokenized_swag[\"train\"]) // batch_size) * num_train_epochs\n",
"optimizer, schedule = create_optimizer(init_lr=5e-5, num_warmup_steps=0, num_train_steps=total_train_steps)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"그리고 `TFAutoModelForMultipleChoice`로 BERT를 가져올 수 있습니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import TFAutoModelForMultipleChoice\n",
"\n",
"model = TFAutoModelForMultipleChoice.from_pretrained(\"bert-base-uncased\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`prepare_tf_dataset()`을 사용하여 데이터 세트를 `tf.data.Dataset` 형식으로 변환합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data_collator = DataCollatorForMultipleChoice(tokenizer=tokenizer)\n",
"tf_train_set = model.prepare_tf_dataset(\n",
" tokenized_swag[\"train\"],\n",
" shuffle=True,\n",
" batch_size=batch_size,\n",
" collate_fn=data_collator,\n",
")\n",
"\n",
"tf_validation_set = model.prepare_tf_dataset(\n",
" tokenized_swag[\"validation\"],\n",
" shuffle=False,\n",
" batch_size=batch_size,\n",
" collate_fn=data_collator,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[`compile`](https://keras.io/api/models/model_training_apis/#compile-method)을 사용하여 훈련 모델을 구성합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.compile(optimizer=optimizer)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"훈련을 시작하기 전에 설정해야 할 마지막 두 가지는 예측의 정확도를 계산하고 모델을 허브로 푸시하는 방법을 제공하는 것입니다. 이 두 가지 작업은 모두 [Keras 콜백](https://huggingface.co/docs/transformers/main/ko/tasks/../main_classes/keras_callbacks)을 사용하여 수행할 수 있습니다.\n",
"\n",
"`compute_metrics`함수를 `KerasMetricCallback`에 전달하세요:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers.keras_callbacks import KerasMetricCallback\n",
"\n",
"metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"모델과 토크나이저를 업로드할 위치를 `PushToHubCallback`에서 지정하세요:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers.keras_callbacks import PushToHubCallback\n",
"\n",
"push_to_hub_callback = PushToHubCallback(\n",
" output_dir=\"my_awesome_model\",\n",
" tokenizer=tokenizer,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"그리고 콜백을 함께 묶습니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"callbacks = [metric_callback, push_to_hub_callback]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 모델 훈련을 시작합니다! 훈련 및 검증 데이터 세트, 에폭 수, 콜백을 사용하여 [`fit`](https://keras.io/api/models/model_training_apis/#fit-method)을 호출하고 모델을 미세 조정합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=2, callbacks=callbacks)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"훈련이 완료되면 모델이 자동으로 허브에 업로드되어 누구나 사용할 수 있습니다!\n",
"\n",
"\n",
"\n",
"\n",
"객관식 모델을 미세 조정하는 방법에 대한 보다 심층적인 예는 아래 문서를 참조하세요.\n",
"[PyTorch notebook](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/multiple_choice.ipynb)\n",
"또는 [TensorFlow notebook](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/multiple_choice-tf.ipynb).\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 추론 하기[[inference]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 모델을 미세 조정했으니 추론에 사용할 수 있습니다!\n",
"\n",
"텍스트와 두 개의 후보 답안을 작성합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"prompt = \"France has a bread law, Le Décret Pain, with strict rules on what is allowed in a traditional baguette.\"\n",
"candidate1 = \"The law does not apply to croissants and brioche.\"\n",
"candidate2 = \"The law applies to baguettes.\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"각 프롬프트와 후보 답변 쌍을 토큰화하여 PyTorch 텐서를 반환합니다. 또한 `labels`을 생성해야 합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import AutoTokenizer\n",
"\n",
"tokenizer = AutoTokenizer.from_pretrained(\"my_awesome_swag_model\")\n",
"inputs = tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensors=\"pt\", padding=True)\n",
"labels = torch.tensor(0).unsqueeze(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"입력과 레이블을 모델에 전달하고 `logits`을 반환합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import AutoModelForMultipleChoice\n",
"\n",
"model = AutoModelForMultipleChoice.from_pretrained(\"my_awesome_swag_model\")\n",
"outputs = model(**{k: v.unsqueeze(0) for k, v in inputs.items()}, labels=labels)\n",
"logits = outputs.logits"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"가장 높은 확률을 가진 클래스를 가져옵니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'0'"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predicted_class = logits.argmax().item()\n",
"predicted_class"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"각 프롬프트와 후보 답안 쌍을 토큰화하여 텐서플로 텐서를 반환합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import AutoTokenizer\n",
"\n",
"tokenizer = AutoTokenizer.from_pretrained(\"my_awesome_swag_model\")\n",
"inputs = tokenizer([[prompt, candidate1], [prompt, candidate2]], return_tensors=\"tf\", padding=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"모델에 입력을 전달하고 `logits`를 반환합니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from transformers import TFAutoModelForMultipleChoice\n",
"\n",
"model = TFAutoModelForMultipleChoice.from_pretrained(\"my_awesome_swag_model\")\n",
"inputs = {k: tf.expand_dims(v, 0) for k, v in inputs.items()}\n",
"outputs = model(inputs)\n",
"logits = outputs.logits"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"가장 높은 확률을 가진 클래스를 가져옵니다:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'0'"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predicted_class = int(tf.math.argmax(logits, axis=-1)[0])\n",
"predicted_class"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}