Menu

Self-consistency prompting: chọn đáp án theo đa số

Self-consistency prompting hỏi cùng một câu hỏi suy luận nhiều lần, để mỗi lần chạy tự suy luận theo cách riêng, rồi giữ lại đáp án xuất hiện nhiều nhất. Bài này giải thích cách nó hoạt động, cách làm thủ công và cách làm bằng code.

Mọi prompt bên dưới đều có thể chỉnh sửa: thay đổi nó, rồi mở trong ChatGPT, Claude hoặc ứng dụng AI khác.

Self-consistency prompting nghĩa là hỏi mô hình cùng một câu hỏi suy luận nhiều lần rồi giữ lại đáp án xuất hiện nhiều nhất. Mỗi lần chạy tự viết ra lập luận của mình, như trong chain of thought prompting, và vì mô hình chọn từ ngữ với một mức ngẫu nhiên nhất định, các lần chạy sẽ đi theo những hướng khác nhau. Những hướng đúng thường dẫn tới cùng một đáp án. Những lỗi sai thì thường rải rác ở nhiều đáp án sai khác nhau. Bỏ phiếu theo đa số tận dụng chính khác biệt đó.

Kỹ thuật này đến từ bài báo của Wang và cộng sự năm 2022, "Self-Consistency Improves Chain of Thought Reasoning in Language Models". Bài báo so sánh việc lấy mẫu nhiều hướng suy luận rồi bỏ phiếu với việc chỉ lấy một câu trả lời tham lam (greedy) duy nhất, và thấy bỏ phiếu cải thiện độ chính xác trên các bộ benchmark về số học và suy luận thông thường.

Khối bên dưới cho thấy ba lần chạy của cùng một prompt. Mỗi tab là một lần chạy với câu trả lời riêng. Hai lần đếm đúng; một lần mắc một lỗi rất dễ mắc.

Chữ số 7 xuất hiện bao nhiêu lần khi bạn viết ra tất cả các số nguyên từ 1 đến 100? Hãy suy nghĩ từng bước, rồi đưa đáp án cuối cùng ở dòng cuối theo dạng "Answer: N".
Try it
Example replyReplies vary between models and runs.

Đếm các chữ số 7 theo từng hàng.

  • Hàng đơn vị: 7, 17, 27, 37, 47, 57, 67, 77, 87, 97. Tức là 10 chữ số 7.
  • Hàng chục: từ 70 đến 79. Thêm 10 chữ số 7 nữa.
  • Hàng trăm: chỉ có 100 là số có ba chữ số, và nó không có chữ số 7.

77 xuất hiện ở cả hai danh sách, điều này đúng, vì nó chứa hai chữ số 7.

Answer: 20

Lần chạy 2 đã trả lời một câu hỏi hơi khác: có bao nhiêu số chứa chữ số 7, chứ không phải chữ số đó xuất hiện bao nhiêu lần. Lập luận của nó đọc lên cũng tự tin không kém hai lần còn lại, và nếu chỉ nhìn riêng nó, bạn sẽ không có lý do gì để nghi ngờ. Qua ba lần chạy, kết quả bỏ phiếu là 20, 19, 20, và đáp án đa số là đáp án đúng.

Self-consistency hoạt động thế nào

  1. Viết một prompt chain-of-thought có dòng đáp án cố định. Yêu cầu lập luận trước và đáp án cuối cùng ở sau, theo một dạng bạn tìm được dễ dàng, như "Answer: N". Không có dòng cố định, bạn phải đọc từng lần chạy mới tìm ra đáp án.
  2. Lấy mẫu nhiều lần chạy với độ ngẫu nhiên được bật. Mỗi lần chạy cần được tự do đi theo một hướng khác. Trong API, temperature lớn hơn 0 sẽ làm điều này. Ở temperature 0, phần lớn các lần chạy sẽ lặp lại cùng một lập luận, và lặp lại một lỗi năm lần không phải là bằng chứng.
  3. Lấy đáp án cuối cùng từ mỗi lần chạy. Bỏ qua phần lập luận ở bước này. Hai lần chạy cùng ra 20 theo hai cách khác nhau được tính là hai phiếu cho 20.
  4. Chọn đáp án phổ biến nhất. Chuẩn hóa trước khi đếm, để "20", "20." và "hai mươi" được tính là cùng một đáp án.

Bản thân mức độ đồng thuận cũng là thông tin hữu ích. Khi cả năm lần chạy đều đồng ý, khả năng có lỗi ngẫu nhiên là thấp. Khi phiếu bị chia làm ba, câu hỏi này khó với mô hình, và đó là tín hiệu để bạn tự kiểm tra đáp án hoặc viết lại prompt. Bài báo cũng ghi nhận rằng những câu hỏi có mức đồng thuận giữa các mẫu cao hơn thì có khả năng được trả lời đúng cao hơn.

Self-consistency làm thủ công

Bạn có thể áp dụng kỹ thuật này trong bất kỳ ứng dụng chat nào. Gửi prompt, ghi lại dòng cuối, rồi lấy thêm một lần chạy độc lập: nhấn tạo lại, hoặc dán cùng prompt vào một cuộc chat mới. Lặp lại cho đến khi có ba hoặc năm đáp án.

Đừng hỏi lại trong cùng cuộc trò chuyện bằng "Bạn chắc chứ?" hay "Thử lại đi". Mô hình thấy được câu trả lời trước của nó, nên câu trả lời mới không còn độc lập: nó thường hoặc lặp lại đáp án đầu, hoặc đổi đáp án chỉ vì bạn có vẻ nghi ngờ. Cả hai đều không phải là một lá phiếu.

Prompt này đã được chuẩn bị sẵn để bỏ phiếu. Điền câu hỏi và dạng đáp án của bạn, rồi chạy nó vài lần.

Prompt sẵn sàng để bỏ phiếu
Fill in
Parts
Một cửa hàng bán bút theo gói 3 chiếc giá $2. Maya mua 12 chiếc bút và trả bằng tờ $10. Maya được thối lại bao nhiêu tiền?
Hãy suy nghĩ từng bước. Sau đó đưa riêng đáp án cuối cùng ở dòng cuối theo dạng "Answer: một số tiền tính bằng đô la".
Try it
Example replyReplies vary between models and runs.

12 chiếc bút là 12 ÷ 3 = 4 gói.

4 gói có giá 4 × 2=2 = 8.

Tiền thối từ 10:10: 10 trừ 8=8 = 2.

Answer: $2

Phần định dạng là thứ giúp việc bỏ phiếu khả thi. Tắt nó đi và các lần chạy thường diễn đạt đáp án theo những cách khác nhau, hay nằm đâu đó giữa đoạn văn, biến một phép đếm đơn giản thành việc đọc kỹ từng câu trả lời.

Self-consistency bằng code

Trong code, vòng lặp rất ngắn: chạy cùng một prompt N lần, lấy ra các dòng đáp án và đếm chúng. Phiên bản này dùng OpenAI Python SDK; API nào cho phép đặt temperature cũng làm được theo cách tương tự.

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.")

Các lần chạy là độc lập, nên trong môi trường production bạn sẽ gửi chúng song song thay vì lần lượt. Một số mô hình suy luận chỉ chấp nhận temperature mặc định và trả về lỗi nếu bạn đặt giá trị khác; với những mô hình đó, hãy bỏ temperature đi. Các lần chạy của chúng vẫn khác nhau, vì mặc định chúng đã lấy mẫu ngẫu nhiên.

Khi nào nên dùng, và chi phí ra sao

Self-consistency đáng dùng khi có đủ ba điều: đáp án ngắn và so sánh được (một con số, một nhãn, một lựa chọn), một đáp án sai gây tốn kém hơn vài lần gọi thêm, và mô hình chưa đáng tin cậy với nhiệm vụ đó. Các bài toán có lời văn, việc phân loại với nhiều trường hợp biên khó và câu hỏi trắc nghiệm rất phù hợp.

Chi phí xấp xỉ N lần số token của một câu trả lời, và nó không giúp được gì khi mô hình mắc cùng một hiểu lầm ở mọi lần chạy. Nếu cả năm lần chạy cùng mắc một lỗi, kết quả bỏ phiếu là đồng thuận tuyệt đối và sai. Bỏ phiếu giảm được lỗi ngẫu nhiên, không giảm được lỗi có hệ thống, nên nó không thay thế được việc thỉnh thoảng đối chiếu đáp án với một kết quả đã biết.

Những mô hình tự suy luận bên trong trước khi trả lời vốn đã suy nghĩ kỹ về bài toán ở mỗi lần chạy, nên lợi ích từ việc bỏ phiếu thường nhỏ đi. Dù vậy, nó vẫn có thể đáng giá với những câu hỏi khó mà các lần chạy cho kết quả khác nhau.

Self-consistency chỉ bỏ phiếu trên các đáp án đã hoàn chỉnh. Tree of thought prompting tiến thêm một bước: so sánh các lập luận dang dở ngay trong lúc giải bài toán, giữ lại những nhánh hứa hẹn và bỏ những nhánh yếu trước khi chúng đi tới đáp án.

Câu hỏi thường gặp

Self-consistency prompting là gì?

Self-consistency prompting là một kỹ thuật từ bài báo của Wang và cộng sự (2022). Bạn gửi cùng một prompt chain-of-thought nhiều lần với chế độ lấy mẫu ngẫu nhiên được bật, để mỗi lần chạy suy luận theo một hướng khác nhau, rồi chọn đáp án cuối cùng xuất hiện nhiều nhất. Thay vì tin vào một chuỗi suy luận duy nhất, bạn để nhiều chuỗi bỏ phiếu.

Nên lấy bao nhiêu mẫu cho self-consistency?

Với việc dùng hằng ngày, từ ba đến năm lần chạy là đủ để áp đảo một lần sai ngẫu nhiên, và một số lẻ giúp tránh hòa giữa hai đáp án. Bài báo gốc lấy mẫu nhiều hướng suy luận hơn hẳn cho mỗi câu hỏi và thấy độ chính xác tiếp tục tăng khi có thêm mẫu, nhưng mức tăng nhỏ dần. Dùng nhiều lần chạy hơn khi một đáp án sai gây tốn kém, và ít hơn khi chi phí hoặc tốc độ là quan trọng.

Self-consistency khác chain of thought như thế nào?

Chain of thought là một lần chạy trong đó mô hình viết ra lập luận trước khi đưa đáp án. Self-consistency xây dựng trên nền đó: nó chạy chain of thought nhiều lần và bỏ phiếu cho các đáp án cuối cùng. Chain of thought thay đổi prompt; self-consistency thay đổi số câu trả lời bạn thu thập và cách bạn chọn một đáp án.

Self-consistency có dùng được cho bài luận hay câu trả lời mở không?

Không dùng trực tiếp được, vì bỏ phiếu cần những đáp án có thể so sánh bằng nhau: một con số, một nhãn, một chữ cái trắc nghiệm hoặc một thông tin ngắn. Với văn bản mở, một cách thường dùng là tạo nhiều phiên bản rồi hỏi mô hình phiên bản nào khớp nhất với các phiên bản còn lại, nhưng đó là đánh giá chứ không phải đếm.

Có dùng self-consistency trong ChatGPT hoặc Claude được không?

Được, bằng cách làm thủ công. Gửi prompt trong vài cuộc chat mới, hoặc tạo lại câu trả lời vài lần, rồi ghi lại đáp án cuối của mỗi lần chạy. Hãy dùng cuộc chat mới hoặc nút tạo lại thay vì hỏi lại trong cùng một cuộc trò chuyện, vì mô hình thấy được câu trả lời trước của nó thường sẽ lặp lại câu trả lời đó.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu