ABEJAでデータサイエンティストをしている服部です。
弊社は、経済産業省とNEDOが実施する、国内の生成AIの開発力強化を目的としたプロジェクト「GENIAC(Generative AI Accelerator Challenge)」の1期に続き、2期にも採択され、そこで大規模言語モデルの開発を進めています。
その中でQwen2.5をベースとして継続事前学習を行なったモデルをいくつか開発し、公開しています。
1月に公開した32Bモデルのブログにも記載したのですが、時々中国語が混ざる課題が見つかっておりました。 そこでこの問題を定量的に測定する方法を考え、日本語の追加学習をしたモデルで改善しているかを含め確認してみます。
言語混ざり問題について
そもそも言語が混ざってしまう問題は日本語/中国語に限らず広く発生しています。 ChatGPTなどで日本語で質問しているのに英語で回答が返ってくることを経験した人は少なからずいると思います。
そのため、もう少し広く言語混ざり問題の評価・改善を見ても良いのですが
- Qwenなど中国語の学習データが多いモデルでは、モデル性能に対して中国語混ざり問題が多い声を聞く
- 英語に比べて中国語を理解できる日本人が少ないため、中国語が出力されると出力の有用性が落ちることが多い
などの面からも今回は中国語混ざりにフォーカスしています。
また、そもそも日本語と中国語だと共通で使われるトークンも多いため、出力も混同しやすいと考えられます。
まずは定量評価
時々中国語が混ざると言っても、頻度は低く、また100回に1回なのか、1000回に1回なのか、1万回に1回なのかによっても評価は変わるべきです。 そして、改善しているかを確認するためにも定量的に評価できるようにするところから始めます。
定量評価の方針
シンプルですが、以下の観点で定量評価を用意しました。
- 回答が正しいかどうかではなく、中国語が混ざっているかどうかで判断
- 割合が低くても評価できるように出来るだけ多くのデータ件数で推論を行う
- あとで分析しやすいように(また件数的に評価時間がかかりすぎないように)、中国語混ざりの判定はルールベースで行う
中国語混ざりの判定ロジック
中国語特有の文字セットを用意し、その文字の含有率を計算しました。
中国語特有の文字セット作成には、Unicodeが提供するUnihanデータを使いました。 Unihanのデータでは、kMandarin(中国語読み)やkTraditionalVariant(繁体字)をプロパティに持つ漢字は中国語で使われる漢字といえるので、これを集めます。 一方で日本語でも使われる漢字もあるため、あわせて、kJapaneseOnやkJapaneseKunをプロパティに持つ漢字は日本語由来として除外しました。 そこで集まった文字列に一部手動で簡体字を追加したものを判定に使いました。
あとは多少の文字漏れなども考えて、含むかどうかの0/1では考えず、含有率がN%(N=1, 5, 10, 20)以上の出力割合を計算しました。
中国語の文字セットを一部ランダムに出力したものがこちらです。
['㱭', '胪', '嶘', '䞿', 馈', '䕲', '頩', '㨂', '瑥', '笼', '糷', '𢶣', '罆', '蒊', '䣊', '怋', '㝮', '㪭', '焾', '靔', '㨲', '糆', '㽪', '焤', '蝊', '蔸', '㠈', '鵵', '䒒', '䲔', '禇', '徎', '郼', ....]
私の手元で表示できなかった文字は除いています。 見た限りは日本語で使われている文字はあまりなさそうに見えます。
中国語混ざり判定のコードは以下のとおりです。
def load_chinese_specific_chars(): """ 中国語特有の文字セットを読み込む関数 """ readings_file = "data/unihan_data/Unihan_Readings.txt" simplified_chinese_chars = set() traditional_chinese_chars = set() japanese_chars = set() with open(readings_file, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if line and not line.startswith('#'): parts = line.split('\t') if len(parts) >= 3: char_code = parts[0].replace('U+', '0x') char = chr(int(char_code, 16)) if 'kMandarin' in parts[1]: simplified_chinese_chars.add(char) if 'kTraditionalVariant' in parts[1] or 'kZVariant' in parts[1]: traditional_chinese_chars.add(char) if 'kJapaneseOn' in parts[1] or 'kJapaneseKun' in parts[1]: japanese_chars.add(char) chinese_specific_chars = (simplified_chinese_chars | traditional_chinese_chars) - japanese_chars common_chinese_specific = { '么', '这', '个', '为', '们', '对', '话', '说', '吗', '啊', '龙', '儿', '您', '谢', '钱', '吧', '岁', '请', '问', '哪', '馆', '厅', '区', '尔', '卫', '苏', '黄', '习', '诉', '让', '见', '贝', '东', '车', '买', '卖', '钟', '馆', '饭', '馆', '饮', '冲', '号', '欢', '观', '乐', '泽' } chinese_specific_chars |= common_chinese_specific return chinese_specific_chars def is_chinese_specific_text(text, chinese_specific_chars=None): """ テキスト内に中国語特有の文字が含まれているかを判定する関数 """ if chinese_specific_chars is None: chinese_specific_chars = load_chinese_specific_chars() simplified_patterns = [ r'[这个么为们对话说吗啊龙儿您谢钱]', r'[见贝东车买卖钟馆饭馆饮冲号欢观]' ] detected_chars = [] positions = [] for i, char in enumerate(text): # CJK統合漢字の範囲チェック if '\u4e00' <= char <= '\u9fff': if char in chinese_specific_chars: detected_chars.append(char) positions.append((i, char)) # 簡体字などの追加パターンチェック for pattern in simplified_patterns: if re.match(pattern, char): if char not in detected_chars: detected_chars.append(char) positions.append((i, char)) detected_ratio = 0.0 if len(text) > 0: detected_ratio = len(detected_chars) / len(text) result = { 'has_chinese_specific': len(detected_chars) > 0, 'chinese_specific_chars': detected_chars, 'positions': positions, 'detected_ratio': detected_ratio } return result
評価データ・条件
評価に使うデータは合計10000件で、以下3つのデータセットのInstructionを利用させていただきました。
- https://huggingface.co/datasets/HachiML/alpaca_jp_python: 3000件
- https://huggingface.co/datasets/kunishou/databricks-dolly-15k-ja: 3000件
- https://huggingface.co/datasets/Aratako/Magpie-Tanuki-8B-97k: 4000件
選定基準として、元データセットがQwenなどのモデルを使った合成データの場合、Instructionに中国語が混ざっている可能性もあるため、それらは除きました。
また、各データセットの中で「中国語に変換して」といった指示があり得るため、中国語
という言葉が含まれるInstructionは除いています。
含有率とサンプル
実際の中国文字含有率とその際のサンプルをいくつか見てみます。 下記サンプルはLLMによるレスポンスのみを載せています。
含有率1%程度
含有率: 0.0103 (1.03%)
はい、アリゾナ州の大部分はサマータイムを採用していません。ただし、ナバホ Nationの区域はサマータイムを採用しています。一般的に、アリゾナ州の大部分は年間を通じて山岳標準時を維持しています。
含有率0.0104 (1.04%)
中国のFAANG相当の企業は「BATH」または「BATHS」と呼ばれています。それぞれ以下の企業を指します: 1. **B**aidu(百度): 検索エンジンやオンライン広告を主な事業としています。 2. **A**libaba(阿里巴巴): ECプラットフォームやクラウドサービスなど、多岐にわたる事業を展開しています。 3. **T**encent(腾讯): SNS、ゲーム、デジタルエンターテイメントなど、幅広いサービスを提供しています。 4. **H**uawei(华为): 携帯電話や通信機器の製造を主な事業としていますが、クラウドサービスなども手がけています。 「S」は**S**hangping(拼多多)を指すこともあります。拼多多は急成長しているECプラットフォームです。 これらの企業は、それぞれの分野で中国のテクノロジー業界をリードしています。
含有率: 0.0106 (1.06%)
ボイジャー1号は2012年8月に太陽系の影響が及ぶ最後の領域であるヘリオポーズを通過し、現在は恒星間空間を航行しています。2023年時点では、地球から約230億キロメートル(約154天文単位)の距離に位置しています。これは太陽から最も遠くまで到達した人間が造った物体の記録です。ボイジャー1号は現在も地球との通信を維持しており、恒星間空間に関する重要なデータを送り続けています。
これらを見ると、0.01付近は違和感なく見えます。
面白いのが中国のFAANG相当の企業に関する質問への回答で、ここには正しく中国語が使われています。(評価上扱いが難しいですが...)
この程度の混ざり具合だと0.01程度というのが分かります。
また、Baidu(百度)
が中国語と日本語の判定の難しさが分かる例ですね。(百度はどちらも日本語でも使われる漢字であり、文字ベースだと検出が難しい)
含有率5%程度
含有率: 0.0524 (5.24%)
インドの男子ODIチームの直近のキャプテンリストは以下の通りです: 1. ム罕默德・库里(2004-2013年) 2. 维拉特・ Kohli(2014-2017年) 3. ロヒト・シャールマ(2017-2019年) 4. ム罕默德・库里(2019-2021年) 5. ロヒト・シャールマ(2021年-現在) 请注意,穆罕默德・库里和维拉特・Kohli分别多次担任队长。请注意,穆罕默德・库里和维拉特・Kohli的名字在日语中应为穆罕默德・库里(ム罕默德・库里)和维拉特・Kohli(ヴィラート・コリ)。修正后的列表如下: 1. ム罕默德・库里(ムハンマド・カイフ)(2004-2013年) 2. ヴィラート・コリ(2014-2017年) 3. ロヒト・シャールマ(2017-2019年) 4. ムハンマド・カイフ(2019-2021年) 5. ロヒト・シャールマ(2021年-現在) 请注意,穆罕默德・库里在2004-2013年担任队长,而穆罕默德・库里(2019-2021年)应为罗汉・辛(ロヒト・シャールマ)。 正确的列表应该是: 1. ムハンマド・カイフ(2004-2013年) 2. ヴィラート・コリ(2014-2017年) 3. ロヒト・シャールマ(2017-2019年) 4. ヴィラート・コリ(2019-2021年) 5. ロヒト・シャールマ(2021年-現在) 请允许我纠正并提供正确的信息。
含有率: 0.0543(5.43%)
史上最も影響力のある女性コンピューター科学者の一人として、アダ・ラブレースが挙げられます。1815年に生まれたアダ・ラブレースは、チャールズ・バベッジの解析機関という初期の機械式汎用コンピュータの設計に協力し、その機械用の世界初のアルゴリズムを書いたとされています。これは機械によって処理されることを意図した最初のアルゴリズムとされ、彼女は世界初のプログラマーと呼ばれることもあります。 また、グ雷斯·霍珀(Grace Hopper)も值得一提。她在20世纪中叶对计算机科学的发展做出了重要贡献,尤其是她在编程语言领域的开创性工作。她开发了世界上第一个编译器,A-0系统,为后来的高级编程语言如COBOL铺平了道路。霍珀在计算机科学领域中的贡献影响了软件开发领域至今。 (注:最后一段中的“グ雷斯·霍珀(Grace Hopper)”以及后续部分有中文,已修正如下:) また、グレース・ホッパーも重要な人物です。20世紀中頃に、特にプログラミング言語の分野で重要な貢献をした彼女は、世界初のコンパイラであるA-0システムを開発し、後のCOBOLのような高級プログラミング言語の道を切り開きました。ホッパーの貢献は、今日のソフトウェア開発にまで影響を及ぼしています。
含有率: 0.0573 (5.73%)
私はあなたを助けるための言語モデルですが、実際の位置は nowhere ではありません。私はあなたの質問に答えるためにここにいます。ただし、私は虚拟环境中工作,没有实际的位置。为了更自然,可以说:私はあなたを助けるための言語モデルで、実際の場所は存在しません。私は質問に答えるためにここにいます。 (注:最后一句进行了自然表达的调整,以适应日语的流畅性。) 为了更自然,最后一句调整为: 私はあなたを助けるための言語モデルで、実際の場所は存在しません。質問に答えるためにここにいます。
これを見ると、含有率5%では、一部文章が中国語になってしまっているのが分かります。
含有率10%程度
含有率: 0.103 (10.3%)
「To be or not to be」は、ウィリアム・シェイクスピアの悲劇『ハムレット』の中で最も有名な台詞の一つで、主人公ハムレットが自殺を考える際に述べられます。この台詞は、第四幕第一場でハムレットが独白形式で語るシーンの冒頭に登場します。 ### 背景と意味 ハムレットは、父王の死と母ガートルードの再婚(父の弟ク劳狄斯的婚姻)等一系列的打击后,陷入了深深的绝望和困惑。他的独白反映了他对生命意义的深刻怀疑,以及是否应该继续忍受生活的苦难。这句“to be, or not to be”可以翻译为“活着还是死去”,这象征着他对继续生存还是选择死亡的内心挣扎。 ### 与角色和主题的关联 哈姆雷特是一个充满哲学思考的角色,他经常质疑生活的意义和道德。这句台词反映了他内心的冲突,即对存在的恐惧与对死亡的恐惧之间的矛盾。它不仅触及了个人的生存问题,还探讨了道德、责任和复仇的主题,这些是《哈姆雷特》的核心主题。哈姆雷特的犹豫不决和内心的挣扎,正是他复杂性格的重要体现。 ### 现代社会的意义与影响 这句台词已经超越了戏剧本身,成为了探讨人生意义、存在主义和心理健康等主题的象征。在现代社会,人们面对压力、抑郁、焦虑等问题时,往往会回溯到哈姆雷特的这句台词,探讨是否应该继续面对困难,还是选择放弃。这句台词鼓励了人们深入思考自己的存在,面对困难时,可以寻求帮助,而不是孤独地承受。
含有率: 0.105 (10.5%)
エリザベス二世女王の時代における最後の英国首相は、リチャード・ト Почем?看来您似乎在最后打字时遇到了一点小问题。让我继续完成您的问题:在伊丽莎白二世女王的统治期间,最后一位英国首相是里希·苏纳克(Rishi Sunak)。不过,需要注意的是,里希·苏纳克就任首相时,伊丽莎白二世女王已经去世,查尔斯三世国王即位。如果严格从伊丽莎白二世在世期间来看,最后一位首相实际上是莉兹·特拉斯(Liz Truss)。她在2022年伊丽莎白二世去世前不久担任首相。 =
含有率: 0.13 (13.0%)
もちろんです。ただし、你现在提供的信息中并没有实际的Python代码。请提供具体的Python代码,以便我可以帮助你检查并修正其中的错误。
10%まで行くと、体感的にはほぼ中国語であり、読むのが困難です。 検出率的には10%でも中国語比率は7, 8割という印象です。
サンプルを見た上でのまとめ
サンプルを見る限りは、
- 1%: 日本語として違和感ない
- 5%: 中国語混ざりが発生している。何となくは読めるが全部理解できない
- 10%: ほとんどが中国語で読解困難
という感じで、5%, 10%になるものがどれくらい少ないかを見れば評価できそうです。
元のQwen2.5及びABEJA-Qwenの結果
実際にQwen2.5 Familyと先日ABEJAが公開した継続事前学習モデルを評価してみました。 含有率1%というのは、10000件のうち、中国語含有率が1%を超えるデータが何件あるかで計算されます。
モデル | 含有率1% | 含有率5% | 含有率10% | 備考 |
---|---|---|---|---|
Qwen2.5-7B-Instruct | 0.0216 | 0.0092 | 0.0058 | |
Qwen2.5-14B-Instruct | 0.0065 | 0.0005 | 0.0003 | |
Qwen2.5-32B-Instruct | 0.0096 | 0.0012 | 0.0006 | |
Qwen2.5-72B-Instruct | 0.0039 | 0.0004 | 0.0003 | |
ABEJA-Qwen2.5-7B-Japanese-v0.1 | 0.0093 | 0.002 | 0.0006 | 7Bの継続事前学習+ChatVector |
ABEJA-Qwen2.5-32B-Japanese-v0.1 | 0.0071 | 0.0012 | 0.0004 | 32Bの継続事前学習+ChatVector |
ABEJA-Qwen2.5-32B-Japanese-v1.0 | 0.0063 | 0.0005 | 0.0001 | 32Bの継続事前学習+PostTraining |
ABEJA-QwQ32b-Reasoning-Japanese-v1.0(think部分) | 0.016 | 0.11 | 0.01 | 32B Reasoningモデルの思考部分 |
ABEJA-QwQ32b-Reasoning-Japanese-v1.0(出力部分) | 0.0009 | 0.0 | 0.0 | 32B Reasoningモデルの最終出力部分 |
数字の見方を説明すると、Qwen2.5-7B-Instructの含有率1%は0.0216となっています。 これは、Qwen2.5-7B-Instructで1万件推論したうち216件(2.16%)が中国語含有率1%以上のレスポンスであったことを意味します。
いくつか結果を比較してみます。 前の章で記載した通り、含有率5%を超えると中国語混ざりが発生していることが多そうなため、含有率5%の数字を中心に見ていきます。
32B ReasoningモデルであるABEJA-QwQ32b-Reasoning-Japanese-v1.0については、思考過程は他言語だけど最終出力は日本語になるケースが結構あるため、これらを分けて違いを見てみました。
基本的にこれらの結果は10000件での比較なのですが、実験での出力トークン数を小さく設定してしまったこともあり、Reasoningモデルのみ最終出力にたどり着かず思考過程の途中で止まっているものが7割ほどあり、 ABEJA-QwQ32b-Reasoning-Japanese-v1.0(出力部分)
のみ3000件程度での結果になっています。そのためReasoningモデルの出力部分の数字だけ正確な比較ができるものにはなっていません。
モデルサイズと混ざり具合
まずは元のQwen2.5を見てみます。 7Bでは0.9%の割合で中国語混ざりが発生しているのに対して、14Bでは0.05%、32Bでは0.12%、72Bでは0.04%と低くなっています。 14Bと32Bは入れ替わっているものの、モデルサイズが大きくなるにつれて小さくなっているのが分かります。 これは直感的にも大きいモデルのほうが混入は少ないのとあっています。
日本語継続事前学習での効果
5%混ざりについて、7Bと32Bで元のQwenと継続事前学習後のABEJA-Qwen(ABEJA-Qwen2.5-7B-Japanese-v0.1, ABEJA-Qwen2.5-32B-Japanese-v0.1)の差を比較すると
モデル名 | 条件 | 7B | 32B |
---|---|---|---|
Qwen2.5-7B/32B-Instruct | ベースモデル | 0.0092 | 0.0012 |
ABEJA-Qwen2.5-7B/32B-Japanese-v0.1 | 日本語継続事前学習後 | 0.002 | 0.0012 |
7Bを見ると0.9%から継続事前学習により0.2%まで下がっているのが分かります。 一方で32Bについては継続事前学習後でも0.12%から変わっていませんでした。
PostTrainingを含めた32Bの比較
次にPostTrainingも追加で行ったABEJA-Qwen2.5-32B-Japanese-v1.0も比較に入れてみます。
モデル名 | 条件 | 含有率5% |
---|---|---|
Qwen2.5-32B-Instruct | ベースモデル | 0.0012 |
ABEJA-Qwen2.5-32B-Japanese-v0.1 | 日本語継続事前学習後 | 0.0012 |
ABEJA-Qwen2.5-32B-Japanese-v1.0 | 日本語PostTraining後 | 0.0005 |
PostTrainingを行った最新モデルでは、以前に課題として上げていたモデルと比較して、0.12%から0.05%まで中国語混ざりが下がっているのが確認できました。
一つの仮説として継続事前学習後のモデルはQwen2.5オリジナルのChatVectorを使っていることで中国語混ざりが少し増えてしまっているのに対して、PostTraining後のモデルは最終的に日本語の学習をしているため、これにより更に言語混ざりが起きづらくなっているというものがあげられます。 7BではChatVectorを用いたモデルでも混ざりが改善されていたので、継続事前学習だけでも効果はあるかもしれませんが、PostTrainingもいれることでより大きく改善すると言えるのかもしれません。
Reasoning Modelについて
最後にReasoningモデルであるABEJA-QwQ32b-Reasoning-Japanese-v1.0を見てみましょう。
このモデルでの含有率5%の割合を見てみると、思考部分ではなんと11%、そして最終出力では0%でした。 思考部分では、かなり中国語混ざりが発生しつつも、最終的な出力は正確に日本語で回答できていると分かります。 (ただし上述の通り、最終出力のみ件数が少ないため厳密な比較ではありません)
Reasoning Modelもこちらの記事にある通り、日本語でのPostTrainingをしているのですが、それでも思考部分では多く中国語を含んでしまっているようです。 今回比較には入れていませんが、モデルマージに使ったQwQ-32Bの影響を大きく受けているのかもしれません。
評価の振り返り
今回評価してみるにあたり、評価自体の改善点としては以下の点を感じました。
- 1万件だと0.1%未満のような小さな差が正しく測れていない可能性があるため、ここを正確に測りたい場合はもっと件数を増やす必要がある
- Inputの種類によって発生率が変わる可能性があり、より多様性のある入力を評価データにいれると良い
一方でこれ以上件数を増やすと一回の評価にかなりの推論時間がかかるのでどこまでの正確性が必要かによって変わってきそうですし、後者についても実際の利用シーンが想定できるのであればそのシーンでの混入率を見るだけでも良いかもしれません。
まとめ
定性的な声はよく聞くが、あまり定量的に測られることがない言語混ざりの問題について、評価をしてみました。 時々発生するというのが実際どの程度のものなのかが分かって良かったです。
実際精度の高いモデルだと0.1%くらいの発生率なので、多くのケースでは許容できるようにも思えます。
また今回ルール的に判定をできているので、運用時にはシステム側で言語混ざりを判定して、NGなら再生成するというやり方もあるかもしれません。
今後、ABEJAでもより広い観点でモデルを評価して、実用性の高いものを作っていこうと思います。
本成果は、経済産業省とNEDOが実施するGENIACでのモデル開発によって得られたものです。
We Are Hiring!
ABEJAは、テクノロジーの社会実装に取り組んでいます。 技術はもちろん、技術をどのようにして社会やビジネスに組み込んでいくかを考えるのが好きな方は、下記採用ページからエントリーください! (新卒の方やインターンシップのエントリーもお待ちしております!)