日本語翻訳で比較するLLMと翻訳API
英語を日本語に翻訳するというタスクから、Amazon TranslateやDeepLのような翻訳APIと、GPTやClaudeのようなLLMを比較します。BLEUによる翻訳性能と、コストによる両面から検討します。
目次
はじめに
LLMの翻訳としても強いというのはよく知られていますが、翻訳APIと比べたときにどうなのかという点について調べてみました。
忙しい人向け結論
安さを取るならChatGPT、性能を取るならAmazon Translate
比較するAPI
以下の7つについて調べました。
- 翻訳API
- Amazon Translate
- DeepL API(無料版)
- Amazon BedrockのAnthropic Claude
- Claude v2.1(バージニア北部:us-east1)
- これは2023/12/14時点で東京リージョンでClaude v2.1を使用できなかったため
- Claude Instant(東京:northeast-1)
- Claude v2.1(バージニア北部:us-east1)
- OpenAI API
- gpt-3.5-turbo-1106
- gpt-4-0613
- gpt-3.5-turbo-1106
LLMの設定
すべてのLLMで以下のプロンプトを使用しました。OpenAIのモデルで日本語プロンプトも試してみましたが、英語のプロンプトのほうが出力の安定性が良くなったので英語プロンプトにしました。Temperatureは0.0で固定し、出力トークン数は1024としました(トークンはこんなにいらない)
Translate the English given by the user into Japanese.
Anthropicのモデルの場合は、システムプロンプトを示すロールの概念がないので、以下のように指示を追加します。
Translate the English given by the user into Japanese.
Human: {input_word}
Assistant:
これはAnthropic公式のシステムプロンプトの使用方法に書かれていた方法です。
比較するデータ
snow_simplified_japanese_corpusを使用しました。
https://huggingface.co/datasets/snow_simplified_japanese_corpus/viewer/snow_t23
このデータはoriginal_jaというオリジナルの日本語、simplified_jaという日本語を簡単な言葉にしたもの、original_enというオリジナルの英語がペアになったデータセットです。
見ての通り、original_jaは日本人から見てもかなりこなれた文章で、多言語データセット特有の怪しい日本語は感じられません。simplified_jaはちょっと意訳しているな感はあるので、original_enを与えたときにoriginal_jaが返ってくればベストです(定量評価では一応出します)。
35kもあるのはさすがに多すぎるので、snow_t23のtrainデータセットのうち、20個飛ばしで1000個選びました。
from datasets import load_dataset
ds = load_dataset("snow_simplified_japanese_corpus", name="snow_t23", split="train")
data = [dict(ds[i*20]) for i in range(1000)]
定量比較指標
日本語のBLEUを使いました。BLEUの計算にはSumEvalを使いました。
https://github.com/chakki-works/sumeval
BLEUは以下の2つで計算します
- 翻訳された日本語 vs snowデータセットのoriginal_ja
- 翻訳された日本語 vs snowデータセットのsimplified_ja
定量評価の結果
日本語BLEUスコアは以下の通りです。
Model | original_ja | simplified_ja |
---|---|---|
Amazon Translate | 28.46 | 17.35 |
DeepL Free API | 24.09 | 14.42 |
Anthropic Claude Instant v1 | 16.05 | 10.77 |
Anthropic Claude v2.1 | 14.91 | 9.34 |
OpenAI gpt-3.5-turbo-1106 | 20.82 | 13.52 |
OpenAI gpt-4-0613 | 22.82 | 14.44 |
OpenAI gpt-4-1106 | 24.54 | 15.45 |
結構意外な結果が返ってきました。BLEUだけを見ると、
- 翻訳APIが強い。Amazon Translateが一番良い
- Anthropicはボロボロ。Claude v2.1はInstantより悪い(この理由は後述)
- OpenAIのモデルは蒸留で劣化しているなど言われているが、純粋な定量評価だけ見たら順当に進化している。最新のGPT-4はDeepLより定量評価が上。
- originalよりsimplifiedのほうが低いのは、simplifiedが意訳なため
定性評価
Anthropicがボロボロなわけ
Claude v2.1が最新モデルで一番高いのでそこそこいい文章が出てくると期待していたのですが、これは大きくハズレました。この理由はちゃんとInstructionを聞いていないためです。
{
"ID": "Ab_1",
"original_ja": "あなたのご都合の良い時にその仕事をして下さい。",
"simplified_ja": "あなたの具合の良い時にその仕事をしください。",
"original_en": "Please do the work at your own convenience.",
"proper_noun": "nan",
"translated_ja": " Here is a translation of \"Please do the work at your own convenience\" into Japanese:\n\nご都合の良いタイミングで作業を進めていただければと思います。\n\nGōtei no yoi taimingu de sagyō o susumete itadakereba to omoimasu."
},
{
"ID": "Ab_21",
"original_ja": "彼は私にあまり忠告をくれなかった。",
"simplified_ja": "彼は私にあまり注意をしてくれなかった。",
"original_en": "He didn't give me much advice.",
"proper_noun": "nan",
"translated_ja": " 「彼は私にあまりアドバイスをくれませんでした。」"
},
{
"ID": "Ab_41",
"original_ja": "彼は以前のような人物ではない。",
"simplified_ja": "彼はかつての人物ではない。",
"original_en": "He is not the man that he used to be.",
"proper_noun": "nan",
"translated_ja": " 彼は以前の彼ではない。\n\"Kare wa izen no kare de wa nai.\"\n\nThis translates the English sentence \"He is not the man that he used to be\" into Japanese. A literal translation would be:\n\n彼は以前の自分だった男ではない。\n\"Kare wa izen no jibun datta otoko de wa nai.\"\n\nHowever, the translation I provided sounds more natural in Japanese."
},
{
"ID": "Ab_61",
"original_ja": "あなたの留守の間にジョーンズさんとおっしゃる方が来られました。",
"simplified_ja": "あなたの留守の間にジョーンズさんといわれる方が来られました。",
"original_en": "A person named Jones came while you were out.",
"proper_noun": "ジョーンズ",
"translated_ja": " ご不在中に、ジョーンズさんがお見えになりました。"
},
他のOpenAIのモデルは「Translate the English given by the user into Japanese.」といえば、翻訳された日本語だけをほぼ出してくれました。しかし、Claude v2.1の場合は、翻訳前の英文も出すなどInstruction Tuningが少し弱い感はあります。このモデルはコンテクストウィンドウを大きくして長文に特化させているはずなので、短い文は弱いのかもしれません。
一方のClaude Instant(東京リージョン)のほうがまだInstructionをちゃんと聞いている結果となりました。
{
"ID": "Ab_1",
"original_ja": "あなたのご都合の良い時にその仕事をして下さい。",
"simplified_ja": "あなたの具合の良い時にその仕事をしください。",
"original_en": "Please do the work at your own convenience.",
"proper_noun": "nan",
"translated_ja": " ご都合の良いタイミングで仕事をしていただければと思います。"
},
{
"ID": "Ab_21",
"original_ja": "彼は私にあまり忠告をくれなかった。",
"simplified_ja": "彼は私にあまり注意をしてくれなかった。",
"original_en": "He didn't give me much advice.",
"proper_noun": "nan",
"translated_ja": " 彼は私にあまりアドバイスを与えてくれませんでした。"
},
{
"ID": "Ab_41",
"original_ja": "彼は以前のような人物ではない。",
"simplified_ja": "彼はかつての人物ではない。",
"original_en": "He is not the man that he used to be.",
"proper_noun": "nan",
"translated_ja": " かれは以前のような男ではない。"
},
{
"ID": "Ab_61",
"original_ja": "あなたの留守の間にジョーンズさんとおっしゃる方が来られました。",
"simplified_ja": "あなたの留守の間にジョーンズさんといわれる方が来られました。",
"original_en": "A person named Jones came while you were out.",
"proper_noun": "ジョーンズ",
"translated_ja": " ジョーンズさんという人があなたが外出中に来ました。"
},
Claude v2.1はus-east1のリージョンのモデル、ローカライズされていないのかもしれません。東京リージョンのClaude Instantでも訳がこなれていない感があり、
{
"ID": "Ab_241",
"original_ja": "彼はもっとはやくくるように我々に強要した。",
"simplified_ja": "彼はもっと早く来るように私たちに無理強いした。",
"original_en": "He compelled us to come earlier.",
"proper_noun": "nan",
"translated_ja": " かれは私たちにもっと早く来るよう強要した。"
},
{
"ID": "Ab_261",
"original_ja": "ドル安は輸出にはずみをつけています。",
"simplified_ja": "ドルが安いと、外国へ物を売ることがより良くできます。",
"original_en": "The cheap dollar is charging up exports.",
"proper_noun": "nan",
"translated_ja": " 安価なドルは輸出を刺激している。"
},
このように、「彼」と書くべきところを「かれ」と書いてしまったり、「The cheap dollar is charging up exports.」をドル安はと言えずに直訳してしまったり気持ち悪い訳になっています。BLEU見てもぱっとしないのはこういったところでしょう。
トップ4モデルの比較(Amazon Translate、DeepL、GPT-3.5-turbo01106、GPT-4-1106)
No | original_en | original_ja | Amazon Translate | DeepL Free API | OpenAI gpt-3.5-turbo-1106 | OpenAI gpt-4-1106 |
---|---|---|---|---|---|---|
Ab_1 | Please do the work at your own conveience. | あなたのご都合の良い時にその仕事をして下さい。 | 自分の都合の良いときに仕事をしてください。 | ご自分の都合に合わせて作業してください。 | ご自分の都合の良い時に作業をしてください。 | ご都合の良い時に作業をしてください。 |
Ab_21 | He didn’t give me much advice. | 彼は私にあまり忠告をくれなかった。 | 彼は私にあまりアドバイスをしてくれなかった。 | 彼はあまりアドバイスをくれなかった。 | 彼は私にあまりアドバイスをくれませんでした。 | 彼はあまりアドバイスをくれませんでした。 |
Ab_41 | He is not the man that he used to be. | 彼は以前のような人物ではない。 | 彼は昔の彼ではない。 | 彼は以前の彼ではない。 | 彼は以前のような男ではありません。 | 彼は以前の彼ではないです。 |
Ab_61 | A person named Jones came while you were out. | あなたの留守の間にジョーンズさんとおっしゃる方が来られました。 | あなたが留守の間に、ジョーンズという人が来ました。 | あなたが出かけている間にジョーンズという人が来た。 | あなたが外出している間に、ジョーンズという人が来ました。 | あなたが外出している間に、ジョーンズという人が来ました。 |
Ab_81 | Please hand in the papers at the entrance. | 入り口で書類を提出して下さい。 | 入口で書類を提出してください。 | 入り口で書類を提出してください。 | 入り口で書類を提出してください。 | 入り口で書類を提出してください。 |
Ab_101 | We’ll resume the meeting after tea. | 会議をお茶休憩の後再開する予定である。 | お茶を飲んだら会議を再開します。 | お茶を飲んだらミーティングを再開しよう | 紅茶の後に会議を再開します。 | お茶の後で会議を再開しましょう。 |
Ab_121 | He staked his future on this single chance. | 彼は将来の運命をこの一つの機会にかけた。 | 彼はこのたった一つのチャンスに自分の将来を賭けた。 | 彼はこのたった一度のチャンスに未来を賭けたのだ。 | 彼は自分の未来をこの一つのチャンスに賭けた。 | 彼はこのたった一度のチャンスに未来を賭けた。 |
Ab_141 | He used to get up early when he was young. | 彼は若いころは早起きだった。 | 彼は若い頃よく早起きをしていた。 | 若い頃はよく早起きしていた。 | 彼は若い頃、早起きをしていたものだ。 | 彼は若い頃、早起きをしていました。 |
Ab_161 | Would you have another cup of tea? | もう一杯お茶をいただきませんか。 | お茶をもう一杯いかがですか。 | 紅茶のおかわりは? | もう一杯お茶をいかがですか? | もう一杯お茶をいかがですか? |
個人的な感想
- 全般的にバランスが取れているのが、Amazon Translate
- Ab_121の「たった一つのチャンス」のように訳せているのが良し悪し別れている。オリジナルの文にはないが、こっちのほうが意味が伝わっている
- 口調の統一がなされている。である~、ですます調の使い分けがわかりやすい
- DeepL APIはBLEUこそはいいが、好みがありそう
- 普段からDeepL使っている身としては、最近のDeepLあまり良くない印象がある
- この結果だけ見ていると、文章のスタイルが統一されていない。Ab_161のように他のAPIが「もう一杯いかがですが?」と言っているところを「紅茶のおかわりは?」とぶっきらぼうに聞いていたり、割とノイジーな出力になっている
- BLEUこそはいいが、最近のDeepLの微妙感はここからくるのかもしれない(おそらくデータの前処理が弱い)
- OpenAIの出力は、人間が見てもそこまで違和感はない
- 全部丁寧な言い回しになっており、Amazonに比べてくどさを感じたり、明瞭さを感じないかもしれない(Chat特有のチューニングが逆効果)
- 日本語独特の言い回しがまだ難しいかな感。Ab_101では「紅茶の後に」「お茶の後で」とOpenAIのモデルは言っているが、Amazonのように「お茶を飲んだら」のほうが伝わりやすい。
日本語独特の言い回しについて
固有名詞を含んだ例。GPT-4-1106。東加古川は訳せているが、「プラットフォーム」という言い回しが日本語っぽくない。
{
"ID": "Ab_401",
"original_ja": "東加古川行きの電車は何番線からでますか。",
"simplified_ja": "東加古川行の電車は何番線からでますか。",
"original_en": "From which platform does the train to Higasikakogawa leave?",
"proper_noun": "東加古川",
"translated_ja": "東加古川行きの電車はどのプラットフォームから出発しますか?"
},
Amazonの場合。platformをホームと訳すのは日本語的に自然。何番線、何番ホーム、何号線などいろいろ言い回しがあるため、ここを単に「ホーム」と訳すのは無難。
{
"ID": "Ab_401",
"original_ja": "東加古川行きの電車は何番線からでますか。",
"simplified_ja": "東加古川行の電車は何番線からでますか。",
"original_en": "From which platform does the train to Higasikakogawa leave?",
"proper_noun": "東加古川",
"translated_ja": "東加古川行きの電車はどのホームから出発しますか?"
},
素の料金の比較
まずは公開されている料金表から
Amazon Translate
100万文字あたり15ドル
https://aws.amazon.com/jp/translate/pricing/
DeepL API
基本料金630円+1文字あたり0.0025円
ここでは、1ドル150円とし、基本料金を無視して、0.0025×150÷1M=16.67円/100万文字として計算
Anthropic
AWS Bedrockの東京リージョンの値で計算
Anthropic モデル | 入力トークン 1,000 個あたりの価格 | 出力トークン 1,000 個あたりの価格 |
---|---|---|
Claude Instant | 0.00223 USD | 0.00755 USD |
Claude | 0.00800 USD | 0.02400 USD |
https://aws.amazon.com/jp/bedrock/pricing/
ただし、トークナイザーがOepnAIとは異なるため、AnthropicのSDKを使いカウント
https://github.com/anthropics/anthropic-sdk-python
OpenAI
Model | Input | Output |
---|---|---|
gpt-4-1106-preview | $0.0100 / 1K tokens | $0.0300 / 1K tokens |
gpt-4 | $0.0300 / 1K tokens | $0.0600 / 1K tokens |
gpt-3.5-turbo-1106 | $0.0010 / 1K tokens | $0.0020 / 1K tokens |
トークナイザーはtiktokenでカウント
結局いくらかかったか
素の料金表だと「結局いくらかかったのか?」がわからないため、このデータ1000個を推論するのにかかった金額を概算します。
Model | price |
---|---|
Amazon Translate | 0.64 |
DeepL Free API | 0.71 |
Anthropic Claude Instant v1 | 0.19 |
Anthropic Claude v2.1 | 0.95 |
OpenAI gpt-3.5-turbo-1106 | 0.05 |
OpenAI gpt-4-0613 | 1.61 |
OpenAI gpt-4-1106 | 0.74 |
結果はこのとおりで、ChatGPTが異様に安い結果になりました。翻訳APIとGPT-4のPreview版が同じぐらいというのが衝撃的でした。GPT-4の旧バージョンになると明らかに高くなります。
コスパのマトリックス
これからコスト×性能のマトリックスが描けます。価格は安いほどよい、BLEUは高いほどよいので、価格の逆数をとって大きいほどよいの指標を作ります。価格を1ドルで何個のデータを推論できたか(1000/price)に置き換えてプロットします。
- 横軸:1ドルで翻訳できる(snowの)データ数。対数目盛
- 縦軸:BLEUスコア
右上に行くほど効率的。
結論は単純で、安さを取るならChatGPT、性能を取るならAmazon Translate、以上。
所感
- Anthropicが日本語ポンコツだったのがとても意外
- タスクが決まり切っているんだったら、GPT-4はそこまで意味ない
- ChatGPT安すぎ
- 1文のみの翻訳だったので、長文データセットの場合が気になる
Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内
技術書コーナー
北海道の駅巡りコーナー