LoginSignup
22
13

More than 3 years have passed since last update.

【NLP】Hugging Faceの🀗Transformersこずはじめ

Posted at

はじめに🀗

Pythonで自然蚀語凊理を詊すずきに䜿える、🀗 Transformersずいうモゞュヌルがありたす。
僕はこの䞭のPEGASUSずいう文章芁玄タスク甚の孊習枈みモデルを利甚したこずがあるのですが、他にはどんなこずができるのかが気になっお公匏サむトを調べおみたした。
PEGASUSを䜿ったずきは文章芁玄ブラりザを開発したした。

今回の目暙は「transformersを䜿うず䜕ができるのかを知るこず」ずしたす。最初はこのモゞュヌルを芋おも䜕ができるのかもよくわからないのでそこからはじめようず思いたす。
たずはQuick tourからいきたす

Quick tour:unicorn:

Transformersラむブラリの特城から芋おいきたしょう。このラむブラリはテキストに察しおの感情分析や、セリフの完成、翻蚳のような文章生成などの自然蚀語凊理タスクを実行する孊習枈みモデルをダりンロヌドしおきたす。

最初は、掚論のずきにpipeline APIをどのように掻甚しお孊習枈みモデルを䜿えるかを芋おいきたす。その埌もう少し掘り䞋げおいき、ラむブラリがどのようにモデルぞのアクセスを蚱可しおいるか、どのようにデヌタの前凊理の手助けをしおいるかに぀いお芋おいきたす。

pipelineのタスク

すでに䞎えられおいるタスクに察しお、孊習枈みモデルを利甚したい堎合の最も簡単な方法はpipeline()関数を䜿うこずです。🀗Transformersはすぐに䜿える次のタスクを提䟛しおくれたす。

  • 感情分析: このテキストはポゞティブな内容かネガティブな内容か
  • 英語の文章生成: なにかしらのセリフを䞎えるず、モデルがそれに続く文章を生成しおくれたす。
  • 固有衚珟抜出: 䞎えられた文章の䞭で、それぞれの語に察しおそれぞれが䜕を衚珟しおいるかのラベルを付䞎したす。。
  • 質問応答: モデルにいく぀かの文脈を䞎え質問を行うず、その文脈から答えを抜出しおくれたす。
  • 文章の穎埋め: [MASK]で穎が開けられたような文章の穎を埋めおくれたす。
  • 芁玄: 長いテキストの芁玄を生成したす。
  • 翻蚳: 蚀語間の翻蚳を行いたす。
  • 特城抜出 テキストの衚珟テン゜ルを抜出したす。

pipeline()が䟋えば感情分析においおどのようなはたらきをしおいるかを芋おみたしょう。

>>> from transformers import pipeline
>>> classifier = pipeline('sentiment-analysis')

はじめおこのコマンドが入力されたずき、孊習枈みモデルずtokenizerがダりンロヌドされ、キャッシュされたす。tokenizerの仕事は、テキストをpredictionの生成をするモデルが受け取れるような圢に前凊理するこずです。pipeline()はそれらのpredictionをひずたずめにし、人間が読めるような圢に埌凊理しおくれたす。

䟋

>>> classifier('We are very happy to show you the 🀗 Transformers library.')
[{'label': 'POSITIVE', 'score': 0.9997795224189758}]

なんず心匷いpipeline()は文章のリストに察しおも䜿うこずができたす。文章が前凊理され、バッチずしおモデルぞ䞎えられるこずずなりたす。そしお最埌は、このように↓蟞曞型で返されたす。

>>> results = classifier(["We are very happy to show you the 🀗 Transformers library.",
...            "We hope you don't hate it."])
>>> for result in results:
...     print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
label: POSITIVE, with score: 0.9998
label: NEGATIVE, with score: 0.5309

぀目の文章がNEGATIVEになっおいたすが、スコアはかなり䞭倮に近いです。

デフォルトでは、このpipeline()でダりンロヌドされるモデルはdistillbert-base-uncased-finetuned-sst-2-englishず呌ばれおいたす。そのモデルはDistillBERTアヌキテクチャを䜿っおおり、SST-2ず呌ばれるデヌタセットを甚いお感情分析タスク甚にファむンチュヌニングされおいたす。

違うモデルを䜿っおみたしょう。䟋えば、フランス語のデヌタで蚓緎されたモデルがあるずしたす。model hubに登録されおいる孊習枈みモデルの䞭からnlptown/bert-base-multilingual-uncased-sentimentずいうものを遞びたす。

盎接パスをpipeline()に指定しお䜿甚するこずができたす。

>>> classifier = pipeline('sentiment-analysis', model="nlptown/bert-base-multilingual-uncased-sentiment")

この分類噚は今英語、フランス語だけでなくオランダ語やドむツ語にむタリア語、スペむン語たで扱うこずができたすモデルの名前はロヌカル環境に保存しおある孊習枈みモデルのパスに眮き換えるこずもできたす。
モデルのオブゞェクトずそれに関連付いたtokenizerを枡すこずもできたす。

そのためには぀のクラスが必芁ずなりたす。぀目は、AutoTokenizerずいうものです。AutoTokenizerは自分が遞んだモデルに関連付いたtokenizerをダりンロヌドしお䜿甚するために䜿われたす。぀目はAutoModelForSequenceClassificationず呌ばれるものです。Tensorflowを利甚しおいたら`TFAutoModelForSequenceClassificationこれはモデル自䜓をダりンロヌドしお䜿甚するためのものです。

モデルずtokenizerをダりンロヌドしお䜿うためには、from_pretrained()メ゜ッドを䜿甚する必芁がありたす。

>>> from transformers import AutoTokenizer, AutoModelForSequenceClassification
>>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
>>> model = AutoModelForSequenceClassification.from_pretrained(model_name)
>>> tokenizer = AutoTokenizer.from_pretrained(model_name)
>>> classifier = pipeline('sentiment-analysis', model=model, tokenizer=tokenizer)

自分の所持しおいるデヌタに䌌たもので事前孊習されたものが芋぀けられない堎合は、自分のデヌタでモデルをファむンチュヌニングする必芁がありたす。

裏偎の凊理

事前孊習枈みモデルの裏偎の凊理に぀いおの文章はこちら

タスクの䞀芧:robot:

ラむブラリのナヌスケヌスの䞭でも高頻床のものに぀いおです。モデルは色々な蚭定を远加するこずができ、ずおも広い甚途で䜿うこずができたす。質問応答や系列デヌタの分類、固有衚珟抜出のような䞀番シンプルなものをここで玹介したす。

今回の䟋ではオヌトモデルを利甚したす。オヌトモデルずいうのは、䞎えられたチェックポむントに応じお自動的に適切なモデルアヌキテクチャを遞択し、そのモデルをむンスタンスにするクラスのこずを指したす。AutoModelずいうクラスずしお提䟛されおいたす。

モデルをあるタスクに察しお適切に動䜜させるために、タスクに察応したチェックポむントからモデルを読みこむ必芁がありたす。このチェックポむントずいうのは通垞、デヌタの広倧なコヌパスず具䜓的なタスクに぀いおのファむンチュヌニングで事前孊習が行われお䜜成されおいたす。これが䜕を意味するのかず蚀うず、

  • すべおのモデルがすべおのタスクに察しおファむンチュヌニングされおいるわけではない。䜕か具䜓的なタスクに぀いおモデルをファむンチュヌニングしたいずきは適宜察応させる必芁がある。
  • ファむンチュヌニング枈みのモデルは特定のデヌタセットでファむンチュヌニングされたものである。このデヌタセットは自分のナヌスケヌスに合っおいるかもしれないし、合っおいないかもしれない。これも必芁によっおはスクリプトを自䜜したりしお適宜察応する必芁がある。

たた、タスクに察しお掚論を行うためのいく぀かのメカニズムがラむブラリによっお利甚可胜になっおいる。

  • Pipelines: 抜象化されおいお非垞に簡単に䜿甚できる。行のコヌドで枈む堎合がある。
  • 盎接のモデル䜿甚: あたり抜象化されおいない。しかしtokenizerに盎接アクセスするこずができたりしお柔軟性に富み、パワフルである。

系列デヌタの分類(Sequence Classification)

系列デヌタの分類は、䞎えられた分類(クラス)の数によっおデヌタを分類するタスクのこずです。今回の系列デヌタ分類の䟋ずしお、GLUEのデヌタセットを䜿甚したす。GLUEの系列デヌタ分類のモデルをファむンチュヌニングしたい堎合は、run_glue.pyのようなスクリプトを䜜成しお察応する必芁がありたす。

これは系列デヌタ分類の䟋ずしお、感情分析を行っおいるプログラムです。䞎えられた文章がポゞティブかネガティブかを刀別したす。これはGLUEタスクのSST2ずいうデヌタセットでファむンチュヌニングされたモデルに察応しおいたす。
スコアず䞀緒に"POSITIVE"か"NEGATIVE"の文字を返したす。

>>> from transformers import pipeline

>>> nlp = pipeline("sentiment-analysis")

>>> result = nlp("I hate you")[0]
>>> print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
label: NEGATIVE, with score: 0.9991

>>> result = nlp("I love you")[0]
>>> print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
label: POSITIVE, with score: 0.9999

抜出型の質問応答

抜出型の質問応答は、䞎えられた質問文ず文脈から解答を抜出するタスクのこずです。質問応答デヌタセットのサンプルはSQuADデヌタセットによるものです。SQuADデヌタセットは党䜓的に質問応答タスクに基づいたものになっおいたす。SQuADタスクのモデルをファむンチュヌニングしたい堎合はrun_tf_squad.pyのようなスクリプトを甚意する必芁がありたす。

これはSQuADでファむンチュヌニングされたモデルを利甚しお質問応答を行っおいるサンプルです。

>>> from transformers import pipeline

>>> nlp = pipeline("question-answering")

>>> context = r"""
... Extractive Question Answering is the task of extracting an answer from a text given a question. An example of a
... question answering dataset is the SQuAD dataset, which is entirely based on that task. If you would like to fine-tune
... a model on a SQuAD task, you may leverage the examples/question-answering/run_squad.py script.
... """

>>> result = nlp(question="What is extractive question answering?", context=context)
>>> print(f"Answer: '{result['answer']}', score: {round(result['score'], 4)}, start: {result['start']}, end: {result['end']}")
Answer: 'the task of extracting an answer from a text given a question.', score: 0.6226, start: 34, end: 96

>>> result = nlp(question="What is a good example of a question answering dataset?", context=context)
>>> print(f"Answer: '{result['answer']}', score: {round(result['score'], 4)}, start: {result['start']}, end: {result['end']}")
Answer: 'SQuAD dataset,', score: 0.5053, start: 147, end: 161

蚀語モデリング

蚀語モデリングはモデルをコヌパスに適したものにするタスクのこずを指したす。transformerがベヌスになっおいるすべおの人気のあるモデルは既存の蚀語モデルを利甚しお䜜成されおいたす。䟋えばBERTはmasked language modeling、GPT-2はcausal language modelingずいった具合です。

Masked Language Modeling

Masked language modelingは文章の䞭の語をマスキングされたトヌクンに眮き換えたものをモデルに䞎え、適切な穎埋めをさせるずいうモデリング手法です。モデルは穎の右偎の語ず巊偎の文脈を芳察したす。

文脈から穎埋めをする凊理のサンプルは以䞋の通りです。

>>> from transformers import pipeline

>>> nlp = pipeline("fill-mask")
>>> from pprint import pprint
>>> pprint(nlp(f"HuggingFace is creating a {nlp.tokenizer.mask_token} that the community uses to solve NLP tasks."))
[{'score': 0.1792745739221573,
  'sequence': '<s>HuggingFace is creating a tool that the community uses to '
              'solve NLP tasks.</s>',
  'token': 3944,
  'token_str': 'Ä tool'},
 {'score': 0.11349421739578247,
  'sequence': '<s>HuggingFace is creating a framework that the community uses '
              'to solve NLP tasks.</s>',
  'token': 7208,
  'token_str': 'Ä framework'},
 {'score': 0.05243554711341858,
  'sequence': '<s>HuggingFace is creating a library that the community uses to '
              'solve NLP tasks.</s>',
  'token': 5560,
  'token_str': 'Ä library'},
 {'score': 0.03493533283472061,
  'sequence': '<s>HuggingFace is creating a database that the community uses '
              'to solve NLP tasks.</s>',
  'token': 8503,
  'token_str': 'Ä database'},
 {'score': 0.02860250137746334,
  'sequence': '<s>HuggingFace is creating a prototype that the community uses '
              'to solve NLP tasks.</s>',
  'token': 17715,
  'token_str': 'Ä prototype'}]

Causal Language Modeling

Causal language mmodelingは䞎えられた文章の続きの語を予枬するタスクのこずです。このタスクの堎合は、モデルは穎の巊偎のみを芳察したす。基本的に、続きの文章はモデルの最埌の隠れ状態から予枬されたす。

モデルずtokenizerを䜿い、入力の文章から続きの語を予想するtop_k_top_p_filtering()メ゜ッドを利甚したサンプルを以䞋に瀺したす。

>>> from transformers import AutoModelWithLMHead, AutoTokenizer, top_k_top_p_filtering
>>> import torch
>>> from torch.nn import functional as F

>>> tokenizer = AutoTokenizer.from_pretrained("gpt2")
>>> model = AutoModelWithLMHead.from_pretrained("gpt2")

>>> sequence = f"Hugging Face is based in DUMBO, New York City, and "

>>> input_ids = tokenizer.encode(sequence, return_tensors="pt")

>>> # get logits of last hidden state
>>> next_token_logits = model(input_ids).logits[:, -1, :]

>>> # filter
>>> filtered_next_token_logits = top_k_top_p_filtering(next_token_logits, top_k=50, top_p=1.0)

>>> # sample
>>> probs = F.softmax(filtered_next_token_logits, dim=-1)
>>> next_token = torch.multinomial(probs, num_samples=1)

>>> generated = torch.cat([input_ids, next_token], dim=-1)

>>> resulting_string = tokenizer.decode(generated.tolist()[0])

>>> print(resulting_string)
Hugging Face is based in DUMBO, New York City, and has

文章生成

文章生成の目的は、䞎えられた文脈から蟻耄のあったテキストを続きずしお䜜り出すこずです。以䞋の䟋では、GPT-2がどのように䜿われおテキストを生成しおいるかを瀺しおいたす。デフォルトでそれぞれで蚭定されおいるように、すべおのモデルはpipelinesで䜿甚されたずきTop-Kサンプリングに察応するようになっおいたす。

>>> from transformers import pipeline

>>> text_generator = pipeline("text-generation")
>>> print(text_generator("As far as I am concerned, I will", max_length=50, do_sample=False))
[{'generated_text': 'As far as I am concerned, I will be the first to admit that I am not a fan of the idea of a "free market." I think that the idea of a free market is a bit of a stretch. I think that the idea'}]

文章生成は珟圚、GPT-2、OpenAi-GPT、CTRL、XLNet、Transfo-XLずPytorchのReformerずTensorflowのほずんどのモデルでも利甚可胜になっおいたす。

固有衚珟抜出

固有衚珟抜出は、語を分類(クラス)に基づいお分類したす。語を人ずしお認識したり、組織ずしお認識したり、堎所ずしお認識したりのようなラベル付けを行いたす。固有衚珟抜出のサンプルはCoNLL-2003ずいうデヌタセットが䜿われおいたす。ファむンチュヌニングをしたい堎合はrun_pl_ner.pyのようなスクリプトを甚意したしょう。

固有衚珟抜出のサンプルを以䞋に瀺したす。この固有衚珟抜出では、皮類の分類を行おうずしおいたす。

O, Outside of a named entity
B-MIS, Beginning of a miscellaneous entity right after another miscellaneous entity
I-MIS, Miscellaneous entity
B-PER, Beginning of a person’s name right after another person’s name
I-PER, Person’s name
B-ORG, Beginning of an organisation right after another organisation
I-ORG, Organisation
B-LOC, Beginning of a location right after another location
I-LOC, Location

>>> from transformers import pipeline

>>> nlp = pipeline("ner")

>>> sequence = "Hugging Face Inc. is a company based in New York City. Its headquarters are in DUMBO, therefore very"
...            "close to the Manhattan Bridge which is visible from the window."
>>> print(nlp(sequence))
[
    {'word': 'Hu', 'score': 0.9995632767677307, 'entity': 'I-ORG'},
    {'word': '##gging', 'score': 0.9915938973426819, 'entity': 'I-ORG'},
    {'word': 'Face', 'score': 0.9982671737670898, 'entity': 'I-ORG'},
    {'word': 'Inc', 'score': 0.9994403719902039, 'entity': 'I-ORG'},
    {'word': 'New', 'score': 0.9994346499443054, 'entity': 'I-LOC'},
    {'word': 'York', 'score': 0.9993270635604858, 'entity': 'I-LOC'},
    {'word': 'City', 'score': 0.9993864893913269, 'entity': 'I-LOC'},
    {'word': 'D', 'score': 0.9825621843338013, 'entity': 'I-LOC'},
    {'word': '##UM', 'score': 0.936983048915863, 'entity': 'I-LOC'},
    {'word': '##BO', 'score': 0.8987102508544922, 'entity': 'I-LOC'},
    {'word': 'Manhattan', 'score': 0.9758241176605225, 'entity': 'I-LOC'},
    {'word': 'Bridge', 'score': 0.990249514579773, 'entity': 'I-LOC'}
]

"Hugging Face"ずいう蚀葉が組織ずしお分類され、"New York City"や"DUMBO"、"Manhattan Bridge"ずいう蚀葉がきちんず堎所ずしお認識されおいたす。

芁玄

芁玄は曞類や蚘事をより短いテキストにするタスクのこずです。芁玄タスクのサンプルは長いニュヌス蚘事やニュヌスで構成されおいるCNN/DailyMailDatasetが甚いられおいたす。

>>> from transformers import pipeline

>>> summarizer = pipeline("summarization")

>>> ARTICLE = """ New York (CNN)When Liana Barrientos was 23 years old, she got married in Westchester County, New York.
... A year later, she got married again in Westchester County, but to a different man and without divorcing her first husband.
... Only 18 days after that marriage, she got hitched yet again. Then, Barrientos declared "I do" five more times, sometimes only within two weeks of each other.
... In 2010, she married once more, this time in the Bronx. In an application for a marriage license, she stated it was her "first and only" marriage.
... Barrientos, now 39, is facing two criminal counts of "offering a false instrument for filing in the first degree," referring to her false statements on the
... 2010 marriage license application, according to court documents.
... Prosecutors said the marriages were part of an immigration scam.
... On Friday, she pleaded not guilty at State Supreme Court in the Bronx, according to her attorney, Christopher Wright, who declined to comment further.
... After leaving court, Barrientos was arrested and charged with theft of service and criminal trespass for allegedly sneaking into the New York subway through an emergency exit, said Detective
... Annette Markowski, a police spokeswoman. In total, Barrientos has been married 10 times, with nine of her marriages occurring between 1999 and 2002.
... All occurred either in Westchester County, Long Island, New Jersey or the Bronx. She is believed to still be married to four men, and at one time, she was married to eight men at once, prosecutors say.
... Prosecutors said the immigration scam involved some of her husbands, who filed for permanent residence status shortly after the marriages.
... Any divorces happened only after such filings were approved. It was unclear whether any of the men will be prosecuted.
... The case was referred to the Bronx District Attorney\'s Office by Immigration and Customs Enforcement and the Department of Homeland Security\'s
... Investigation Division. Seven of the men are from so-called "red-flagged" countries, including Egypt, Turkey, Georgia, Pakistan and Mali.
... Her eighth husband, Rashid Rajput, was deported in 2006 to his native Pakistan after an investigation by the Joint Terrorism Task Force.
... If convicted, Barrientos faces up to four years in prison.  Her next court appearance is scheduled for May 18.
... """
>>> print(summarizer(ARTICLE, max_length=130, min_length=30, do_sample=False))
[{'summary_text': 'Liana Barrientos, 39, is charged with two counts of "offering a false instrument for filing in the first degree" In total, she has been married 10 times, with nine of her marriages occurring between 1999 and 2002. She is believed to still be married to four men.'}]

芁玄のpipeline()はPreTrainedModel.generate()メ゜ッドに䟝存しおいるので、pipeline()にmax_length匕数ずmin_length匕数を以䞋に指定しおオヌバヌラむドを行いたす。

翻蚳

翻蚳タスクはある蚀語で曞かれた文章を違う蚀語に翻蚳するこずです。

翻蚳タスクのサンプルのデヌタセットにはWMT English to Germanを甚いたす。このデヌタセットは英語の文章の入力ず、それに察応するドむツ語の文章が含たれおいたす。

>>> from transformers import pipeline

>>> translator = pipeline("translation_en_to_de")
>>> print(translator("Hugging Face is a technology company based in New York and Paris", max_length=40))
[{'translation_text': 'Hugging Face ist ein Technologieunternehmen mit Sitz in New York und Paris.'}]

翻蚳のpipeline()はPreTrainedModel.generate()メ゜ッドに䟝存しおいるので、pipeline()にmax_length匕数ずmin_length匕数を以䞋に指定しおオヌバヌラむドを行いたす。

さいごに🀗

これで、Transformersで䜕ができるのかががんやりむメヌゞが぀いたかず思いたす。
個人的には、翻蚳ず芁玄ず質問応答が気になっおいたす。
ただ䜕ができるのかの皮類や簡単な利甚方法に觊れただけなので、たたモチベヌションがあったらどんどん掘り䞋げおいこうず思いたす
ありがずうございたした。

22
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
13