Projeleriniz için GPU · KYC'siz kripto ödeme Nasıl kiralanır
Türkçe
Konsolu aç
Uygulamalı rehber / KERNODECK

DataLoader bloke oluyor: worker'lardan önce verileri doğrulayın

num_workers=0 ve sabit bir sırayla başlayın, önce bir örneği ardından tam bir batch'i doğrulayın ve okuma, dönüşümler, birleştirme ile GPU transferini birbirinden ayırın. Ardından worker'ları kademeli olarak yeniden devreye alın. Bekleyen bir GPU, depolamanın yavaş olduğunu kanıtlamaz: bir veri hatası, bir serileştirme veya maliyetli bir birleştirme, hesaplamadan önce zinciri bloke edebilir.

6 dk okuma · Geliştiriciler için rehber

Yükleyicinin ne teslim etmesi gerektiğini tanımlama

Optimizasyondan önce çıktı sözleşmesini yazın: öğe sayısı, her alanın türü, boyutlar, hedeflerin aralığı ve eksik girdi kuralı. Örneğin tanımlayıcısını bir batch içindeki konumundan ayırt edin. Bir dönüşüm bir şekli değiştirebilir veya bir girdiyi filtreleyebilir; eğitim programı bunun izin verilip verilmediğini bilmelidir.

Sıradan bir dosya, bir sınır durumu ve veri kümesinin son öğesini içeren temsili bir örnek alın. Her öğeyi Dataset ile tamamen aynı hazırlıkla açın. Ardından bunların birleştirilmesini inceleyin. Tek tek başarılı bir erişim, birden fazla sonucun üst üste yığılabileceğini kanıtlamaz. Bir metin için padding ve maskeyi belgeleyin; bir görüntü için kanalları, boyutları ve eksen sırasını.

Kapsamı sabitleyin: veriler yerel mi uzak mı, kod çözme dahil mi, dönüşümler sabit mi rastgele mi. Bunu iki ayar arasında tutun; görünürdeki bir kazanç, kaldırılan bir işten kaynaklanabilir.

Hatayı okumak için tek bir sürece dönme

Önce num_workers=0, shuffle=False ve küçük bir batch ile yeniden üretin. Yükleme bu durumda ana süreçte gerçekleşir ve hata izi genellikle daha okunaklıdır. DataLoader belgeleri hata ayıklama için bu olasılığı önerir. Başarısız olan öğenin tanımlayıcısını, kodunu çözmeden önce kaydedin; hassas içeriğini günlüklere kopyalamayın.

Ayırarak ilerleyin: ham erişim, dönüşüm, collate_fn, ardından transfer. Akış transferden önce başarısız olursa, CUDA'yı değiştirmek ilk izlenecek yol değildir. Yalnızca birden fazla worker ile bloke oluyorsa, bu süreçlere aktarılan nesneleri ve kaynakları inceleyin. İlk yinelemeyi sonrakilerle karşılaştırın: worker'ların başlatılması, sürekli bir sorun oluşturmaksızın başlangıçtaki bir beklemeyi açıklayabilir.

Bir timeout bir beklemeyi görünür kılabilir, ancak ne kullanılamayan bir kaynağı ne de bloke olmuş bir worker'ı onarır. Bu süreyi sonsuza dek artırmak yerine, bilinen son adımı koruyun ve girdi sayısını azaltın.

İşlenmiş örnek: üç kanal bekleniyor, farklı bir görüntü

Dört eğitici kayıt ele alalım. İlk üçü [3, 16, 16] şeklinde bir tensör verir, dördüncüsü [1, 16, 16]. Üç kanalı zorunlu kılan bir sözleşmeyle, dördüncü öğe üst üste yığılmadan önce belirlenmelidir. Bu senaryo burada çalıştırılmamıştır; seçilen şekillere dayanarak beklenen bir sonucu açıklar.

Aşağıdaki fonksiyon her kaydın id, x ve y alanlarına sahip olduğunu, x'in bir CPU tensörü ve y'nin bir tam sayı indeksi olduğunu varsayar. Tutarsızlığı görüntüyü sessizce silmek yerine reddeder. Projeniz için, tek renkli bir görüntünün üç kanala dönüştürülmesi mi yoksa içe aktarımda reddedilmesi mi gerektiğine açıkça karar verin. Bu karar, verilerin anlamına ve modelin beklediği ön işlemeye bağlıdır.

Düzeltmeden sonra dört tanımlayıcı da mevcut kalmalı ve birleştirilmiş tensör [4, 3, 16, 16] şeklinde olmalıdır. Hedeflere uygun bir koruma ekleyin: boyutu doğru olan bir görüntü yine de geçersiz bir anotasyon taşıyabilir.

Önerilen, çalıştırılmamış eğitici birleştirme
import torch
from torch.utils.data import DataLoader

def assemble(records):
    for item in records:
        if tuple(item["x"].shape) != (3, 16, 16):
            raise ValueError(f"Forme inattendue pour {item['id']}")
    return {
        "ids": [item["id"] for item in records],
        "x": torch.stack([item["x"] for item in records]),
        "y": torch.tensor([item["y"] for item in records],
                          dtype=torch.long),
    }

# dataset, açıklanan kayıtları üreten Dataset nesnenizdir.
# Çok işlemli bir betikte, loader'ı main koruması altında oluşturun.
if __name__ == "__main__":
    loader = DataLoader(dataset, batch_size=4, num_workers=0,
                        shuffle=False, collate_fn=assemble)
    iterator = iter(loader)
    batch = next(iterator)

Verileri değiştirmeden worker'ları yeniden devreye alma

Sıfırdan küçük bir worker sayısına geçerken batch, sıra ve dönüşümleri koruyun. Bir tam epoch, ardından bir tane daha test edin: bazı hatalar yalnızca bir iterator yeniden başlatıldığında veya kaynaklar tüketildiğinde ortaya çıkar. Paralelliği artırmak, ancak hazırlık işi gerçekten paralel ilerleyebiliyorsa faydalıdır.

Başlatma yöntemleri işletim sistemine ve Python sürümüne bağlıdır. spawn ile programın girişini if __name__ == '__main__' ile koruyun ve Dataset, collate_fn ile worker fonksiyonlarını yerel lambda'lar yerine modül düzeyinde tanımlayın. Süreç dokümantasyonu ayrıca devralınan kilitlerin veya thread'lerin neden kilitlenmelere yol açabileceğini açıklar. Kütüphane gerektirdiğinde, erişim başlatmalarını her sürece özel tutun.

Bir IterableDataset için worker'lar arasındaki bölümlendirmeyi tanımlayıcılar aracılığıyla doğrulayın: birden çok worker her biri aynı akışın tamamını tüketmemelidir. Yalnızca batch sayısına bakmayın; kopyaları ve eksik öğeleri de arayın.

Beklemeyi ve verimliliği net bir birimle ölçme

Birbirini tamamlayan iki gözlem kullanın. Yalnızca yükleyiciyi baştan sona çalıştırmak, belirli bir aralıkta hazırlanan örnekleri sayar. Bütünleşik bir çalıştırma ise model bu verileri tükettiğinde ne olduğunu inceler. İlki hazırlığı yalıtmaya yardımcı olur; eğitim verimliliğini otomatik olarak temsil etmez.

Protokolünüzde gerçekten teslim edilen örnekleri sayın, ardından geçen saniyeye bölün. Başlangıç için hariç tutulan geçişleri, veri önbelleğini, dönüşümleri ve tekrar sayısını belirtin. Yalnızca en iyisini seçmek yerine her geçişin değerlerini saklayın. Aşağıdaki tablo bir kayıt sayfasıdır: hiçbir performans değeri doldurulmamıştır.

Şekiller değişiyorsa, saniyedeki örnek sayısı yük değişimini gizleyebilir. Örnekleri de koruyarak, çözülen piksel veya gerçekten hazırlanan token gibi ilgili birim ekleyin. Tam döngüdeki beklemeleri tespit etmek için, sonraki batch okumasını hesaplamadan ayrı olarak adlandırın.

Tüm sütunları görmek için tabloyu kaydırın.
Kendi yükünüzle doldurulacak, varsayımsal performans değeri içermeyen kayıt
AyarDoğrulanan öğelerGözlenen süreBeklenen sonuç
workers=0Tanımlayıcılar, şekiller, hedeflerSaniye cinsinden ölçülecekDoğru referans
Küçük worker sayısıAynı giriş kümesiSaniye cinsinden ölçülecekGerçek kazanç veya ek maliyet
Aynı ayar, ikinci epochKayıp veya kopyalama yokSaniye cinsinden ölçülecekBaşlatmanın ve önbelleklerin etkisi

Bellek, ön yükleme ve transferleri ayrı ele alma

Worker'lar ve bekleyen batch'ler ana bellek tüketir. Yalnızca VRAM'in önemli olduğu sonucuna varmadan önce, denemeniz sırasında belleği izleyin. Daha derin bir ön yükleme, beklemeyi kaydırırken kullanımı artırabilir; saniyede daha fazla sonuç garanti etmez. Önce şüpheli değişkeni azaltın ve aynı kapsamı karşılaştırın.

pin_memory ve bloklamayan transferler, verilerin bir hızlandırıcıya aktarılmasıyla ilgilidir. PyTorch optimizasyon tarifi bunları, donanım ve yük ile birlikte incelenecek araçlar olarak sunar. Hatalı bir çözümlemeyi düzeltmezler. Worker'lardaki CPU verileriyle başlayın, ardından transferi hesaplamayı yürüten süreçte düzenleyin. Fayda ve gerçek örtüşme varsayılmamalı, gözlenmelidir.

persistent_workers kullanılıyorsa, iki epoch arasında korunan kaynakları ve durumları göz önünde bulundurun. Tek bir batch üzerinde tatmin edici bir ayar, dosyaların kapatıldığını veya kaynağın yenilendiğini doğrulamak için yeterli değildir.

Bir ayarı yalnızca veriler doğru kaldığında kabul edin

Beklenen sonuç, seçilen çerçevede öngörülen tüm girdileri sessiz hata olmadan alan bir döngüdür. Optimizasyondan önce ve sonra kimlikleri ve hedefleri karşılaştırın. Son eksik batch'i dışarıda bırakıyorsanız drop_last ayarını açıklayın. Dönüşümler rastgele ise, bu politikayla çelişecek bir piksel eşitliği talep etmek yerine politikalarını kontrol edin.

Ölçülen ihtiyacı karşılayan en basit ayarı koruyun. Depolama, kod çözme veya model zaten bir sınır koyuyorsa, worker sayısını artırmak hiçbir şeyi iyileştirmeyebilir. Bir sunucunun CPU, RAM ve depolama kaynakları GPU'sunun adından çıkarılamaz: Kernodeck ortamınızı hazırlarken bu ihtiyaçları ayrıca belirtin.

Sorularınız

num_workers=0 GPU eğitimini devre dışı bırakır mı?

Hayır. Veri yüklemeyi ana sürece yerleştirir. Model yine de GPU üzerinde hesaplayabilir. Bu ayar özellikle okuma, dönüştürme ve birleştirme hatalarını daha doğrudan görmenizi sağlar.

CPU çekirdek sayısı kadar worker seçmeli miyim?

Otomatik olarak değil. Doğru ayar hazırlık işine, belleğe, veri erişimlerine ve modelin tüketim hızına bağlıdır. Aynı yükü koruyarak ve teslim edilen girdileri kontrol ederek birkaç değeri karşılaştırın.

Daha küçük bir batch, duran bir worker'ı düzeltir mi?

Bellek baskısını değiştirebilir ancak geçersiz bir anotasyonu, serileştirilemeyen bir kaynağı veya okunamayan bir dosyayı düzeltmez. Önce sıfır worker ile yeniden üretip sorunlu adımı belirleyin.

next(iterator) içinde geçen süre diski mi ölçer?

Hayır. iterator=iter(loader) sonrasında next(iterator) bir batch bekler. Çözme, dönüşümler, birleştirme, süreçler arası iletişim ve ön yükleme devreye girebilir. Yalnızca okumayı ölçmek ile tüm döngüyü izlemek farklı sorulara yanıt verir.