Temperature, Top-p, dan Determinisme yang Sebenarnya Tidak Kamu Punya
Temperature membagi logits sebelum softmax—fakta kecil yang meruntuhkan ide “tombol kreativitas”.
Di halaman ini
Inilah request yang sama dikirim ke model yang sama lima kali. Bobot yang sama, prompt yang sama, mesin yang sama, random seed yang sama. Satu-satunya hal yang berubah hanyalah satu angka.
prompt: "Q: What is the capital of France?\nA:"
T = 0.0 " Paris\nWhat is the question and does the answer answer it? The
question is: What is the capital of France?..."
T = 0.7 " Paris\nWhat is the question: Which city is the capital of
France?..."
T = 1.0 " Paris\nWhat is a good geographical qualifier for describing
Paris concerning its location?\nA: Near the Mediterranean Sea..."
T = 1.5 " Paris\nWhat clue from premise allows we to conclude that Godwin
was &, He chose Healing Crimson Colour No:white flour Pure..."
T = 2.0 "安全感金华.ITEMT]]];\naims assume parental.st-importe.valtermination
Screens قطر_Zeroหมายเลข-zA ('$ספטמבר..."Tidak ada yang rusak. Setiap token di baris terakhir diambil secara sah dari distribusi probabilitas model itu sendiri atas kosakata berisi 151.936 entri. Angka yang berubah disebut temperature, di sebagian besar dokumentasi dijelaskan sebagai tombol kreativitas, dan deskripsi itu keliru dengan cara yang bisa bab ini demonstrasikan, bukan sekadar klaim.
Ini juga bab tempat tiga janji sebelumnya akhirnya dibayar. Bab 4 mendefinisikan logit dan belum benar-benar memakainya. Kotak floating-point di Bab 2 berakhir dengan instruksi — ingat ini saat Bab 17 bertanya mengapa prompt, model, dan seed yang sama bisa menghasilkan token berbeda. Dan kotak mixture-of-experts di Bab 9 menjanjikan katalog empat penyebab non-determinisme. Ketiganya muncul di bawah.
Satu baris yang menopang seluruh bab
Tautan ke bagian: Satu baris yang menopang seluruh babBab 4 memperkenalkan logit sebagai skor bernilai riil yang belum dinormalisasi, satu per kelas. Bab 8 membuat language model menghasilkan satu skor per entri kosakata. softmax mengubah vektor itu menjadi probabilitas:
Temperature masuk di sini — namanya dipinjam dari fisika statistik, tempat parameter yang sama mengontrol seberapa tajam distribusi Boltzmann berkonsentrasi pada state berenergi rendahnya1 — dan ia membagi logits sebelum eksponensial:
Penempatan itu adalah seluruh mekanismenya, dan dua baris aljabar cukup untuk melihat mengapa ia tidak mungkin berada di tempat lain. Misalkan kamu mencoba menerapkan temperature ke probabilitas saja — menskalakannya dengan lalu menormalisasi ulang. Kamu akan mendapat
Konstantanya saling meniadakan. Menskalakan probabilitas tidak melakukan apa pun; distribusinya kembali tanpa berubah. Temperature hanya berpengaruh karena ia bekerja pada eksponen, tempat membagi dengan sebelum mengeksponensialkan sama dengan menaikkan setiap probabilitas ke pangkat — pembentukan ulang nonlinier yang mengubah rasio antar-entri, bukan skala bersama mereka.
Dari penempatan itu, kedua batas langsung mengikuti tanpa kerja tambahan. Saat , logit terbesar menjauh dari yang lain dan runtuh ke satu token dengan skor tertinggi: greedy decoding. Saat membesar, setiap menuju nol, setiap eksponensial menuju 1, dan distribusi merata menuju uniform atas seluruh kosakata. Tepat pada , rumusnya membagi dengan nol, jadi setiap implementasi menanganinya secara khusus sebagai maksimum aritmetis — termasuk widget di bawah, yang beralih ke argmax pada .
Satu peringatan, karena benturan nama ini menimbulkan kebingungan nyata. Ada hal kedua yang tidak terkait bernama temperature dalam machine learning: temperature scaling, metode kalibrasi yang menyesuaikan satu nilai pada validation set agar confidence classifier cocok dengan akurasinya.2 Rumusnya sama, tidak ada hubungannya dengan generation. Paper yang mengatakan “temperature” sering berarti yang itu; bab ini tidak pernah begitu.
Inilah distribusi itu, dengan aritmetikanya di depan matamu. Logits-nya tetap dan masuk akal, jadi angka-angka dalam prosa di bawah bisa kamu cocokkan dengan yang terlihat:
Temperature bukan tombol kreativitas
Tautan ke bagian: Temperature bukan tombol kreativitasAngka ␣banana adalah seluruh argumen dalam bentuk mini: menaikkan temperature tidak bisa memberi model ide yang tidak ia miliki. Logits sudah dihitung, ranking sudah tetap, dan temperature mempertahankannya persis — sepanas apa pun, token berskor lebih rendah tidak pernah berpindah ke atas token berskor lebih tinggi. Yang ia lakukan hanyalah mendistribusikan ulang mass ke bawah sepanjang ranking yang dihasilkan model itu sendiri. Temperature tinggi tidak membuat model lebih inventif; ia membuat model lebih mungkin mengeluarkan token yang ia nilai buruk.
Pada kosakata nyata, ini berhenti menjadi keanehan kecil dan menjadi alasan output temperature tinggi tidak bisa dipakai. Diukur pada Qwen/Qwen2.5-0.5B-Instruct, satu forward pass, prompt di atas, menghitung berapa banyak token yang dibutuhkan untuk mengakumulasi bagian tertentu dari probability mass:
| temperature | probabilitas top-1 | entropy | token yang memegang 80 % | 90 % | 95 % | 99 % |
|---|---|---|---|---|---|---|
| 0.5 | 99,98 % | 0,00 nats | 1 | 1 | 1 | 1 |
| 0.7 | 99,65 % | 0,03 nats | 1 | 1 | 1 | 1 |
| 1.0 | 96,01 % | 0,30 nats | 1 | 1 | 1 | 14 |
| 1.2 | 88,20 % | 0,88 nats | 1 | 2 | 13 | 252 |
| 1.5 | 62,83 % | 3,07 nats | 29 | 353 | 2.672 | 26.787 |
| 2.0 | 16,62 % | 8,19 nats | 13.516 | 32.966 | 55.231 | 101.205 |
Baca baris terbawah pelan-pelan. Pada , untuk pertanyaan dengan tepat satu jawaban benar, 32.966 token berbeda berbagi 90 % teratas dari probability mass. Itu bukan ruang kreatif yang lebih luas. Itu model yang diberi tahu, oleh aritmetika, untuk memperlakukan partikel bahasa Korea dan identifier C++ sebagai opsi hidup untuk kata setelah A:. Sampah di blok pembuka adalah konsekuensi langsungnya, dan itu bukan bug di model atau library — itulah yang diminta request tersebut.
Rentang yang berguna sempit dan bergantung pada tugas, bukan selera. Pada pertanyaan faktual, jawabannya satu token dan panas apa pun di atas sekitar 1,2 menyuntikkan error tanpa manfaat. Pada pertanyaan terbuka, memang ada lebih dari satu kelanjutan yang baik, dan sedikit panas membeli variasi yang tetap lancar:
"Write a two-sentence story about a lighthouse."
T = 0.0 "The lighthouse stood tall and proud, its beacon illuminating the
night sky above. A lone sailor, his eyes fixed on the distant
horizon..."
T = 0.7 "In the quiet, stormy waters of the sea, a lighthouse stood
sentinel over the horizon, its golden dome casting a warm glow
on the fog-shrouded streets below..."
T = 1.0 "In the quiet night, a lone lighthouse stood sentinel over the
sea, its shining beacon a beacon of hope and solace for sailors
and fishermen across the vast and endless ocean..."
T = 1.3 "In the gentle sunlight, now reflecting upon the opening of Jack's
lighthouse, Jim Trahan, a small-time individual difficult to
define in paperwork, wondered about a career where simplicity
reigns..."Pada 1,3 model sudah menciptakan nama diri dan kalimat yang tidak bisa diparse. Rentang antara “identik setiap kali” dan “tidak koheren” kira-kira 0,6 sampai 1,1 untuk model ini pada tugas ini, dan saran jujurnya adalah kamu menemukannya dengan mengukur pada tugas kamu, bukan menyalin angka dari blog post.
Mengapa teks yang paling mungkin adalah teks yang buruk
Tautan ke bagian: Mengapa teks yang paling mungkin adalah teks yang burukAda pertanyaan jelas yang bersembunyi di balik semua ini: jika model punya distribusi probabilitas dan satu token paling mungkin, mengapa tidak selalu mengambilnya? Greedy decoding gratis, reproducible, dan tidak butuh parameter.
Karena hasilnya seperti ini:
prompt: "In a shocking finding, scientists discovered a herd of unicorns
living in a remote valley."
greedy: " The unicorns were so rare that they were not even recognized by
the local people. The unicorns were so rare that they were not
even recognized by the local people. The unicorns were so rare
that they were not even recognized by the local people. ..."
repeated 4-grams: 87.6 %Delapan kalimat, satu kalimat. Hampir sembilan dari sepuluh window empat token sudah muncul sebelumnya dalam output yang sama. Ini adalah neural text degeneration, dinamai dan dijelaskan oleh Holtzman et al. dalam paper yang memperkenalkan top-p.3 Modelnya tidak rusak; memaksimalkan probabilitas sekuens hanyalah objective yang salah untuk teks terbuka. Tulisan manusia bukanlah urutan kata yang paling mungkin — ia membawa kejutan, probabilitas per token-nya bergerak, turun, lalu pulih — sementara jalur probabilitas maksimum adalah fixed point yang, setelah dimasuki, tidak punya alasan untuk keluar.
Itulah alasan sampling ada. Ini juga, dan bagian ini sering ditinggalkan, bukan hukum universal. Bab 12 mengukur 24 dari 24 benar pada soal kata dua langkah dengan plain greedy decoding, dan sampling pada temperature 0,8 menurunkannya menjadi 81 %; self-consistency lalu menghabiskan enam kali token untuk naik kembali ke tempat greedy sudah berada. Kedua fakta ini sama-sama benar:
Open-ended generation. Tidak ada satu kelanjutan benar, jadi yang paling mungkin adalah jebakan — ia berulang, dan 87,6 % darinya disalin dari dirinya sendiri. Sample.
Tugas dengan satu jawaban benar. Memang ada satu kelanjutan benar, jadi mengambil apa pun selain itu berarti mengambil error. 100 % di Bab 12 menjadi 81 % persis karena alasan ini. Jangan sample.
Sebagian besar prompt production adalah jenis kedua tetapi dikonfigurasi seperti jenis pertama, karena temperature dibiarkan pada apa pun yang dipakai example code.
Dua cara memotong, dan hanya satu yang beradaptasi
Tautan ke bagian: Dua cara memotong, dan hanya satu yang beradaptasiSampling dari distribusi penuh bukanlah yang benar-benar dilakukan siapa pun, karena tail-nya sangat besar dan penuh omong kosong. Sesuatu harus dipotong. Ada dua jawaban klasik dan keduanya berbeda dalam satu hal yang menentukan segalanya.
Top-k mempertahankan jumlah kandidat tetap. Urutkan berdasarkan probabilitas, pertahankan pertama, buang sisanya, normalisasi ulang.4 Top-p, juga disebut nucleus sampling, mempertahankan jumlah mass tetap: ambil token dalam urutan menurun sampai probabilitas kumulatifnya mencapai , lalu berhenti.3 Secara formal, nucleus adalah set terkecil dengan
Perbedaannya terdengar kosmetik, padahal tidak, karena dua prompt yang kamu kirim pada menit yang sama memiliki bentuk distribusi yang sama sekali berbeda. Keduanya adalah model yang sama pada temperature 1:
Q: What is the capital of France?\nA: | Once upon a time, | |
|---|---|---|
| probabilitas top-1 | 96,01 % | 25,39 % |
| token yang memegang 90 % mass | 1 | 467 |
| top-k = 40 mempertahankan | 99,61 % mass | 78,87 % mass |
| mass di ranking 2 sampai 40 | 3,61 % | 53,48 % |
| token di ranking 40 | ␣Av, 0,0093 % | ␣Dr, 0,128 % |
Satu tetap, dua kegagalan berlawanan arah. Pada prompt faktual, mengizinkan 39 token yang secara total bernilai 3,6 % — ia membiarkan sampah masuk, termasuk kandidat pada sembilan per seratus ribu persen, karena aturannya menghitung slot, bukan evidence. Pada prompt cerita, yang sama membuang 21 % mass yang benar-benar diberikan model, karena nucleus sebenarnya di sana selebar 467 token.
Top-p membuat satu angka melakukan kedua pekerjaan itu. Setel dan ia mempertahankan 1 token pada prompt pertama dan 467 pada prompt kedua, karena ia mengajukan pertanyaan tentang distribusi alih-alih memaksakan hitungan padanya. Lihat adaptasi itu langsung — pemotongan yang sama, empat temperature:
Widget itu juga meluruskan miskonsepsi yang perlu dinamai, karena biayanya uang sungguhan. Pada distribusi yang percaya diri, top_p = 0.9 bukan “sedikit variasi”. Itu greedy. Pada temperature 1, token terdepan di sini memegang 96,90 %, yang sudah di atas 0,9, jadi nucleus selebar satu token dan tidak ada yang lain yang bisa pernah diambil. Tim menyetel top_p ke 0,9 dengan keyakinan mereka sudah melonggarkan sesuatu lalu bingung mengapa setiap respons identik.
Setel top-k sebagai gantinya dan kegagalan sebaliknya sama terlihatnya:
Penalty, dengan rumusnya, karena kebingungan di sini endemik
Tautan ke bagian: Penalty, dengan rumusnya, karena kebingungan di sini endemikTiga mekanisme berbeda berjalan dengan nama yang mirip, mereka melakukan hal berbeda, dan perbedaannya bisa diukur. Misalkan adalah berapa kali token sudah muncul.
Presence penalty
Tautan ke bagian: Presence penaltyKurangi konstanta dari token mana pun yang sudah pernah muncul. Muncul sekali dan muncul empat puluh kali dikenai penalty identik. Ini switch, bukan dial.
Frequency penalty
Tautan ke bagian: Frequency penaltyKurangi sebanding dengan hitungan. Token yang dipakai empat kali dikenai penalty empat kali lebih keras daripada token yang dipakai sekali, dan tekanannya berlipat saat teks bertambah.
Repetition penalty (CTRL)
Tautan ke bagian: Repetition penalty (CTRL)Yang asli, dari paper CTRL.7 Ia membagi, bukan mengurangi, dengan kasus tanda yang diperlukan karena membagi logit negatif akan membuatnya lebih besar. Jadi kekuatannya bergantung pada magnitudo logit, yang berarti yang sama menghantam berbeda di titik berbeda dalam kalimat yang sama.
Kelanjutan degeneratif yang sama dari sebelumnya, dengan masing-masing diterapkan. “Steps altered” menghitung berapa dari 120 langkah generation yang memilih token berbeda dibanding yang akan dipilih model tanpa penalty. Run ini 120 langkah, dibanding 140 di blok di atas, itulah mengapa baseline tanpa penalty terbaca 85,5 %, bukan 87,6 %:
| setting | repeated 4-grams | steps altered |
|---|---|---|
| tidak ada | 85,5 % | 0 / 120 |
| presence 0.5 | 65,0 % | 3 / 120 |
| presence 1.0 | 3,4 % | 11 / 120 |
| frequency 0.5 | 6,0 % | 12 / 120 |
| frequency 1.0 | 0,0 % | 20 / 120 |
| repetition 1.2 (CTRL) | 0,0 % | 35 / 120 |
Tiga hal muncul. Presence pada 0,5 mengubah tiga keputusan dari 120 dan memangkas repetisi seperempat — loop itu ditahan oleh segelintir token. Frequency pada 0,5 mengubah keputusan empat kali lebih banyak untuk efek yang jauh lebih besar, karena pengali hitungan terus bertambah sementara konstanta presence tidak. Dan penalty CTRL pada nilai 1,2 yang banyak disalin menulis ulang 35 dari 120 keputusan, yang bukan dorongan kecil; itu model yang berbeda.
Angka terakhir itu adalah setup untuk kegagalan yang tidak diperingatkan siapa pun.
Apa yang dilakukan penalty pada teks yang memang seharusnya berulang
Tautan ke bagian: Apa yang dilakukan penalty pada teks yang memang seharusnya berulangCode berulang. Tabel berulang. Daftar berulang. Structured output berulang menurut definisi — itulah yang disebut struktur. Penalty tidak bisa membedakan antara model yang terjebak dalam loop dan model yang benar mengeluarkan baris keempat sebuah tabel, karena keduanya terlihat seperti token muncul lagi.
Tiga tugas yang sama, dihasilkan dengan tiga cara:
| task | tidak ada | frequency 0.5 | repetition 1.2 |
|---|---|---|---|
| markdown table, 6 rows | 0 / 56 steps altered | 0 / 56 | 2 / 62 |
| Python function | 0 / 93 | 0 / 93 | 10 / 110 |
| bulleted list, 1 to 12 | 0 / 50 | 0 / 50 | 0 / 50 |
Frequency penalty pada 0,5 ternyata tidak berbahaya pada ketiganya, hasil yang berguna dan agak mengejutkan, dan ia mengatakan sesuatu yang presisi: karena tidak ada keputusan yang berubah, token struktural pasti memenangkan posisinya dengan margin lebih besar daripada penalty yang dikurangkan, bahkan setelah muncul lima dan enam kali. Penalty CTRL, yang membagi sebagai gantinya, memang menggeser mereka, dan inilah yang dihasilkannya:
repetition 1.2, markdown table:
| n | 2^n |
| --- | --- |
| 0 | 1 |
| 1 | 2 |
| 2 | 4 |Alignment-nya berantakan: jumlah padding di dalam setiap cell berubah dari baris ke baris, karena deretan spasi sebelum pipe penutup persis jenis repetisi yang ingin dipecah penalty. Kosmetik, dan biayanya enam token ekstra. Kasus Python bukan kosmetik:
nothing / frequency 0.5:
total = 0
for i in range(1, n + 1):
total += i ** 2
return total
repetition 1.2:
# Initialize total_sum with 0
total_sum = 0
# Loop through numbers from 1 to n, incrementing by 2 each time
for i in range(1, n + 1,Penalty mendorong model menjauh dari total — yang sudah dipakai dalam docstring — ke total_sum, mengisi output dengan komentar rekaan untuk menghabiskan budget pada token yang belum dipakai, lalu masuk ke range tiga argumen dengan stride. Komentarnya mengatakan incrementing by 2 each time, yang salah untuk jumlah kuadrat dari 1 sampai . Repetition penalty menghasilkan code yang salah dari prompt yang dijawab benar tanpanya.
Aturan berikutnya singkat: penalty untuk prosa terbuka, dan harus dimatikan untuk code, structured output, data tabular, dan apa pun dengan schema. Bab 18 membahas persis kategori kedua itu.
Urutan penerapan, dan mengapa ia mengubah jawaban
Tautan ke bagian: Urutan penerapan, dan mengapa ia mengubah jawabanSetiap implementasi nyata menerapkan ini dalam satu urutan spesifik:
penalties → temperature → top-k → top-p → sample
Ini bukan pembukuan arbitrer, dan menukar dua tahap menghasilkan distribusi yang benar-benar berbeda. Dua pengukuran, keduanya pada prompt faktual.
Memotong sebelum atau sesudah temperature. Nucleus dihitung pada distribusi apa pun yang diserahkan kepadanya, dan temperature mengubah distribusi itu secara radikal:
| top-p 0.9 setelah temperature | top-p 0.9 sebelum temperature | |
|---|---|---|
| 1 token | 1 token | |
| 353 token | 1 token | |
| 32.966 token | 1 token |
Pada , setting nominal yang sama menghasilkan candidate set berisi 32.966 atau 1, murni tergantung tahap mana yang berjalan dulu. Jika kamu pernah bertanya-tanya mengapa menaikkan temperature “tidak melakukan apa-apa” pada satu provider dan menghancurkan output pada provider lain dengan dua angka yang sama, tabel ini adalah jawaban yang masuk akal.
Memberi penalty sebelum atau sesudah temperature. Mengurangkan penalty lalu membaginya dengan menghasilkan penalty efektif ; membagi dulu lalu mengurangi menghasilkan . Dengan presence penalty 1,0 diterapkan ke token terdepan:
| temperature | beri penalty, lalu temper | temper, lalu beri penalty |
|---|---|---|
| 0.5 | 99,858 % | 99,948 % |
| 1.0 | 89,839 % | 89,839 % |
| 2.0 | 10,783 % | 6,830 % |
Identik pada , sebagaimana harusnya. Berbeda faktor 1,58 pada . “Presence penalty 1.0” bukan jumlah penalty yang terdefinisi dengan baik kecuali kamu juga tahu di mana temperature diterapkan, dan tidak ada API yang mendokumentasikan ini.
Tampilkan detail
Opsional: seluruh pipeline, dalam urutan di atas.
Enam belas baris, dan semua yang ada di bab ini ada di dalamnya. Ini komputasi yang sama dengan yang dilakukan widget, pada vektor logit nyata, bukan sepuluh angka tetap.
def sample(logits, counts, presence=0.0, frequency=0.0,
temperature=1.0, top_k=0, top_p=1.0, generator=None):
z = logits.clone()
idx = torch.tensor(list(counts)) # 1. penalties
if len(idx):
z[idx] -= presence
z[idx] -= frequency * torch.tensor([float(c) for c in counts.values()])
if temperature <= 0: # 2. temperature
return int(z.argmax()) # T=0 is argmax
p = torch.softmax(z / temperature, -1)
p, order = p.sort(descending=True)
if top_k: # 3. top-k
p[top_k:] = 0
p = p * ((p.cumsum(0) - p) < top_p) # 4. top-p
p = p / p.sum() # 5. renormalise
return int(order[torch.multinomial(p, 1, generator=generator)])cumsum(0) - p pada baris top-p adalah mass kumulatif tanpa token saat ini, yang membuat nucleus menyertakan token yang melewati threshold, bukan berhenti tepat sebelumnya. Salah satu langkah dan top_p = 0.9 diam-diam menjadi pemotongan yang sedikit lebih ketat daripada setiap implementasi lain.
Ini salah satu dari sedikit tempat di paruh kedua kursus tempat Python adalah bahasa yang tepat, dan alasannya struktural, bukan gaya: setiap baris di atas membutuhkan seluruh vektor logits di tanganmu, dan melalui HTTP API vektor itu tidak ada. Kamu bisa mengirim temperature dan top_p ke provider; kamu tidak bisa mengimplementasikannya, dan kamu tidak bisa melihat apa yang mereka lakukan.
Tidak ada sampling API universal
Tautan ke bagian: Tidak ada sampling API universalSetiap provider menerima subset berbeda dari kontrol ini, dengan rentang berbeda, dan mengabaikan sisanya diam-diam. Ini bukan keluhan abstrak. Aplikasi apa pun yang menawarkan pilihan model harus menuliskan perbedaan itu di suatu tempat, dan file tempat ia melakukannya adalah peta inkompatibilitas. Inilah yang dideklarasikan salah satu katalog seperti itu untuk satu parameter di sembilan sumber teks yang didukungnya:
| declared temperature range | sources |
|---|---|
| 0 to 1 | Anthropic, Google, Meta, Cerebras, PaLM |
| 0 to 1.5 | Mistral |
| 0 to 2 | OpenAI, DeepSeek, xAI |
Katanya sama; skalanya tidak. “Temperature 1” adalah distribusi yang tidak dimodifikasi pada satu tempat dan panas maksimum yang diizinkan pada tempat lain, dan separuh katalog tidak bisa mengekspresikan nilai yang diperlakukan separuh lainnya sebagai netral-plus-sedikit. Knob lainnya sama tidak ratanya: entri OpenAI, DeepSeek, dan xAI menerima presence dan frequency penalties dan tidak ada topK; entri Google, Meta, Cerebras, dan PaLM menerima topK dan tidak ada penalties; Anthropic menerima topK, topP, dan stop sequences serta tidak ada penalties; dan tepat satu dari sembilan — Mistral — menerima seed. Mengirim parameter yang tidak diimplementasikan provider umumnya tidak menghasilkan error sama sekali: request berhasil, knob tidak melakukan apa pun, dan kamu menyimpulkan setting itu tidak berpengaruh.
Dan perhatikan apa file seperti itu: sebuah klaim tentang API milik orang lain, ditulis pada satu hari tertentu, yang tidak diverifikasi lagi setelahnya. Katalog yang mengatakan 0 sampai 1 untuk provider yang sekarang menerima 0 sampai 2 akan diam-diam membatasi setiap request.
Dua kontrol lagi masuk keluarga yang sama. logprobs, jika ditawarkan, mengembalikan log-probabilities dari token yang dipilih dan sering beberapa alternatif teratas — satu-satunya jendela yang kamu punya ke distribusi yang dibahas bab ini, dan dasar setiap heuristic confidence yang dibangun di atas model tertutup. Dan maximum tokens plus stop sequences mengakhiri generation tanpa merujuk probabilitas sama sekali: hard cap dan pencocokan string. Keduanya muncul sebagai finish_reason dari Bab 14, tempat length berarti jawabanmu terpotong di tengah kalimat oleh budget, bukan selesai oleh model.
Seed, dan determinisme yang tidak kamu punya
Tautan ke bagian: Seed, dan determinisme yang tidak kamu punyaSetel seed dan sampling menjadi reproducible. Bagian itu nyata, dan mudah diverifikasi:
seed = 1234 " Paris\nWhat is a good geographical qualifier for describing
Paris concerning its location?\nA: Near the Mediterranean Sea"
seed = 1234 " Paris\nWhat is a good geographical qualifier for describing
Paris concerning its location?\nA: Near the Mediterranean Sea"
seed = 7 " Paris is the capital of France. The appellation of Paris is
\"Île de Paris\"."
seed = 7 " Paris is the capital of France. The appellation of Paris is
\"Île de Paris\"."Byte-identical dalam satu seed, berbeda antar-seed, persis seperti yang diiklankan. Jadi yang diperbaiki seed adalah random draw di baris terakhir fungsi sample itu — token mana yang dipilih dari suatu distribusi.
Yang tidak ia perbaiki adalah distribusinya. Dan di situlah masalahnya, karena vektor logits yang dihasilkan modelmu bukan objek matematis; ia adalah output dari miliaran penjumlahan floating-point, dan penjumlahan itu punya urutan.
Bab 2 meninggalkan eksperimen ini siap pakai. Jutaan angka float32 yang sama, dijumlahkan dalam pengelompokan berbeda:
sequential 998.564270020 error vs float64: 6.393e-03
pairwise (numpy) 998.570556641 error vs float64: 1.061e-04
in 4 chunks 998.570495605 error vs float64: 1.672e-04
in 8 chunks 998.570556641 error vs float64: 1.061e-04
in 16 chunks 998.570678711 error vs float64: 1.594e-05
sequential == pairwise? False
4 chunks == 8 chunks? FalseLihat baris terakhir. Jumlah chunk mengubah jawabannya. Itu bukan keanehan tentang numpy; itu mekanismenya, karena ketika inference server membagi reduction ke lebih banyak atau lebih sedikit unit paralel, ia melakukan tepat ini. Dan server membagi berdasarkan berapa banyak request yang sedang dilayaninya.
Inilah efek itu pada modelnya sendiri. Prompt yang sama, forward pass yang sama, satu-satunya perbedaan adalah berapa banyak request lain yang kebetulan ada dalam batch:
20 identical forward passes, batch of 1: 20 / 20 bit-for-bit identical
the same prompt inside a batch of 2: 147,321 of 151,936 logits differ
the same prompt inside a batch of 4: 146,515 of 151,936 logits differ
the same prompt inside a batch of 8: 146,515 of 151,936 logits differ
the same prompt inside a batch of 16: 147,321 of 151,936 logits differ
largest change to any logit: 2.5e-05Dijalankan sendiri, modelnya perfectly deterministic — dua puluh pass, identik hingga bit. Masukkan prompt identik ke batch bersama request yang tidak terkait dan 97 % logits-nya berubah. Tidak ada apa pun tentang request kamu yang berubah. Request orang lain tiba.
Sekarang bagian jujurnya, karena ini biasanya diceritakan seolah-olah itulah akhir cerita. Perubahan sebesar hanya mengubah output jika dua candidate token berjarak sedekat itu satu sama lain. Dari 717 langkah generation di dua belas prompt, gap terkecil antara dua logits teratas adalah — seratus kali lebih besar daripada perturbation — dan tidak ada langkah yang cukup dekat untuk flip. Jadi pada model ini, dalam float32, di laptop, batching menggerakkan setiap logit dan tidak mengubah satu token pun.
Itu deskripsi kondisi yang menguntungkan, bukan penenang, dan satu perubahan pada kondisi itu sudah cukup:
same weights, same prompts, greedy decoding, no seed involved
float32 vs bfloat16: 6 of 8 answers diverge
first divergence at step 23, on average
float32: "...it is scattered and dispersed into different colors,
including blue. The blue light is scattered more than other
colors, so it appears to come from the sky."
bfloat16: "...it is scattered and scattered, causing the colors of the
sun to be scattered and scattered, creating the appearance
of a blue color."Enam dari delapan jawaban menyimpang, dan salah satunya memburuk parah. Tabel Bab 2 menjelaskan alasannya: bfloat16 menyimpan 7 bit mantissa, jadi dekat magnitudo logit 16, nilai yang bisa direpresentasikan berjarak 0,125 — 16,0, lalu 16,125, lalu 16,25 — dan rounding bisa menggeser logit hingga 0,0625. Sementara itu, 4,7 % dari langkah generation yang diukur di atas punya gap top-two di bawah 0,1. Itulah seluruh perbedaan antara kedua eksperimen: dalam float32, perturbation seratus kali lebih kecil daripada keputusan terdekat, dan dalam bfloat16 ukurannya sama. Production inference berjalan dalam 16-bit, pada hardware dengan fused kernels dan urutan reduction yang tidak dijanjikan siapa pun untuk tetap. Apakah “numerical noise bisa diabaikan” adalah pertanyaan tentang precision dan hardware, bukan tentang model.
Jadi, empat penyebabnya, dikatalogkan seperti yang dijanjikan Bab 9:
Penjumlahan floating-point tidak asosiatif
Tautan ke bagian: Penjumlahan floating-point tidak asosiatifKotak Bab 2. Urutan penjumlahan mengubah nilainya, jadi perubahan apa pun dalam cara reduction dibagi mengubah logits. Ini substratnya; tiga lainnya adalah cara mengubah urutan.
Dynamic batching mengelompokkan request kamu dengan milik orang asing
Tautan ke bagian: Dynamic batching mengelompokkan request kamu dengan milik orang asingContinuous batching, dari Bab 13, adalah alasan inference terjangkau — dan itu berarti bentuk matriks yang dilalui token kamu bergantung pada traffic. Diukur di atas: 147.321 logits bergerak karena batch size berubah.
Mixture-of-experts routing bergantung pada batch
Tautan ke bagian: Mixture-of-experts routing bergantung pada batchKotak Bab 9 sudah mengatakannya. Router membuat pilihan diskret per token per layer, tunduk pada batas kapasitas per-expert yang dihitung atas batch. Token yang sendirian akan pergi ke expert 7, saat bersama yang lain pergi ke expert 12. Ini bukan perbedaan rounding; ini set bobot yang berbeda.
Model di balik nama berubah
Tautan ke bagian: Model di balik nama berubahVersion string seperti -latest adalah pointer, dan pointer bisa diarahkan ulang. Provider juga memperbarui serving stack di bawah identifier versi tetap. Tidak satu pun diumumkan pada granularitas yang memungkinkanmu mengorelasikannya dengan perubahan output milikmu sendiri.
Parameter seed milik OpenAI jujur tentang ini dengan satu-satunya cara yang bisa ia lakukan: ia dikirim bersama field system_fingerprint yang mengidentifikasi konfigurasi backend, dan dokumentasi menyatakan bahwa determinisme bersifat best-effort dan fingerprint yang berubah berarti hasil bisa berbeda. Bacalah apa adanya — provider memberi tahu kamu bahwa ia mengontrol keempat penyebab di atas, kamu tidak mengontrol satu pun, dan satu hal yang bisa ia tawarkan adalah memberi tahu kamu setelah fakta bahwa sesuatu bergerak.
Ke mana setelah ini
Tautan ke bagian: Ke mana setelah iniSemua di sini membahas sebuah knob dan konsekuensinya. Mundur satu level dan masalah yang lebih sulit muncul: objek yang selama ini kita tuning adalah distribusi probabilitas, dan distribusi probabilitas tidak punya interface.
Function call punya. Database row punya. Handler POST yang mengharapkan JSON body dengan tiga field wajib punya, dan ia akan menolak apa pun selain itu. Di antara model dan setiap component lain dalam sistemmu ada kontrak yang salah satu sisinya tidak bisa berjanji: model akan menghasilkan sesuatu, diambil dari distribusi yang sudah kamu bentuk tetapi belum kamu tetapkan, dan code di sisi lain membutuhkan nilai dengan tipe yang diketahui atau ia throw.
Jembatan antara dua dunia itu dibangun dari materi bab ini, bukan dari parsing dan retry. Jika sebuah token akan merusak struktur yang diwajibkan, kamu tidak men-sample-nya lalu berharap — kamu menyetel logit-nya ke sebelum softmax pernah melihatnya. Constrained decoding adalah mask atas vektor yang sama yang sepanjang bab ini kita bentuk ulang, dan ia mengubah “tolong balas dalam JSON” dari request menjadi guarantee.
Bab 18 adalah kontrak itu: tool calling, JSON Schema, structured outputs, dan apa yang diperlukan untuk membuat sistem deterministic aman dibangun di atas sistem probabilistik.
Sumber dan metode
Tautan ke bagian: Sumber dan metodeSemua pengukuran dalam bab ini berasal dari Qwen/Qwen2.5-0.5B-Instruct pada CPU, float32 kecuali dinyatakan lain, dengan sampling diimplementasikan seperti tertulis di bagian opsional alih-alih didelegasikan ke library. Itu model kecil, dan nilai spesifiknya miliknya; mekanismenya bukan. Artikel Von Platen How to generate text with different decoding methods (Hugging Face, 2020) adalah artikel yang menjadi pembanding pengukuran tulisan ini dan masih merupakan pengantar singkat terbaik untuk materi yang sama. Untuk bagian determinisme: catatan reproducibility PyTorch menjelaskan apa yang diperbaiki dan tidak diperbaiki seed pada satu mesin, dokumentasi OpenAI tentang seed dan system_fingerprint menjelaskan apa yang bisa dan tidak bisa dijanjikan provider, dan diskusi Thinking Machines tahun 2025 tentang batch-invariant kernels adalah penjelasan publik paling jelas tentang mengapa memperbaiki ini di level inference-server mungkin dilakukan tetapi tidak gratis.
Referensi
Tautan ke bagian: Referensi-
Ackley, D. H., Hinton, G. E. and Sejnowski, T. J. A Learning Algorithm for Boltzmann Machines. Cognitive Science 9(1), pp. 147–169 (1985), tempat temperature dalam softmax berasal dari fisika statistik. Hinton, G., Vinyals, O. and Dean, J., Distilling the Knowledge in a Neural Network, arXiv:1503.02531 (2015), section 2, adalah tempat parameter yang sama muncul kembali dalam deep learning modern — sebagai cara membuka distribusi lengkap teacher, yaitu soft labels Bab 13, bukan sampling bab ini. ↩
-
Guo, C., Pleiss, G., Sun, Y. and Weinberger, K. Q. On Calibration of Modern Neural Networks. arXiv:1706.04599 (2017). Jangan bingungkan ini dengan temperature dalam bab ini. Temperature scaling menyesuaikan satu nilai pada validation set agar confidence model cocok dengan akurasinya; ini metode kalibrasi post-hoc yang diterapkan pada output classifier. Temperature sampling adalah kontrol runtime atas cara generator mengambil tokens. Rumus yang sama, tujuan berbeda, dan tidak ada nilai bersama. ↩
-
Holtzman, A., Buys, J., Du, L., Forbes, M. and Choi, Y. The Curious Case of Neural Text Degeneration. arXiv:1904.09751 (2019). Memperkenalkan nucleus sampling dan pengukuran bahwa decoding berbasis maksimisasi menghasilkan teks yang profil probabilitasnya sama sekali tidak seperti teks manusia. ↩ ↩2
-
Fan, A., Lewis, M. and Dauphin, Y. Hierarchical Neural Story Generation. arXiv:1805.04833 (2018). Paper yang memopulerkan top-k sampling. ↩
-
Nguyen, M. et al. Turning Up the Heat: Min-p Sampling for Creative and Coherent LLM Outputs. arXiv:2407.01082 (2024). ↩
-
Meister, C., Pimentel, T., Wiher, G. and Cotterell, R. Locally Typical Sampling. arXiv:2202.00666 (2022). ↩
-
Keskar, N. S., McCann, B., Varshney, L. R., Xiong, C. and Socher, R. CTRL: A Conditional Transformer Language Model for Controllable Generation. arXiv:1909.05858 (2019). Section 4.1 adalah repetition penalty asli — yang membagi. ↩