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.
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.| Ayar | Doğrulanan öğeler | Gözlenen süre | Beklenen sonuç |
|---|---|---|---|
| workers=0 | Tanımlayıcılar, şekiller, hedefler | Saniye cinsinden ölçülecek | Doğru referans |
| Küçük worker sayısı | Aynı giriş kümesi | Saniye cinsinden ölçülecek | Gerçek kazanç veya ek maliyet |
| Aynı ayar, ikinci epoch | Kayıp veya kopyalama yok | Saniye cinsinden ölçülecek | Baş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.