Self-Consistency プロンプティングとは、同じ推論の質問をモデルに何度か尋ね、最も多く出てきた答えを採用する方法です。各実行は Chain-of-Thought プロンプティングのように自分の推論を書き出し、モデルはある程度のランダムさをもって言葉をサンプリングするので、実行ごとに違う道筋をたどります。正しい道筋は同じ答えにたどり着きやすく、間違いはばらばらの誤答に散らばりやすい。多数決はこの違いを利用します。
この手法は Wang らの2022年の論文「Self-Consistency Improves Chain of Thought Reasoning in Language Models」から来ています。論文は、多くの推論の道筋をサンプリングして投票する方法と、貪欲法による1つの答えをとる方法を比べ、投票によって算数と常識推論のベンチマークで精度が上がることを確かめました。
下のブロックは、同じプロンプトを3回実行したものです。各タブが1回の実行とその返答です。2回は正しく数え、1回はやりがちなミスをしています。
位ごとに 7 を数えます。
- 一の位:7、17、27、37、47、57、67、77、87、97。7 が10個です。
- 十の位:70 から 79。さらに10個です。
- 百の位:3桁なのは 100 だけで、7 はありません。
77 は両方のリストに入っていますが、7 を2つ含むのでこれで正しいです。
Answer: 20
実行2は、少し違う質問に答えています。数字の 7 が何回現れるかではなく、7 を含む数がいくつあるかです。その推論もほかの2つと同じくらい自信ありげで、単独で見れば疑う理由はありません。3回の実行で票は 20、19、20 となり、多数派の答えが正解です。
Self-Consistency の仕組み
- 答えの行が決まった Chain-of-Thought プロンプトを書く。まず推論を、最後に最終的な答えを、「Answer: N」のような見つけやすい形で書かせます。決まった行がないと、各実行の答えを探すためにすべてを読まなければなりません。
- ランダムさを有効にして何回か実行する。各実行には違う道筋をたどる自由が必要です。API では、0 より大きい temperature でそうなります。temperature 0 では大半の実行が同じ推論を繰り返し、同じ間違いを5回繰り返しても証拠にはなりません。
- 各実行から最終的な答えを取り出す。この段階では推論は無視します。違う道筋で 20 にたどり着いた2つの実行は、20 への2票です。
- 最も多い答えを採用する。数える前に表記をそろえ、「20」「20.」「二十」を同じ答えとして数えます。
一致の度合いそのものも役に立つ情報です。5回の実行がすべて一致していれば、偶然のミスである可能性は低いでしょう。票が3つに割れたら、その質問はモデルにとって難しいということで、自分で答えを確かめるか、プロンプトを書き直すべきだというサインです。論文も、サンプル間の一致が強い質問ほど正しく答えられている可能性が高いと報告しています。
手作業での Self-Consistency
この手法はどのチャットアプリでも使えます。プロンプトを送って最後の行を書き留め、それとは独立した実行をもう1回得ます。再生成ボタンを押すか、同じプロンプトを新しいチャットに貼り付けます。答えが3つか5つ集まるまで繰り返します。
同じ会話の中で「本当に?」や「もう一度やって」と聞き直してはいけません。モデルには前の返答が見えているので、新しい答えは独立していません。最初の答えを繰り返すか、あなたが疑っているように見えたからという理由だけで答えを変えがちです。どちらも投票にはなりません。
このプロンプトは投票向けに作ってあります。自分の質問と答えの形式を入れて、何度か実行してください。
ペン12本は 12 ÷ 3 = 4 パックです。
4 パックの代金は 4 × 200円 = 800円です。
1,000円からのおつり:1,000円 から 800円 を引いて 200円。
Answer: 200円
投票を可能にしているのは形式のパートです。これをオフにすると、実行ごとに答えの書き方がばらばらになり、文章の途中に書かれることも多くなって、単純に数えるだけの作業が注意深く読む作業に変わってしまいます。
コードでの Self-Consistency
コードでは、ループは短く済みます。同じプロンプトを N 回実行し、答えの行を取り出して数えます。この版は OpenAI の Python SDK を使っていますが、temperature を設定できる API ならどれでも同じように動きます。
import re
from collections import Counter
from openai import OpenAI
client = OpenAI()
MODEL = "your-model-id" # e.g. from your provider's model list
PROMPT = (
"How many times does the digit 7 appear when you write out all the whole "
"numbers from 1 to 100? Think it through step by step, then give the final "
'answer on the last line in the form "Answer: N".'
)
def final_answer(text):
# Also matches "**Answer: 20**", since chat models often bold the last line.
lines = re.findall(r"^\**Answer:\**\s*(.+)$", text, re.MULTILINE)
return lines[-1].strip(" *.") if lines else None
answers = []
for _ in range(5):
response = client.chat.completions.create(
model=MODEL,
temperature=0.8,
messages=[{"role": "user", "content": PROMPT}],
)
answers.append(final_answer(response.choices[0].message.content))
votes = Counter(a for a in answers if a is not None)
if votes:
best, count = votes.most_common(1)[0]
print(f"{best} ({count} of {len(answers)} runs agree)")
else:
print("No run gave an answer line.")
各実行は独立しているので、本番では順番に送るのではなく並列に送ります。推論モデルの中にはデフォルトの temperature しか受け付けず、設定するとエラーを返すものがあります。その場合は temperature を省いてください。デフォルトでもサンプリングしているので、実行ごとの結果はやはり変わります。
使いどきとコスト
Self-Consistency が割に合うのは、3つの条件がそろうときです。答えが短く比べられる(数値、ラベル、選択肢)こと、間違った答えの代償が数回分の追加の呼び出しより大きいこと、そしてモデルがそのタスクですでに安定しているわけではないことです。算数の文章題、ややこしい境界ケースのある分類、選択式の問題がよく合います。
コストはおよそ1回の答えの N 倍のトークンで、モデルがどの実行でも同じ思い込みをしている場合には役に立ちません。5回の実行がすべて同じ間違いをすれば、投票は満場一致で間違います。投票が減らすのは偶然のミスであって系統的な誤りではないので、ときどき答えを既知の結果と照らし合わせる作業の代わりにはなりません。
答える前に内部で推論するモデルは、どの実行でもすでに問題をじっくり解いているので、投票による上積みは小さくなりがちです。それでも、実行ごとに答えが割れる難しい質問では効果が出ることがあります。
Self-Consistency が投票するのは完成した答えだけです。Tree of Thought プロンプティングはさらに一歩進み、問題を解いている途中の推論を比べて、見込みのある枝を残し、弱い枝を答えにたどり着く前に切り捨てます。
よくある質問
Self-Consistency プロンプティングとは何ですか?
Self-Consistency プロンプティングは、Wang ら(2022)による手法です。サンプリングを有効にした状態で同じ Chain-of-Thought プロンプトを何度か送り、実行ごとに違う道筋で推論させてから、最も多く現れた最終的な答えを採用します。1本の推論を信じる代わりに、複数の推論で投票するのです。
Self-Consistency ではサンプルをいくつ取ればいいですか?
日常的な用途なら、たまに起きるミスを票で上回るには3〜5回の実行で十分で、奇数にすれば2つの答えが同数になるのを避けられます。元の論文は1問あたりもっと多くの道筋をサンプリングし、サンプルを増やすほど精度は上がり続けるものの、増えるごとの効果は小さくなることを確かめました。間違った答えの代償が大きいときは回数を増やし、コストや速度が重要なときは減らしてください。
Self-Consistency と Chain-of-Thought の違いは何ですか?
Chain-of-Thought は、モデルが答えの前に推論を書き出す1回の実行です。Self-Consistency はそれを発展させたもので、Chain-of-Thought を何度か実行して最終的な答えで投票します。Chain-of-Thought はプロンプトを変え、Self-Consistency は集める答えの数と、その中から1つを選ぶ方法を変えます。
Self-Consistency は作文や自由回答にも使えますか?
そのままでは使えません。投票には、数値、ラベル、選択肢の記号、短い事実のように、同じかどうかを比べられる答えが必要だからです。自由記述の文章では、いくつかの版を生成してから、どれがほかと最もよく一致しているかをモデルに尋ねる方法がよく使われますが、それは数えることではなく判断です。
ChatGPT や Claude で Self-Consistency を使えますか?
手作業で使えます。いくつかの新しいチャットでプロンプトを送るか、返答を何度か再生成し、各実行の最終的な答えを書き留めます。同じスレッドで聞き直すのではなく、新しいチャットか再生成ボタンを使ってください。前の答えが見えているモデルは、それを繰り返しがちだからです。