การสุ่มตัวอย่างแบบ top-k
จำกัดตัวเลือกไว้ที่โทเค็น k รายการซึ่งมีความน่าจะเป็นสูงที่สุด และผลต่อความหลากหลายของข้อมูลส่งออก
การสุ่มตัวอย่างแบบ top-k เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Prompt Engineering และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
การสุ่มแบบ top-k คืออะไร
การสุ่มแบบ top-k จำกัดให้โมเดลสุ่มจาก โทเค็นที่มีความน่าจะเป็นสูงสุดจำนวน k รายการ ในแต่ละขั้นตอน โทเค็นทั้งหมดที่อยู่นอก top-k จะถูกกำหนดให้มีความน่าจะเป็นเป็นศูนย์และไม่สามารถถูกเลือกได้
k=1 คือการถอดรหัสแบบเลือกโทเค็นที่มีความน่าจะเป็นสูงสุด (มีโทเค็นที่มีความน่าจะเป็นสูงสุดเพียงรายการเดียว) k=50 เป็นช่วงค่าทั่วไปสำหรับงานสร้างสรรค์ k=vocabulary_size เทียบเท่ากับการสุ่มโดยไม่มีข้อจำกัด
ขั้นตอนวิธี Top-k
ขั้นตอนวิธีนี้ง่ายกว่า top-p:
- คำนวณความน่าจะเป็นจาก softmax สำหรับชุดคำศัพท์ทั้งหมด
- เรียงโทเค็นตามความน่าจะเป็นจากมากไปน้อย
- เก็บไว้เฉพาะโทเค็น k รายการแรก และกำหนดโทเค็นที่เหลือทั้งหมดให้เป็น 0
- ปรับความน่าจะเป็นของ top-k ใหม่ให้ผลรวมเป็น 1
- สุ่มจากการแจกแจงที่ปรับใหม่แล้ว
import numpy as np
def softmax(logits, temperature=1.0):
scaled = logits / temperature
e = np.exp(scaled - np.max(scaled))
return e / e.sum()
def top_k_sample(logits, k=50, temperature=1.0):
probs = softmax(logits, temperature)
# Find top-k indices
top_k_indices = np.argsort(probs)[::-1][:k]
top_k_probs = probs[top_k_indices]
# Renormalize
top_k_probs = top_k_probs / top_k_probs.sum()
# Sample
chosen = np.random.choice(top_k_indices, p=top_k_probs)
return chosen
# With a 10-token vocabulary:
logits = np.random.randn(10)
print('Chosen token:', top_k_sample(logits, k=3))k=1: การถอดรหัสแบบเลือกค่าที่น่าจะเป็นสูงสุด
เมื่อ k=1 ชุดตัวเลือกจะมีโทเค็นที่มีความน่าจะเป็นสูงสุดเพียงรายการเดียว การสุ่มจากชุดที่มีขนาด 1 จะให้ผลลัพธ์ที่กำหนดแน่นอน โมเดลจะเลือกโทเค็นนั้นเสมอ ซึ่งเหมือนกับการถอดรหัสแบบเลือกค่าที่น่าจะเป็นสูงสุด (temperature=0)
logits = np.array([3.0, 2.0, 1.0, 0.5, -1.0])
# k=1: greedy
top_1 = top_k_sample(logits, k=1)
print(f'k=1 always picks: {np.argmax(logits)}') # index 0, the highest logit
print(f'top_k_sample result: {top_1}') # always 0
# Multiple runs
for _ in range(5):
print(top_k_sample(logits, k=1), end=' ')
# Output: 0 0 0 0 0 — perfectly deterministicช่วงค่าทั่วไปสำหรับงานสร้างสรรค์: k=50
k=50 เป็นค่าเริ่มต้นที่ใช้บ่อยสำหรับการสร้างข้อความเชิงสร้างสรรค์ ค่านี้เปิดให้สำรวจโทเค็น 50 รายการในแต่ละขั้นตอน พร้อมป้องกันไม่ให้โมเดลเลือกโทเค็นที่มีความมั่นใจต่ำมาก
เมื่อชุดคำศัพท์มีโทเค็น 50,000 รายการ k=50 หมายความว่าโมเดลจะพิจารณาเฉพาะโทเค็น 0.1% แรกในแต่ละขั้นตอนเท่านั้น นี่เป็นข้อจำกัดอย่างมาก เพราะโทเค็นส่วนใหญ่ในชุดคำศัพท์จะถูกตัดออก
import openai
client = openai.OpenAI(api_key='sk-...')
# Note: OpenAI API does not expose top_k directly in chat completions.
# Top-k is primarily a parameter in Hugging Face Transformers and Anthropic's API.
# Hugging Face example:
from transformers import pipeline
generator = pipeline('text-generation', model='gpt2')
output = generator(
'Once upon a time',
max_new_tokens=100,
do_sample=True,
top_k=50,
temperature=1.0
)
print(output[0]['generated_text'])Top-k ในส่วนต่อประสานโปรแกรมประยุกต์ของ Anthropic Claude
ส่วนต่อประสานโปรแกรมประยุกต์ของ Anthropic Claude เปิดให้ใช้ top_k เป็นพารามิเตอร์โดยตรง ทำให้ทดลองผลของการตัดชุดคำศัพท์แบบคงที่ที่มีต่อผลลัพธ์ของ Claude ได้ง่าย
import anthropic
claude = anthropic.Anthropic(api_key='sk-ant-...')
# top_k limits the number of tokens considered
message = claude.messages.create(
model='claude-opus-4-5',
max_tokens=256,
temperature=1.0,
top_k=50, # sample from top 50 most probable tokens
messages=[{
'role': 'user',
'content': 'Write a short poem about debugging code.'
}]
)
print(message.content[0].text)ปัญหาของค่า k คงที่
ข้อจำกัดพื้นฐานของ top-k คือ ค่า k คงที่ ไม่ว่าระดับความมั่นใจของโมเดลในขั้นตอนนั้นจะเป็นอย่างไร
เมื่อโมเดลมีความมั่นใจสูงมาก (โทเค็นหนึ่งมีความน่าจะเป็น 95%) k=50 ก็ยังรวมโทเค็นที่ไม่เกี่ยวข้องเป็นส่วนใหญ่อีก 49 รายการไว้ด้วย เมื่อโมเดลไม่แน่ใจอย่างมาก (โทเค็น 50 รายการมีความน่าจะเป็นรายการละประมาณ 2%) k=50 อาจเป็นค่าที่เหมาะสมจริง ๆ
ปัญหาคือ k=50 อาจจำกัดมากเกินไปและเปิดกว้างเกินไปได้พร้อมกัน ขึ้นอยู่กับบริบท top-p แก้ปัญหานี้ด้วยการกำหนดขนาดกลุ่มแกนกลางแบบปรับเปลี่ยนได้
# Illustrating the fixed-k problem
logits_confident = np.array([5.0] + [0.1] * 9) # model is very sure
logits_uncertain = np.array([1.0] * 10) # model has no idea
probs_conf = softmax(logits_confident)
probs_unc = softmax(logits_uncertain)
print('Confident — top 3 tokens cover:', np.sort(probs_conf)[::-1][:3].sum().round(3))
# ~0.998 — k=50 is extremely wasteful, includes near-zero probability tokens
print('Uncertain — top 3 tokens cover:', np.sort(probs_unc)[::-1][:3].sum().round(3))
# ~0.30 — k=50 may actually be needed to cover a reasonable nucleusTop-k ที่ส่วนหางของการแจกแจง
Top-k และ top-p แตกต่างกันอย่างชัดเจนที่สุดที่ ส่วนหางของการแจกแจง:
- เมื่อใช้ top-k=50 โทเค็นลำดับที่ 50 อาจมีความน่าจะเป็น 0.001% (ไม่น่าจะเป็นอย่างยิ่ง แต่ยังอยู่ในชุดตัวเลือก)
- เมื่อใช้ top-p=0.9 โทเค็นใดก็ตามที่อยู่นอกกลุ่มแกนกลาง 90% จะถูกตัดออก รวมถึงโทเค็นที่อาจอยู่ใน top-k ด้วย
Top-p จัดการกับพฤติกรรมของส่วนหางได้มีหลักการมากกว่า โดยตัดโทเค็นที่ไม่น่าจะเป็นออกตามความน่าจะเป็น ไม่ใช่ตามตำแหน่งในลำดับจัดอันดับ
# Tail behavior comparison
import numpy as np
# Highly skewed distribution (one dominant token)
skewed_logits = np.array([4.0, 2.0, 1.5, 1.0, 0.5,
0.1, 0.0, -0.1, -0.5, -1.0])
probs = softmax(skewed_logits)
print('Probability of tokens 6-9 (tail):')
for i in range(6, 10):
print(f' Token {i}: {probs[i]:.4%}')
# These tokens are very unlikely but are included in top-k=10
# Top-p=0.9 would exclude them entirelyการใช้ top-k และ top-p ร่วมกัน
การนำไปใช้บางรูปแบบใช้ทั้ง top-k และ top-p โดยตัดให้เหลือ top-k ก่อน แล้วจึงใช้การสุ่มจากกลุ่มแกนกลางแบบ top-p ภายในชุดนั้น วิธีนี้กำหนดขีดจำกัดตายตัวของขนาดชุดคำศัพท์ด้วย top-k พร้อมทั้งใช้การกรองตามความน่าจะเป็นด้วย top-p
def top_k_top_p_sample(logits, k=50, p=0.9, temperature=1.0):
probs = softmax(logits, temperature)
# First apply top-k
top_k_indices = np.argsort(probs)[::-1][:k]
top_k_probs = probs[top_k_indices]
# Then apply top-p within top-k
sorted_k = np.sort(top_k_probs)[::-1]
cumulative = np.cumsum(sorted_k)
nucleus_size = np.searchsorted(cumulative, p) + 1
final_indices = top_k_indices[:nucleus_size]
final_probs = top_k_probs[:nucleus_size]
final_probs = final_probs / final_probs.sum()
return np.random.choice(final_indices, p=final_probs)เมื่อควรเลือกใช้ Top-k แทน Top-p
แม้ top-p จะมีข้อได้เปรียบทางทฤษฎี แต่ในบางสถานการณ์นิยมใช้ top-k มากกว่า:
- งานที่มีชุดคำศัพท์จำกัด: เมื่อโมเดลควรส่งออกเฉพาะค่าจากชุดที่กำหนดไว้ (เช่น แบบเลือกตอบ A/B/C/D) ค่า top-k ขนาดเล็ก (4) จะบังคับใช้ข้อจำกัดนี้โดยตรง
- การทำซ้ำผลลัพธ์: พฤติกรรมของ top-k เข้าใจได้ง่ายกว่า — “พิจารณาโทเค็น 50 รายการพอดีเสมอ”
- การนำไปใช้ที่ปรับให้เหมาะกับฮาร์ดแวร์: กลไกอนุมานบางชนิดใช้ top-k ได้มีประสิทธิภาพมากกว่า top-p
# Constrained output with top-k=4
# For a multiple choice task (A, B, C, D)
# If A/B/C/D tokens have indices 32, 33, 34, 35
# top-k=4 with those as the top-4 logits forces selection from those 4 only
multiple_choice_prompt = (
'Answer with only A, B, C, or D.\n'
'What is the capital of France?\n'
'A) Berlin\n'
'B) Paris\n'
'C) Rome\n'
'D) Madrid\n'
'Answer:'
)
# With temperature=0, top_k=1: always picks the highest logit tokenแนวทางการใช้ Top-k ในทางปฏิบัติ
ควรใช้ top-k เมื่อใด และควรเลือกค่าเท่าใด:
- k=1: การเลือกค่าที่น่าจะเป็นสูงสุด / งานข้อเท็จจริง
- k=5–20: งานสร้างสรรค์ที่มุ่งเน้น ความหลากหลายน้อย
- k=40–100: ช่วงค่ามาตรฐานสำหรับงานสร้างสรรค์ในโมเดลภาษาส่วนใหญ่
- k=500+: การสำรวจที่เปิดกว้างมาก (ไม่ค่อยจำเป็น ควรใช้ top-p แทน)
ในส่วนต่อประสานโปรแกรมประยุกต์ของ LLM สมัยใหม่ส่วนใหญ่ top-p เป็นพารามิเตอร์ที่นิยมใช้มากกว่า ใช้ top-k เมื่อคุณต้องการจำกัดขนาดชุดคำศัพท์อย่างตายตัว หรือเมื่อส่วนต่อประสานโปรแกรมประยุกต์มี top-k ให้ใช้แต่ไม่มี top-p
TOP_K_GUIDELINES = {
'factual_qa': 1, # greedy
'code_generation': 10, # near-greedy, correct syntax
'summarization': 20, # slightly varied but focused
'chat': 50, # natural variation
'creative_writing': 100, # wider vocabulary exploration
'poetry': 200, # unusual word choices encouraged
}
def call_with_top_k(task, prompt, model='claude-opus-4-5'):
k = TOP_K_GUIDELINES.get(task, 50)
claude = anthropic.Anthropic(api_key='sk-ant-...')
return claude.messages.create(
model=model,
max_tokens=512,
top_k=k,
messages=[{'role': 'user', 'content': prompt}]
)การใช้ k อันดับแรกและอุณหภูมิร่วมกัน
การสุ่มแบบ k อันดับแรกและอุณหภูมิจะถูกนำมาใช้ตามลำดับ: เริ่มจากอุณหภูมิปรับรูปร่างการกระจายของลอจิต จากนั้นจึงตัดทอนให้เหลือโทเค็นที่มีความน่าจะเป็นสูงสุด k รายการ การใช้ทั้งสองอย่างร่วมกันพบได้บ่อยในกระบวนการทำงานของ Hugging Face Transformers
การตั้งค่าที่ใช้กันทั่วไป: อุณหภูมิ=0.9 (ความหลากหลายระดับปานกลาง) + จำนวนโทเค็นสูงสุด k=50 (จำกัดคลังคำอย่างเข้มงวด) วิธีนี้ช่วยหลีกเลี่ยงทั้งความแบนราบจากการใช้อุณหภูมิสูงเพียงอย่างเดียวและปัญหาการสุ่มจากส่วนหาง
from transformers import pipeline
generator = pipeline('text-generation', model='gpt2')
# Combined top-k + temperature
output = generator(
'The future of AI is',
max_new_tokens=80,
do_sample=True,
top_k=50,
temperature=0.9
)
print(output[0]['generated_text'])
# Compare: top-k=1 (greedy)
greedy_output = generator(
'The future of AI is',
max_new_tokens=80,
do_sample=False # greedy, equivalent to top_k=1
)
print(greedy_output[0]['generated_text'])ตรวจสอบความรู้
ในการสุ่มแบบ k อันดับแรก หากกำหนด k=1 โมเดลจะแสดงพฤติกรรมใด
ทบทวน: การสุ่มแบบ k อันดับแรก
การสุ่มแบบ k อันดับแรกจะตัดทอนคลังคำให้เหลือโทเค็นที่มีความน่าจะเป็นสูงสุด k รายการก่อนการสุ่ม:
- k=1: การถอดรหัสโดยเลือกตัวเลือกสูงสุด — กำหนดผลแน่นอนและเลือกโทเค็นอันดับสูงสุดเสมอ
- k=50: ช่วงสร้างสรรค์ที่ใช้กันทั่วไป — สมดุลระหว่างความหลากหลายและความสอดคล้อง
- ข้อจำกัดสำคัญ: ค่า k คงที่โดยไม่คำนึงถึงความมั่นใจของโมเดล — อาจเปิดกว้างหรือจำกัดมากเกินไป
- เทียบกับการสุ่มแบบนิวเคลียส: ขอบเขตนิวเคลียสแบบไดนามิกจะปรับตามความมั่นใจ แต่การสุ่มแบบ k อันดับแรกไม่ปรับ
ใช้การสุ่มแบบ k อันดับแรกเมื่อต้องการจำกัดคลังคำอย่างเข้มงวด สำหรับแอปพลิเคชันใช้งานจริงส่วนใหญ่ ควรเลือกการสุ่มแบบนิวเคลียส บทเรียนถัดไป: การเลือกพารามิเตอร์สำหรับกรณีการใช้งานเฉพาะของคุณ
คำถามที่พบบ่อย
บทเรียน “การสุ่มตัวอย่างแบบ top-k” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสุ่มตัวอย่างแบบ top-k” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Prompt Engineering ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสุ่มตัวอย่างแบบ top-k”
จำกัดตัวเลือกไว้ที่โทเค็น k รายการซึ่งมีความน่าจะเป็นสูงที่สุด และผลต่อความหลากหลายของข้อมูลส่งออก คุณปฏิบัติ AI Prompt Engineering ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Prompt Engineering หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Prompt Engineering บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การสุ่มตัวอย่างแบบ top-k” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Prompt Engineering นี้ได้ไหม
ได้ บทเรียน AI Prompt Engineering ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- อุณหภูมิใน LLM คืออะไร
- การสุ่มตัวอย่างนิวเคลียสแบบ top-p
- การสุ่มตัวอย่างแบบ top-k
- การเลือกพารามิเตอร์ให้เหมาะกับกรณีใช้งาน