텐서플로우 자연어처리 BERT-base
이 튜토리얼에서는 자연어처리 모델 중 하나인 BERT의 마스크드 언어모델(masked language model) 태스크를 사용합니다. 마스크드 언어모델은 문장 내에서 마스킹 된 단어를 예측하는 태스크입니다. 이 튜토리얼을 통해 RBLN 컴파일러를 사용하여 허깅페이스 BERT-base 모델을 컴파일하고, RBLN 런타임을 사용하여 추론하는 방법을 배울 수 있습니다.
이 튜토리얼은 두 단계로 구성되어 있습니다:
- 텐서플로우
BERT-base
모델을 컴파일하고 디스크에 저장하는 방법
- 컴파일된 모델을 로드하고 추론하는 방법
사전 준비
시작하기에 앞서 아래의 파이썬 패키지들이 설치되어 있는지 확인합니다:
참고
세부 사항을 생략하고, 빠르게 컴파일 및 추론하는 방법을 확인하려면 요약을 참고하세요. 컴파일 및 추론을 위한 모든 코드가 정리되어있어 빠르게 프로젝트를 시작 할 수 있습니다.
1단계. 컴파일 방법
모델 준비
허깅페이스에서 제공하는 transformers
라이브러리를 통해 TFBertForMaskedLM
모델을 로드하고, tf.function
객체로 변환합니다.
| from transformers import TFBertForMaskedLM
import tensorflow as tf
import rebel # RBLN 컴파일러
# 허깅페이스 텐서플로우 BERT-base 모델 준비
model = TFBertForMaskedLM.from_pretrained("bert-base-uncased")
func = tf.function(
lambda input_ids, attention_mask, token_type_ids: model(
input_ids, attention_mask, token_type_ids
)
)
|
모델 컴파일
rebel.compile_from_tf_function()
함수를 이용하여 준비 된 텐서플로우 모델(tf.function
)을 컴파일 할 수 있습니다.
| # 모델 컴파일
MAX_SEQ_LEN = 128
input_info = [
("input_ids", [1, MAX_SEQ_LEN], tf.int64),
("attention_mask", [1, MAX_SEQ_LEN], tf.int64),
("token_type_ids", [1, MAX_SEQ_LEN], tf.int64),
]
compiled_model = rebel.compile_from_tf_function(
func,
input_info,
# 호스트에 NPU가 설치되어 있는 경우, 아래의 `npu`인자는 명시하지 않아도 자동으로 감지됩니다.
npu="RBLN-CA12",
)
|
호스트 머신에 NPU가 설치되어 있는 경우, NPU를 자동으로 감지하여 사용하기 때문에 rebel.compile_from_tf_function
함수에 npu
인자를 생략할 수 있습니다.
NPU가 설치되지 않은 호스트 머신에서 컴파일을 수행할 경우 컴파일 함수에 npu
인자를 명시해야 합니다. 그렇지 않으면 에러가 발생합니다.
현재 지원하는 NPU는 RBLN-CA02
, RBLN-CA12
입니다. 사용하려는 NPU의 이름은 NPU가 설치된 호스트 머신에서 rbln-stat
명령어를 통해 확인할 수 있습니다.
컴파일된 모델 저장
compiled_model.save()
함수를 통해 컴파일된 모델을 디스크에 저장할 수 있습니다.
| # 컴파일된 모델 디스크에 저장
compiled_model.save("bert_base.rbln")
|
2단계. 추론 방법
RBLN 런타임 모듈 rebel.Runtime()
을 통해 이전 단계에서 컴파일된 모델을 로드하고 추론할 수 있습니다.
입력 데이터 준비
transformers
라이브러리에서 제공하는 BertTokenizer
를 사용하여 입력문자열을 토큰화하고, 마스크드 언어모델의 입력문자열로 사용하기 위해 사전처리 과정을 수행합니다.
| from transformers import BertTokenizer, pipeline
import tensorflow as tf
import rebel # RBLN 런타임
# 입력 데이터 준비
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
text = "The capital of Korea is [MASK]."
MAX_SEQ_LEN = 128
inputs = tokenizer(text, return_tensors="np", padding="max_length", max_length=MAX_SEQ_LEN)
|
추론
RBLN 런타임 모듈 rebel.Runtime()
을 통해 컴파일된 모델을 로드합니다. RBLN 런타임 모듈의 멤버함수 run()
을 통해 주어진 문장에 대해 추론할 수 있습니다. 또는 __call__
매직함수를 사용할 수도 있습니다.
| # 컴파일된 모델 불러오기
module = rebel.Runtime("bert_base.rbln")
# 추론
out = module.run(**inputs)
|
print(module)
을 통해 로드된 모델의 입출력 형태 및 모델크기 등 요약된 정보를 확인할 수 있습니다.
결과 확인
입력 문자열의 [MASK]
토큰의 인덱스를 특정하고, 추론 결과 로짓값 out
으로부터 해당 토큰이 위치한 로짓값을 추출합니다. 추출된 로짓값 중 가장 높은값의 단어를 디코딩하여 최종 결과 단어를 확인할 수 있습니다.
| # 결과 확인
mask_token_index = tf.where((inputs.input_ids == tokenizer.mask_token_id)[0])
selected_logits = tf.gather_nd(out[0], indices=mask_token_index)
predicted_token_id = tf.math.argmax(selected_logits, axis=-1)
print("Masked word is [", tokenizer.decode(predicted_token_id), "].")
|
최종 결과는 다음과 같습니다:
요약
허깅페이스에서 제공하는 텐서플로우 BERT-base
모델의 컴파일을 위한 완성된 코드는 아래와 같습니다:
| from transformers import TFBertForMaskedLM
import tensorflow as tf
import rebel # RBLN 컴파일러
# 허깅페이스 텐서플로우 BERT-base 모델 준비
model = TFBertForMaskedLM.from_pretrained("bert-base-uncased")
func = tf.function(
lambda input_ids, attention_mask, token_type_ids: model(
input_ids, attention_mask, token_type_ids
)
)
# 모델 컴파일
MAX_SEQ_LEN = 128
input_info = [
("input_ids", [1, MAX_SEQ_LEN], tf.int64),
("attention_mask", [1, MAX_SEQ_LEN], tf.int64),
("token_type_ids", [1, MAX_SEQ_LEN], tf.int64),
]
compiled_model = rebel.compile_from_tf_function(
func,
input_info,
# 호스트에 NPU가 설치되어 있는 경우, 아래의 `npu`인자는 명시하지 않아도 자동으로 감지됩니다.
npu="RBLN-CA12",
)
# 컴파일된 모델 디스크에 저장
compiled_model.save("bert_base.rbln")
|
컴파일된 BERT-base
모델의 추론을 위한 완성된 코드는 아래와 같습니다:
| from transformers import BertTokenizer, pipeline
import tensorflow as tf
import rebel # RBLN 런타임
# 입력 데이터 준비
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
text = "The capital of Korea is [MASK]."
MAX_SEQ_LEN = 128
inputs = tokenizer(text, return_tensors='np', padding="max_length", max_length=MAX_SEQ_LEN)
# 컴파일된 모델 불러오기
module = rebel.Runtime("bert_base.rbln")
# 추론
out = module.run(**inputs)
# 결과 확인
mask_token_index = tf.where((inputs.input_ids == tokenizer.mask_token_id)[0])
selected_logits = tf.gather_nd(out[0], indices=mask_token_index)
predicted_token_id = tf.math.argmax(selected_logits, axis=-1)
print("Masked word is [", tokenizer.decode(predicted_token_id), "].")
|