İstatistik
Bir türlü yeniden üretilemeyen bootstrap
Aynı analizin iki çalıştırması — aynı veri, aynı iş akışı, aynı tohum — iki farklı güven aralığı veriyor. Çarpıcı biçimde farklı değil: [12.31, 13.02] karşısında [12.32, 13.01]. İkinci ondalıkta bir kıpırdanma; yorgun bir insanın “bootstrap işte” deyip geçiştireceği türden. Geçiştirmeyin. Bu yazı, “kararsız” sözcüğünü bir ruh hâlinden bir teşhise çeviren yürüyüş — ve suçlu, çoğu zaman olduğu gibi, kendi yazdığınız kodun içinde oturuyor.
Adım adım örnek
Kurgulanmış bir vaka; laboratuvar raporu değil: stüdyo henüz açılmadı (bugün neredeyiz). Aşağıdaki istatistiğin tamamı birebir doğrudur ve her satırını kâğıt üzerinde kendiniz doğrulayabilirsiniz. Platformun davranışı — determinizm kademeleri, sayaç tabanlı RNG, her düğümdeki içerik hash'i — motorun yapmak üzere kurulduğu ve doğrulandığı davranıştır. Çalıştırma günlüğü de kanıtın biçimini gösterir; birinin yaşadığı bir oturumu değil.
İki aralık, tek tohum#
Zemin, sıradan istatistik. Sağa çarpık, pozitif bir ölçüm sütunu: üst akıştaki bir birleştirmenin 19 satırı mükerrer bıraktığı 431 satır; tekilleştirmeden sonra 412. Bu çarpıklıkta ortalama ± standart hata dürüst olmayan bir özet olurdu; hedef büyüklük bu yüzden medyan: 12.67, yani 206. ile 207. sıra istatistiklerinin ortalaması. Aralık için bariz parametrik olmayan araç: bootstrap. 412 satırdan yerine koyarak 412 satır çekin, medyanı alın, bunu B = 10 000 kez tekrarlayın; her yeniden örneklem ortalamada satırların yaklaşık %36.8'ini dışarıda bırakır — folklordaki e⁻¹ — ve on bin medyanın saçılımı, sizin tek medyanınızın örnekleme gürültüsünü tahmin eder. %95'lik yüzdelik aralığı, deneysel 2.5 ve 97.5 yüzdeliklerini okur: esasında sıralanmış bootstrap medyanlarının 250. ile 9 751. değerleri. Tam olarak hangi kuantil kuralının geçerli olduğunu, kuantil op'u beyan eder — bir kütüphanenin “type 7”sini bir başkasının varsayılanıyla uzlaştırmak zorunda kalmış herkes, bu dipnotun ikinci ondalıkları belirlediğini bilir. Daha incesi de var, örneğin BCa; n = 412'de sade bir medyan için yüzdelik aralığı savunulabilir.
Yani: tohum 42, B = 10 000, [12.31, 13.02]. Commit etmeden önce, kuşkudan değil titizlikten, bir kez daha çalıştırın. Aynı tohum. [12.32, 13.01].
İstatistikçi refleksi#
Dürüst ilk içgüdü nicelendirmektir. Yüzdelik aralığının uçları da birer Monte Carlo tahminidir; standart hataları √(α(1−α)/B) bölü o kuantildeki bootstrap yoğunluğudur. On bin medyanın standart sapması yaklaşık 0.18 ise, normal yaklaşım altında 2.5'lik kuantil civarındaki yoğunluk yaklaşık 0.058/0.18 ≈ 0.32, her ucun Monte Carlo standart hatası da 0.005 dolayında olur. Gözlenen iki kayma da yaklaşık 0.01 — iki Monte Carlo standart hatası. Farklı tohumlu çalıştırmalar arasında bu, omuz silkilecek bölgedir; rahatsız olan B'yi dörde katlayıp hatayı yarılar.
Ama tohumlar farklı değil. Sabit tohum altında farkın referans dağılımı “küçük” değildir — sıfıra yığılmış tek bir noktadır. Sapmanın büyüklüğü hiçbir bilgi taşımaz; varlığı, bulgunun tamamıdır. Her şeyi masum gösteren öteki ipucu şudur: Nokta tahmini iki çalıştırmada da tamı tamına aynı çıkar, 12.67 — tüm örneklem üzerinden bir medyan, satır sırasını umursamaz. Aralığın kuyrukları dışında her şey sağlıklı görünür; yorgun bir insanın gürültüyü beklediği yer de tam olarak kuyruklardır.
Üç şüpheli#
Birinci şüpheli: GPU. WebGPU'da kayan nokta yürütmesi birleşme özelliği taşımaz — bir indirgemenin toplanma sırası zamanlamalar arasında garanti edilmez — ve prod kademesinin bit eşitliği yerine beyan edilmiş bir tolerans sınıfı içinde yeniden üretim vaat etmesi tam da bundandır. Ama bir bootstrap indeksi tam sayıdır; “satır 227”nin etrafında tolerans topu olmaz. Medyan bir seçimdir — çift n'de bir toplama ve bir yarılama — uzun bir birikim değil. Üstelik 12.3 üzerinde 0.01, göreli olarak yaklaşık 8 × 10⁻⁴ eder: bir seçim op'unun ciddi bir yüzle beyan edebileceği her toleransın kat kat ötesi. Akla yatkın şüpheli, zayıf gerekçe.
İkinci şüpheli: platformun rastgele sayıları. Scellis RNG'si sayaç tabanlıdır, Philox tarzı: Bir çekiliş, (tohum, akış, sayaç) üçlüsünün saf bir fonksiyonudur — bozulacak gizli küresel durum yoktur; aynı koordinatlar her arka uçta aynı çıktıyı verir; karıştırma, dropout ve veri artırma adlandırılmış alt akışlardır; durum, çalıştırmayla birlikte checkpoint'lenir. Masum olsun diye tasarlanmış — ama bu platformun bütün doktrini, masumiyetin iddia değil doğrulama konusu olduğudur. Üçüncü şüpheli: kendi yazdığınız ön işleme bloğu.
İlk alet, kademe merdiveninin kendisi. Bir çalıştırmanın determinizm kademesi açıktır — çalıştırma kaydında durur, asla sessizce varsayılana düşmez. İş akışını prod'dan debug'a çevirin: aynı tohumla, aynı cihazda bit düzeyinde özdeş tekrar; bedeli de dürüstçe yazılıdır — deterministik çekirdek varyantları ve sabitlenmiş indirgeme sıraları (daha yavaş; sözleşme bunu açıkça söyler). İki debug çalıştırması, iki farklı yapıt hash'i. Bu bir hükümdür, belirti değil. debug'da “herhangi bir biçimde farklı” tanım gereği kusurdur — istatistik gerekmez, yorum payı yoktur. Çalıştırmaya bir yerden gerçek entropi sızıyor.
İkinci alet, referans yolu. Yerleşik her sayısal op bir CPU referansı taşır — her GPU çekirdeğinin karşısında denetlendiği referans. Aynı iş akışını orada iki kez daha çalıştırın: bit-kesin ve her GPU'dan bağımsız. Yine iki farklı hash. Silikon aklandı; zar atan her neyse donanımda değil, programda oturuyor.
İzi hash'lerle sürmek#
Burada platform, alet olmaktan çıkıp haritaya dönüşür. Her ara yapıt içerik adreslidir ve bir çalıştırmanın köken kaydı her düğümdeki hash'i not eder. İki debug çalıştırmasını yan yana koyup çizgeyi adımlayın: veri alımı — özdeş hash'ler. Tipleme, özetler — özdeş. Tekilleştirme bloğu — farklı. İlk ıraksama; akış aşağısındaki her şey zehri miras alır. Düğüm: user/kemal/dedup_rows@1 — sizin; haftalar önce bir öğleden sonra kendi yazdığınız blok.
// user/kemal/dedup_rows@1 — reference body (the guilty version)
const rows = dedupeByKey(input.rows, "sample_key");
// notebook reflex: "shuffle so later splits don't inherit file order"
for (let i = rows.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1)); // <- unseeded entropy
[rows[i], rows[j]] = [rows[j], rows[i]];
}
return { rows };Tekilleştirme işin dürüst yarısı. Ardından satırlar üzerinde, Math.random() ile dönen bir Fisher–Yates karıştırması geliyor — tohumsuz, adsız, görünmez entropi. Bir defter refleksi: tekilleştirmeden sonra karıştır ki sonraki bölmeler dosya sırasını miras almasın. Orada durduğunu unutmuştunuz. Bloğun üstverisi ise deterministik beyan ediyor — platformun, kum havuzundaki bir gövde için kendi cihazınızda geçici olarak sözünüze güvendiği bir beyan; platform bu konuda açık sözlüdür. Statik analiz bu tür bir yalanı mahkûm edemez; sözleşmenin işi başkadır: Yalanı tek bir akşamda yanlışlanabilir kılar.
Kendini silen düzeltme#
En öğretici kısım, karıştırmanın ne işe yaradığı: hiçbir işe. Bootstrap, satırları düzgün dağılımlı rastgele indekslerle çeker; bir permütasyonu düzgün çekilişlerle birleştirdiğinizde elinizde yine düzgün çekilişler kalır. İki çalıştırmanın aralıkları da geçerli %95 yüzdelik aralıklarıydı ve tamı tamına aynı Monte Carlo dağılımından çekilmişlerdi. Hiçbir yerde yanlılık yok; iki sayının da yanlış bir tarafı yok.
Not
Bu hatayı hiçbir p-değeri yakalayamaz. Tohumsuz karıştırma hiçbir dağılımı değiştirmedi — iki aralık da geçerliydi, tahminciye dokunulmamıştı. Kırık olan tek şey yeniden üretilebilirlikti; o da dağılımların değil baytların özelliğidir. Bunu testle değil, hash'le yakalarsınız.
Bloğun 2. sürümü karıştırmayı düpedüz siliyor — özdeş girdi baytları üzerinde ilk-geleni-tut tekilleştirme zaten kendiliğinden sıra-kararlıdır. Karıştırmanın gerçekten önemli olduğu yerde — örneğin bir doğrulama bölmesinde — onu çalıştırmanın tohumlanmış akışından çekersiniz: sayaç tabanlı RNG'nin adlandırılmış bir alt akışı; o zaman her şey gibi yeniden üretilir ve checkpoint'lenir. 1. sürüm de yok olmuyor: Baytları, iki suç mahalli çalıştırmasının köken kaydına hash'le mıhlıdır; sonsuza dek atıf yapılabilir. Hatanızı sessizce yeniden yazamazsınız; ancak yerine yenisini koyabilirsiniz. Değişmezlik insanı pohpohlamaz — ve onunla barışmaya değer.
tier debug · seed 42 · same device
run A -> ci_artifact sha256:6b01…e4
run B -> ci_artifact sha256:9d57…22 ✗ debug promises bitwise equality
after the fix — user/kemal/dedup_rows@2
run A′ -> ci_artifact sha256:c8a3…7f
run B′ -> ci_artifact sha256:c8a3…7f ✓ identical bytesSonra asıl çalıştırma: B = 10 000, tohum 42, kademe debug — [12.31, 13.02]. Akşamın ilk çalıştırmasıyla aynı rakamlar; ve ilk kez belirli tanımlığı hak ediyorlar: aralığın ta kendisi.
debug gerçekte neyi sabitler#
Bu yürüyüşten aklımızda kalması gereken, merdivenin kesin hâli. debug, bit düzeyinde özdeş tekrarı sabitler — aynı tohum, aynı cihaz — bunu deterministik çekirdeklerle, sabitlenmiş indirgeme sıralarıyla ve sayaç tabanlı RNG ile yapar; bedeli gerçek bir hız kaybıdır. Cihazlar arasında bit eşitliği vaat etmez: farklı GPU'lardaki kayan noktalar meşru biçimde ayrışabilir; cihazlar arası bit-kesinlik referans yolunun işidir ve prod, onun yerine beyan edilmiş bir tolerans sınıfı vaat eder. fast, determinizm dışılığa yalnızca güvenli diye beyan edildiği yerde izin verir. Ve hiçbir kademe asla sessizce varsayılan olmaz — çalıştırmanın köken kaydına damgalanır ve paylaştığınız bağlantıyla birlikte gider.
İş akışını commit edin ve anlık görüntü bağlantısını çıkarın:
scellis.com/studio?repro=c8a3…7f
dataset@1 · user/kemal/dedup_rows@2 · B 10000 · seed 42 · tier debugBağlantıyı açan herkes commit edilmiş baytları yeniden çözer — veri, blok sürümleri, tohum, kademe; “bit bit aynı” tam olarak o baytlar demektir. Referans yolunda yeniden hesaplayan onları birebir üretir; başka bir GPU'da prod'da yeniden hesaplayan, beyan edilmiş tolerans içinde üretir — platform da ikisinden hangisini aldığınızı söyler; kayan noktaların tutamayacağı bir söz vermez. Uygulamanın adım adım anlatımı rehberde.
“Kararsız” bir teşhis değildir. Sisteminizde adını koymadığınız bir entropi bulunduğunun itirafıdır. İstatistik bizi, kastettiğimiz belirsizliği nicelendirmeye alıştırır; aletlerimizden isteyebileceğimiz asgari şey, ekledikleri her belirsizliğin adıyla, akışıyla ve tohumuyla gelmesidir.