Načtení dat do AI Runtime

Důležité

Modul runtime AI pro úlohy s jedním uzlem je ve verzi Public Preview. Distribuované trénovací rozhraní API pro úlohy s více GPU zůstává v beta verzi.

Načtení trénovacích dat v prostředí AI Runtime pro úlohy strojového učení a hlubokého učení Veškerý přístup k datům prochází katalogem Unity: Pomocí Spark Connect můžete číst tabulková data z tabulek Delta a svazky katalogu Unity pro velké datové sady a nestrukturované soubory, jako jsou obrázky, zvuk a text. Pro trénování ve více epochách ukládejte data místně do /tmp, abyste k nim měli rychlejší přístup. Informace o načtení a transformaci dat pomocí rozhraní API Python Sparku najdete v tomto kurzu.

Poznámka:

Vyžaduje se katalog Unity. Veškerý přístup k datům v modulu runtime AI prochází katalogem Unity. Vaše tabulky a svazky musí být zaregistrované v katalogu Unity a přístupné vašemu uživateli nebo služebnímu principálu.

Načítání tabulkových dat

Použijte Spark Connect k načtení tabulkových dat strojového učení z tabulek Delta.

Pro trénování s jedním uzlem můžete datové rámce Apache Sparku převést na datové rámce pandas pomocí metody toPandas() a pak volitelně převést na formát NumPy pomocí metody to_numpy().

Poznámka:

Spark Connect odkládá analýzu a řešení názvů na dobu provádění, což může změnit chování vašeho kódu. Viz Porovnání Spark Connect s Klasickým Sparkem.

Spark Connect podporuje většinu rozhraní API PySpark, včetně Spark SQL, rozhraní Pandas API ve Sparku, strukturovaném streamování a knihovně MLlib (založené na datovém rámci). Nejnovější podporovaná rozhraní API najdete v referenční dokumentaci k rozhraní API PySpark .

Další omezení najdete v tématu Omezení výpočetních prostředků bez serveru.

Načtení velkých tabulek Delta pomocí objemů

U velkých tabulek Delta, které jsou příliš velké na převod s toPandas(), exportujte data do svazku katalogu Unity a načtěte je přímo pomocí PyTorch nebo Hugging Face:

# Step 1: Export the Delta table to Parquet files in a UC volume
output_path = "/Volumes/catalog/schema/my_volume/training_data"
spark.table("catalog.schema.my_table").write.mode("overwrite").parquet(output_path)
# Step 2: Load the exported data directly using Hugging Face datasets
from datasets import load_dataset

dataset = load_dataset("parquet", data_files="/Volumes/catalog/schema/my_volume/training_data/*.parquet")

Tento přístup eliminuje režijní zátěž softwaru Spark během trénování a dobře funguje jak pro pracovní postupy s jednou GPU, tak pro distribuované tréninkové workflow.

Načtení nestrukturovaných dat ze svazků pomocí UCVolumeDataset

Pro nestrukturovaná data, jako jsou obrázky, zvuk a textové soubory uložené ve svazcích katalogu Unity, použijte UCVolumeDataset z serverless_gpu.data balíčku. UCVolumeDataset je PyTorch IterableDataset, který při prvním přístupu zkopíruje každý soubor ze svazku do rychlé místní mezipaměti a vrací cestu k místnímu souboru uloženému v mezipaměti. Řeší problémy s výkonem a distribucí, které byste jinak implementovali ručně:

  • Místní ukládání do mezipaměti Soubory se při prvním přístupu zkopírují z přípojného bodu FUSE do místního adresáře mezipaměti a poté se načítají z mezipaměti, takže při trénování přes více epoch nedochází k opětovnému čtení svazku.
  • Automatické dělení Při inicializaci torch.distributed se soubory rozdělí mezi ranky a poté dále mezi pracovníky DataLoader, takže každá dvojice (rank, worker) obdrží nepřekrývající se část bez nutnosti další konfigurace.

Poznámka:

UCVolumeDataset a serverless_gpu.data.DataLoader vyžadují prostředí GPU Environment 5 nebo novější.

UCVolumeDataset poskytuje nezpracované místní cesty k souborům. Chcete-li tyto soubory dekódovat na tensory, zabalte je do druhého IterableDataset, které zpracovává proud cest a používá vaši logiku parsování. Díky tomu jsou vstupně-výstupní operace a analýzy oddělené.

from serverless_gpu.data import UCVolumeDataset
from torch.utils.data import IterableDataset
from PIL import Image
import torchvision.transforms.functional as TF

class ImageDataset(IterableDataset):
    """Decodes each cached file path from UCVolumeDataset into a tensor."""

    def __init__(self, path_dataset: UCVolumeDataset):
        self._path_dataset = path_dataset

    def __iter__(self):
        for local_path in self._path_dataset:
            image = Image.open(local_path).convert("RGB")
            yield TF.to_tensor(image)

path_dataset = UCVolumeDataset("/Volumes/catalog/schema/my_volume/images")
dataset = ImageDataset(path_dataset)

Obálka přijímá již uložené místní cesty v mezipaměti, takže krok analýzy se nikdy nedotkne připojení FUSE. Můžete řetězit další obaly pro rozšíření, tokenizaci nebo filtrování.

Pro optimální výkon spárujte UCVolumeDataset s serverless_gpu.data.DataLoader namísto výchozího PyTorch DataLoader. Je vyladěný pro vstupně-výstupní operace GPU bez serveru a současně načítá a ukládá soubory do mezipaměti při výpočtu GPU. Viz Výkon načítání dat.

Načtení dat uvnitř dekorátoru @distributed

Při použití Serverless GPU API pro distribuované trénování přesuňte kód načítání dat do dekorátoru @distributed. Velikost datové sady může překročit maximální velikost povolenou funkcí pickle, takže je doporučeno vygenerovat datovou sadu uvnitř dekorátoru, jak je znázorněno níže:

from serverless_gpu import distributed

# This may cause a pickle error if the dataset is too large
dataset = get_dataset(file_path)

@distributed(gpus=8, gpu_type='H100')
def run_train():
    # Load data inside the decorator to avoid pickle serialization issues
    dataset = get_dataset(file_path)
    ...

Když uvnitř dekorátoru vytvoříte UCVolumeDataset, během iterace načte informace o torch.distributed ranku a automaticky rozdělí soubory mezi ranky, takže pro objemová data založená na souborech nepotřebujete DistributedSampler.

Výkon načítání dat

/Workspace a /Volumes adresáře jsou hostované ve vzdáleném úložišti Katalogu Unity. Pokud je vaše datová sada uložená v katalogu Unity, rychlost načítání dat je omezená dostupnou šířkou pásma sítě. Pokud trénujete více epoch, doporučujeme použít UCVolumeDataset tento postup ukládání do mezipaměti: zkopíruje každý soubor do místního úložiště při prvním přístupu a obsluhuje následné čtení z místní kopie. Pro datové sady ve svazcích to upřednostněte před ručním shutil.copytree, které předem zkopíruje celý strom, i když trénování využije jen jeho část.

Pokud je vaše datová sada velká, můžou zvýšit propustnost následující techniky:

  • Použijte serverless_gpu.data.DataLoader k paralelizaci načítání. Jedná se o dílčí podtřídu torch DataLoader vyladěné pro vstupně-výstupní operace GPU bez serveru: num_workers výchozí hodnota je 6 a prefetch_factor 4 (ve srovnání s PyTorch 0 a 2), takže soubory se načítají a ukládají do mezipaměti souběžně, zatímco GPU počítá. Protokoluje také časování dávkového načítání do aktivního spuštění MLflow, které pomáhá odhalit kritické body načítání dat.

    from serverless_gpu.data import DataLoader
    
    loader = DataLoader(
        dataset,
        batch_size=32,
        pin_memory=True,
        # num_workers=6, by default
        # prefetch_factor=4, by default
        # raise num_workers to increase parallel reads, or prefetch_factor to deepen each worker's queue.
    )
    

    Všechny procesy musí používat stejnou hodnotu num_workers, protože UCVolumeDataset rozděluje soubory pomocí globálního kroku napříč world_size × num_workers sloty. Neshodující se hodnoty způsobí, že soubory budou duplikovány nebo přeskočeny.

  • Zvětšete velikost dávky. Větší dávky rozkládají režii načítání dat připadající na jednu dávku mezi více vzorků a snižují počet operací načítání souborů na krok. Pokud je paměť GPU omezujícím faktorem, zkombinujte větší velikost dávky s akumulací gradientu, abyste zachovali efektivní velikost dávky.

Streamování datových sad

U velmi velkých datových sad, které se nevejdou do paměti, použijte přístupy ke streamování: