ナタヌシャプロゞェクト。自然なロシア語凊理NLPのための高品質のオヌプン゜ヌスツヌルのセット

2幎前、私はHabrに、YargyパヌサヌずNatashaラむブラリに぀いおの蚘事を曞き、ルヌルに基づいおロシア語のNER問題を解決するこずに぀いお話したした。プロゞェクトは奜評でした。 Yargyパヌサヌは眮き換えられたYandexの富田パヌサヌをズベルバンク、むンタファクスやRIA通信瀟の内郚倧芏暡なプロゞェクトで。ナタヌシャラむブラリは珟圚、HSE、MIPT、モスクワ州立倧孊の教育プログラムに統合されおいたす。



プロゞェクトは成長し、ラむブラリは珟圚、ロシアの自然蚀語を凊理するすべおの基本的なタスクを解決しおいたす。トヌクンず文ぞのセグメンテヌション、圢態孊的および構文的分析、レンマ化、名前付き゚ンティティの抜出です。



ニュヌス蚘事の堎合、すべおのタスクの品質は既存の゜リュヌションず同等たたはそれ以䞊です。..。たずえば、NatashaはDeeppavlov BERT NERF1 PER 0.97、LOC 0.91、ORG 0.85よりも1パヌセントポむント悪いNERタスクに察凊し、モデルの重量は75分の127MBで、CPU䞊で2倍高速25蚘事/秒で実行されたす。 GPUのBERTNERより。



プロゞェクトには9぀のリポゞトリがあり、Natashaラむブラリはそれらを1぀のむンタヌフェむスに結合したす。この蚘事では、新しいツヌルに぀いお説明し、それらを既存の゜リュヌションDeeppavlov、SpaCy、UDPipeず比范したす。





このロングリヌドの前に、natasha.github.ioに䞀連の投皿がありたした。





テキストはt.me/natural_language_processingチャットからのメモずディスカッションを䜿甚し、新しい資料ぞのリンクは同じ堎所に衚瀺されたす。





以䞋のテキストのサむズに䞍安がある堎合は、ナタヌシャプロゞェクトの歎史に぀いおのチュヌブストリヌムの最初の20分間をご芧ください。短い説明がありたす





もっず聞きたい人は、Datafest 2020での毎時のトヌクをチェックしおください、それはほずんどこの投皿をカバヌしおいたす



コンテンツ







Natasha — .







以前、Natashaラむブラリはロシア語のNER問題を解決し、ルヌルに基づいお構築され、平均的な品質ずパフォヌマンスを瀺したした。珟圚、ナタヌシャは党䜓ずしお倧きなプロゞェクトであり、9぀のリポゞトリで構成されおいたす。Natashaラむブラリは、それらを1぀のむンタヌフェむスに統合し、自然なロシア語を凊理する基本的なタスクを解決したす。トヌクンず文ぞのセグメンテヌション、事前にトレヌニングされた埋め蟌み、圢態ず構文の分析、レンマ化、NERです。すべおの゜リュヌションはニュヌストピックで最高の結果を瀺し、CPUで高速に実行されたす。



ナタヌシャは他のコンバむンラむブラリに䌌おいたすSpaCy、UDPipe、Stanza..。SpaCyはモデルを初期化しお暗黙的に呌び出し、ナヌザヌはテキストをマゞック関数nlpに枡し、完党に解析されたドキュメントを取埗したす。



import spacy

#  load    ,
#     ,   NER
nlp = spacy.load('...')

#    ,   
text = '...'
doc = nlp(text)


ナタヌシャのむンタヌフェヌスはより冗長です。ナヌザヌはコンポヌネントを明瀺的に初期化したす。事前にトレヌニングされた埋め蟌みをロヌドし、モデルコンストラクタヌに枡したす。サムは、メ゜ッドを呌び出しsegment、tag_morph、parse_syntax圢態や構文の解析、トヌクンず需芁ぞのセグメンテヌション。



>>> from natasha import (
    Segmenter,
    
    NewsEmbedding,
    NewsMorphTagger,
    NewsSyntaxParser,
    
    Doc
)

>>> segmenter = Segmenter()

>>> emb = NewsEmbedding()
>>> morph_tagger = NewsMorphTagger(emb)
>>> syntax_parser = NewsSyntaxParser(emb)

>>> text = '      ,    ,        2019          ()  ...'
>>> doc = Doc(text)

>>> doc.segment(segmenter)
>>> doc.tag_morph(morph_tagger)
>>> doc.parse_syntax(syntax_parser)

>>> sent = doc.sents[0]
>>> sent.morph.print()
                NOUN|Animacy=Anim|Case=Nom|Gender=Masc|Number=Sing
              PROPN|Animacy=Inan|Case=Gen|Gender=Masc|Number=Sing
                   ADP
              PROPN|Animacy=Inan|Case=Loc|Gender=Fem|Number=Sing
                PROPN|Animacy=Anim|Case=Nom|Gender=Masc|Number=Sing
                 PROPN|Animacy=Anim|Case=Nom|Gender=Masc|Number=Sing
...

>>> sent.syntax.print()
        ┌──►          nsubj
        │           
        │ ┌►             case
        │ └─        
        │ ┌─          
        │ └►           flat:name
┌─────┌─└───      
│     │ ┌──► ,             punct
│     │ │ ┌►            mark
│     └►└─└─         ccomp
│     │   ┌►              case
│     └──►└─            obl
...


名前付き゚ンティティ゚クストラクタは、圢態孊的および解析の結果に䟝存せず、個別に䜿甚できたす。



>>> from natasha import NewsNERTagger

>>> ner_tagger = NewsNERTagger(emb)
>>> doc.tag_ner(ner_tagger)
>>> doc.ner.print()
      ,    , 
      LOC────    LOC──── PER───────                                   
       2019    
                   LOC──────────────                                
      () 
              LOC─── ORG─────────────────────────────────────── 
 ...
PER──────────── 


ナタヌシャは、芋出し語凊理の問題を解決䜿甚しPymorphy2ず圢態玠解析の結果を。



>>> from natasha import MorphVocab

>>> morph_vocab = MorphVocab()

>>> for token in doc.tokens:
>>>     token.lemmatize(morph_vocab)

>>> {_.text: _.lemma for _ in doc.tokens}
{'': '',
 '': '',
 '': '',
 '': '',
 '': '',
 '': '',
 '': '',
 ',': ',',
 '': '',
 '': ''
...


フレヌズを通垞の圢にするためには、個々の単語の補題を芋぀けるだけでは十分ではありたせん。ロシア倖務省にずっおは、ロシア倖務省、りクラむナ囜民䞻矩者組織、぀たりりクラむナ囜民䞻矩組織であるこずが刀明したす。ナタヌシャは、解析の結果を䜿甚し、単語間の関係を考慮し、名前付き゚ンティティを正芏化したす。



>>> for span in doc.spans:
>>>    span.normalize(morph_vocab)

>>> {_.text: _.normal for _ in doc.spans}
{'': '',
 '': '',
 ' ': ' ',
 ' ': ' ',
 '': '',
 '   ()': '   ()',
 ' ': ' ',
...


ナタヌシャは、テキスト内の名前、組織、堎所の名前を芋぀けたす。ラむブラリ内の名前に぀いおは、Yargyパヌサヌの既成のルヌルのセットがあり、モゞュヌルは正芏化された名前を郚分に分割し、「ViktorFedorovichYushchenko」から取埗し{first: , last: , middle: }たす。



>>> from natasha import (
    PER,
    NamesExtractor,
)

>>> names_extractor = NamesExtractor(morph_vocab)

>>> for span in doc.spans:
>>>    if span.type == PER:
>>>        span.extract_fact(names_extractor)

>>> {_.normal: _.fact.as_dict for _ in doc.spans if _.type == PER}
{' ': {'first': '', 'last': ''},
 ' ': {'first': '', 'last': ''},
 ' ': {'first': '', 'last': ''},
 '': {'last': ''},
 ' ': {'first': '', 'last': ''}}


ラむブラリには、日付、金額、䜏所を解析するためのルヌルが含たれおいたす。これらは、ドキュメントずリファレンスブックに蚘茉されおいたす。



ナタヌシャラむブラリは、教育で䜿甚されるプロゞェクトテクノロゞヌのデモンストレヌションに最適です。モデルの重みを持぀アヌカむブはパッケヌゞに組み蟌たれおいたす。むンストヌル埌、䜕もダりンロヌドしお構成する必芁はありたせん。



Natashaは、他のプロゞェクトラむブラリを1぀のむンタヌフェむスに統合したす。実際の問題を解決するには、それらを盎接䜿甚する必芁がありたす。



  • Razdel-テキストを文ずトヌクンに分割したす。

  • Navec-高品質のコンパクトな埋め蟌み。

  • Slovnet-圢態、構文、NERの最新のコンパクトモデル。

  • Yargy-構造化された情報を抜出するためのルヌルず語圙。

  • Ipymarkup -NERず構文マヌクアップの芖芚化。

  • コヌラス-ロシア語の公開デヌタセットぞのリンクのコレクション。

  • Nerusは、名前付き゚ンティティ、圢態、および構文の自動マヌクアップを備えた倧きなコヌパスです。





Razdel-ロシア語のテキストをトヌクンずオファヌに分割







RazdelラむブラリはNatashaプロゞェクトの䞀郚であり、ロシア語のテキストをトヌクンず文に分割したす。Razdelリポゞトリでのむンストヌル手順、䜿甚䟋、およびパフォヌマンス枬定。



>>> from razdel import tokenize, sentenize

>>> text = '-  0.5 (50/64 ³, 516;...)'
>>> list(tokenize(text))
[Substring(start=0, stop=13, text='-'),
 Substring(start=14, stop=16, text=''),
 Substring(start=17, stop=20, text='0.5'),
 Substring(start=20, stop=21, text=''),
 Substring(start=22, stop=23, text='(')
 ...]

>>> text = '''
... - "    ?" - " --".
...  . .  . .  ,  
... '''
>>> list(sentenize(text))
[Substring(start=1, stop=23, text='- "    ?"'),
 Substring(start=24, stop=40, text='- " --".'),
 Substring(start=41, stop=56, text=' . .  . .'),
 Substring(start=57, stop=76, text=' ,  ')]


最近のモデルは、セグメンテヌションを気にせず、BPEを䜿甚し、驚くべき結果を瀺し、GPTずBERT動物園のすべおのバヌゞョンを芚えおいるこずがよくありたす。ナタヌシャは、圢態ず構文の解析の問題を解決したす。これらは、1぀の文内の別々の単語に察しおのみ意味がありたす。したがっお、私たちは責任を持っおセグメンテヌションの段階に近づき、人気のあるオヌプンデヌタセットSynTagRus、OpenCorpora、GICRYAからマヌクアップを繰り返そうずしたす。



Razdelの速床ず品質は、ロシア語の他のオヌプン゜ヌス゜リュヌションず同等かそれ以䞊です。

トヌクンセグメンテヌション゜リュヌション 1000トヌクンあたりの゚ラヌ 凊理時間、秒
Regexp-ベヌスラむン 19 0.5
SpaCy

17 5.4
NLTK

130 3.1
MyStem

19 4.5
モヌセ

十䞀 1.9
SegTok

12 2.1
SpaCy Russian Tokenizer

8 46.4
RuTokenizer

15 1.0
Razdel

7 2.6


1000 ,
Regexp-baseline 76 0.7
SegTok

381 10.8
Moses

166 7.0
NLTK

57 7.1
DeepPavlov

41 8.5
Razdel 43 4.8


SynTagRus、OpenCorpora、GICRYA、RNCの4぀のデヌタセットの平均゚ラヌ数。詳现に぀いおは、Razdelリポゞトリをご芧ください。



通垞の線のベヌスラむンが同様の品質を提䟛し、ロシア語甚の既補の゜リュヌションがたくさんあるのに、なぜRazdelが必芁なのですか実際、Razdelは単なるトヌクナむザヌではなく、小さなルヌルベヌスのセグメンテヌション゚ンゞンです。セグメンテヌションは基本的なタスクであり、実際によく発生したす。たずえば、叞法行為があり、その䞭の運甚郚分を匷調衚瀺し、それを段萜に分割する必芁がありたす。圓然のこずながら、既補の゜リュヌションではそれができたせん。゜ヌスコヌドで独自のルヌルを䜜成する方法をお読みください。さらに、自分自身をプッシュし、゚ンゞンでトヌクンずオファヌのトップ゜リュヌションを䜜成する方法に぀いお説明したす。



難しさは䜕ですか



ロシア語では、文は通垞、ピリオド、疑問笊、たたは感嘆笊で終わりたす。テキストを通垞の匏で分割しおみたしょう[.?!]\s+。この゜リュヌションでは、1000文あたり76゚ラヌが発生したす。間違いの皮類ず䟋



略語

... 3,000人以䞊の芖聎者がいるプラットフォヌムはブロガヌです。

... 17䞖玀の終わりからビヌトが圌らの䞊に立っおいたした。


▒B.A。にちなんで名付けられたChamberMusicalTheaterでポクロフスキヌ。



むニシャル

V.A.▒Mozart-R.▒Straussによるオペラ「Idomeneo」に続く...



リスト

2.フィンランド領事通には矎しい長い列があるず思いたした...

g 。ロシアの鉄道の列車のチケット...



文の終わりに、笑顔たたは掻字の省略蚘号

マむナスを取り陀く方法を提䟛する人は誰でも-そのおかげで▒私は芋た、思慮深い...▒コンテンツが壊れおしたうので、これはもっず䞍快です。



匕甚、盎接スピヌチ、文末に匕甚マヌク

-あなたは町に花嫁がいたすか」▒「誰のために花嫁がいたすか」

「それは私がそのようではないほど良いです」▒今、翻蚳䞭に、私はフロむトの間違いを犯したした「idology」。



Razdelはこれらのニュアンスを考慮に入れ、゚ラヌの数を1000文あたり76から43に枛らしたす。



状況はトヌクンでも同様です。優れた基本的な解決策はregexで[--]+|[0-9]+|[^-0-9 ]、1000トヌクンあたり19゚ラヌになりたす。䟋



分数、耇雑な句読点

... 1980幎代埌半から1990幎代初頭

...BS-▒3の質量はわずかに少ない3▒、▒6t

-そしお圌女は▒.▒死んだ。鷹、女の子が分かりたすか▒



Razdelは、゚ラヌ率を1000トヌクンあたり7に枛らしおいたす。



動䜜原理



システムはルヌルに基づいお構築されおいたす。トヌクンずオファヌぞのセグメンテヌションの原則は同じです。



候補者のコレクション



本文には、ピリオド、楕円、括匧、匕甚笊など、文末のすべおの候補が含たれおいたす。



6.▒「私はうれしい」ずいう回答の最も頻繁で同時に高い評䟡のオプション▒13のステヌトメント、25ポむント▒–承認ず励たしを受ける状況▒7.▒「私は知っおいる」ずいう回答では、最も兞型的なものずしお掚定されおいるこずは泚目に倀したす、しかし、「私は女性です」ずいう答えに出くわしたずきだけ▒;「この人生で私を埅っおいるのは1぀の結婚だけです」▒ず「遅かれ早かれ私は出産しなければなりたせん」▒.▒コンパむラV.▒P.▒ゎロビン、F.▒V.▒Zanichev、A.▒L.▒Rastorguev、R.▒V.▒Savko、I.▒I.▒Tuchkov。



トヌクンの堎合、テキストをアトムに分割したす。トヌクンの境界線は、アトム内を正確に通過したせん。



1980幎の終わりに▒-▒▒-beginning1990▒-

▒▒BS▒-▒3▒わずかに▒

小さい質量▒▒3▒、▒6▒▒▒▒—をマヌクするこずが可胜です。 Da▒and▒umerla▒.▒.▒.▒Got▒ligirl、▒thefalcon▒▒



連合



私たちは䞀貫しお分離の候補をバむパスし、䞍芁なものを削陀したす。ヒュヌリスティックのリストを䜿甚したす。



リストアむテム。区切り文字はピリオドたたは括匧で、巊偎は数字たたは文字

6です。▒最も頻繁であるず同時に高く評䟡されおいる回答「うれしい」13ステヌトメント、25ポむントは、承認ず励たしを受けおいる状況です。 7.▒「私は知っおいる」ずいう答えの䞭で...



むニシャルであるこずは泚目に倀したす。セパレヌタ-ドット、巊偎に1぀の倧文字

...V.▒P.▒Golovin、F.▒V.▒Zanichev、A.▒L.▒Rastorguev、R.▒V.▒Savko、I.▒I.▒Tuchkovによっお線集されたした。 ..。



セパレヌタヌの右偎にスペヌスはありたせん

...しかし、「私は女性です」ずいう答えは䞀床だけです▒; 「この人生で私を埅っおいるのは1぀の結婚だけです」ず「遅かれ早かれ私は出産しなければならない」ずいう声明がありたす▒。



終了匕甚笊たたは括匧の前に文末蚘号はありたせん。これは匕甚笊たたは盎接のスピヌチではありたせん。6

。最も頻繁で高く評䟡されおいる回答は、「うれしい」です«13ステヌトメント、25ポむント▒-承認ず励たしを埗る状況。 ...「この人生で私を埅っおいるのは1぀の結婚だけです」そしお「遅かれ早かれ私は出産しなければなりたせん」。



その結果、2぀の区切り文字が残っおいるので、それらを文の終わりず芋なしたす。



6.「私はうれしい」13のステヌトメント、25のポむントずいう回答の最も頻繁で同時に高く評䟡されおいる倉圢は、承認ず励たしを受けおいる状況です。▒7。 「私は知っおいる」ずいう答えで最も兞型的なものずしお評䟡されおいるこずは泚目に倀したすが、「私は女性です」ずいう答えに出䌚ったのは䞀床だけです。 「この人生で私を埅っおいるのは1぀の結婚だけです」、「遅かれ早かれ私は出産しなければならない」ずいう声明がありたす。V.P。Golovin、F.V。Zanichev、A.L。Rastorguev、R.V。 Savko、I。I。Tuchkov



手順はトヌクンの堎合ず䌌おいたすが、ルヌルが異なりたす。



分数たたは合理的な数

...3▒、▒6t...



耇雑な句読点

-はい、死亡したした。▒.▒。鷹、女の子が分かりたすか▒



ハむフンの呚りにスペヌスはありたせん。これは盎接のスピヌチの始たりではありたせん。

1980幎の終わりに▒-▒-1990幎の初め

▒-▒BS▒-▒3に泚意しおください...



残っおいるものはすべおトヌクンの境界ず芋なされたす。



1980幎代の終わりに-x▒-始たり-1990-x▒BS

-3▒それは▒▒通知▒わずかに䜎い質量▒▒3.6▒t▒▒▒—

はい、そしお死んだ。 ..▒了解▒li▒girl、▒sokol▒



制限事項



Razdelルヌルは、正しい句読点できれいに曞かれたテキスト甚に最適化されおいたす。この゜リュヌションは、ニュヌス蚘事、文孊テキストでうたく機胜したす。゜ヌシャルネットワヌクからの投皿、電話での䌚話の蚘録では、品質が䜎くなりたす。文の間にスペヌスがないか、末尟にピリオドがない堎合、たたは文が小文字で始たる堎合、Razdelは間違いを犯したす。゜ヌスコヌドで



タスクのルヌルを䜜成する方法を読んでください。このトピックはただドキュメントで開瀺されおいたせん。



Slovnet-自然なロシア語凊理のための深局孊習モデリング







このプロゞェクトでは、ナタヌシャスロブネットは、ロシア語を話すNLPの最新モデルの教育ず掚論に取り組んでいたす。ラむブラリには、名前付き゚ンティティを抜出し、圢態ず構文を解析するための高品質のコンパクトモデルが含たれおいたす。すべおのタスクの品質は、ニュヌステキストのロシア語の他のオヌプン゜リュヌションず同等たたはそれ以䞊です。むンストヌルの手順、䜿甚䟋-äž­Slovnetリポゞトリ。 NER問題の解決策がどのように配眮されおいるかを詳しく芋おみたしょう。圢態ず構文に぀いおは、すべおが類掚によるものです。



2018幎の終わりに、BERTに関するGoogleからの蚘事の埌、英語のNLPで倚くの進歩がありたした。 2019幎、DeepPavlovプロゞェクトのメンバヌロシア語に適応した倚蚀語BERT、RuBERTが登堎したした。CRFヘッドが䞊郚でトレヌニングされ、DeepPavlov BERTNER-ロシア語のSOTAであるこずが刀明したした。モデルの品質は優れおおり、最も近い远跡者であるDeepPavlov NERの2分の1の゚ラヌですが、サむズずパフォヌマンスは恐ろしいものです。6GB-GPURAMの消費、2GB-モデルのサむズ、毎秒13蚘事-優れたGPUでのパフォヌマンス。



2020幎、Natashaプロゞェクトでは、DeepPavlov BERT NERに品質を近づけるこずができたした。モデルのサむズは、75分の127MB、メモリ消費量は30分の1205MB、CPUの速床は2分の125蚘事/秒でした。 。

ナタヌシャ、スロブネットNER DeepPavlov BERT NER
トヌクンごずのPER / LOC / ORG F1、Collection5ごずの平均、factRuEval-2016、BSNLP-2019、Gareev 0.97 / 0.91 / 0.85 0.98 / 0.92 / 0.86
モデルサむズ 27MB 2GB
メモリ消費 205MB 6GBGPU
パフォヌマンス、1秒あたりのニュヌス蚘事1蚘事≈1KB CPUあたり25Core i5 13 GPURTX 2080 Ti、1 CPU
初期化時間、秒 1 35
ラむブラリはサポヌトしたす Python 3.5以降、PyPy3 Python 3.6+
䟝存関係 NumPy TensorFlow


Slovnet NERの品質は、SOTA DeepPavlov BERT NERの品質よりも1パヌセントポむント䜎く、モデルのサむズは75分の1で、メモリ消費量は30分の1で、CPUの速床は2分の1です。Slovnetリポゞトリ内のロシア語を話すNER甚のSpaCy、PullEntiおよびその他の゜リュヌションずの比范。



この結果をどのように取埗したすか短いレシピ

Slovnet NER = Slovnet BERT NER - DeepPavlov BERT NERのアナログ+ WordCNN-CRFでの合成マヌクアップNerusによる蒞留ず量子化された埋め蟌みNavec+ NumPyでの掚論甚゚ンゞン。



今順番に。蚈画は次のずおりです。手動で泚釈を付けた小さなデヌタセットで、BERTアヌキテクチャを䜿甚しお重いモデルをトレヌニングしたす。ニュヌスコヌパスでマヌクを付けるず、倧きくお汚い合成トレヌニングデヌタセットが埗られたす。その䞊でコンパクトなプリミティブモデルをトレヌニングしたしょう。このプロセスは蒞留ず呌ばれたす。重いモデルは教垫であり、コンパクトなモデルは孊生です。BERTアヌキテクチャはNERの問題に察しお冗長であり、コンパクトモデルは重いモデルに比べお品質がそれほど䜎䞋しないず考えおいたす。



モデル教垫



DeepPavlov BERT NERは、RuBERT゚ンコヌダヌずCRFヘッドで構成されおいたす。私たちの重い教垫モデルは、マむナヌな改善を加えおこのアヌキテクチャを繰り返したす。



すべおのベンチマヌクは、ニュヌステキストのNER品質を枬定したす。ニュヌスでRuBERTを蚓緎したしょう。Corusリポゞトリには、ロシア語の公開ニュヌスコヌパスぞのリンク、合蚈12GBのテキストが含たれおいたす。RoBERTaに関するFacebookの蚘事の手法を䜿甚したす倧芏暡な集玄バッチ、動的マスク、次の文NSPの予枬の拒吊。 RuBERTは、120,000個のサブトヌクンの巚倧な蟞曞を䜿甚したす。これはGoogleの倚蚀語BERTの遺産です。最も頻床の高いニュヌスアむテムのサむズを50,000に枛らすず、カバレッゞは5枛少したす。NewsRuBERTを入手する、モデルは、ニュヌスの停装サブトヌクンをRuBERTよりも5パヌセントポむント良く予枬したすトップ1の63。Collection5の



1000件の蚘事甚にNewsRuBERT゚ンコヌダヌずCRFヘッドをトレヌニングしたしょう。Slovnet BERT NERを入手し、品質はDeepPavlov BERT NERより0.5パヌセントポむント優れおおり、モデルサむズは4分の1473MB、3倍高速毎秒40蚘事です。

NewsRuBERT = RuBERT + 12GBのニュヌス+ RoBERTaのテクノロゞヌ+ 50K-蟞曞。

Slovnet BERT NERDeepPavlov BERT NERのアナログ= NewsRuBERT + CRFヘッド+コレクション5。



珟圚、BERTのようなアヌキテクチャでモデルをトレヌニングするには、HuggingFaceのTransformersを䜿甚するのが通䟋です。トランスフォヌマヌは100,000行のPythonコヌドです。掚論で損倱やゎミが爆発した堎合、䜕が悪かったのかを理解するのは困難です。さお、そこにはたくさんのコヌドが耇補されおいたす。RoBERTaをトレヌニングしたずしおも、問題を玄3000行のコヌドにすばやくロヌカラむズできたすが、これも倚くのこずです。最新のPyTorchでは、Transformersラむブラリはそれほど関連性がありたせん。torch.nn.TransformerEncoderLayerロベルタのようなモデルコヌド100行を取りたす。



class BERTEmbedding(nn.Module):
    def __init__(self, vocab_size, seq_len, emb_dim, dropout=0.1, norm_eps=1e-12):
        super(BERTEmbedding, self).__init__()
        self.word = nn.Embedding(vocab_size, emb_dim)
        self.position = nn.Embedding(seq_len, emb_dim)
        self.norm = nn.LayerNorm(emb_dim, eps=norm_eps)
        self.drop = nn.Dropout(dropout)

    def forward(self, input):
        batch_size, seq_len = input.shape
        position = torch.arange(seq_len).expand_as(input).to(input.device)

        emb = self.word(input) + self.position(position)
        emb = self.norm(emb)
        return self.drop(emb)
      

def BERTLayer(emb_dim, heads_num, hidden_dim, dropout=0.1, norm_eps=1e-12):
    layer = nn.TransformerEncoderLayer(
        d_model=emb_dim,
        nhead=heads_num,
        dim_feedforward=hidden_dim,
        dropout=dropout,
        activation='gelu'
    )
    layer.norm1.eps = norm_eps
    layer.norm2.eps = norm_eps
    return layer


class BERTEncoder(nn.Module):
    def __init__(self, layers_num, emb_dim, heads_num, hidden_dim,
                 dropout=0.1, norm_eps=1e-12):
        super(BERTEncoder, self).__init__()
        self.layers = nn.ModuleList([
            BERTLayer(
                emb_dim, heads_num, hidden_dim,
                dropout, norm_eps
            )
            for _ in range(layers_num)
        ])

    def forward(self, input, pad_mask=None):
        input = input.transpose(0, 1)  # torch expects seq x batch x emb
        for layer in self.layers:
            input = layer(input, src_key_padding_mask=pad_mask)
        return input.transpose(0, 1)  # restore
          
          
class BERTMLMHead(nn.Module):
    def __init__(self, emb_dim, vocab_size, norm_eps=1e-12):
        super(BERTMLMHead, self).__init__()
        self.linear1 = nn.Linear(emb_dim, emb_dim)
        self.norm = nn.LayerNorm(emb_dim, eps=norm_eps)
        self.linear2 = nn.Linear(emb_dim, vocab_size)

    def forward(self, input):
        x = self.linear1(input)
        x = F.gelu(x)
        x = self.norm(x)
        return self.linear2(x)


class BERTMLM(nn.Module):
    def __init__(self, emb, encoder, head):
        super(BERTMLM, self).__init__()
        self.emb = emb
        self.encoder = encoder
        self.head = head

    def forward(self, input):
        x = self.emb(input)
        x = self.encoder(x)
        return self.head(x)


これはプロトタむプではなく、コヌドはSlovnetリポゞトリからコピヌされたす。トランスフォヌマヌは読みやすく、倚くの䜜業を行い、Arxivを䜿甚しお蚘事のコヌドを詰め蟌みたす。倚くの堎合、Python゜ヌスは科孊蚘事の説明よりも明確です。



合成デヌタセット



Lenta.ruコヌパス からの700,000件の蚘事に重いモデルでマヌクを付けたしょう。巚倧な合成トレヌニングデヌタセットを取埗したす。アヌカむブは、NatashaプロゞェクトのNerusリポゞトリで入手できたす。マヌクアップは非垞に高品質で、F1はトヌクンで掚定したすPER-99.7、LOC-98.6、ORG-97.2。゚ラヌのたれな䟋



     
       ORG────────────── LOC────────────────────────────
    241-   4-  10-
    <  
                               LOC───            LOC──────
 >.
───────────~~~~~~~~~~~

     
ORG────────────────────~~~~~~~~~~~~~~~~
 .
LOC───

  <>    
                    ~~~~~~~~    LOC──────────────────
     .

         
       ~~~~   ~~~~~~                    LOC───
.
LOC────

     -  
  PER─────────────────────
  M&A.
                  ~~~

       : 
           ~~~~~~~~~~~~ORG───   LOC──
   ,   
PER───────                  LOC───
  ,      
           ORG─  LOC─────────────
  .
            LOC


モデル孊習者



ヘビヌティヌチャヌモデルのアヌキテクチャの遞択に問題はありたせんでした。唯䞀のオプションはトランスフォヌマヌでした。コンパクトな孊生モデルはより難しく、倚くのオプションがありたす。 2013幎から2018幎にかけお、word2vecの登堎からBERTに関する蚘事たで、人類はNER問題を解決するための䞀連のニュヌラルネットワヌクアヌキテクチャを考案したした。すべおに共通のスキヌムがあり





たす。NERタスクのニュヌラルネットワヌクアヌキテクチャのスキヌムトヌクン゚ンコヌダヌ、コンテキスト゚ンコヌダヌ、タグデコヌダヌ。ダン2018によるレビュヌ蚘事の略語の説明。



アヌキテクチャには倚くの組み合わせがありたす。どちらを遞択したすかたずえば、CharCNN + Embedding-WordBiLSTM-CRFは、2019幎たでのロシア語のSOTAであるDeepPavlovNERに関する蚘事のモデル図です。



CharCNN、CharRNNのオプションをスキップしたす。各トヌクンのシンボルによっお小さなニュヌラルネットワヌクを起動するのは、私たちのやり方ではなく、遅すぎたす。たた、WordRNNを避けたいのですが、゜リュヌションはCPUで機胜し、各トヌクンのマトリックスをゆっくりず乗算する必芁がありたす。NERの堎合、線圢ずCRFのどちらを遞択するかは条件付きです。BIO゚ンコヌディングを䜿甚したす。タグの順序は重芁です。私たちはひどいブレヌキに耐えなければなりたせん、CRFを䜿甚しおください。1぀のオプションが残っおいたす-埋め蟌み-WordCNN-CRF。このモデルは倧文字ず小文字を区別したせん。NERにずっお重芁なのは、「垌望」は単なる単語であり、「垌望」はおそらく名前です。ShapeEmbeddingを远加したす-トヌクンのアりトラむンを埋め蟌みたす。䟋 "NER" -EN_XX、 "Vainovich" -RU_Xx、 "" --PUNCT_ 、 "および" --RU_x、 "5.1" -NUM、 "ニュヌペヌク" --RU_Xx-Xx。Slovnet NERスキヌム-WordEmbedding + ShapeEmbedding-WordCNN-CRF。



è’žç•™



巚倧な合成デヌタセットでSlovnetNERをトレヌニングしたしょう。結果を重いモデル教垫のSlovnetBERTNERず比范しおみたしょう。品質は、手動でマヌクされたCollection5、Gareev、factRuEval-2016、BSNLP-2019で蚈算され、平均化されたす。トレヌニングサンプルのサむズは非垞に重芁です。250のニュヌス蚘事サむズfactRuEval-2016の堎合、PER、LOC、LOG F1の平均は0.64、1000コレクション5のアナログの平均は0.81、デヌタセット党䜓の堎合は0.91、Slovnet BERTNERの品質は0.92です。





Slovnet NERの品質、合成トレヌニングの䟋の数ぞの䟝存。灰色の線-SlovnetBERTNERの品質。 Slovnet NERは、手曞きの䟋を認識せず、合成デヌタのみをトレヌニングしたす。



原始的な孊生モデルは、ハヌド教垫モデルよりも1パヌセントポむント悪いです。これは玠晎らしい結果です。普遍的なレシピはそれ自䜓を瀺唆しおいたす

䞀郚のデヌタを手動でマヌクアップしたす。重い倉圧噚を蚓緎したす。倚くの合成デヌタを生成したす。倧きなサンプルで単玔なモデルをトレヌニングしたす。トランスの品質、シンプルなモデルのサむズずパフォヌマンスが埗られたす。



Slovnetラむブラリには、このレシピに埓っおトレヌニングされた2぀のモデルがありたす。SlovnetMorph-圢態孊的タガヌ、Slovnet構文-構文パヌサヌ。Slovnet Morphは、ヘビヌティヌチャヌモデルより2パヌセントポむント遅れおいたす。SlovnetSyntax- 5です。どちらのモデルも、ニュヌス蚘事甚の既存のロシアの゜リュヌションよりも優れた品質ずパフォヌマンスを備えおいたす。



定量化



SlovnetNERのサむズは289MBです。287MBは、埋め蟌みのあるテヌブルで占められおいたす。このモデルは250,000行の倧きな語圙を䜿甚し、ニュヌステキストの単語の98をカバヌしおいたす。量子化を䜿甚しお、300次元のフロヌトベクトルを100次元の8ビットベクトルに眮き換えたす。モデルのサむズは10分の127MBになり、品質は倉わりたせん。Navecラむブラリは、量子化された事前トレヌニング枈みの埋め蟌みのコレクションであるNatashaプロゞェクトの䞀郚です。フィクションでトレヌニングされたりェむトは50MBかかり、合成掚定に埓っおすべおの静的RusVectoresモデルをバむパスしたす。



掚論



Slovnet NERは、トレヌニングにPyTorchを䜿甚しおいたす。 PyTorchパッケヌゞの重量は700MBです。掚枬のために本番環境にドラッグしたくありたせん。 PyTorchは、PyPyむンタヌプリタヌでも機胜したせん。 Slovnetはず共に䜿甚されるYargyパヌサヌ、のアナログYandexの富田パヌサ。 PyPyを䜿甚するず、文法の耇雑さに応じお、Yargyは2〜10倍速く動䜜したす。 PyTorchに䟝存しおいるために速床を萜ずしたくありたせん。



暙準的な解決策は、TorchScriptを䜿甚するか、モデルをONNXに倉換し、ONNXRuntimeで掚論を行うこずです。 Slovnet NERは、非暙準のブロック量子化された埋め蟌み、CRFデコヌダヌを䜿甚したす。 TorchScriptずONNXRuntimeはPyPyをサポヌトしおいたせん。



Slovnet NERはシンプルなモデルで、NumPyのすべおのブロックを手動で実装し、PyTorchによっお蚈算された重みを䜿甚したす。少しNumPyの魔法を適甚しお、CNNブロック、CRFデコヌダヌを泚意深く実装し、量子化された埋め蟌みを解凍するには5行かかりたす。CPUでの掚論速床は、ONNXRuntimeおよびPyTorchの堎合ず同じで、Corei5では毎秒25のニュヌス蚘事がありたす。



この手法は、より耇雑なモデルで機胜したす。SlovnetMorphずSlovnetSyntaxもNumPyに実装されおいたす。Slovnet NER、Morph、Syntaxは、共通の埋め蟌みテヌブルを共有しおいたす。別のファむルで重みを取り出したしょう。テヌブルはメモリずディスクに耇補されたせん。



>>> navec = Navec.load('navec_news_v1_1B.tar')  # 25MB
>>> morph = Morph.load('slovnet_morph_news_v1.tar')  # 2MB
>>> syntax = Syntax.load('slovnet_syntax_news_v1.tar')  # 3MB
>>> ner = NER.load('slovnet_ner_news_v1.tar')  # 2MB

# 25 + 2 + 3 + 2  25+2 + 25+3 + 25+2
>>> morph.navec(navec)
>>> syntax.navec(navec)
>>> ner.navec(navec)


制限事項



ナタヌシャは、名前、トポニヌムの名前、組織などの暙準゚ンティティを抜出したす。この゜リュヌションは、ニュヌスで優れた品質を瀺しおいたす。他の゚ンティティやテキストの皮類を操䜜する方法は新しいモデルをトレヌニングする必芁がありたす。これは簡単ではありたせん。モデル準備の耇雑さにより、コンパクトなサむズず䜜業速床を実珟したす。重い教垫のモデルを補造するためのスクリプトのラップトップ、孊生モデルのためのスクリプトのラップトップ、量子化された埋め蟌みを調補するための説明曞。



Navec-ロシア語甚のコンパクトな埋め蟌み







コンパクトなモデルは䜜業に䟿利です。それらは迅速に開始し、メモリをほずんど䜿甚せず、より倚くの䞊列プロセスが1぀のむンスタンスに適合したす。



NLPでは、モデルの重みの80〜90が埋め蟌みテヌブルにありたす。Navecラむブラリは、ロシア語甚に事前にトレヌニングされた埋め蟌みのコレクションであるNatashaプロゞェクトの䞀郚です。固有の品質メトリックに関しおは、RusVectoresのトップ゜リュヌションをわずかに䞋回っおいたすが、重み付きのアヌカむブのサむズは5〜6倍小さく51MB、蟞曞は2〜3倍倧きくなっおいたす500Kワヌド。

品質* モデルサむズ、MB 蟞曞のサむズ、×10 3
ナベック 0.719 50.6 500
RusVectores 0.638-0.726 220.6〜290.7 189-249
*セマンティック近接性を決定するタスクの品質。6぀の平均スコアデヌタセットSimLex965、LRWC、HJ、RT、AE、AE2



私たちは、に぀いおお話したす叀き良きワヌドごずの埋め蟌み2013幎にNLPに革呜をもたらしたした。この技術は今日でも重芁です。Natashaプロゞェクトでは、圢態、構文の解析、および名前付き゚ンティティの抜出のモデルが、単語ごずのNavec埋め蟌みで機胜し、他のオヌプン゜リュヌションよりも優れた品質を瀺したす。



RusVectores



ロシア語の堎合、RusVectoresから事前にトレヌニングされた埋め蟌みを䜿甚するのが通䟋です。これらには䞍快な機胜がありたす。テヌブルには単語ではなく、「word_POS-tag」のペアが含たれたす。ペア「oven_VERB」の堎合、「cook_VERB」、「cook_VERB」、および「oven_NOUN」の堎合、「hut_NOUN」、「furnace_NOUN」に類䌌したベクトルが必芁です。



実際には、そのような埋め蟌みを䜿甚するこずは䞍䟿です。テキストをトヌクンに分割するだけでは䞍十分です。トヌクンごずに、䜕らかの方法でPOSタグを定矩する必芁がありたす。埋め蟌みテヌブルが膚らんでいたす。「become」ずいう1぀の単語の代わりに、62぀の劥圓な「become_VERB」、「become_NOUN」、および4぀の奇劙な「become_ADV」、「become_PROPN」、「become_NUM」、「become_ADJ」を栌玍したす。250,000゚ントリのテヌブルには195,000の䞀意の単語がありたす。



品質



セマンティック近接問題ぞの埋め蟌みの品質を芋積もりたしょう。いく぀かの単語を芋おみたしょう。埋め蟌みベクトルを芋぀けるたびに、䜙匊の類䌌性を蚈算したす。同様の単語「cup」ず「jug」のNavecは、「fruit」ず「oven」の堎合、0.49を返したす--- 0.0047。類䌌性の参照マヌクを持぀倚くのペアを収集し、スピアマンず私たちの答えずの盞関関係を蚈算したしょう。



RusVectoresの䜜成者は、SimLex965ペアの小さく、泚意深くチェックされ、改蚂されたテストリストを䜿甚したす。RUSSEプロゞェクトから新しいYandexLRWCずデヌタセットを远加したしょうHJ、RT、AE、AE2

6぀のデヌタセットの平均品質 読み蟌み時間、秒 モデルサむズ、MB 蟞曞のサむズ、×10 3
ナベック hudlit_12B_500K_300d_100q 0.719 1.0 50.6 500
news_1B_250K_300d_100q 0.653 0.5 25.4 250
RusVectores ruscorpora_upos_cbow_300_20_2019 0.692 3.3 220.6 189
ruwikiruscorpora_upos_skipgram_300_2_2019 0.691 5.0 290.0 248
tayga_upos_skipgram_300_2_2019 0.726 5.2 290.7 249
tayga_none_fasttextcbow_300_10_2019 0.638 8.0 2741.9 192
araneum_none_fasttextcbow_300_5_2018 0.664 16.4 2752.1 195
Navecリポゞトリ内のデヌタセットごずの内蚳を含むテヌブル。



品質はhudlit_12B_500K_300d_100qRusVectores゜リュヌションず同等かそれ以䞊で、蟞曞は2〜3倍倧きく、モデルサむズは5〜6倍小さくなっおいたす。どのようにしおこの品質ずサむズを手に入れたしたか



動䜜原理



hudlit_12B_500K_300d_100q-手袋-埋め蟌みのために蚓緎された小説の145ギガバむト。RUSSEプロゞェクトからのテキストを含むアヌカむブを芋おみたしょう。Cで元のGloVe実装を䜿甚し、䟿利なPythonむンタヌフェむスでラップしおみたしょう。



なぜword2vecではないのですか倧芏暡なデヌタセットでの実隓は、GloVeを䜿甚するず高速になりたす。コロケヌションマトリックスを蚈算したら、それを䜿甚しおさたざたな次元の埋め蟌みを準備し、最適なオプションを遞択したす。



なぜfastTextではないのですかナタヌシャプロゞェクトでは、ニュヌステキストを扱いたす。それらにはタむプミスがほずんどなく、OOVトヌクンの問題は倧きな蟞曞によっお解決されたす。衚の250,000行は、news_1B_250K_300d_100qニュヌス蚘事の単語の98をカバヌしおいたす。



蟞曞のサむズhudlit_12B_500K_300d_100q-500,000゚ントリ、フィクションテキストの単語の98をカバヌしたす。ベクトルの最適な次元は300です。フロヌト数の500,000×300のテヌブルは578MBを取り、重み付きのアヌカむブのサむズhudlit_12B_500K_300d_100qは12分の148MBです。それは量子化に぀いおです。



定量化



32ビットの浮動小数点数を8ビットのコヌドに眮き換えたしょう[-∞、-0.86-コヌド0、[-0.86、-0.79-コヌド1、[-0.79、-0.74-2、 、[0.86、 ∞-255。テヌブルのサむズは4分の1143MBに枛少したす。



:
-0.220 -0.071  0.320 -0.279  0.376  0.409  0.340 -0.329  0.400
 0.046  0.870 -0.163  0.075  0.198 -0.357 -0.279  0.267  0.239
 0.111  0.057  0.746 -0.240 -0.254  0.504  0.202  0.212  0.570
 0.529  0.088  0.444 -0.005 -0.003 -0.350 -0.001  0.472  0.635
                     ────── ──────
-0.170  0.677  0.212  0.202 -0.030  0.279  0.229 -0.475 -0.031
                            ──────                      ──────
:
    63    105    215     49    225    230    219     39    228
   143    255     78    152    187     34     49    204    198
   163    146    253     58     55    240    188    191    246
   243    155    234    127    127     35    128    237    249
                        ───    ───
    76    251    191    188    118    207    195     18    118
                               ───                         ───


デヌタは粗くなり、異なる倀-0.005ず-0.003が1぀のコヌド127、-0.030ず-0.031を眮き換えたす-118



コヌドを1぀ではなく、3぀の数字に眮き換えたしょう。k-meansアルゎリズムを䜿甚しお、埋め蟌みテヌブルの数倀のすべおのトリプレットを256のクラスタヌにクラスタヌ化したす。各トリプレットの代わりに、0から255たでのコヌドを栌玍したす。テヌブルは3倍48MB枛少したす。 NavecはPQk-meansラむブラリを䜿甚し、マトリックスを100列に分割し、それぞれを個別にクラスタヌ化したす。合成テストの品質は1パヌセントポむント䜎䞋したす。k-NNのProductQuantizersの蚘事で量子化に぀いお明確になっおいたす。



量子化された埋め蟌みは、通垞のものよりも遅くなりたす。圧瞮されたベクトルは、䜿甚する前に解凍する必芁がありたす。手順を慎重に実行し、Numpyマゞックを適甚したす、PyTorchではtorch.gatherを䜿甚したす。Slovnet NERでは、埋め蟌みテヌブルぞのアクセスに合蚈蚈算時間の0.1がかかりたす。Slovnetラむブラリの



モゞュヌルNavecEmbeddingは、NavecをPyTorchモデルに統合したす。



>>> import torch

>>> from navec import Navec
>>> from slovnet.model.emb import NavecEmbedding

>>> path = 'hudlit_12B_500K_300d_100q.tar'  # 51MB
>>> navec = Navec.load(path)  # ~1 sec, ~100MB RAM

>>> words = ['', '<unk>', '<pad>']
>>> ids = [navec.vocab[_] for _ in words]

>>> emb = NavecEmbedding(navec)
>>> input = torch.tensor(ids)

>>> emb(input)  # 3 x 300
tensor([[ 4.2000e-01,  3.6666e-01,  1.7728e-01,
        [ 1.6954e-01, -4.6063e-01,  5.4519e-01,
        [ 0.0000e+00,  0.0000e+00,  0.0000e+00,
	  ...




Nerusは、圢態、構文、名前付き゚ンティティのマヌクアップを備えた倧芏暡な合成デヌタセットです







Natashaプロゞェクトでは、圢態、構文分析、および名前付き゚ンティティの抜出は、Slovnet NER、Slovnet Morph、およびSlovnetSyntaxの3぀のコンパクトモデルによっお行われたす。゜リュヌションの品質は、BERTアヌキテクチャを備えた重い゜リュヌションよりも1〜5パヌセントポむント悪く、サむズは50〜75倍小さく、CPUの速床は2倍高速です。モデルは、圢態、構文、および名前付き゚ンティティのCoNLL-Uマヌクアップを含む700,000のニュヌス蚘事のアヌカむブで、巚倧な合成Nerusデヌタセットでトレヌニングされたす。



# newdoc id = 0
# sent_id = 0_0
# text = -      ,      ...
1    -   _   NOUN   _   Animacy=Anim|C...   7   nsubj     _   Tag=O
2                 _   ADP    _   _                     4   case      _   Tag=O
3         _   ADJ    _   Case=Dat|Degre...   4   amod      _   Tag=O
4           _   NOUN   _   Animacy=Inan|C...   1   nmod      _   Tag=O
5            _   PROPN  _   Animacy=Anim|C...   1   appos     _   Tag=B-PER
6           _   PROPN  _   Animacy=Anim|C...   5   flat:name _   Tag=I-PER
7         _   VERB   _   Aspect=Perf|Ge...   0   root      _   Tag=O
8    ,              _   PUNCT  _   _                   13  punct     _   Tag=O
9                  _   ADP    _   _                   11  case      _   Tag=O
10             _   DET    _   Case=Loc|Numbe...   11  det       _   Tag=O
11          _   NOUN   _   Animacy=Inan|C...   13  obl       _   Tag=O
12            _   PROPN  _   Animacy=Inan|C...   11  nmod      _   Tag=B-LOC
13     _   VERB   _   Aspect=Perf|Ge...   7   ccomp     _   Tag=O
14          _   ADV    _   Degree=Pos          15  advmod    _   Tag=O
15           _   ADJ    _   Case=Nom|Degre...   16  amod      _   Tag=O
16        _   NOUN   _   Animacy=Inan|C...   13  nsubj     _   Tag=O
17                _   ADP    _   _                   18  case      _   Tag=O
18              _   NOUN   _   Animacy=Inan|C...   16  nmod      _   Tag=O
19   ,              _   PUNCT  _   _                   20  punct     _   Tag=O
20          _   VERB   _   Aspect=Imp|Moo...   0   root      _   Tag=O
21               _   PROPN  _   Animacy=Inan|C...   20  nsubj     _   Tag=B-ORG
22           _   PROPN  _   Animacy=Inan|C...   21  appos     _   Tag=I-ORG
23   .              _   PUNCT  _   _                   20  punct     _   Tag=O

# sent_id = 0_1
# text =   ,         , , ...
1                 _   ADP    _   _                   2   case      _   Tag=O
2             _   NOUN   _   Animacy=Inan|C...   9   parataxis _   Tag=O
...


Slovnet NER、Morph、Syntax-プリミティブモデル。トレヌニングセットに1000の䟋がある堎合、Slovnet NERは重いBERTアナログより11パヌセントポむント遅れ、10,000の䟋3ポむントの堎合、500,000の堎合



は1です。Nerusは䜜業の結果であり、BERTアヌキテクチャを備えた重いモデルSlovnet BERT NER、Slovnet BERTモヌフ、SlovnetBERT構文。 Tesla V100では、700,000件のニュヌス蚘事の凊理に20時間かかりたす。他の研究者の時間を節玄し、完成したアヌカむブをオヌプンアクセスにしたす。でスペむシヌ-ルテニりムロシア語圏のスペむシヌためNerus定性的なモデルで教える、公匏リポゞトリにパッチを準備したす。







合成マヌクアップには高品質がありたす。圢態孊的タグの決定の粟床は98、構文リンクは96です。 NERの堎合、F1はトヌクンで掚定したすPER-99、LOC-98、ORG-97。品質を評䟡するために、SynTagRus、Collection5、およびニュヌススラむスGramEval2020をマヌクアップし、参照マヌクアップを私たちのものず比范しお、Nerusリポゞトリの詳现を確認したす。構文のマヌクアップに゚ラヌがあるため、ルヌプず耇数のルヌトがあり、POSタグが構文゚ッゞに察応しない堎合がありたす。UniversalDependenciesのバリデヌタヌを䜿甚するず䟿利です。そのような䟋はスキップしおください。



PythonパッケヌゞNerusは、マヌクアップをロヌドおよびレンダリングするための䟿利なむンタヌフェむスを線成したす。



>>> from nerus import load_nerus

>>> docs = load_nerus('nerus_lenta.conllu.gz')
>>> doc = next(docs)
>>> doc

NerusDoc(
    id='0',
    sents=[NerusSent(
         id='0_0',
         text='-      ,     ...',
         tokens=[NerusToken(
              id='1',
              text='-',
              pos='NOUN',
              feats={'Animacy': 'Anim',
               'Case': 'Nom',
               'Gender': 'Masc',
               'Number': 'Sing'},
              head_id='7',
              rel='nsubj',
              tag='O'
          ),
          NerusToken(
              id='2',
              text='',
              pos='ADP',
...

>>> doc.ner.print()
-      ,       
                                    PER─────────────                              LOC───                     
    ,   .   ,    
                                      ORG────────            PER──────             
...

​
>>> sent = doc.sents[0]
>>> sent.morph.print()
        -  NOUN|Animacy=Anim|Case=Nom|Gender=Masc|Number=Sing
                    ADP
            ADJ|Case=Dat|Degree=Pos|Number=Plur
              NOUN|Animacy=Inan|Case=Dat|Gender=Masc|Number=Plur
               PROPN|Animacy=Anim|Case=Nom|Gender=Fem|Number=Sing
              PROPN|Animacy=Anim|Case=Nom|Gender=Fem|Number=Sing
            VERB|Aspect=Perf|Gender=Fem|Mood=Ind|Number=Sing
...
				   
>>> sent.syntax.print()
  ┌►┌─┌───── -  nsubj
  │ │ │ ┌──►             case
  │ │ │ │ ┌►     amod
  │ │ └►└─└─       nmod
  │ └────►┌─        appos
  │       └►       flat:name
┌─└─────────     
│   ┌──────► ,             punct
│   │   ┌──►              case
│   │   │ ┌►          det
│   │ ┌►└─└─       obl
│   │ │ └──►         nmod
└──►└─└─────  ccomp
    │     ┌►       advmod
    │   ┌►└─        amod
    └►┌─└───     nsubj:pass
      │   ┌►             case
      └──►└─           nmod
          ┌► ,             punct
      ┌─┌─└─       
      │ └►┌─            nsubj
      │   └►        appos
      └────► .             punct


むンストヌルの手順、䜿甚䟋、品質評䟡Nerusリポゞトリむンチ



コヌラス-ロシア語の公開デヌタセットぞのリンクのコレクション+ダりンロヌド甚の関数





CorusラむブラリはNatashaプロゞェクトの䞀郚であり、公開ロシア語NLPデヌタセットぞのリンクのコレクション+ロヌダヌ関数を備えたPythonパッケヌゞです。゜ヌスぞのリンクのリスト、むンストヌル手順、およびCorusリポゞトリでの䜿甚䟋。



>>> from corus import load_lenta

#    Corus   Lenta.ru, :
# wget https://github.com/yutkin/Lenta.Ru-News-Dataset/...

>>> path = 'lenta-ru-news.csv.gz'
>>> records = load_lenta(path)  # 2, 750 000 
>>> next(records)
LentaRecord(
    url='https://lenta.ru/news/2018/12/14/cancer/',
    title='   \xa0  ...',
    text='-     ...',
    topic='',
    tags=''
)


ロシア語の䟿利なオヌプンデヌタセットは非垞によく隠されおいるため、ほずんどの人はそれらに぀いお知りたせん。



の䟋



ニュヌス蚘事のコヌパス



ニュヌス蚘事で蚀語モデルをトレヌニングしたいので、たくさんのテキストが必芁です。最初に頭に浮かぶのは、Taigaデヌタセットのニュヌススラむス〜1GBです。倚くの人がLenta.ruダンプ2GBに぀いお知っおいたす。他の゜ヌスを芋぀けるのはより困難です。 2019幎、Dialogueはヘッドラむンを生成するためのコンテストを䞻催したした。䞻催者は、RIA Novostiのダンプを4幎間3.7GB準備したした。 2018幎、Yuri Baburovは、40のロシア語ニュヌスリ゜ヌス7.5GBからのアップロヌドを公開したした。ニュヌスアゞェンダの分析に぀いおプロゞェクトのために収集されたODS 共有アヌカむブ7GBからのボランティア。 ではコヌラスレゞストリ



すべおの゜ヌスは、機胜・ロヌダヌを持っおいるため、これらのデヌタセットぞのリンクは、«ニュヌス»タグ付けload_taiga_*、load_lenta、load_ria、load_buriy_*、load_ods_*。



NER



ロシア語でNERを教えたいので、泚釈付きのテキストが必芁です。たず、factRuEval-2016コンペティションのデヌタを思い出したす。マヌクアップには欠点がありたす。耇雑な圢匏、゚ンティティスパンの重耇、あいたいな「LocOrg」カテゎリがありたす。Persons-1000の埌継であるNamedEntities5コレクションに぀いお誰もが知っおいるわけではありたせん。暙準フォヌマットのレむアりト、スパンが亀差しない、矎しさ他の3぀の情報源は、ロシア語を話すNERの最も熱心なファンだけが知っおいたす。 Rinat Gareevにメヌルで手玙を曞き、2013幎の圌の蚘事ぞのリンクを添付したす。それに応じお、名前ず組織がタグ付けされた250のニュヌス蚘事を受け取りたす。2019幎にBSNLP-2019コンペティションが開催されたしたスラブ蚀語のNERに぀いおは、䞻催者に手玙を曞き、さらに450のマヌクされたテキストを取埗したす。Winer氏のプロゞェクトは、Wikipediaのダンプから半自動NERマヌクアップを䜜るずいうアむデアを思い付いた、ロシアのための倧芏暡なダりンロヌドがGithubの䞊で䜿甚可胜です。



レゞスタコヌラスをロヌドするためのリンクず機胜load_factru、load_ne5、load_gareev、load_bsnlp、load_wikiner。



リンクのコレクション



ブヌトロヌダヌを取埗しおレゞストリに入る前に、゜ヌスぞのリンクがチケットのセクションに蓄積されたす。30個のデヌタセットのコレクションタむガの新バヌゞョン、クロヌルコモンから568ギガバむトロシア語のテキスト、Banki.ru CレビュヌずAuto.ru。調査結果を共有し、リンク付きのチケットを䜜成するこずをお勧めしたす。



ロヌダヌ機胜



単玔なデヌタセットのコヌドは、自分で簡単に䜜成できたす。Lenta.ruダンプは敎圢匏で、実装は簡単です。Taigaは、玄1,500䞇のCoNLL-Uzipファむルで構成されおいたす。ダりンロヌドが迅速に機胜し、倧量のメモリを䜿甚せず、ファむルシステムを台無しにしないためには、混乱し、䜎レベルのzipファむルでの䜜業を慎重に実装する必芁がありたす。



35の゜ヌスの堎合、CorusPythonパッケヌゞにはロヌダヌ関数がありたす。Taigaにアクセスするためのむンタヌフェヌスは、Lenta.ruダンプよりも耇雑ではありたせん。



>>> from corus import load_taiga_proza_metas, load_taiga_proza

>>> path = 'taiga/proza_ru.zip'
>>> metas = load_taiga_proza_metas(path)
>>> records = load_taiga_proza(path, metas)
>>> next(records)

TaigaRecord(
    id='20151231005',
    meta=Meta(
        id='20151231005',
        timestamp=datetime.datetime(2015, 12, 31, 23, 40),
        genre=' ',
        topic='',
        author=Author(
            name='',
            readers=7973,
            texts=92681,
            url='http://www.proza.ru/avtor/sadshoot'
        ),
        title='  !',
        url='http://www.proza.ru/2015/12/31/1875'
    ),
    text='... ...\n...  ..\n...
)


プルリク゚ストを䜜成し、ロヌダヌ関数を送信するようにナヌザヌを招埅したす。これは、Corusリポゞトリでの簡単な説明です。



Naeval-ロシア語を話すNLPのシステムの定量的比范





ナタヌシャは科孊的なプロゞェクトではなく、SOTAに勝぀ずいう目暙はありたせんが、パフォヌマンスをあたり損なうこずなく高い䜍眮を占めるように、公開ベンチマヌクで品質を確認するこずが重芁です。アカデミヌず同じように、品質を枬定し、数倀を取埗し、他の蚘事からタブレットを取り出し、これらの数倀を自分の数倀ず比范したす。このスキヌムには2぀の問題がありたす。

  1. パフォヌマンスを忘れおください。モデルのサむズや䜜業速床は比范されたせん。品質のみに重点が眮かれおいたす。
  2. コヌドを公開しないでください。品質指暙の蚈算には通垞、100䞇のニュアンスがありたす。他の蚘事ではどの皋床正確にカりントされたしたかわからない。


Naevalは、ロシアの自然蚀語を凊理するためのオヌプン゜ヌスツヌルの品質ず速床を評䟡するための䞀連のスクリプトであるNatashaプロゞェクトの䞀郚です。

仕事 デヌタセット ゜リュヌション
トヌクン化 SynTagRus, OpenCorpora, GICRYA, RNC

SpaCy, NLTK, MyStem, Moses, SegTok, SpaCy Russian Tokenizer, RuTokenizer, Razdel

SynTagRus, OpenCorpora, GICRYA, RNC

SegTok, Moses, NLTK, RuSentTokenizer, Razdel

SimLex965, HJ, LRWC, RT, AE, AE2

RusVectores, Navec

GramRuEval2020 (SynTagRus, GSD, Lenta.ru, Taiga)

DeepPavlov Morph, DeepPavlov BERT Morph, RuPosTagger, RNNMorph, Maru, UDPipe, SpaCy, Stanza, Slovnet Morph, Slovnet BERT Morph

GramRuEval2020 (SynTagRus, GSD, Lenta.ru, Taiga)

DeepPavlov BERT Syntax, UDPipe, SpaCy, Stanza, Slovnet Syntax, Slovnet BERT Syntax

NER factRuEval-2016, Collection5, Gareev, BSNLP-2019, WiNER

DeepPavlov NER、DeepPavlov BERT NER、DeepPavlov Slavic BERT NER、PullEnti、SpaCy、Stanza、Texterra、Tomita、MITIE、Slovnet NER、Slovnet BERT NER

Naevalリポゞトリからの゜リュヌションずテストデヌタセットのグリッド。NatashaプロゞェクトツヌルRazdel、Navec、Slovnet。



以䞋のNER問題を詳しく芋おみたしょう。



デヌタセット



ロシア語を話すNERには、factRuEval-2016、Collection5、Gareev、BSNLP-2019、WiNERの5぀の公開ベンチマヌクがありたす。゜ヌスリンクはCorusレゞストリに収集されたす。すべおのデヌタセットはニュヌス蚘事で構成され、名前の付いたサブストリング、組織の名前、およびトポニヌムがテキストでマヌクされおいたす。䜕が簡単でしょうか



すべおの゜ヌスには、異なるマヌクアップ圢匏がありたす。 Collection5は、Brat、Gareev、およびWiNERナヌティリティのスタンドオフ圢匏を䜿甚したす-BIOマヌクアップの異なる方蚀、BSNLP-2019には独自の圢匏があり、factRuEval-2016にも独自の重芁な仕様がありたす..。Naevalは、すべおの゜ヌスを共通の圢匏に倉換したす。マヌクアップはスパンで構成されたす。スパン-3゚ンティティタむプ、サブストリングの開始ず終了。



゚ンティティタむプ。factRuEval-2016ずCollection5は、「Kremlin」、「EU」、「USSR」のハヌフネヌムの半組織を個別にマヌクしたす。BSNLP-2019ずWiNERは、むベントの名前を匷調しおいたす「ロシアのチャンピオンシップ」、「ブレキシット」。Naevalはいく぀かのタグを適応させお削陀し、参照タグPER、LOC、ORGを残したす人の名前、トポニヌムず組織の名前。



ネストされたスパン。実際、RuEval-2016では、スパンが重耇しおいたす。Naevalはマヌクアップを簡玠化したす。

:
,    5 Retail Group,   
                         org_name───────              
                         Org────────────              
  "", ""  "",
org_descr─────  org_name─    org_name───     org_name  
Org──────────────────────                              
org_descr─────                                         
Org─────────────────────────────────────               
org_descr─────                                         
Org──────────────────────────────────────────────────  
        
  ,    .

:
,    5 Retail Group,  
                         ORG────────────
  "", ""  "",
                ORG──────    ORG────────     ORG─────     

       
  ,    .


モデル



Naevalは、12のオヌプン゜ヌス゜リュヌションをロシアのNER問題ず比范しおいたす。すべおのツヌルは、Webむンタヌフェむスを備えたDockerコンテナにラップされおいたす。



$ docker run -p 8080:8080 natasha/tomita-algfio
2020-07-02 11:09:19 BIN: 'tomita-linux64', CONFIG: 'algfio'
2020-07-02 11:09:19 Listening http://0.0.0.0:8080	    

$ curl -X POST http://localhost:8080 --data \
  '      \
        \
    '

<document url="" di="5" bi="-1" date="2020-07-02">
   <facts>
      <Person pos="18" len="16" sn="0" fw="2" lw="3">
         <Name_Surname val="" />
         <Name_FirstName val="" />
         <Name_SurnameIsDictionary val="1" />
      </Person>
      <Person pos="67" len="14" sn="0" fw="8" lw="9">
         <Name_Surname val="" />
         <Name_FirstName val="" />
         <Name_SurnameIsDictionary val="1" />
      </Person>
   </facts>
</document>


䞀郚の゜リュヌションは、起動ず構成が非垞に難しいため、䜿甚する人はほずんどいたせん。PullEnti、掗緎されたルヌルベヌスのシステムは、2016幎にfactRuEval競争の䞭で第䞀䜍を取りたした。このツヌルは、C甚のSDKずしお配垃されおいたす。Naevalでの䜜業により、PullEntiのラッパヌのセットを含む別のプロゞェクトが䜜成されたした。PullentiServerはCWebサヌバヌであり、pullenti-clientはPullentiServerのPythonクラむアントです。



$ docker run -p 8080:8080 pullenti/pullenti-server
2020-07-02 11:42:02 [INFO] Init Pullenti v3.21 ...
2020-07-02 11:42:02 [INFO] Load lang: ru, en
2020-07-02 11:42:03 [INFO] Load analyzer: geo, org, person
2020-07-02 11:42:05 [INFO] Listen prefix: http://*:8080/

>>> from pullenti_client import Client

>>> client = Client('localhost', 8080)
>>> text = '     ' \
...  '     ' \
...  '    '
>>> result = client(text)
>>> result.graph




すべおのツヌルのマヌクアップ圢匏は少し異なりたす。Naevalは結果をロヌドし、゚ンティティタむプを適応させ、スパンの構造を簡玠化したす。



 (PullEnti):
,      19  
          ORGANIZATION──────────                            
                    GEO─────────                            
     
                                PERSON────────────────
                                PERSONPROPERTY─────── 
       
────────────────             PERSON───────────────────────
                             PERSONPROPERTY────────────── 
                                          ORGANIZATION─── 
 .
──────────────── 

:
,      19  
          ORG────── LOC─────────
     
       
PER─────────────                          ORG────────────
 .
PER─────────────


PullEntiの䜜業の結果は、factRuEval-2016マヌクアップよりも適応が困難です。アルゎリズムはPERSONPROPERTYタグを削陀し、ネストされたPERSON、ORGANIZATION、およびGEOを重耇しないPER、LOC、ORGに分割したす。



比范



「モデル、デヌタセット」の各ペアに぀いお、NaevalはトヌクンによるF1メゞャヌを蚈算し、品質スコアを含むテヌブルを公開したす。



ナタヌシャは科孊的なプロゞェクトではありたせん。゜リュヌションの実甚性は私たちにずっお重芁です。 Naevalは、開始時間、実行速床、モデルサむズ、およびRAM消費量を枬定したす。リポゞトリ内の結果を含むテヌブル。



デヌタセットを準備し、Dockerコンテナで20のシステムをラップし、ロシア語NLPの他の5぀のタスクのメトリックを蚈算したした。結果は、トヌクン化、文ぞのセグメンテヌション、埋め蟌み、圢態および構文分析です。



Yargy- —







YargyパヌサヌはYandexのの類䌌䜓である富田パヌサPython甚。むンストヌルの手順、䜿甚䟋、文曞Yargyリポゞトリむンチ゚ンティティを抜出するためのルヌルは、コンテキストフリヌの文法ず蟞曞を䜿甚しお説明されおいたす。 2幎前、私はHabrに、YargyずNatashaラむブラリに぀いおの蚘事を曞き、ロシア語のNER問題の解決に぀いお話したした。プロゞェクトは奜評でした。 Sberbank、Interfax、RIA Novosti内の倧芏暡プロゞェクトで、Yargy-parserがTomitaに取っお代わりたした。たくさんの教材が登堎しおいたす。 Yandexのワヌクショップからの倧きなビデオ、䟋を䜿っお文法を開発するプロセスに぀いお1時間半。



ドキュメントが曎新され、玹介セクションずリファレンスブックを組み合わせたした。最も重芁なのは、クックブックが登堎したこずです。これは、圹立぀プラクティスのセクションです。これには、t.me / natural_language_processingからの最もよくある質問ぞの回答が含たれおいたす。





Yargyパヌサヌは耇雑なツヌルです。クックブックでは、倧量のルヌルセットを操䜜するずきに発生する非自明なポむントに぀いお説明しおいたす。



Yargyラボではいく぀かの倧芏暡なサヌビスを実行しおいたす。私はコヌドを読み盎し、公開されおいないクックブックに収集されたパタヌンを読みたした。





ドキュメントを読んだ埌、䟋を䜿甚しおリポゞトリを確認するず䟿利です。





Natashaプロゞェクトには、natasha-usageリポゞトリもありたす。これは、Githubで公開されおいるYargyパヌサヌナヌザヌのコヌドが行くずころです。リンクの80は教育プロゞェクトですが、有益な䟋もありたす。





もちろん、Yargyパヌサヌを䜿甚する最も興味深いケヌスは、Githubで公開されおいたせん。䌚瀟がYargyを䜿甚しおいる堎合は、PMに連絡し、気にしない堎合は、natasha.github.ioにロゎを远加しおください。



Ipymarkup-名前付き゚ンティティのマヌクアップず構文䞊の関係の芖芚化





Ipymarkupは、テキスト内のサブストリングを匷調衚瀺するために必芁なプリミティブラむブラリであり、NERの芖芚化です。むンストヌル手順、Ipymarkupリポゞトリでの䜿甚䟋。このラむブラリは、displaCyおよびdisplaCy ENTに䌌おおり、Yargyパヌサヌの文法をデバッグするのに非垞に圹立ちたす。



>>> from yargy import Parser
>>> from ipymarkup import show_span_box_markup as show_markup

>>> parser = Parser(...)
>>> text = '...'
>>> matches = parser.findall(text)
>>> spans = [_.span for _ in matches]
>>> show_markup(text, spans)






Natashaプロゞェクトには、解析の問題に察する解決策がありたす。テキスト内の単語を匷調衚瀺するだけでなく、それらの間に矢印を描く必芁もありたした。既成の解決策はたくさんあり、このトピックに関する科孊的な蚘事もありたす。







もちろん、既存のものはどれも登堎したせんでした。ある日、私は本圓に混乱し、CSSずHTMLの有名な魔法をすべお適甚し、Ipymarkupに新しい芖芚化を远加したした。ドックでの䜿甚方法。



>>> from ipymarkup import show_dep_markup

>>> words = ['', '', '', '', '', '', '-', '', '', '', '', '', '', '', '.']
>>> deps = [(2, 0, 'case'), (2, 1, 'amod'), (10, 2, 'obl'), (2, 3, 'nmod'), (10, 4, 'obj'), (7, 5, 'compound'), (5, 6, 'punct'), (4, 7, 'nmod'), (9, 8, 'case'), (4, 9, 'nmod'), (13, 11, 'case'), (13, 12, 'nummod'), (10, 13, 'nsubj'), (10, 14, 'punct')]
>>> show_dep_markup(words, deps)






珟圚、ナタヌシャずネルスでは、解析の結果を確認するのに䟿利です。






All Articles