การสุ่มตัวอย่างนิวเคลียสแบบ top-p
top-p จำกัดการสุ่มตัวอย่างไว้ที่ชุดโทเค็นซึ่งมีความน่าจะเป็นสูงที่สุดได้อย่างไร
การสุ่มตัวอย่างนิวเคลียสแบบ top-p เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Prompt Engineering และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
การสุ่มแบบ top-p คืออะไร
การสุ่มแบบ top-p (เรียกอีกอย่างว่า การสุ่มจากกลุ่มแกนกลาง) เป็นเทคนิคที่จำกัดการสุ่มให้อยู่ในส่วนย่อยของชุดคำศัพท์ซึ่งปรับเปลี่ยนได้ แทนที่จะสุ่มจากโทเค็นทั้งหมด โมเดลจะพิจารณาเฉพาะชุดโทเค็นที่เล็กที่สุดซึ่งมีความน่าจะเป็นสะสมอย่างน้อย p
เทคนิคนี้เสนอในบทความเรื่อง 'กรณีอันน่าพิศวงของการเสื่อมสภาพของข้อความจากโครงข่ายประสาทเทียม' (Holtzman และคณะ, 2019) และมีประสิทธิภาพเหนือกว่าการปรับสเกลอุณหภูมิแบบง่ายในการสร้างข้อความที่หลากหลายแต่ยังคงสอดคล้องกัน
การทำงานของ top-p ทีละขั้นตอน
ขั้นตอนวิธี:
- คำนวณความน่าจะเป็นจาก softmax สำหรับชุดคำศัพท์ทั้งหมด
- เรียงโทเค็นตามความน่าจะเป็น (จากสูงสุดไปต่ำสุด)
- ไล่ไปตามรายการที่เรียงแล้ว โดยสะสมความน่าจะเป็นจนกว่าผลรวมสะสมจะถึง p
- ชุดโทเค็นนี้คือ กลุ่มแกนกลาง
- สุ่มจากกลุ่มแกนกลางเท่านั้น (ปรับความน่าจะเป็นใหม่ให้ผลรวมเป็น 1)
import numpy as np
def top_p_sample(logits, p=0.9):
probs = softmax(logits, temperature=1.0)
# Sort by probability descending
sorted_indices = np.argsort(probs)[::-1]
sorted_probs = probs[sorted_indices]
# Find nucleus: smallest set with cumulative prob >= p
cumulative = np.cumsum(sorted_probs)
nucleus_size = np.searchsorted(cumulative, p) + 1
nucleus_indices = sorted_indices[:nucleus_size]
nucleus_probs = sorted_probs[:nucleus_size]
# Renormalize
nucleus_probs = nucleus_probs / nucleus_probs.sum()
# Sample
chosen = np.random.choice(nucleus_indices, p=nucleus_probs)
return chosen
token = top_p_sample(logits, p=0.9)กลุ่มแกนกลางที่ปรับตามสถานการณ์
แนวคิดสำคัญของ top-p คือขนาดของกลุ่มแกนกลาง ปรับเปลี่ยนได้ เมื่อโมเดลมีความมั่นใจสูงมาก (โทเค็นหนึ่งมีความน่าจะเป็น 0.95 และเด่นกว่าโทเค็นอื่น) กลุ่มแกนกลางจะมีโทเค็นเพียง 1 รายการ เมื่อโมเดลไม่แน่ใจ (โทเค็นจำนวนมากมีความน่าจะเป็นใกล้เคียงกัน) กลุ่มแกนกลางจะขยายเพื่อรวมโทเค็นไว้มากขึ้น
วิธีนี้ปรับตามระดับความมั่นใจของโมเดลได้เอง — ความมั่นใจสูง → ขนาดชุดคำศัพท์เล็ก → ผลลัพธ์มุ่งเน้น ความมั่นใจต่ำ → ชุดคำศัพท์ใหญ่ขึ้น → สำรวจได้มากขึ้น
# High-confidence situation: model strongly prefers 'the'
high_confidence_logits = np.array([5.0, 1.0, 0.5, 0.1, -0.5])
hc_probs = softmax(high_confidence_logits)
print('High confidence probs:', np.round(hc_probs, 3))
# [0.974, 0.018, 0.011, 0.007, 0.004]
# Top-p=0.9 nucleus: just 1 token (cumulative after token 0 = 97.4% > 90%)
# Low-confidence situation: model unsure
low_confidence_logits = np.array([1.1, 1.0, 0.9, 0.8, 0.7])
lc_probs = softmax(low_confidence_logits)
print('Low confidence probs:', np.round(lc_probs, 3))
# [0.218, 0.208, 0.199, 0.190, 0.181]
# Top-p=0.9 nucleus: all 5 tokens (need all to reach 90%)Top-p ในส่วนต่อประสานโปรแกรมประยุกต์ของ OpenAI
กำหนดค่า top_p ในการเรียกใช้ส่วนต่อประสานโปรแกรมประยุกต์ของคุณ ช่วงค่าที่ใช้ได้คือ 0.0–1.0 ค่าเริ่มต้นคือ 1.0 (ใช้ชุดคำศัพท์ทั้งหมดโดยไม่มีข้อจำกัดจากกลุ่มแกนกลาง)
OpenAI แนะนำว่า หากเปลี่ยน top_p ให้คงอุณหภูมิไว้ที่ 1.0 และในทางกลับกัน การปรับทั้งสองค่าพร้อมกันทำให้คาดเดาพฤติกรรมการสุ่มที่เกิดขึ้นจริงได้ยาก
import openai
client = openai.OpenAI(api_key='sk-...')
# Nucleus sampling: top 90% of probability mass
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Tell me an interesting fact about the ocean.'}],
temperature=1.0, # leave temperature at default
top_p=0.9 # sample from top 90% nucleus
)
print(resp.choices[0].message.content)p=1.0: การสุ่มโดยไม่มีข้อจำกัด
เมื่อ top_p=1.0 กลุ่มแกนกลางจะรวมโทเค็นทั้งหมด ซึ่งก็คือชุดคำศัพท์ทั้งหมด การทำงานนี้เทียบเท่ากับการสุ่มตามอุณหภูมิเพียงอย่างเดียวโดยไม่มีข้อจำกัดจาก top-p โทเค็นทุกตัว ไม่ว่าจะมีความน่าจะเป็นต่ำเพียงใด ก็มีโอกาสที่ไม่เป็นศูนย์ในการถูกเลือก
ใช้ p=1.0 เมื่อคุณต้องการความหลากหลายสูงสุด ที่ p=1.0 มีเพียงอุณหภูมิเท่านั้นที่ควบคุมรูปร่างของการแจกแจง
# p=1.0: all tokens in nucleus
resp_full = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Generate a creative story opening.'}],
temperature=1.0,
top_p=1.0 # no nucleus restriction
)
# p=0.5: very focused nucleus
resp_focused = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Generate a creative story opening.'}],
temperature=1.0,
top_p=0.5 # only top 50% probability mass
)ข้อแลกเปลี่ยน: top-p กับอุณหภูมิ
พารามิเตอร์ทั้งสองควบคุมความหลากหลายของผลลัพธ์ แต่ทำงานแตกต่างกัน:
- อุณหภูมิ ปรับรูปร่างของการแจกแจงทั้งหมด — ความน่าจะเป็นสัมพัทธ์ของโทเค็นเมื่อเทียบกับโทเค็นอื่นทั้งหมดจะเปลี่ยนไป
- Top-p ตัดการแจกแจง — โทเค็นจะถูกตัดออกทันทีหากอยู่นอกกลุ่มแกนกลาง โดยไม่ขึ้นกับความน่าจะเป็นสัมพัทธ์ของโทเค็นนั้น
Top-p ป้องกันปัญหา 'การสุ่มจากส่วนหาง': เมื่อใช้อุณหภูมิสูง โทเค็นที่ไม่น่าจะเป็นอย่างยิ่ง (ข้อความไร้สาระหรือคำที่ไม่เกี่ยวข้อง) อาจถูกสุ่มได้เป็นครั้งคราว Top-p จะนำโทเค็นเหล่านี้ออกจากการพิจารณาโดยสิ้นเชิง
# The tail problem with temperature alone
high_temp_logits = np.array([3.0, 2.0, 1.0, 0.0, -1.0, -5.0, -10.0])
probs_high_temp = softmax(high_temp_logits, temperature=2.0)
print('High temp probs:', np.round(probs_high_temp, 4))
# The last token (logit=-10) still has a small probability
# With many tokens in a real vocab, these rare tokens accumulate
# and occasionally get sampled, producing incoherent output
# Top-p=0.9 cuts these off entirely
# ensuring only tokens contributing to the top 90% are consideredการใช้อุณหภูมิและ top-p ร่วมกัน
เมื่อใช้พารามิเตอร์ทั้งสองร่วมกัน จะใช้อุณหภูมิก่อน (เพื่อปรับรูปร่างของการแจกแจง) จากนั้นจึงใช้ top-p กับความน่าจะเป็นที่ได้ (เพื่อตัดให้เหลือกลุ่มแกนกลาง)
การกำหนดค่าที่ใช้บ่อยในการใช้งานจริง:
- การเขียนเชิงสร้างสรรค์: temp=1.0, top_p=0.95
- การสนทนา: temp=0.8, top_p=0.9
- โค้ด: temp=0.2, top_p=1.0 (top-p ไม่จำกัดมากนักเมื่ออุณหภูมิต่ำ)
def combined_sample(logits, temperature=1.0, top_p=0.9):
# Step 1: apply temperature
probs = softmax(logits, temperature=temperature)
# Step 2: apply top-p nucleus
sorted_idx = np.argsort(probs)[::-1]
sorted_probs = probs[sorted_idx]
cumulative = np.cumsum(sorted_probs)
nucleus_size = np.searchsorted(cumulative, top_p) + 1
nucleus_idx = sorted_idx[:nucleus_size]
nucleus_probs = probs[nucleus_idx]
nucleus_probs = nucleus_probs / nucleus_probs.sum()
return np.random.choice(nucleus_idx, p=nucleus_probs)Top-p กับการเกิดซ้ำ
ค่า top-p ต่ำอาจทำให้เกิดการซ้ำ เมื่อกลุ่มแกนกลางมีขนาดเล็กมาก (เช่น p=0.5) โมเดลจะสุ่มซ้ำ ๆ จากชุดโทเค็นขนาดเล็ก ผลลัพธ์จะซ้ำและคาดเดาได้ง่าย ซึ่งตรงข้ามกับผลด้านความสร้างสรรค์ที่ต้องการ
ให้สังเกตการซ้ำเพื่อใช้เป็นสัญญาณว่า top-p ต่ำเกินไปสำหรับงานนั้น ตัวบ่งชี้ที่มีประโยชน์คือ หากโมเดลวนซ้ำอยู่กับวลีเดิม ให้เพิ่ม top-p หรืออุณหภูมิ
def detect_repetition(text, window=20):
words = text.split()
if len(words) < window * 2:
return False
# Check if any window of words repeats within the text
for i in range(len(words) - window):
phrase = ' '.join(words[i:i + window])
rest = ' '.join(words[i + window:])
if phrase in rest:
return True
return False
response = call_llm(prompt)
if detect_repetition(response):
print('Warning: repetition detected — consider increasing top_p or temperature')Top-p กับ top-k: ดูภาพรวม
ทั้ง top-p และ top-k จะตัดชุดคำศัพท์ก่อนการสุ่มตัวอย่าง แต่ทำงานแตกต่างกัน:
- Top-p: ขนาดกลุ่มแกนกลางปรับเปลี่ยนได้ — ขยายเมื่อโมเดลไม่แน่ใจ และหดลงเมื่อโมเดลมั่นใจ
- Top-k: ขนาดกลุ่มแกนกลางคงที่ — พิจารณาโทเค็นจำนวน k รายการพอดีเสมอ ไม่ว่าระดับความมั่นใจจะเป็นอย่างไร
โดยทั่วไปนิยมใช้ top-p มากกว่า เพราะปรับตามระดับความมั่นใจของโมเดลได้ ส่วน top-k จะอธิบายโดยละเอียดในบทเรียนถัดไป
# Top-k equivalent for comparison
def top_k_sample(logits, k=50):
probs = softmax(logits)
# Keep only top-k tokens
top_k_indices = np.argsort(probs)[::-1][:k]
top_k_probs = probs[top_k_indices]
top_k_probs = top_k_probs / top_k_probs.sum()
return np.random.choice(top_k_indices, p=top_k_probs)
# Key difference: k is always 50, regardless of model confidence
# Top-p nucleus size varies from 1 to thousands depending on confidenceค่าเริ่มต้นและเวลาที่ควรเปลี่ยน
ค่าเริ่มต้นของส่วนต่อประสานโปรแกรมประยุกต์: top_p = 1.0 (ไม่มีข้อจำกัดจากกลุ่มแกนกลาง) ควรเปลี่ยนค่าเมื่อใด
- ลด top_p (0.7–0.9): เมื่อผลลัพธ์ดูไม่สอดคล้องกันหรือมีคำที่ไร้ความหมาย — มีการสุ่มจากส่วนหางมากเกินไป
- คงไว้ที่ 1.0: เมื่ออุณหภูมิต่ำอยู่แล้ว — ที่อุณหภูมิต่ำ การแจกแจงจะมีจุดเด่นชัดอยู่แล้ว และ top-p ก็ไม่ได้จำกัดเพิ่มเติมมากนัก
- อย่าลดให้ต่ำกว่า 0.5: เพราะจะทำให้เกิดการซ้ำและสูญเสียความหลากหลาย
# Guidance: what to adjust based on symptoms
TROUBLESHOOTING = {
'output is incoherent or contains random words': {
'fix': 'lower top_p to 0.9 or 0.85',
'or': 'lower temperature'
},
'output is repetitive and looping': {
'fix': 'increase top_p or temperature',
'also': 'try adding frequency_penalty or presence_penalty'
},
'output is too predictable and boring': {
'fix': 'increase temperature to 0.9-1.2',
'keep': 'top_p at 0.95'
},
'output needs to be deterministic': {
'fix': 'set temperature=0, top_p=1.0'
}
}Top-p ใน Anthropic Claude
ส่วนต่อประสานโปรแกรมประยุกต์ของ Anthropic Claude ยังเปิดให้ใช้ top_p เป็นพารามิเตอร์ด้วย การทำงานเหมือนกันทุกประการ: โมเดลจะสร้างกลุ่มแกนกลางจากชุดโทเค็นที่เล็กที่สุดซึ่งมีความน่าจะเป็นสะสมถึงค่าขีดจำกัด p จากนั้นจึงสุ่มจากกลุ่มแกนกลางนั้น
ใช้ร่วมกับอุณหภูมิเพื่อควบคุมได้ละเอียด: ใช้อุณหภูมิเพื่อกำหนดรูปร่างของการแจกแจง และใช้ top_p เพื่อจำกัดว่าโทเค็นใดบ้างที่เลือกได้จากการแจกแจงนั้น
import anthropic
claude = anthropic.Anthropic(api_key='sk-ant-...')
# Creative writing with nucleus sampling
message = claude.messages.create(
model='claude-opus-4-5',
max_tokens=256,
temperature=1.0,
top_p=0.95,
messages=[{
'role': 'user',
'content': 'Write a short poem about the ocean.'
}]
)
print(message.content[0].text)ตรวจสอบความรู้
ข้อได้เปรียบสำคัญของการสุ่มแบบ top-p (กลุ่มแกนกลาง) เหนือการสุ่มแบบ top-k คืออะไร
สรุป: การสุ่มแบบ top-p จากกลุ่มแกนกลาง
การสุ่มแบบ top-p สร้างกลุ่มแกนกลางที่ปรับเปลี่ยนได้ ซึ่งเป็นชุดโทเค็นที่เล็กที่สุดและครอบคลุมความน่าจะเป็นรวมอย่างน้อย p:
- p=1.0: ชุดคำศัพท์ทั้งหมด ไม่มีข้อจำกัด
- p=0.9: มวลความน่าจะเป็น 90% แรก — ค่าที่ใช้ทั่วไปสำหรับงานสร้างสรรค์
- p=0.5: มุ่งเน้นมาก — มีความเสี่ยงที่จะเกิดการซ้ำ
กลุ่มแกนกลางจะขยายเมื่อโมเดลไม่แน่ใจ และหดลงเมื่อโมเดลมั่นใจ วิธีนี้ป้องกันการสุ่มจากส่วนหาง (ข้อความไร้สาระจากโทเค็นที่ไม่น่าจะเป็น) พร้อมทั้งรักษาความหลากหลายไว้ บทเรียนถัดไป: การสุ่มแบบ top-k และความแตกต่างจาก top-p
คำถามที่พบบ่อย
บทเรียน “การสุ่มตัวอย่างนิวเคลียสแบบ top-p” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสุ่มตัวอย่างนิวเคลียสแบบ top-p” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Prompt Engineering ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสุ่มตัวอย่างนิวเคลียสแบบ top-p”
top-p จำกัดการสุ่มตัวอย่างไว้ที่ชุดโทเค็นซึ่งมีความน่าจะเป็นสูงที่สุดได้อย่างไร คุณปฏิบัติ AI Prompt Engineering ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Prompt Engineering หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Prompt Engineering บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การสุ่มตัวอย่างนิวเคลียสแบบ top-p” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Prompt Engineering นี้ได้ไหม
ได้ บทเรียน AI Prompt Engineering ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- อุณหภูมิใน LLM คืออะไร
- การสุ่มตัวอย่างนิวเคลียสแบบ top-p
- การสุ่มตัวอย่างแบบ top-k
- การเลือกพารามิเตอร์ให้เหมาะกับกรณีใช้งาน