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.
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.| Instelling | Gecontroleerde elementen | Waargenomen duur | Verwachte conclusie |
|---|---|---|---|
| workers=0 | Identifiers, vormen, doelen | Te meten in seconden | Correcte referentie |
| Klein aantal workers | Dezelfde set inputs | Te meten in seconden | Werkelijke winst of meerkosten |
| Dezelfde instelling, tweede epoch | Geen verlies of duplicatie | Te meten in seconden | Effect 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.