마스크 언어 모형으로 문장 중간의 빈 칸 예측 :: 대화형 AI - mindscale
Skip to content

마스크 언어 모형으로 문장 중간의 빈 칸 예측

마스크 언어 모형 파이프라인을 초기화한다.

from transformers import pipeline
nlp = pipeline("fill-mask")
Some weights of RobertaForMaskedLM were not initialized from the model checkpoint at distilroberta-base and are newly initialized: ['lm_head.decoder.bias']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.

마스크 토큰

nlp.tokenizer.mask_token
'<mask>'

파이프라인에 문장을 입력한다.

nlp(f"Pizza is my {nlp.tokenizer.mask_token} food")
[{'score': 0.4141102433204651,
  'sequence': '<s>Pizza is my favorite food</s>',
  'token': 2674,
  'token_str': 'Ġfavorite'},
 {'score': 0.31080567836761475,
  'sequence': '<s>Pizza is my comfort food</s>',
  'token': 5863,
  'token_str': 'Ġcomfort'},
 {'score': 0.138148233294487,
  'sequence': '<s>Pizza is my favourite food</s>',
  'token': 5548,
  'token_str': 'Ġfavourite'},
 {'score': 0.015286021865904331,
  'sequence': '<s>Pizza is my dream food</s>',
  'token': 3366,
  'token_str': 'Ġdream'},
 {'score': 0.013527910225093365,
  'sequence': '<s>Pizza is my signature food</s>',
  'token': 6543,
  'token_str': 'Ġsignature'}]

빈 칸(마스크)가 2개 이상인 경우 직접 모형을 만들어야 한다.

from transformers import TFAutoModelForMaskedLM, AutoTokenizer

모형을 다운로드

tokenizer = AutoTokenizer.from_pretrained("distilroberta-base")
model = TFAutoModelForMaskedLM.from_pretrained("distilroberta-base")

토크나이저

vocab = tokenizer.get_vocab()
id2word = {i: word for word, i in vocab.items()}

문장

sequence = f"Pizza is my {tokenizer.mask_token} food."

토큰화

input_ids = tokenizer.encode(sequence, return_tensors="tf")

빈 칸의 위치 찾기

mask_token_indices = tf.where(input_ids[0] == tokenizer.mask_token_id)[0].numpy().tolist()

모형에 입력

result = model(input_ids)

로짓

logits = result[0]

빈 칸 위치

i = mask_token_indices[0]
i
5

빈 칸의 로짓

mask_token_logits = logits[0, i, :]

가장 로짓이 높은 토큰 10개

top = tf.math.top_k(mask_token_logits, k=10)

출력

for i in top.indices.numpy().tolist():
    print(id2word[i])
Ġfavorite
Ġcomfort
Ġfavourite
Ġsignature
Ġdream
Ġpreferred
Ġpassion
Ġstaple
Ġbreakfast
Ġeveryday

빈 칸이 2개인 경우

sequence = f"Pizza {tokenizer.mask_token} my {tokenizer.mask_token} food."
input_ids = tokenizer.encode(sequence, return_tensors="tf")
mask_token_indices = tf.where(input_ids[0] == tokenizer.mask_token_id)
mask_token_indices = tf.squeeze(mask_token_indices).numpy().tolist()
mask_token_indices
[3, 5]

각 빈 칸의 가장 로짓(=확률)이 높은 토큰들 출력

result = model(input_ids)
logits = result[0]
for i in mask_token_indices:
    print(f'=== {i} ===')
    mask_token_logits = logits[0, i, :]
    top = tf.math.top_k(mask_token_logits, k=10)
    for i in top.indices.numpy().tolist():
        print(id2word[i])
=== 3 ===
Ġis
Ġwas
Ġas
Ġbecomes
Ġequals
Ġfor
Ġdelivers
Ġmakes
Ġand
Ġwith
=== 5 ===
Ġfavorite
Ġcomfort
Ġfavourite
Ġjunk
Ġbreakfast
Ġlunch
Ġown
Ġsnack
Ġfried
Ġpreferred