GPU's voor je projecten · crypto-betaling zonder KYC Hoe huren
Nederlands
Console openen
Praktische gids / KERNODECK

De DataLoader loopt vast: controleer de data vóór de workers

Begin met num_workers=0 en een vaste volgorde, controleer één voorbeeld en daarna een volledige batch, en scheid lezen, transformaties, samenvoegen en overdracht naar de GPU. Voer daarna de workers geleidelijk weer in. Een GPU die wacht bewijst niet dat de opslag traag is: een datafout, een serialisatie of een kostbare samenvoeging kan de keten vóór de berekening blokkeren.

7 min leestijd · Gids voor ontwikkelaars

Bepalen wat de loader moet leveren

Schrijf het uitvoercontract voordat je gaat optimaliseren: aantal elementen, type van elk veld, dimensies, bereik van de doelen en de regel voor onvolledige invoer. Onderscheid de identificatie van het voorbeeld van zijn positie in een batch. Een transformatie kan een vorm wijzigen of een invoer filteren; het trainingsprogramma moet weten of dat is toegestaan.

Neem een representatief voorbeeld met een gewoon bestand, een randgeval en het laatste element van de dataset. Open elk element met exact dezelfde voorbereiding als de Dataset. Bekijk daarna hun samenvoeging. Een geslaagde individuele toegang bewijst niet dat meerdere resultaten gestapeld kunnen worden. Documenteer voor tekst padding en masker; voor een afbeelding kanalen, dimensies en volgorde van de assen.

Bepaal de scope: data lokaal of op afstand, decodering inbegrepen of niet, vaste of willekeurige transformaties. Houd die tussen twee metingen; een schijnbare winst kan komen van werk dat je hebt weggelaten.

Terug naar één proces om de fout te lezen

Reproduceer eerst met num_workers=0, shuffle=False en een kleine batch. Het laden gebeurt dan in het hoofdproces en de foutmelding is doorgaans beter leesbaar. De DataLoader-documentatie raadt deze mogelijkheid aan voor debuggen. Log de identificatie van het element dat faalt vóór het decoderen, zonder de gevoelige inhoud ervan naar de logs te kopiëren.

Werk stapsgewijs: ruwe toegang, transformatie, collate_fn en dan overdracht. Als het traject faalt vóór de overdracht, is CUDA aanpassen niet het eerste spoor. Als het alleen met meerdere workers vastloopt, onderzoek dan de objecten en bronnen die aan die processen worden doorgegeven. Vergelijk de eerste iteratie met de volgende: het opstarten van de workers kan een initiële wachttijd verklaren zonder dat er sprake is van een terugkerend probleem.

Een timeout kan een wachttijd zichtbaar maken, maar verhelpt noch een onbeschikbare bron noch een vastgelopen worker. Houd de laatst bekende stap vast en verklein het aantal invoeren in plaats van die time-out eindeloos te verhogen.

Uitgewerkt voorbeeld: drie kanalen verwacht, één afwijkende afbeelding

Laten we vier didactische records nemen. De eerste drie geven een tensor met vorm [3, 16, 16], de vierde [1, 16, 16]. Met een contract dat drie kanalen vereist, moet het vierde element vóór het stapelen worden geïdentificeerd. Dit scenario is hier niet uitgevoerd; het beschrijft een te verwachten resultaat op basis van de gekozen vormen.

De onderstaande functie gaat ervan uit dat elk record de velden id, x en y heeft, dat x een CPU-tensor is en dat y een geheel getal als index is. Ze weigert de inconsistentie in plaats van de afbeelding stilzwijgend te verwijderen. Beslis voor je project expliciet of een monochrome afbeelding naar drie kanalen moet worden geconverteerd of bij de import moet worden geweigerd. Die beslissing hangt af van de betekenis van de data en de voorbewerking die het model verwacht.

Na correctie moeten de vier identificaties aanwezig blijven en moet de samengevoegde tensor de vorm [4, 3, 16, 16] hebben. Voeg een controle toe die op de doelen is toegesneden: een correct gedimensioneerde afbeelding kan nog steeds een ongeldige annotatie bevatten.

Voorgestelde didactische samenvoeging, niet uitgevoerd
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"Onverwachte vorm voor {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 is uw Dataset die de beschreven records oplevert.
# Maak in een multiprocesscript de loader aan onder de main-guard.
if __name__ == "__main__":
    loader = DataLoader(dataset, batch_size=4, num_workers=0,
                        shuffle=False, collate_fn=assemble)
    iterator = iter(loader)
    batch = next(iterator)

Workers opnieuw inschakelen zonder de data te wijzigen

Ga van nul naar een klein aantal workers met behoud van batch, volgorde en transformaties. Test een volledige epoch, dan een tweede: sommige fouten komen pas aan het licht bij het herstarten van een iterator of wanneer resources verbruikt zijn. Meer parallellisme is alleen nuttig als het voorbereidende werk daadwerkelijk parallel kan verlopen.

De startmethoden hangen af van het systeem en de Python-versie. Bescherm bij spawn het programma-entrypoint met if __name__ == '__main__' en definieer Dataset, collate_fn en workerfuncties op moduleniveau in plaats van in lokale lambdas. De procesdocumentatie legt ook uit waarom geërfde locks of threads vastlopers kunnen veroorzaken. Houd de initialisatie van toegangen per proces gescheiden wanneer de bibliotheek dat vereist.

Controleer voor een IterableDataset de verdeling over workers aan de hand van identifiers: meerdere workers mogen niet elk dezelfde volledige stream verbruiken. Beoordeel niet alleen het aantal batches; zoek ook naar duplicaten en ontbrekende elementen.

Wachttijd en doorvoer meten met een duidelijke eenheid

Gebruik twee complementaire observaties. Een losse ronde door de loader telt de voorbeelden die binnen een bepaald interval zijn voorbereid. Een geïntegreerde ronde onderzoekt wat er gebeurt wanneer het model deze data verbruikt. De eerste helpt de voorbereiding te isoleren; die vertegenwoordigt niet automatisch de doorvoer van de training.

Tel in uw protocol de daadwerkelijk geleverde voorbeelden en deel die door de verstreken seconden. Vermeld de overgeslagen rondes voor het opstarten, de datacache, de transformaties en het aantal herhalingen. Bewaar de waarden van elke ronde in plaats van alleen de beste te selecteren. De onderstaande tabel is een invulformulier: er zijn geen prestaties ingevuld.

Als de vormen variëren, kan een aantal voorbeelden per seconde een verandering in belasting verbergen. Voeg de relevante eenheid toe, zoals gedecodeerde pixels of daadwerkelijk voorbereide tokens, en behoud ook de voorbeelden. Benoem voor het lokaliseren van wachttijden in de volledige lus het lezen van de volgende batch apart van de berekening.

Scroll door de tabel om alle kolommen te lezen.
Formulier in te vullen met uw belasting, zonder veronderstelde prestatiecijfers
InstellingGecontroleerde elementenWaargenomen duurVerwachte conclusie
workers=0Identifiers, vormen, doelenTe meten in secondenCorrecte referentie
Klein aantal workersDezelfde set inputsTe meten in secondenWerkelijke winst of meerkosten
Dezelfde instelling, tweede epochGeen verlies of duplicatieTe meten in secondenEffect van opstarten en caches

Geheugen, voorladen en overdrachten apart behandelen

Workers en wachtende batches verbruiken hostgeheugen. Houd dat tijdens uw test in het oog voordat u concludeert dat alleen VRAM telt. Dieper voorladen kan de wachttijd verplaatsen terwijl het verbruik stijgt; het garandeert niet meer resultaten per seconde. Verklein eerst de verdachte variabele en vergelijk hetzelfde bereik.

pin_memory en niet-blokkerende overdrachten betreffen het doorgeven van data naar een accelerator. De optimalisatierecepten van PyTorch presenteren ze als knoppen om te onderzoeken samen met de hardware en de belasting. Ze verhelpen geen foutieve decodering. Begin met CPU-data in de workers en organiseer daarna de overdracht in het proces dat de berekening aanstuurt. Het voordeel en de effectieve overlap moeten worden waargenomen, niet verondersteld.

Als persistent_workers wordt gebruikt, let dan op de resources en toestanden die tussen twee epochs bewaard blijven. Een instelling die op één batch goed werkt, is niet genoeg om te controleren of bestanden worden gesloten of de bron wordt vernieuwd.

Accepteer een instelling alleen als de gegevens correct blijven

Het verwachte resultaat is een lus die alle voorziene invoer ontvangt, binnen het gekozen kader, zonder stille fouten. Vergelijk de identifiers en doelen vóór en na de optimalisatie. Leg drop_last uit als je de laatste onvolledige batch overslaat. Als de transformaties willekeurig zijn, controleer dan hun beleid in plaats van pixelgelijkheid te eisen die dat beleid zou tegenspreken.

Behoud de eenvoudigste instelling die aan de gemeten behoefte voldoet. Een hoger aantal workers levert misschien niets op als de opslag, het decoderen of het model al een limiet oplegt. De CPU-, RAM- en opslagresources van een server kun je niet afleiden uit de naam van zijn GPU: geef deze behoeften afzonderlijk aan wanneer je je Kernodeck-omgeving voorbereidt.

Jouw vragen

Schakelt num_workers=0 de GPU-training uit?

Nee. Het plaatst het laden van gegevens in het hoofdproces. Het model kan nog steeds op de GPU rekenen. Deze instelling maakt het vooral mogelijk om lees-, transformatie- en assemblagefouten directer te lezen.

Moet je evenveel workers kiezen als CPU-cores?

Niet automatisch. De juiste instelling hangt af van het voorbereidingswerk, het geheugen, de gegevenstoegang en de verbruikssnelheid van het model. Vergelijk een paar waarden met dezelfde belasting en controleer de geleverde invoer.

Verhelpt een kleinere batch een worker die stopt?

Het kan de geheugendruk veranderen, maar verhelpt geen ongeldige annotatie, een niet-serialiseerbare resource of een onleesbaar bestand. Reproduceer eerst met nul workers om de betrokken stap te identificeren.

Meet de tijd in next(iterator) de schijf?

Nee. Na iterator=iter(loader) wacht next(iterator) op een batch. Decoderen, transformaties, assemblage, communicatie tussen processen en vooraf laden kunnen tussenkomen. Een meting van alleen lezen en een trace van de volledige lus beantwoorden verschillende vragen.