Upgrade to Pro — share decks privately, control downloads, hide ads and more …

言語処理ライブラリ開発における失敗談 / NLPHacks

言語処理ライブラリ開発における失敗談 / NLPHacks

NLP Hacks Vol.5 での発表スライドです。
詳細:https://nlp-hacks.elyza.ai/

7b5bbcad8cad0559a385206fbe038744?s=128

taishi-i

June 08, 2022
Tweet

More Decks by taishi-i

Other Decks in Programming

Transcript

  1. 言語処理ライブラリ開発における失敗談 ソフトウェアを開発者に利用してもらうために必要だと考えること NLP Hacks Vol.5 池田 大志

  2. 自己紹介 • 名前 ◦ 池田 大志(Taishi Ikeda) • 略歴 ◦

    2015/04 - 2017/03: 奈良先端大 自然言語処理学研究室(松本研) ◦ 2017/04 - 2022/05: NTTドコモ(自然言語処理に関する研究開発) • 個人開発者としての取り組み ◦ 単語分割/品詞タグ付けライブラリ nagisa の開発 ◦ 形態素解析器比較ライブラリ toiro の開発 ◦ PyCon JP 2018, 2019, 2020 の発表 2
  3. 3 PyCon JP 2020 での発表 • 最先端自然言語処理ライブラリの最適な選択と有用な利用方法 ◦ 日本語処理ライブラリの特徴と利用方法を説明 ◦

    どのようにライブラリを選択すべきか判断基準を説明
  4. 単語分割/品詞タグ付けライブラリ nagisa • 特徴と利点 ◦ シンプルな単語分割と品詞タグ付け機能を Python ライブラリとして提供 ◦ ユーザー辞書の追加が容易、系列ラベリングモデルの学習が可能

    • 解析手法 ◦ BLSTMs を用いた系列ラベリングによる単語分割と品詞タグ付け • 分割基準 ◦ UniDic(短単位) 4
  5. Python で簡単に使えるライブラリとして開発 • インストール方法 • 実装方法 5 $ pip install

    nagisa >>> import nagisa >>> text = 'Python で前処理を実行する' >>> tokens = nagisa.tagging(text) >>> print(tokens) Python/名詞  /空白 で/助詞 前/名詞 処理/名詞 を/助詞 実行/名詞 する/動詞 >>> print(tokens.words) ['Python', '\u3000', 'で', '前', '処理', 'を', '実行', 'する'] >>> print(tokens.postags) ['名詞', '空白', '助詞', '名詞', '名詞', '助詞', '名詞', '動詞']
  6. 6 nagisa の開発状況 • 最新の更新 ◦ 2022年5月に Python 3.10+ (Linux),

    Python 3.9+ (macOS) の Wheel を公開 ◦ 現在、Python 3.9+ (Windows) の Wheel を作成中 ◦ メンテナンスは継続中だが、この2年間新しい機能の追加はなし
  7. 7 nagisa の開発状況 • 最新の更新 ◦ 2022年5月に Python 3.10+ (Linux),

    Python 3.9+ (macOS) の Wheel を公開 ◦ 現在、Python 3.9+ (Windows) の Wheel を作成中 ◦ メンテナンスは継続中だが、この2年間新しい機能の追加はなし 今回トークでは、私の失敗談として、 開発停滞となった原因を共有
  8. 本発表について • 概要 ◦ nagisa の開発に取り組んだ経緯 ◦ 開発者にライブラリを利用してもらうために工夫したこと ◦ ライブラリ開発において改善すべきだったこと

    ◦ 開発者に利用されるライブラリの分析結果の共有 • 目的 ◦ ライブラリ開発の失敗談を共有することで、 言語処理関連のライブラリ開発の参考にしてもらいたい • 想定する聞き手 ◦ 言語処理ライブラリ開発に取り組んでいる人 ◦ ライブラリ開発に挑戦したい人 ◦ 研究テーマに迷っている学生 8
  9. 9 本発表の目的 • ライブラリ開発の失敗談を共有することで、 言語処理関連のライブラリ開発の参考にしてもらいたい ◦ ライブラリ開発における失敗談は滅多に表に出ない ◦ 一定の利用者がいるライブラリ開発者として、実体験を共有 •

    どのようなライブラリが必要か、コミュニティで議論したい ◦ NLP Hacks は「NLP × 実装」をテーマとしたコミュニティ ◦ 誰でも参加できるコミュニティは素晴らしい! 失敗談の共有 議論
  10. 10 本発表の目的(理想形のイメージ) • ライブラリ開発の失敗談を共有することで、 言語処理関連のライブラリ開発の参考にしてもらいたい ◦ ライブラリ開発における失敗談は滅多に表に出ない ◦ 一定の利用者がいるライブラリ開発者として、実体験を共有 •

    どのようなライブラリが必要か、コミュニティで議論したい ◦ NLP Hacks は「NLP × 実装」をテーマとしたコミュニティ ◦ 誰でも参加できるコミュニティは素晴らしい! 失敗談の共有 議論 💡 活性化 💡 フィードバック 💡 ライブラリ 開発者の誕生
  11. 本発表の方針 • 前半と後半の二部構成 ◦ 前半:20分 ◦ 後半:15分 ◦ 途中で休憩を挟みます:5分 •

    懇親会でも議論 ◦ 全体で聞きづらい話は懇親会で話しましょう😆 • 発表当日以降の質問 ◦ NLP Hacks の Slack または Twitter(@taishinlp)で質問に回答します😆 11
  12. 目次(1/2) • nagisa の開発に取り組んだ経緯 ◦ 大学の卒業研究でツイッターの話題分析 ◦ 言語処理学会 2017 の論文発表

    ◦ ACL 2017, EMNLP 2017 のリジェクト ◦ 新卒研修中にプロトタイプを開発 • ライブラリを開発者に利用してもらうために工夫したこと ◦ PyCon JP 2018 のポスター発表に参加 ◦ PyCon JP 2018 での意見を参考にする ◦ PyCon JP 2019 のトーク発表に参加 ◦ その他の工夫したこと ◦ まとめ:工夫による効果 • (休憩コーナー)実際に手を動かしてみよう ◦ 単語分割の違いを確認してみよう 12
  13. 目次(2/2) • ライブラリ開発において改善すべきだったこと ◦ 解析速度 ◦ 精度至上主義 ◦ (余談)SentencePiece の実装を参考にする

    ◦ 品詞タグの小・中分類情報の追加 ◦ Wheel の管理不足 ◦ まとめ:改善すべきだったこと • 開発者に利用されるライブラリの分析結果 ◦ どのようなライブラリが利用されているか調査 ◦ 比較対象ライブラリ一覧 ◦ インストールの総数・トレンド ◦ SudachiPy が利用される理由 ◦ 今は Rust の時代?VAporetto の登場 ◦ まとめ:開発者に利用されるライブラリ 13
  14. nagisa の開発に取り組んだ経緯

  15. 大学の卒業研究でツイッターの話題分析 • 特定の単語を含むツイートをトピックモデルで分析 ◦ MeCab で形態素解析を行うが、理想と異なる単語分割を多く発見 ◦ ツイートなど未知語を多く含むテキストデータの言語処理に興味を持つ • 奈良先端大

    自然言語処理学研究室に出願 ◦ 在学中の研究テーマは、崩れ文字の正規化と単語分割 15
  16. 言語処理学会 2017 の論文発表 • 辞書情報と単語分散表現を組み込んだ リカレントニューラルネットワークによる日本語単語分割 ◦ ソースコードを GitHub に公開(現在は非公開、nagisa

    に統合済み) ◦ 当時のスター数は5件ほど ◦ Python ファイルを実行する形式では、ユーザーには使ってもらえず ▪ 多くのユーザーに試してもらうためには、 ライブラリ形式の配布が必要 16 ※ 当時のリポジトリの README.md の一部
  17. ACL 2017, EMNLP 2017 のリジェクト • Japanese Word Segmentation using

    Character-level Recurrent Networks with Dictionary Information ◦ 文字単位ニューラルネットワークに辞書情報を追加することで精度向上 ◦ これまで nagisa を論文で引用したいと何度も連絡があり、 当時 arXiv に論文を投稿しておけば良かったと後悔 17
  18. 新卒研修中にプロトタイプを開発 • 研修のため、半年間、研究環境がない期間が発生 ◦ 大学も卒業し、会社のサーバーも使える状況ではなかった ◦ ニューラルネットワークを学習するための強力な計算環境がない ▪ 今できることに取り組もうと、これまで学習していたモデルを利用して、 単語分割機能を

    Python ライブラリ化することを決意 ▪ 単語分割と品詞タグ付けによるマルチタスク学習も精度検証していたので、 その品詞タグ付けモデルを nagisa に統合 18
  19. ライブラリを開発者に 利用してもらうために工夫したこと

  20. PyCon JP 2018 のポスター発表に参加 • NLP初心者のための日本語単語分割/品詞タグ付けツールの紹介 ◦ Python 利用者をターゲットに言語処理のライブラリを紹介 ◦

    普段、言語処理を行わない開発者と対面で議論 ◦ PyCon JP をきっかけに徐々にユーザーが増え始める 20
  21. PyCon JP 2018 での意見を参考にする • PyCon JP のポスター発表をきっかけに想定ユーザーを絞る ◦ 当時(2017~2018年)、形態素解析といえば

    MeCab の時代 ◦ Python で利用するためには、MeCab 本体のインストールも必要だった ▪ pip install だけで利用できるライブラリの重要性を感じた ◦ シンプルで簡単に利用できるライブラリを目指し、開発を行う • 既存ライブラリの足りない部分を考え、新しい機能を追加 ◦ ユーザー辞書の登録が難しいとの声(単語のパラメータ設定など) ▪ 辞書の追加が容易できる機能を追加 ◦ 開発者ができる限り前処理を行わないにする ▪ 品詞フィルター機能を標準で搭載 ▪ Unicode 正規化を標準で搭載 ▪ 単語列の出力結果をリストで取得できるよう実装 21
  22. PyCon JP 2019 のトーク発表に参加 • Python による日本語自然言語処理 〜系列ラベリングによる実世界テキスト分析〜 ◦ 日本語コーパスから固有表現抽出モデルを実装する方法について発表

    ◦ 言語処理に取り組むきっかけとなるチュートリアルを作成 ◦ 系列ラベリング学習機能を追加し、nagisa を利用してもらう 22
  23. その他の工夫したこと(1/3) 23 • Cython を利用して、処理速度の高速化 ◦ 解析速度を少しでも早くするため(だが、大幅な高速化にはならず) • 解析時に処理を実行するように実装 ◦

    nagisa の内部では、単語分割と品詞タグ付けのモデルが別々に存在する ◦ 品詞タグが必要ない場合はタグ付け処理は行わない実装 • ライブラリをインポートする際に、クラスを初期化するように設計 ◦ ユーザーが書くコードを一行でも減らすため
  24. その他の工夫したこと(2/3) 24 • できる限りモデルサイズを最小限にする ◦ ライブラリインポート時の速度を少しでも高速化するため ◦ もちろん、精度とのトレードオフを考えながら • 素性抽出の前処理部分とニューラルネットワーク処理を

    C++ で実装 ◦ ライブラリの実装が複雑化するため、最終的には採用せず • モデルを含め、オリジナルの解析器であることを強調 ◦ MeCab の派生系ではない ◦ 学習機能もあるため、研究用ベースラインとして利用できる
  25. その他の工夫したこと(3/3) 25 • Word segmentation/POS-tagging ライブラリとして紹介 ◦ 英語で検索する場合、形態素解析(Morphological analysis)より Word

    segmentation や POS-tagging をキーワードとすると仮定 ◦ 実際はあまり違いはない?
  26. まとめ:工夫による効果 26 • PyCon JP への参加 ◦ 普段、言語処理を行わない開発者にライブラリを周知 ◦ 発表資料をそのままライブラリのチュートリアルとして利用できる

    ◦ チュートリアルを参考に、まずはインストールしてもらう ◦ ライブラリの認知度が上がり、GitHub などの検索の上位になる • フィードバックを参考に新しい機能を追加 ◦ 他のライブラリとの差別化できる • 開発モチベーションの向上 ◦ ひとりでもユーザーがいると、開発のモチベーションとなる ◦ コードも慎重に書くようになる
  27. (休憩コーナー) 実際に手を動かしてみよう

  28. 単語分割の違いを確認してみよう 28 • 「きょうとに行った」を形態素解析してみよう! ◦ 各ライブラリの単語分割の違いを確認しよう ◦ NEologd や SudachiPy

    の各辞書(small, core, full)でも確認してみよう ◦ 他に理想と異なる単語分割の例があれば、Slack で教えてください😆 ◦ コミュニティで議論しましょう!
  29. 形態素解析器比較ライブラリ toiro の紹介 • 日本語処理の便利機能を搭載した Python ライブラリ ◦ 日本語コーパスのダウンローダーと前処理機能を搭載 ◦

    数行のコードで処理速度の比較、単語分割の比較、後段タスクでの精度比較 が可能 ◦ Dockerでは、環境構築なしに9種類の解析器の比較が可能 ◦ https://github.com/taishi-i/toiro 29
  30. toiro の利用方法 • インストール方法 • 各ライブラリのインストール ◦ Janome はデフォルトでインストール済み ◦

    比較したいライブラリを追加でインストール 30 $ pip install toiro $ pip install nagisa $ pip install sudachipy sudachidict_core $ pip install mecab-python3 $ pip install fugashi[unidic-lite]
  31. 数行のコードで単語分割を比較 • 簡単に単語分割結果の比較が可能 ◦ 他のライブラリと比較し、nagisa の単語分割が正しい事例のひとつ ◦ 逆に nagisa が正しく分割できない事例も多く存在

    31 >>> from toiro import tokenizers >>> text = "きょうとに行った" >>> tokenizers.print_words(text, delimiter="|") mecab-python3: きょう|と|に|行っ|た janome: きょう|と|に|行っ|た nagisa: きょうと|に|行っ|た sudachipy: きょう|と|に|行っ|た fugashi-unidic: きょう|と|に|行っ|た
  32. ライブラリ開発において 改善すべきだったこと

  33. 解析速度 • 実利用を想定した場合、現状の解析速度では不十分 ◦ 大規模データを単語分割する場合、待ち時間はストレスとなる ◦ 事前学習モデルを利用する今の時代のニーズに合っていなかった • 取り組んだ解決策 ◦

    Cython, C++ でライブラリを実装し、解析速度を検証 ▪ しかし、文字数分タグ付けを行う BLSTMs では根本的に計算時間がかかる ▪ ラティスベースの解析器(MeCab, SudachiPy など)には、到底敵わず 33
  34. 精度至上主義 • NAIST時代の研究の延長上でライブラリ開発 ◦ 研究内容をライブラリにしようとする思いが強かった ◦ 当時(2017~2018年)、BLSTMs を使うことが目的となっていた ◦ やはり、実利用を最優先にライブラリ開発を行うべきだった

    ▪ 解析速度や品詞タグなど、形態素解析器として実利用に耐える 条件を満たしつつ、オリジナリティを追加すべきだった • 新規性と実用性のトレードオフ ◦ しかし、新規性を取り入れつつ(または精度向上を実現しつつ)、 MeCab 並の実用性を実現するのは難しい ◦ もし実用性が不十分であれば、それ以上のライブラリを利用する メリットが必要であった ▪ nagisa はこの部分が弱かった 34
  35. (余談)SentencePiece の実装を参考にする • 解析速度向上のため、SentencePiece の実装のコツを探ってみる ◦ 本体は C++ で実装、Python ライブラリは

    Swig でラッパーを作成 ◦ C++ の文字列操作では、Abseil(Google製 C++ライブラリ) を利用 ◦ esaxx, darts_clone を利用 ▪ esaxx(極大部分文字列抽出ライブラリ) で学習コーパスの部分文字列取得 ▪ darts_clone (ダブル配列ライブラリ)で共通接頭辞検索 • ソースコードから学べることはある ◦ MeCab の存在があってからこその SentencePiece だと気づき感動 ◦ SentencePiece は、形態素解析器に必要な実装が盛りだくさん 35
  36. 品詞タグの小・中分類情報の追加 • nagisa の品詞タグ付け処理は大分類のみ ◦ 単語をフィルタリングする場合、大分類だけでは不十分なことがある • 取り組んだ解決策 ◦ 小分類、中分類の品詞タグ付けを行う

    BLSTMs モデルを作成し検証 ▪ しかし、その分処理時間がかかり、更に解析速度が低下する ▪ モデルの読み込み時間がかかり、ライブラリインポート時の速度が低下 36
  37. Wheel の管理不足 • 深層学習ライブラリ dynet の開発が停止 ◦ Python 3.9 以降の

    Wheel (コンパイル済みパッケージ) が提供されず ◦ Python 3.9 以降では、インストール時に dynet のビルドが必要となり、 ほとんどの環境でインストールエラーとなっていた ◦ 現状、Windows で dynet のビルドができず、Wheel が作成できない • 取り組んだ解決策 ◦ dynet をフォークし、Python 3.9 以降ではフォーク版の Wheel を利用 ◦ GitHub Actions と cibuildwheel を利用して、Wheel の作成を半自動化 (Linux, macOS) 37
  38. まとめ:改善すべきだったこと • 結論、開発者ファーストの徹底不足 ◦ 形態素解析器として実利用に耐える条件(速度、品詞タグなど)を 第一に満たすべきだった ◦ あらゆる開発者が利用できるように、 Linux, macOS,

    Windows の Wheel を全て提供すべきだった ◦ PyTorch 版のライブラリの作成するなど、 ひとつのライブラリに依存しない工夫も必要だった 38
  39. 開発者に利用される ライブラリの分析結果

  40. どのようなライブラリが利用されているか調査 • 日本語の言語処理に特化した Python ライブラリを調査(31件) ◦ 形態素解析器、依存構造解析器、文字列正規化ライブラリなど ◦ GitHub のスター数と

    pip install の数を基準とし比較 40
  41. 比較対象ライブラリ一覧 • 形態素解析 ◦ SudachiPy ◦ Janome ◦ mecab-python3 ◦

    fugashi ◦ nagisa ◦ pyknp ◦ kytea ◦ konoha • 依存構造解析 ◦ ginza ◦ unidic2ud ◦ camphr ◦ suparunidic ◦ depccg 41 • 文字列変換 ◦ pykakasi ◦ cutlet • 文字列正規化 ◦ neologdn ◦ jaconv ◦ mojimoji • 文分割 ◦ bunkai ◦ japanese-sent ence-breaker • その他 ◦ oseti ◦ manga-ocr ◦ mokuro ◦ namedivider-python ◦ asa ◦ toiro ◦ ja-timex ◦ daaja ◦ pysummarization ◦ sudachitra
  42. インストールの総数(2022/06/08 時点) • X軸:GitHub のスター数、Y軸:pip install の総数 • ダウンロード数 7,627,542

    件で、jaconv が一位👑 • 形態素解析器、文字列正規化ライブラリが上位を占める 42
  43. インストールのトレンド(2022/06/01~06/08) • X軸:GitHub のスター数、Y軸:pip install の数(週間) • ダウンロード数 94,064 件で、SudachiPy

    が一位👑 • こちらも形態素解析器、文字列正規化ライブラリが上位を占める 43
  44. SudachiPy が利用される理由 • Rust による高速化 ◦ Python 実装(バージョン 0.5.*)の解析速度問題を Rust

    で解決 • chiTra(Sudachi Transformers)の存在 ◦ Transformers を簡単に使える環境を提供していることは強い • 複数の分割単位の併用、企業による辞書更新 ◦ 必要に応じて単語の分割基準を切り替えることができるのは便利 • spaCy に搭載されている安心感 ◦ 巨大なエコシステムに一部であることは強い 44
  45. 今は Rust の時代?VAporetto の登場 • SudachiPy だけではない、高速な単語分割器 VAporetto の登場 ◦

    Rust 実装で、速度の高みを目指した日本語トークナイザ ◦ 今後、どのように開発者に利用されていくか注目 • 参考資料 ◦ Vaporetto: 点予測法に基づく高速な日本語トークナイザ ◦ 速度の高みを目指す:高速な単語分割器 Vaporetto の技術解説 ◦ VAporetto: POintwise pREdicTion based TOkenizer 45
  46. まとめ:開発者に利用されるライブラリ • 日本語の言語処理に特化した Python ライブラリでは、 形態素解析器、文字列正規化ライブラリが利用の上位を占める ◦ その他のライブラリ(依存構造解析器など)は、そもそも利用する ユーザーの母数が少ない? ◦

    前処理に必要となる機能を持つライブラリは多くの開発者に利用される • 利用していてストレスがないライブラリ ◦ 上位のライブラリは、インストールエラーがなく問題なく利用できる ◦ ドキュメントも整備されており、継続的にメンテナンスもされている ◦ やはり、実利用に耐える性能を持っている 46
  47. おわりに • ソフトウェアを開発者に利用してもらうために必要だと考えること ◦ 開発者ファーストの徹底 ▪ まずはライブラリの実利用に耐える条件を満たそう ▪ その後にオリジナリティを追加しよう ◦

    PyCon JP への参加(ユーザーを増やす工夫) ▪ 学会ほど堅苦しくないし、個人開発者を歓迎してもらえる ▪ フィードバックをもらえる ◦ ユーザーを大切にしよう ▪ コードも慎重に書くようになる ▪ ユーザーがいると、GitHub などの検索の上位になり、更にユーザーが増える ▪ 開発のモチベーションを保つことができる 47