📖

ShareGPT データセットを日本語翻訳したいメモ(現状: 事前調査)

2023/04/27に公開

背景

LLM 向け chat 用日本語データセット用意したい...
既存の英語のデータセットを NLLB あたりで自動翻訳してデータセットつくるでどうか!

ShareGPT があった!

情報

huggingface にはいくつか sharegpt データセットの repo があるのですが, 大元のは削除されているようです. とりあえずは「はーと」が多い repo を使うようにしてみます.

https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered

Vicuna 用(?)の形式になった json データを見てみます.

  • ShareGPT_V3_unfiltered_cleaned_split.json
  • ShareGPT_V3_unfiltered_cleaned_split_no_imsorry.json

の二つです. 用途に応じて選択しましょう.

形式

https://github.com/lm-sys/FastChat/blob/main/playground/data/dummy.json

[
  {
    "id": "identity_0",
    "conversations": [
      {
        "from": "human",
        "value": "Who are you?"
      },
      {
        "from": "gpt",
        "value": "I am Vicuna, a language model trained by researchers from Large Model Systems Organization (LMSYS)."
      },
      {
        "from": "human",
        "value": "What can you do?"
      },
      {
        "from": "gpt",
        "value": "I can chat with you."
      }
    ]
  },

value の中身を翻訳すればいいことがわかります.

ちなみにソースコードなどの場合やテキスト罫線, 数値データなどもありました.

That\u2019s why we created the \u201890-Day Brave Wrk Transformation.\u2019 Think of this as a 90 day book camp to get you in optimal shape in every area of your life and business!\n\nYOU WILL:

また, \u2019 などエスケープされた UTF-8 文字もあります.

        "from": "human",
        "value": "\uc704 \ub0b4\uc6a9\uc744 \ud55c\uad6d\uc5b4\ub85c \ubc88\uc5ed\ud574\uc11c \ubcf4\uc5ec\uc918"
      },
      {
        "from": "gpt",
        "value": "\ub124! \uc5ec\uae30 2023\ub144 \uc0c1\ubc18\uae30\uc5d0 \uc2dc\uc7a5 \ubc0f \ud310\ub9e4\uc790 \ud655\uc7a5\uc744 \uc704\ud55c \ub85c\ub4dc\ub9f5\uc758 \ud14c\uc774\ube14\uc785\ub2c8\ub2e4:\n\n| \uc804\ub7b5\uc801 \ubc29\ud5a5 | \uc561\uc158 \uc544\uc774\ud15c | 1\uc6d4 | 2\uc6d4 | 3\uc6d4 | 4\uc6d4 | 5\uc6d4 | 6\uc6d4 |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| \ub9c8\ucf13\ud50c\ub808\uc774\uc2a4 \ud655\uc7a5 | \ub300\uc0c1 \uc2dc\uc7a5 \ubd84\uc11d | \u2611\ufe0f | \u2611\ufe0f |  |  |  |  |\n|  | \uc7a0\uc7ac\uc801\uc778 \ub9c8\ucf13\ud50c\ub808\uc774\uc2a4 \ubc0f \uc694\uad6c\uc0ac\ud56d \ud655\uc778 |  | \u2611\ufe0f | \u2611\ufe0f |  |  |  |\n|  | \uc7a0\uc7ac\uc801\uc778 \ub9c8\ucf13\ud50c\ub808\uc774\uc2a4\uc640 \uc5f0\uacc4 \uad6c\ucd95 |  |  | \u2611\ufe0f | \u2611\ufe0f |  |  |\n|  | Cafe24 \ud50c\ub7ab\ud3fc\uc5d0 \uc0c8\ub85c\uc6b4 \ub9c8\ucf13\ud50c\ub808\uc774\uc2a4 \ub4f1\ub85d |  |  |  | \u2611\ufe0f | \u2611\ufe0f |  |\n| \ud310\ub9e4\uc790 \ud655\ubcf4 | \ud310\ub9e4\uc790 \uc694\uad6c\uc0ac\ud56d \ubc0f \uc120\ud638\ub3c4 \uc870\uc0ac | \u2611\ufe0f | \u2611\ufe0f |  |  |  |  |\n|  | \ub300\uc0c1 \ub9c8\ucf00\ud305 \ucea0\ud398\uc778 \uac1c\ubc1c |  |  | \u2611\ufe0f | \u2611\ufe0f | \u2611\ufe0f |  |\n|  | \ud310\ub9e4\uc790 \ucd94\ucc9c \uc81c\ub3c4 \ud655\uc7a5 |  |  |  |  | \u2611\ufe0f | \u2611\ufe0f |\n|  | \uc2e0\uaddc \ud310\ub9e4\uc790 \uc6d0\ud65c\ud55c \ub4f1\ub85d \ud504\ub85c\uc138\uc2a4 \uac1c\uc120 |  |  |  |  | \u2611\ufe0f | \u2611\ufe0f |\n\n\ucc38\uace0: \uc774 \ud14c\uc774\ube14\uc740 1\uc6d4\ubd80\ud130 6\uc6d4\uae4c\uc9c0\uc758 \ub2ec\uc744 \ubcf4\uc5ec\uc90d\ub2c8\ub2e4. \uac01 \uc561\uc158 \uc544\uc774\ud15c\uc774 \uc218\ud589\ub418\ub294 \uc6d4\uc744 \ub098\ud0c0\ub0b4\ub294 \uccb4\ud06c\ubc15\uc2a4\uac00 \uc788\uc2b5\ub2c8\ub2e4."

とか!

また,

Sure, here's a roadmap for the 'plan' to continue securing key partners in the app store (including companies utilizing AI) for the first half of 2023:\n\n| Strategic Direction | Action Items | January | February | March | April | May | June |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| Secure Key Partners | Identify potential partners | \u2611 | \u2611 |  |  |  |  |\n|  | Contact and pitch to partners |  | \u2611 | \u2611 |  |  |  |\n|  | Negotiate terms and agreements |  |  | \u2611 | \u2611 |  |  |\n|  | Sign partnership agreements |  |  |  | \u2611 | \u2611 | \u2611 |\n|  | Integrate partner apps into Cafe24's platform |  |  |  |  | \u2611 | \u2611 |\n\nNote: The roadmap is just an example and the specific action items and timeline may vary depending on the company's strategies and goals.

のような入力を翻訳すると,

もちろん,2023年上半期にApp Storeで重要なパートナー (AIを利用する企業を含む) を確保し続ける"計画"のロードマップは以下の通りです. 戦略的方向性 行動項目 1月 2月 3月 4月 5月 6月 鍵となるパートナーを確保 潜在的なパートナーを特定 条件と契約を交渉し 提携契約に署名 特定の項目と時間軸はCafe24のプラットフォームにパートナーアプリを統合する 会社の戦略と目標によって異なります.

となります. 罫線情報やエスケープされた文字(改行, UTF code)は無視されてしまいましたので,

  • 前処理でテキスト(sentence)だけ抜く
  • 日本語訳

というステップがいることがわかりました.
また, 罫線(テキストテーブル)は日本語にするとずれてしまうので, それの対応もいるでしょう
(python あたりでええ感じに罫線フォーマット(Markdown?)整えてくれるのあったようななかったような?)

あと, the app storeApp Store に翻訳されちゃいましたネ.

ソースコードの場合は

You can use the `String.format()` method in Java to replace placeholders in a string with values from a map. Here's an example code snippet that demonstrates how you can achieve this:\n```java\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class StringReplaceExample {\n    public static void main(String[] args) {\n        String input = \"This is a new {object} at {place}\";\n        Map<String, String> replacements = new HashMap<>();\n        replacements.put(\"object\", \"student\");\n        replacements.put(\"place\", \"point 3, 4\");\n\n        String output = replacePlaceholders(input, replacements);\n        System.out.println(output);\n    }\n\n    public static String replacePlaceholders(String input, Map<String, String> replacements) {\n        for (Map.Entry<String, String> entry : replacements.entrySet()) {\n            String placeholder = \"{\" + entry.getKey() + \"}\";\n            String replacement = entry.getValue();\n            input = input.replace(placeholder, replacement);\n        }\n        return input;\n    }\n}\n```\nIn this example, we define the input string as \"This is a new {object} at {place}\", and create a `HashMap` called `replacements` that maps the placeholders \"object\" and \"place\" to their corresponding values \"student\" and \"point 3, 4\". We then pass these values to the `replacePlaceholders()` method, which iterates over the entries in the `replacements` map and replaces each placeholder in the input string with its corresponding value using the `replace()` method. Finally, the `replacePlaceholders()` method returns the modified string, which is printed to the console.\n\nThe output of this program will be:\n```csharp\nThis is a new student at point 3, 4\n```\nNote that you can modify the `replacements` map to include additional placeholders and their corresponding values, and the `replacePlaceholders()` method will automatically replace them in the input string.

と triple quote でエスケープされているので判定しやすいでしょうか.

Markdown?

Python の markdown

https://pypi.org/project/Markdown/

では html に変換で, markdown に再度戻すというのができない(or めんどそう)なので,

https://qiita.com/nanbuwks/items/781f144a3a85d4fdef05

JavaScript の remark 使うのがいいかもしれません.

https://www.kwbtblog.com/entry/2023/02/25/192520

ShareGPT raw を変換?

ただ, Markdown をパースしてはめんどそうなことがわかりました.
ShareGPT は元データ sharegpt-raw は html(?) で, ある程度自前で markdown に変換していましたので,

https://huggingface.co/datasets/philschmid/sharegpt-raw

sharegpt-raw で,

  • html -> 日本語訳してから Markdown

がよさそうです!

翻訳エンジン

https://twitter.com/syoyo/status/1655277443081711616?s=20

ChatGPT(GPT-3.5)も Google 翻訳程度でした.
ChatGPT もあんまり翻訳性能よくないね...

高品位狙うなら現状は NLLB-Moe 54B 一択そうです!

一文ごと or 特定の token 数に収めたい

ML 系(Transformer 系)の翻訳モデルですと, token 数に制限があります.

https://zenn.dev/ttya16/articles/6d3bf5e4c86f94a1ae20

https://huggingface.co/facebook/nllb-moe-54b/blob/main/config.json

NLLB-Moe-54B は max_position_embeddings 1024 ですが, max_length=200(max_length はちょい古いパラメータ)で, generation も

https://huggingface.co/facebook/nllb-moe-54b/blob/main/generation_config.json

max_new_tokens=200 とあります.
どこかで, NLLB では 256 tokens 以上はうまく翻訳できない(repeat が出やすい), みたいなのを見たので, いずれにせよ 200 tokens に収めるのがよいでしょう.

https://platform.openai.com/tokenizer

で,

VEX uses the VEXcode framework, which enables users to start coding quickly and easily. VEXcode can be written in Blocks, Python, or C++.  A VSCode extension can be found in the marketplace to assist students with coding.

は 52 tokens(221 chars)

日本語の場合は, 文字単位になやりやすいです.

VEXは,ユーザーが迅速かつ簡単にコーディングを開始できるようにするVEXcodeフレームワークを使用している. VEXcodeはBlocks,Python,またはC++
で記述できる. VSCode拡張機能は,学生のコーディングを支援するためにマーケットプレイスで見つけることができる.

で 144 tokens(144 chars)

英語の場合, 平均 4 chars で 1 word, 翻訳された日本語が英語の 1/2 chars 程度とすると,
入力の英語は 200 ~ 300 chars(50 ~ 75 words)に収めるのが安全でしょう.

入力テキストから, まずは文ごとに区切りたいですね.

文に区切ってくれたり, なるべく文脈を保って特定の word 数に区切ってくれる LLM モデルがあるかもしれませんが,
とりあえずぺろっと文ごとに区切りたい場合は nltk の sent_tokenizer がよいでしょうか.

https://stackoverflow.com/questions/4576077/how-can-i-split-a-text-into-sentences

T.B.W.

現状のまとめ

  • sharegpt-raw をいじり, 文章部分を翻訳
  • Markdown 形式に出力.

でしょうか.

T.B.C.

W.I.P.

git lfs をセットアップしておきます.

$ git lfs install

sharegpt-raw を clone します.

$  https://huggingface.co/datasets/jeffwan/sharegpt_vicuna

とりあえずは merge & html 状態の json つくります.

$ python merge.py sharegpt_90k_raw_dataset/sg_90k_part1.json sharegpt_90k_raw_dataset/sg_90k_part2.json  sharegpt_20230401_html_unformatted.jso
$ python pretty_json.py --in sharegpt_20230401_html_unformatted.json --out sharegpt_20230401_html.json

言語判定

いくつかやり方あるでしょう. 有名(?)なのは fastText でしょうか.

https://medium.com/@c.chaitanya/language-identification-in-python-using-fasttext-60359dc30ed0

2016 年からあるようなので, あまりナウでないためか, fastText はソースコードからのビルドが必要です.

FastChat(vicuna)では polyglot を使っていました.

https://github.com/lm-sys/FastChat/blob/main/fastchat/data/optional_clean.py

https://github.com/aboSamoor/polyglot

ただ, pypi build が 2016 年で止まっています.

sharegpt のツールでは, 英語かどうかの判定に langdetect を使っていました.

https://pypi.org/project/langdetect/

今回は langdetect 使って英語だけ抽出します.

huggingface を漁るといくつか bert ベースの言語判定 Model が見つかりますので,
多言語で言語判定したい場合は, 処理時間はかかるでしょうが,

https://www.nlplanet.org/course-practical-nlp/02-practical-nlp-first-tasks/09-language-detection.html

https://huggingface.co/papluca/xlm-roberta-base-language-detection

がよさそうでしょうか(weight size は 1GB くらいです). ただ, 言語数は 20 なので, より言語欲しい場合は

https://huggingface.co/jb2k/bert-base-multilingual-cased-language-detection

あたりがよいでしょうか.

cleaning

ShareGPT データセット 90k で, 英語の会話を抽出, 望まない(unwanted)会話の除去の clean 処理はおおむね 20 分ほどかかりました.

https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered/blob/main/optional_clean.py

を周到しました.

html から文字の抜き出しと差し替え

sharegpt_vicuna のように, bs4(BeautifulSoup)を使います!

ShareGPT の場合, bullet item が <li> とかであったり, テーブル表が table タグであったりして, それぞれの html tag の text を翻訳する必要があります.

やりたいことは, html タグのそれぞれの文字(p, div, table, ... など事前には tag はわからないが, その中身のテキストを抜き出して翻訳して差し替えしたい, です.

https://stackoverflow.com/questions/15056633/python-find-text-using-beautifulsoup-then-replace-in-original-soup-variable

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#bs4.NavigableString

findAll(text=True) でリストアップし, replace_with で行けました(ただ, inplace 置換はできない)

入力は html タグがきちんとされているとします.

from bs4 import BeautifulSoup

text="<div><p>To initiate a service mesh with mutual TLS (MTLS) with Istio, you can follow these steps: ..."

p = BeautifulSoup(text, "html.parser")
fs = p.findAll(text=True)

for item in fs:
    en_text = item.text # item.string でもよいと思われる
    ja_text = translate(en_text) # 適当な置換関数
    item.replace_with(ja_text)

replace_with で入れ替えしたら, item 自体を print しても中身は変わっていないのですが, 元の 元の BeautifulSoup オブジェクトには反映されています.

print(p)

<div><p>相互 TLS(MTLS) でサービスメッシュに...

バッチ翻訳?

テキストを毎度 NLLB 54B にかけるとめちゃ遅いので, テーブル cell item などの単語数が少ないものは, NLLB 3.3B など処理が軽い翻訳エンジン使うのがよいでしょう.

また, バッチで翻訳する手もありますが, 最大単語長(token 長)で tensor 作って処理することになるため(のはず), 短文長文が混じっていると効率が落ちます.
なるべく同じ長さの文を集めてバッチ翻訳するのがよいでしょう

センテンス(文)の抽出

GiNZA入門 (1) - 事始め
https://note.com/npaka/n/n5c3e4ca67956

LLM 神である npaka 先生のお告げ, ありがたや...

spaCyとGiNZAを使った日本語自然言語処理
https://qiita.com/wf-yamaday/items/3ffdcc15a5878b279d61

日本語では ja-ginza 辞書を使います!

spaCyで英語の文をトークナイズする方法を丁寧に
https://gotutiyan.hatenablog.com/entry/2020/09/26/192750

今回は精度を求めたいので, 英語では en_core_web_trf を使います.

https://spacy.io/models

$ python -m spacy download en_core_web_trf

でダウンロードしておきます.
(460 MB くらいと結構あります)

語尾の統一

こちらも, LLM 神である npaka 先生の記事を参考にさせていただきます!

Google Colab で SudachiPy による会話文の人称と語尾の設定を試す
https://note.com/npaka/n/neb129af1f1d7

GiNZA に SudachiPy が使われているので, pip インストールでは ginza だけでいいかもしれません.

VEXは,ユーザが迅速かつ簡単にコーディングを開始できるようにするVEXcodeフレームワークを使用している.VEXcodeはBlocks,Python,またはC++で記述できる.学生のコーディングを支援するために,VSCode拡張子は市場で見つけることができます.

NLP ライブラリ使って後処理がよいでしょうか. あと, ., ,, など.

(GiNZA(spaCy)でもできるかも?)

T.B.W.

Discussion