1.2重BOS問題の注意
・Gemma, LLamaなどは設定通りに動かすとプロンプトの先頭にBOSが2つ付与されて誤動作を誘発するケースがある
・話題になった事はあるが、トレーニングツール、ベンチマークツール、インターフェースツールのいずれかが誤動作するので現在も解決していない
・最新モデルなどではBOSが不要になる可能性はあるが、歴史的な経緯をしらないと間違える可能性があるのでここにまとめます
2.BOSとは?
AIにある程度詳しい人ならばプロンプトという言葉は聞いたことがあると思います。
実はプロンプトはAIに渡す前に特定のフォーマット(プロンプトテンプレート)に整形されます。
例:<|begin_of_text|><|start_header_id|>…こんにちは!
上記の例では<|begin_of_text|>がBOS、Beginning of Sentence(文頭)です。AIにとっては「開始の合図」です。
この開始の合図が2重に、<|begin_of_text|><|begin_of_text|>になってしまうと、アイキャッチ画像のように「ヨーイドン!」の合図がダブルになってしまいAIが混乱してしまうのが2重BOS問題です。
3.なぜ「2重」になるのか?
Gemma3やLLama3が以下の2項目で2重に設定しているためです。
1)設定ファイル(tokenizer_config.json)内で”add_bos_token”: trueと設定しています
2)同じく設定ファイルのプロンプトテンプレート(chat_template)の中でも先頭にBOS(“chat_template”: “{{- bos_token }}\n…)を付けています
1)は歴史的な理由で主にベンチマーク系のツール/コマンドが使っています。
2)は歴史的な理由で主に推論系ツール系が使っています。
どちらかを一方を削除するとどちらかが誤動作する可能性があるので気軽には消せません。そして、素直に両方を見るツールもあるので、その場合に2重BOS問題が発生します。
この問題はそれなりに知られているのでツール側で自動対処/警告を出してくれる場合もありますが「ツール側はユーザーの設定通りに実行すべきであり、フラグ管理はユーザーの責任」という考え方の元に、先頭に2つのBOSを付けてしまうケースもあります。
llama.cppの場合は” –override-kv tokenizer.ggml.add_bos_token=bool:false”のオプションが別途必要になる事があります。
2重BOS問題が発生しても100%出力がおかしくなるわけではなく「(主に小さいモデルで)繰り返し出力など稀に発生して出力の品質が悪くなる」と言うレベルなので、気づかずに使ってしまう時もあるかもしれませんが、FineTuneや量子化などを実行する際は注意が必要です。
Webbigdataが直近作成した量子化モデル

は迷った末に1)の設定ファイル側でadd_bos_token: falseにしてあります。そのため、このモデルを使ってベンチマーク(llama-perplexityなど)をする際は、何らかの形でadd_bos_tokenをtrueにしないと正確な計測できないケースに注意してください。
4. アテンションシンクとの関係性
なぜBOSが2つあるだけでAIはダメになるのでしょうか?ここに「アテンションシンク」という概念が関わります。
アテンションシンク(Attention Sink)とは、最近のLLM(大規模言語モデル)の特性として、「最初のトークンに何故か強い注意(アテンション)を向けてしまう」という傾向です。そのため、BOSを使わずに例えば「Hello. We are webbigdata.jp.」という文章を与えた場合「Hello」に必要のない注意を払う事になるので、諸々の性能が悪化するのです。先頭にしか出てこない事が約束されており、それ以外の意味を持たないBOSを設定する事で、計算が安定し「キッチンの流し台(シンク)」や「錨(アンカー)」のような役割を果たしてくれる事になるのです。
2重BOSになると、AIは「最初のBOSを錨にすべきか? 2番目のBOSを錨にすべきか?」と混乱します。想定外の挙動を起こし、回答の品質が下がったり、支離滅裂な文繰り返し文章を出したりします。
しかし、Qwen等のより新しいモデルではアテンションシンクを和らげる手法が発見されたため、あまり問題にならなくなってきています(逆に言えば、2重BOS問題を根本的に解決しようとする機運は消えた)。これらはBOSトークンを必須としない設計、あるいはトークナイザーが気を使って2番目のBOSを無視する等の処理をしてくれるようになっています。
とはいえ、Gemma3もLlama3もまだまだ現役なので「なんかどうも挙動がおかしいな?」と思ったら、入力をトークン化してみて「BOSが2重になっていないか?」を実際のトークン化した文字列を確認してみてください。

