NLLB-200 3.3B で日本語翻訳するメモ(moe-54b もあるよ)
LLM で日本語扱いたいけど, ええ感じの日本語特化 LLM まだない...
- 日本語を英語に翻訳して LLM
- 英語の LLM ファインチューンデータセットを日本語訳してファインチューン
でどうか.
翻訳には FuguMT ありますが,
今回は NLLB-200 を使ってみます.
NLLB
fairseq の nllb
branch になっていますので注意ください.
モデルのライセンスは CC-BY-NC 4.0 つまり商用利用はできないです.
(翻訳したものでファインチューンした LLM 作ったら, 元 LLM が商用利用可能だったらファインチューンした LLM 自体は商用利用 OK そうではるが... 要ライセンス確認)
MoE = Mixture of Experts です.
よくわらん... とりま NLLB-moe は全部入りの翻訳モデルってことじゃろかね.
NLLB MoE 54B は元 pth ファイルで 400 GB, (fp16 あたりにしたので?) huggingface に上がっているのでは 250 GB くらいあります.
とりあえずは 3.3B(17 GB) 使います.
(後のほうで 54B CPU 動作のメモもあります)
環境
- CPU: Threadripper + 128 GB CPU mem
- GPU: 3090(24GB)
3.3B のモデルサイズは 17 GB くらいですので, 3090 に収まります.
(実 GPU メモリは 14 GB くらいのようなので, RX6800 や Tesla T4 などの 16 GB GPU mem でも動くかも)
翻訳速度そんなに重要でなければ CPU で処理でもよいでしょう. ただ下の GPT-4 紹介文だと翻訳に数分かかります. GPU 使っても数十秒(powerlimit 3090 で 23 秒)はかかります.
入力の言語自動判定をやめるといくらか速くなるかもはしれません.
日本語
日本語の language code は jpn_Jpan
です. 英語は eng_Latn
とりま CPU で動かします!
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("facebook/nllb-200-3.3B")
model = AutoModelForSeq2SeqLM.from_pretrained("facebook/nllb-200-3.3B")
article = "UN Chief says there is no military solution in Syria"
inputs = tokenizer(article, return_tensors="pt")
translated_tokens = model.generate(
**inputs, forced_bos_token_id=tokenizer.lang_code_to_id["jpn_Jpan"], max_length=30
)
ret = tokenizer.batch_decode(translated_tokens, skip_special_tokens=True)[0]
print(ret)
シリアに軍事的解決はないと国連総長
Cool!
GPT-4 説明を翻訳してみます!
We’ve created GPT-4, the latest milestone in OpenAI’s effort in scaling up deep learning. GPT-4 is a large multimodal model (accepting image and text inputs, emitting text outputs) that, while less capable than humans in many real-world scenarios, exhibits human-level performance on various professional and academic benchmarks. For example, it passes a simulated bar exam with a score around the top 10% of test takers; in contrast, GPT-3.5’s score was around the bottom 10%. We’ve spent 6 months iteratively aligning GPT-4 using lessons from our adversarial testing program as well as ChatGPT, resulting in our best-ever results (though far from perfect) on factuality, steerability, and refusing to go outside of guardrails.
OpenAIのディープラーニングを拡大する取り組みの最新マイルストーンであるGPT-4を作成しました.GPT-4は,多くの現実世界のシナリオで人
間よりも能力が低いが,さまざまな専門的および学術的ベンチマークで人間レベルのパフォーマンスを発揮する大規模なマルチモダルモデル (画像とテキストの入力を受け,テキストの出力) です.例えば,試験受験者の上位10%のスコアでシミュレートされたバー試験に合格します.対照的に,GPT-3.5のスコアは下位10%のスコアでした.我々は6ヶ月間,対抗テストプログラムやChatGPTのレッスンを用いてGPT-4を繰り返し調整し,事実性と制御性,そしてガードレールの外に出ることを拒否する上でこれまでで最も優れた結果 (完璧とは程遠いもの) を得ました.
はわわ... 良き良きっぽ!
ずんだもん構文ためします!
ずんだもんは東北に住む活発でかわいい女の子です。
あなた「きみの名前は?」
ずんだもん「ボクの名前はずんだもんなのだ。」
あなた「今日の天気は?」
ずんだもん「ボクは今日の天気は晴れだと思うのだ」
あなた「今日は何時に起きたの?」
ずんだもん「ボクは7時に起きたのだ」
あなた「年齢は?」
ずんだもん「ボクの年齢は秘密なのだ」
あなた「朝ごはんは何食べたい?」
ずんだもん「ボクはおにぎり食べたいのだ」
あなた「昼ごはんは何食べたい?」
ずんだもん「
"I'm a very active and beautiful girl living in the East". "What's your name?" "I'm supposed to be a pretty girl". "What time did you wake up today?" "I woke up at 7 am". "What's your age?" "I'm supposed to be a secret". "What do you want to eat in the morning?" "I'm supposed to be eating in the afternoon". "What do you want to eat in the afternoon?" "I'm supposed to eat in the morning".
ずんだもんが I'm
になりました...
Chat 用途やキャラ設定付けしたい場合ですと, なんらかの prompt engineering が必要そうです!
MoE 54B
weight が 250GB なので頑張れば CPU 256 GB マシンでオンメモリ or huggigfae accelerate or deepspeed あたりで動かせます.
(fairseq の repo, いろいろコードごちゃまぜなので, とりま nllb-moe pth ファイル使って翻訳だけ利用したいときどうすればいいのかまったくわからん...)
執筆時点(2023/03/25)では pip で入る transformers (ややこしい名前であるが, transformer 系の ML をぺろっと使えるようにするやつ. ただいろいろな ML モデルサポートしすぎてコードは肥大化していってつらっぽ) で動かそうとすると, nllb_moe
key error などでエラーになります.
2023/03/31 時点の transformers git 版で nllb-moe 対応されたので, 動作すると思われます.
そのうち pip で入る transformers のバージョンでも動くでしょう.
とりま 256 GB CPU mem な x299(Skylake-X) マシンで動かしました.
MiB Mem : 257433.3 total, 5389.2 free, 214775.1 used, 37269.0 buff/cache
MiB Swap: 2048.0 total, 1050.7 free, 997.3 used. 40392.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
450952 syoyo 20 0 212.6g 208.2g 157640 R 288.8 82.8 6:05.33 python
実メモリ消費は 210 GB くらいでした.
load model time(s) 435.39693665504456
250 GB くらいあるので, weight の pytorch 処理 + メモリへのロードだけで 7 分くらいと結構時間かかります...
(今回はそんなに性能のよくない PCI-gen3 NVMe 利用)
メモリに直接展開 + mmap できる形式とかにしたらもうちょっと効率化されるかもです.
example の "UN Chief says there is no military solution in Syria"
を日本語にします!
国連事務総長は,シリアに軍事的解決はないと述べた.
run time(s) 5.595441102981567
お~
ずんだもん構文の英訳試します!
ずんだもんは東北に住む活発でかわいい女の子です. You "君の名は?" ずんだもん "ボクの名前ははずんだもんなのだ". You "今日の天気は?" ずん だもん "ボクは今日の天気は晴れだと思うのだ" You "今日は何時に起きたの?" ずんだもん "ボクは7時に起きたのだ" You "年齢は?" ずんだもん " ボクの年齢は秘密である" You "朝ごはんは何食べたい?" ずんだもん "ボクはおにぎり食べたいのだ" You "昼ごはん
run time(s) 35.11597681045532
ぐぬぬ... なんかうまくいきませんでした.
moe-54b は英語 -> 日本訳に使うか, (本来の用途である?) ファインチューン/distilled 用の元モデルとして使うのがいいかもです.
CPU mem 128 GB で動かす.
最近の民生 PC(Core-i9, Ryzen9)ですと, 32 GB x 4(DDR4(or DDR5))で 128 GB も普通になってきているかと思います.
2023/05 時点では DDR4 であれば 128 GB(32 GB x 2 x 2)が 3 万円ちょっとで調達できます.
(https://eetimes.itmedia.co.jp/ee/articles/2303/29/news057.html メモリ不況は 2023 年末くらいまで続くっぽいので, 2023 年の年末だと DDR5 でも 128 GB 3 万円くらいで調達できるかもしれません)
とりま bfloat16 で動きました!
最初は fp16 を試しましたが, fp16 だと, https://huggingface.co/transformers/v4.7.0/_modules/transformers/models/m2m_100/modeling_m2m_100.html M2M100Encoder などで, LayerNorm が fp16 対応していないエラーが出てうごきませんでした...
(特定のレイヤーだけ fp32 のままにするという手もあるが, 面倒なので諦めました)
bfloat16 の場合,
model = AutoModelForSeq2SeqLM.from_pretrained("facebook/nllb-moe-54b", torch_dtype=torch.bfloat16)
と, torch_dtype=torch.bfloat16
指定するだけです.
メモリ消費は 100 ~ 115 GB ほどでした.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1579808 syoyo 20 0 114.4g 110.9g 148408 R 98.3 88.2 8:04.41 python
model のロード(+ bf16 変換)は 572.8429079055786 secs と 10 分くらいでした.
翻訳処理は
article = """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.
"""
の短めのでも 138.76013445854187 secs(Threadripper 1900X 8 cores) で 2 分ちょい.
さすがに時間かかりますね...
VEXは,ユーザーが迅速かつ簡単にコーディングを開始できるようにするVEXcodeフレームワークを使用している. VEXcodeはBlocks,Python,またはC++
で記述できる. VSCode拡張機能は,学生のコーディングを支援するためにマーケットプレイスで見つけることができる.
翻訳品質はさすがで, fp32 の結果(↓「かしこさ」 section 参照)とほぼ同じ.
処理速度については, ggml などにポートできると, ロードと実行が高速化されそうではあります.
(ggml 化できたら, たぶんロードは数十秒(mmap 使用), 翻訳 20 秒くらいでできそう)
save_pretrained()
で bf16 形式の保存も試しましたが,
処理時間はいくらか減りましたが, 劇的というほどではありませんでした.
また, bf16 で保存した場合でも, from_pretrained
では再度 bf16 指定が必要です.
(torch_dtype
を指定しない場合, 内部では bf16 -> fp32(torch_dtype
のデフォルト) に復元している模様)
CPU 実行で Batch 処理は遅いかも?
を参考に,
inputs = tokenizer(batch_sentences, padding=True, truncation=True, return_tensors="pt")
という感じでバッチで処理させると翻訳処理が速くなるかと思い, させてみましたが, 逆にちょっと遅い感じになった模様?
padding で最も長い入力文に tensor が resize されたためですかね.
かしこさ
openassistant データセットから
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.
を翻訳してみます(元英語は LLM が生成したもので, 翻訳のテストに使うにはやや曖昧な文章な感はあるが)
distilled-1.3B
VEXは,ユーザが迅速かつ簡単にコーディングを開始できるようにする VEXcodeフレームワークを使用しています. VEXcodeは,ブロック, Python,または C++ で記述できます. プログラミングの学生を支援するために,VSCode拡張子はマーケットプレイスで見つけることができます.
3.3B
VEXは,ユーザが迅速かつ簡単にコーディングを開始できるようにするVEXcodeフレームワークを使用しています. VEXcodeは,ブロック, Python,または C++で記述できます. 学生のコーディングを支援するために,市場ではVSCode拡張子が見つかります.
3.3B でも, 機械翻訳感があり微妙なところやね.
MOE-54B
fp32 の結果(スクショ)
VEXは,ユーザーが迅速かつ簡単にコーディングを開始できるようにするVEXcodeフレームワークを使用している. VEXcodeはBlocks,Python,またはC++
で記述できる. VSCode拡張機能は,学生のコーディングを支援するためにマーケットプレイスで見つけることができる.
(↑の bfloat16 の結果)
54b は bfloat16 でも翻訳品質さすがですね.
その他
moe-54b は variant として
がありますが, repo にファイルが足りない(tokenizer.json など)です.
試しに作ったがもうメンテされていない repo っぽい感じです.
128 は翻訳で使える最大トークン数(~= 文字数)と思われます.
まとめ
3.3B であれば GPU で動作可能.
54B は 128 GB mem CPU で動作可能.
(もしくは 8bit 量子化して A100 80 GB, or 3090 x 4 は可能であろう)
翻訳精度は 3.3B は Google 翻訳などの機械翻訳程度であまり品質は高くない.
翻訳で LLM 用日本語データセットつくるなら 54B 一択です.
model 構成
Switch Transformer ベース.
fairseq/modules/transformer_layer.py
が Model 構成とおもうが, 他のモデルと共有させているためか, コード構成がややこしい.
transformers の models/nllb_moe/modeling_nllb_moe.py
のほうが理解しやすいでしょう.
データセット
dataset は以下で構成される.
- Primary Dataset
- public data(翻訳データ). download スクリプトあり. 日本語はない. 25 GB くらい
- NLLB Seed : 日本語はない. 50 MB くらい.
- (mined) BiText
- Backtranslation(逆翻訳)
NLLB Seed: Wikimedia の翻訳をベース.
BiText : Web にある public 翻訳データセット.
https://github.com/facebookresearch/LASER と https://github.com/facebookresearch/stopes で mining(web をクロール?)して翻訳ペアを収集?
というわけで日本語は bitext mining(LASER, stopes) と Backtranslation (他の翻訳ツールか, NLLB 自体を使って?)で考慮するっぽい?
(論文には詳細かかれておらず, データセットもいろいろツール多岐に渡っていて調べるのがめんどい)
bitext mining
CCMatrix https://github.com/facebookresearch/LASER/tree/main/tasks/CCMatrix を参考にして, stopes で収集.
ちなみに, NLLB ではないが, 日英翻訳ペアのデータセット構築と pretrained model.
JParaCrawl のデータセットとそれを使っての学習モデルは商用利用はできないので, 手法を参考にして自前で crawl するのがよいでしょう.
Backtranslation
mined bitext で一度学習して, それに対して backtranslation でさらに bitext をふやして, さらに学習という感じでしょうか.
TODO
- NLLB を, Alpaca などのファインチューン用データセットの日本語翻訳に利用して, 日本語 LLM を極める
-
maxtoken
を自動推定して処理時間を改善する - NLLB のデータセット収集方法をしらべ, 日本語と英語, 日本語と中国語など, 日本語に特化させて学習させたい
Discussion
記事に直接関係がないランダムな質問で申し訳ないですが質問させてください。
"その他"のところに"repo にファイルが足りない(tokenizer.json など)です."と書いてありますがtokenizer.jsonはtokenizer.pyなどがあれば簡単に生成できるものではないのですか?モデル作成者が公開しなければ手に入れられないものなのですか?
(私もあるLLMモデルのtokenizer.jsonを必要としているのですが、そのhugging faceには公開されていませんでしたので。)
(昨日からLLMを触っているので意味不明でしたらすみません。)