Datasets documentation

Akış

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v4.8.4).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Akış

Veri kümesi akışı, bir veri kümesini indirmeden üzerinde çalışmanızı sağlar. Veri, veri kümesi üzerinde gezinirken akıtılır. Bu özellikle şu durumlarda faydalıdır:

  • Aşırı büyük bir veri setinin indirilmesini beklemek istemezsiniz.
  • Veri seti boyutu, bilgisayarınızdaki kullanılabilir disk alanını aşıyor.
  • Bir veri setinin yalnızca birkaç örneğini hızlıca incelemek istiyorsunuz.

Örneğin, HuggingFaceFW/fineweb veri setinin İngilizce bölümü 45 terabayttır ancak bunu akışla (streaming) anında kullanabilirsiniz. Bir veri setini akış olarak kullanmak için aşağıda gösterildiği gibi load_dataset() içinde streaming=True parametresini ayarlayın:

>>> from datasets import load_dataset
>>> dataset = load_dataset('HuggingFaceFW/fineweb', split='train', streaming=True)
>>> print(next(iter(dataset)))
{'text': 'How AP reported in all formats from tornado-stricken regionsMarch 8, 2012\nWhen the first serious bout of tornadoes of 2012 blew through middle America in the middle of the night, they touched down in places hours from any AP bureau...', ...,
 'language_score': 0.9721424579620361, 'token_count': 717}

Dataset streaming, herhangi bir dönüştürme işlemi yapmadan yerel dosyalardan oluşan bir veri setiyle çalışmanızı da sağlar. Bu durumda, veri setinin üzerinde gezinirken veri yerel dosyalardan akış olarak alınır. Bu özellikle şu durumlarda faydalıdır:

  • Aşırı büyük bir yerel veri setinin Arrow'a dönüştürülmesini beklemek istemezsiniz.
  • Dönüştürülen dosyaların boyutu, bilgisayarınızdaki kullanılabilir disk alanını aşacaktır.
  • Bir veri setinin yalnızca birkaç örneğini hızlıca incelemek istiyorsunuz.
  • Yalnızca belirli sütunları yüklemek veya bir Parquet veri setini verimli bir şekilde filtrelemek istiyorsunuz.

Örneğin, oscar-corpus/OSCAR-2201 gibi yüzlerce sıkıştırılmış JSONL dosyasından oluşan yerel bir veri setini akış olarak alıp anında kullanabilirsiniz:

>>> from datasets import load_dataset
>>> data_files = {'train': 'path/to/OSCAR-2201/compressed/en_meta/*.jsonl.gz'}
>>> dataset = load_dataset('json', data_files=data_files, split='train', streaming=True)
>>> print(next(iter(dataset)))
{'id': 0, 'text': 'Founded in 2015, Golden Bees is a leading programmatic recruitment platform dedicated to employers, HR agencies and job boards. The company has developed unique HR-custom technologies and predictive algorithms to identify and attract the best candidates for a job opportunity.', ...

Parquet, yalnızca sütunların bir alt kümesini akış olarak okumanıza ve istenmeyen sütunları yok saymanıza olanak tanıyan sütun tabanlı bir biçimdir. Parquet, verimli filtreleme yapılmasını sağlayan sütun istatistikleri gibi (dosya ve satır grubu düzeyinde) meta verileri de saklar. Parquet veri kümelerini akış olarak okumak, sütun seçmek ve filtreler uygulamak için datasets.packaged_modules.parquet.ParquetConfig sınıfının columns ve filters argümanlarını kullanın:

>>> from datasets import load_dataset
>>> dataset = load_dataset('HuggingFaceFW/fineweb', split='train', streaming=True, columns=["url", "date"])
>>> print(next(iter(dataset)))
{'url': 'http://%20jwashington@ap.org/Content/Press-Release/2012/How-AP-reported-in-all-formats-from-tornado-stricken-regions', 'date': '2013-05-18T05:48:54Z'}
>>> dataset = load_dataset('HuggingFaceFW/fineweb', split='train', streaming=True, filters=[("language_score", ">=", 0.99)])
>>> print(next(iter(dataset)))
{'text': 'Everyone wishes for something. And lots of people believe they know how to make their wishes come true with magical thinking.\nWhat is it? "Magical thinking is a belief in forms of causation, with no known physical basis," said Professor Emily Pronin of Princeton...', ...,
 'language_score': 0.9900368452072144, 'token_count': 716}

Akış (streaming) modunda bir veri seti yüklemek, klasik Dataset nesnesi yerine, IterableDataset olarak bilinen yeni bir veri seti türü örneği oluşturur. Bu özel veri seti türünün, aşağıda gösterilen kendi işleme yöntemleri seti vardır.

Bir IterableDataset, bir model eğitimi gibi iteratif işler için faydalıdır. Örneklerin rastgele erişimini gerektiren işler için IterableDataset kullanmamalısınız çünkü bir for döngüsü kullanarak tüm veri setinin üzerinden iterasyon yapmanız gerekir. İteratif bir veri setindeki son örneğe ulaşmak, önceki tüm örneklerin üzerinden iterasyon yapmanızı gerektirir. Daha fazla ayrıntıyı Dataset vs. IterableDataset kılavuzunda bulabilirsiniz.

Sütun indeksleme

Bazen belirli bir sütunun değerleri üzerinde döngü yapmak pratik olabilir. Neyse ki, IterableDataset sütun indekslemeyi destekler:

>>> from datasets import load_dataset
>>> dataset = load_dataset("allenai/c4", "en", streaming=True, split="train")
>>> print(next(iter(dataset["text"])))
Beginners BBQ Class Taking Place in Missoula!...

Bir Dataset'ten dönüştür

Mevcut bir Dataset nesneniz varsa, to_iterable_dataset() işleviyle bunu bir IterableDataset nesnesine dönüştürebilirsiniz. Bu, load_dataset() içinde streaming=True argümanını ayarlamaktan aslında daha hızlıdır çünkü veri yerel dosyalardan akar.

>>> from datasets import load_dataset

# faster 🐇
>>> dataset = load_dataset("ethz/food101")
>>> iterable_dataset = dataset.to_iterable_dataset()

# slower 🐢
>>> iterable_dataset = load_dataset("ethz/food101", streaming=True)

to_iterable_dataset() işlevi, IterableDataset örneklenirken dilimlemeyi (sharding) destekler. Bu, büyük veri setleriyle çalışırken veri setini karıştırmak veya PyTorch DataLoader ile hızlı paralel yükleme etkinleştirmek istendiğinde faydalıdır.

>>> import torch
>>> from datasets import load_dataset

>>> dataset = load_dataset("ethz/food101")
>>> iterable_dataset = dataset.to_iterable_dataset(num_shards=64) # shard the dataset
>>> iterable_dataset = iterable_dataset.shuffle(buffer_size=10_000)  # shuffles the shards order and use a shuffle buffer when you start iterating
dataloader = torch.utils.data.DataLoader(iterable_dataset, num_workers=4)  # assigns 64 / 4 = 16 shards from the shuffled list of shards to each worker when you start iterating

Karıştır

Düzenli bir Dataset nesnesi gibi, IterableDataset nesnesini de IterableDataset.shuffle() ile karıştırabilirsiniz.

buffer_size argümanı, örneklerin rastgele seçileceği tamponun boyutunu kontrol eder. Veri setinizin bir milyon örnek içerdiğini ve buffer_size değerini on bin olarak ayarladığınızı varsayalım. IterableDataset.shuffle(), tampondaki ilk on bin örnekten rastgele örnekler seçer. Tamponda seçilen örnekler, yeni örneklerle değiştirilir. Varsayılan olarak tampon boyutu 1.000'dir.

>>> from datasets import load_dataset
>>> dataset = load_dataset('HuggingFaceFW/fineweb', split='train', streaming=True)
>>> shuffled_dataset = dataset.shuffle(seed=42, buffer_size=10_000)

IterableDataset.shuffle(), karıştırma kalitesini önemli ölçüde artırmak için tamponu bir seferde en fazla max_buffer_input_shards parça (varsayılan 10) kullanarak doldurur. Ayrıca veri seti birden fazla dosyaya bölünmüşse parçaların sırasını da karıştırır.

Sadece bir veya birkaç dosya içeren bir Parquet veri setini akış olarak işliyorsanız, karıştırma işleminden önce reshard() kullanın. Bu, veri setinin dosya bazında yerine satır grubu bazında parçalanmasını sağlayarak karıştırma kalitesini artırır.

Yeniden karıştır

Bazen her epoch sonrasında veri setini yeniden karıştırmak isteyebilirsiniz. Bunun için her epoch için farklı bir seed ayarlamanız gerekir. Epochlar arasında veri setinin hangi epoch’ta olduğunuzu belirtmek için IterableDataset.set_epoch() kullanın.

Tohumunuz fiilen şu hale gelir: initial seed + current epoch.

>>> for epoch in range(epochs):
...     shuffled_dataset.set_epoch(epoch)
...     for example in shuffled_dataset:
...         ...

Veri setini böl

Veri setinizi iki yoldan biriyle bölebilirsiniz:

>>> dataset = load_dataset('HuggingFaceFW/fineweb', split='train', streaming=True)
>>> dataset_head = dataset.take(2)
>>> list(dataset_head)
[{'text': "How AP reported in all formats from tor...},
 {'text': 'Did you know you have two little yellow...}]
>>> train_dataset = shuffled_dataset.skip(1000)

take ve skip, shard'ların sırasını sabitlemeleri nedeniyle shuffle çağrılarının gelecekte yapılmasını engeller. Veri setinizi bölmekden önce shuffle etmeniz gerekir.

Parça

🤗 Datasets, çok büyük bir veri setini önceden tanımlanmış sayıda parçaya bölmek için shard (parçalama) desteği sunar. Veri setinin kaç shard'a bölüneceğini belirlemek için shard() içinde num_shards parametresini belirtin. Ayrıca, döndürmek istediğiniz shard'ı index parametresiyle de sağlamanız gerekir.

Örneğin, amazon_polarity veri setinin 4 parçası (shard) vardır (bu durumda bunlar 4 Parquet dosyasıdır):

>>> from datasets import load_dataset
>>> dataset = load_dataset("fancyzhx/amazon_polarity", split="train", streaming=True)
>>> print(dataset)
IterableDataset({
    features: ['label', 'title', 'content'],
    num_shards: 4
})

Veri seti iki parçaya bölündükten sonra, ilk parçada yalnızca 2 shard bulunacaktır:

>>> dataset.shard(num_shards=2, index=0)
IterableDataset({
    features: ['label', 'title', 'content'],
    num_shards: 2
})

Bir veri setinin shard sayısını artırmak için IterableDataset.reshard() kullanabilirsiniz:

>>> dataset.reshard()
IterableDataset({
    features: ['label', 'title', 'content'],
    num_shards: 3600
})

Resharding mekanizması, veri seti dosya biçimine bağlıdır. Örneğin Parquet için, shard başına bir dosya yerine satır grupları kullanılarak yeniden shard edilir. Her biçim için nasıl çalıştığını IterableDataset.reshard() belgelerinde inceleyin.

Veri setiniz yeniden parçalandıktan sonra bile dataset.num_shards==1 ise, bunun yerine IterableDataset.skip() ve IterableDataset.take() kullanarak parçalara ayırmanız gerekir.

Birleştir

Aynı sütun türlerini paylaşan ayrı veri setleri birleştirilebilir. Veri setlerini concatenate_datasets() ile birleştirin:

>>> from datasets import concatenate_datasets, load_dataset

>>> stories = load_dataset("ajibawa-2023/General-Stories-Collection", split="train", streaming=True)
>>> stories = stories.select_columns(["text"])  # only keep the 'text' column
IterableDataset({
    features: Unknown,
    num_shards: 10
})

>>> wiki = load_dataset("wikimedia/wikipedia", "20231101.en", split="train", streaming=True)
>>> wiki = wiki.select_columns(["text"])  # only keep the 'text' column
IterableDataset({
    features: ['text'],
    num_shards: 41
})

>>> bert_dataset = concatenate_datasets([stories, wiki])
IterableDataset({
    features: ['text'],
    num_shards: 51
})

Birleştirilmiş veri setinin parçaları, girdi veri setlerinin parçalarıdır.

Ayrıca, veri kümelerinin aynı sayıda satıra sahip olması koşuluyla, axis=1 değerini ayarlayarak iki veri kümesini yatay olarak birleştirebilirsiniz:

>>> from datasets import IterableDataset
>>> stories_ids = IterableDataset.from_dict({"ids": list(range(num_stories))})
>>> stories_with_ids = concatenate_datasets([stories, stories_ids], axis=1)

Bu durumda, birleştirilmiş veri setinin yalnızca 1 parçası (shard) vardır; bu, girdi veri setlerinden hizalanmamış parçalarla bitmemek için yapılır.

Araya Ser

interleave_datasets(), sütun türleri aynıysa bir IterableDataset'i diğer veri kümeleriyle birleştirebilir. Birleştirilen veri kümesi, orijinal veri kümelerinden dönüşümlü örnekler döndürür.

>>> from datasets import interleave_datasets
>>> es_dataset = load_dataset('allenai/c4', 'es', split='train', streaming=True)
IterableDataset({
    features: Unknown,
    num_shards: 2048
})
>>> fr_dataset = load_dataset('allenai/c4', 'fr', split='train', streaming=True)
IterableDataset({
    features: Unknown,
    num_shards: 2048
})

>>> multilingual_dataset = interleave_datasets([es_dataset, fr_dataset])
IterableDataset({
    features: ['text', 'timestamp', 'url'],
    num_shards: 2048
})
>>> list(multilingual_dataset.take(2))
[{'text': 'Comprar Zapatillas para niña en chancla con goma por...'},
 {'text': 'Le sacre de philippe ier, 23 mai 1059 - Compte Rendu...'}]

Her bir orijinal veri setinden örnek alma olasılıklarını tanımlayarak, bunların nasıl örneklenip birleştirileceği üzerinde daha fazla kontrol sağlayın. İstediğiniz örnek alma olasılıklarını probabilities argümanını ayarlayarak belirleyin:

>>> multilingual_dataset_with_oversampling = interleave_datasets([es_dataset, fr_dataset], probabilities=[0.8, 0.2], seed=42)
>>> list(multilingual_dataset_with_oversampling.take(2))
[{'text': 'Comprar Zapatillas para niña en chancla con goma por...'},
 {'text': 'Chevrolet Cavalier Usados en Bogota - Carros en Vent...'}]

Son veri setinin yaklaşık %80'i es_dataset, %20'si ise fr_dataset ile oluşturulmuştur.

stopping_strategy parametresini de belirleyebilirsiniz. Varsayılan strateji olan first_exhausted, bir alt örneklem (subsampling) stratejisidir; yani veri setlerinden biri örneklerini tükettiği anda veri seti inşası durdurulur. Aşırı örneklem (oversampling) stratejisi uygulamak için stopping_strategy=all_exhausted parametresini belirleyebilirsiniz. Bu durumda, veri setlerindeki her örnek en az bir kez eklendiği anda veri seti inşası durdurulur. Pratikte bu, bir veri seti tükendiğinde durdurma kriterine ulaşıncaya kadar bu veri setinin başına dönülerek örneklerin tekrar alınacağı anlamına gelir. Örnekleme olasılıkları belirtilmezse, yeni veri setinin max_length_datasets*nb_dataset samples örnek içereceğini unutmayın. Her örneğin tam olarak bir kez görüleceğinden emin olmak için stopping_strategy=all_exhausted_without_replacement seçeneği de mevcuttur.

Sharding kullanılarak doğru paralellik sağlamak için, iç içe geçmiş veri setinin shard'ları, her girdi veri setinden en az 1 shard içerir. Bu nedenle, iç içe geçmiş veri setinin sharding seviyesi, girdi veri setlerinin minimum sharding seviyesidir.

Örneğin, girdi veri kümeleri sırasıyla 32, 48 ve 128 parçaya sahipse, iç içe geçmiş veri kümesi 32 = min(32, 48, 128) parçaya sahip olur ve her yeni parça, ilk veri kümesinden 1 parça, ikinci veri kümesinden 1-2 parça ve üçüncü veri kümesinden 4 parça içerir.

Yeniden adlandırma, kaldırma ve dönüştürme

Aşağıdaki yöntemler, bir veri setinin sütunlarını değiştirmenize olanak tanır. Bu yöntemler, sütunları yeniden adlandırmak veya kaldırmak ve sütunları yeni bir özellik setine dönüştürmek için kullanışlıdır.

Yeniden adlandır

Veri setinizde bir sütunu yeniden adlandırmanız gerektiğinde IterableDataset.rename_column() kullanın. Orijinal sütunla ilişkili özellikler, orijinal sütunun yerinde değiştirilmesi yerine aslında yeni sütun adının altına taşınır.

IterableDataset.rename_column() fonksiyonuna, orijinal sütunun adını ve yeni sütun adını verin:

>>> from datasets import load_dataset
>>> dataset = load_dataset('allenai/c4', 'en', streaming=True, split='train')
>>> dataset = dataset.rename_column("text", "content")

Kaldır

Bir veya daha fazla sütunu kaldırmak gerektiğinde, IterableDataset.remove_columns() fonksiyonuna kaldırmak istediğiniz sütunun adını verin. Birden fazla sütunu kaldırmak için sütun adlarının bir listesini sağlayın:

>>> from datasets import load_dataset
>>> dataset = load_dataset('allenai/c4', 'en', streaming=True, split='train')
>>> dataset = dataset.remove_columns('timestamp')

Dönüştür

IterableDataset.cast(), bir veya daha fazla sütunun özellik türünü değiştirir. Bu yöntem, yeni Features nesnenizi argüman olarak alır. Aşağıdaki örnek kod, ClassLabel ve Value özellik türlerinin nasıl değiştirileceğini göstermektedir:

>>> from datasets import load_dataset
>>> dataset = load_dataset('nyu-mll/glue', 'mrpc', split='train', streaming=True)
>>> dataset.features
{'sentence1': Value('string'),
'sentence2': Value('string'),
'label': ClassLabel(names=['not_equivalent', 'equivalent']),
'idx': Value('int32')}

>>> from datasets import ClassLabel, Value
>>> new_features = dataset.features.copy()
>>> new_features["label"] = ClassLabel(names=['negative', 'positive'])
>>> new_features["idx"] = Value('int64')
>>> dataset = dataset.cast(new_features)
>>> dataset.features
{'sentence1': Value('string'),
'sentence2': Value('string'),
'label': ClassLabel(names=['negative', 'positive']),
'idx': Value('int64')}

Casting, yalnızca orijinal özellik tipi ile yeni özellik tipi uyumluysa çalışır. Örneğin, orijinal sütun yalnızca birler ve sıfırlar içeriyorsa, Value('int32') özellik tipine sahip bir sütunu Value('bool') olarak cast edebilirsiniz.

Tek bir sütunun özellik türünü değiştirmek için IterableDataset.cast_column() kullanın. Sütun adını ve yeni özellik türünü argüman olarak iletin:

>>> dataset.features
{'audio': Audio(sampling_rate=44100, mono=True)}

>>> dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
>>> dataset.features
{'audio': Audio(sampling_rate=16000, mono=True)}

Harita

Düzenli bir Dataset için kullanılan Dataset.map() işlevine benzer şekilde, 🤗 Datasets, bir IterableDataset işlenmesi için IterableDataset.map() işlevini sunar. IterableDataset.map(), örnekler akış halindeyken işlemleri anında uygular.

Bir veri setindeki her örneğe, bağımsız olarak veya toplu halde, bir işlevsel işlem uygulamanızı sağlar. Bu işlem, yeni satırlar ve sütunlar bile oluşturabilir.

Aşağıdaki örnek, bir IterableDataset'in nasıl tokenize edildiğini gösterir. Fonksiyonun bir dict kabul etmesi ve çıkarması gerekir:

>>> def add_prefix(example):
...     example['text'] = 'My text: ' + example['text']
...     return example

Ardından, bu işlevi IterableDataset.map() ile veri setine uygulayın:

>>> from datasets import load_dataset
>>> dataset = load_dataset('allenai/c4', 'en', streaming=True, split='train')
>>> updated_dataset = dataset.map(add_prefix)
>>> list(updated_dataset.take(3))
[{'text': 'My text: Beginners BBQ Class Taking Place in Missoula!\nDo you want to get better at making...',
  'timestamp': '2019-04-25 12:57:54',
  'url': 'https://klyq.com/beginners-bbq-class-taking-place-in-missoula/'},
 {'text': 'My text: Discussion in \'Mac OS X Lion (10.7)\' started by axboi87, Jan 20, 2012.\nI\'ve go...',
  'timestamp': '2019-04-21 10:07:13',
  'url': 'https://forums.macrumors.com/threads/restore-from-larger-disk-to-smaller-disk.1311329/'},
 {'text': 'My text: Foil plaid lycra and spandex shortall with metallic slinky insets. Attached metall...',
  'timestamp': '2019-04-25 10:40:23',
  'url': 'https://awishcometrue.com/Catalogs/Clearance/Tweens/V1960-Find-A-Way'}]

Bir başka örneğe bakalım; bu sefer sütunları IterableDataset.map() ile kaldıracaksınız. Bir sütun kaldırıldığında, bu sütun yalnızca örnek eşlenmiş işlevine (mapped function) sağlandıktan sonra kaldırılır. Bu sayede eşlenmiş işlev, sütunlar kaldırılmadan önce içeriklerini kullanabilir.

IterableDataset.map() içinde remove_columns argümanını kullanarak kaldırılacak sütunu belirtin:

>>> updated_dataset = dataset.map(add_prefix, remove_columns=["timestamp", "url"])
>>> list(updated_dataset.take(3))
[{'text': 'My text: Beginners BBQ Class Taking Place in Missoula!\nDo you want to get better at making...'},
 {'text': 'My text: Discussion in \'Mac OS X Lion (10.7)\' started by axboi87, Jan 20, 2012.\nI\'ve go...'},
 {'text': 'My text: Foil plaid lycra and spandex shortall with metallic slinky insets. Attached metall...'}]

Toplu işleme

IterableDataset.map() ayrıca örneklerin toplu (batch) olarak işlenmesini destekler. Toplular üzerinde işlem yapmak için batched=True değerini ayarlayın. Varsayılan top büyüklüğü 1000'dir ancak batch_size argümanı ile değiştirebilirsiniz. Bu, tokenizasyon, uzun cümlelerin daha kısa parçalara bölünmesi ve veri artırma gibi birçok ilginç uygulamaya kapı açar.

Tokenizasyon

>>> from datasets import load_dataset
>>> from transformers import AutoTokenizer
>>> dataset = load_dataset("allenai/c4", "en", streaming=True, split="train")
>>> tokenizer = AutoTokenizer.from_pretrained('distilbert-base-uncased')
>>> def encode(examples):
...     return tokenizer(examples['text'], truncation=True, padding='max_length')
>>> dataset = dataset.map(encode, batched=True, remove_columns=["text", "timestamp", "url"])
>>> next(iter(dataset))
{'input_ids': [101, 4088, 16912, 22861, 4160, 2465, 2635, 2173, 1999, 3335, ..., 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ..., 0, 0]}

Toplu işleme için diğer örnekleri batched map processing belgelerinde inceleyin. Bunlar, yinelebilir veri kümeleri için de aynı şekilde çalışır.

Filtre

Veri setindeki satırları, bir öngürme (predicate) işlevi temelinde Dataset.filter() kullanarak filtreleyebilirsiniz. Belirtilen koşula uyan satırları döndürür:

>>> from datasets import load_dataset
>>> dataset = load_dataset('HuggingFaceFW/fineweb', streaming=True, split='train')
>>> start_with_ar = dataset.filter(lambda example: example['text'].startswith('San Francisco'))
>>> next(iter(start_with_ar))
{'text': 'San Francisco 49ers cornerback Shawntae Spencer will miss the rest of the sea...}

Dataset.filter(), with_indices=True olarak ayarladığınızda indekslere göre de filtreleme yapabilir:

>>> even_dataset = dataset.filter(lambda example, idx: idx % 2 == 0, with_indices=True)
>>> list(even_dataset.take(3))
[{'text': 'How AP reported in all formats from tornado-stricken regionsMarch 8, 2012 Whe...},
 {'text': 'Car Wash For Clara! Now is your chance to help! 2 year old Clara Woodward has...},
 {'text': 'Log In Please enter your ECode to log in. Forgotten your eCode? If you create...}]

Toplu

batch yöntemi, IterableDataset nesnenizi bir parti (batch) dizilerine dönüştürür. Bu, eğitim döngünüzde partilerle çalışmak istediğinizde veya partili girdiler bekleyen çerçeveleri kullandığınızda özellikle faydalıdır.

map işlevi kullanılarak veri toplamlarına bir işlev uygulamak için “Batch Processing” seçeneği de mevcuttur; bu seçenek yukarıdaki Map bölümünde ele alınmıştır. Burada açıklanan batch yöntemi farklıdır ve veri setinizden toplamlar oluşturmak için daha doğrudan bir yol sunar.

batch yöntemini şu şekilde kullanabilirsiniz:

from datasets import load_dataset

# Load a dataset in streaming mode
dataset = load_dataset("some_dataset", split="train", streaming=True)

# Create batches of 32 samples
batched_dataset = dataset.batch(batch_size=32)

# Iterate over the batched dataset
for batch in batched_dataset:
    print(batch)
    break

Bu örnekte, batched_dataset hâlâ bir IterableDataset’tir, ancak her bir öğe artık tek bir örnek yerine 32 örnekten oluşan bir partidir. Bu partileme, veri kümesi üzerinde gezinirken anlık olarak yapılır ve IterableDataset’in bellek verimli doğasını korur.

Batch yöntemi ayrıca drop_last_batch parametresini de sağlar. True olarak ayarlandığında, son batch, belirtilen batch_size'dan küçükse atılır. Bu, aşağı akış işlemlerinizin tüm batch'lerin aynı boyutta olmasını gerektirdiği senaryolarda faydalı olabilir:

batched_dataset = dataset.batch(batch_size=32, drop_last_batch=True)

Eğitim döngüsünde akış

IterableDataset bir eğitim döngüsüne entegre edilebilir. Önce veri setini karıştırın:

Pytorch
Hide Pytorch content
>>> seed, buffer_size = 42, 10_000
>>> dataset = dataset.shuffle(seed, buffer_size=buffer_size)

Son olarak, basit bir eğitim döngüsü oluşturun ve eğitime başlayın:

>>> import torch
>>> from torch.utils.data import DataLoader
>>> from transformers import AutoModelForMaskedLM, DataCollatorForLanguageModeling
>>> from tqdm import tqdm
>>> dataset = dataset.with_format("torch")
>>> dataloader = DataLoader(dataset, collate_fn=DataCollatorForLanguageModeling(tokenizer))
>>> device = 'cuda' if torch.cuda.is_available() else 'cpu' 
>>> model = AutoModelForMaskedLM.from_pretrained("distilbert-base-uncased")
>>> model.train().to(device)
>>> optimizer = torch.optim.AdamW(params=model.parameters(), lr=1e-5)
>>> for epoch in range(3):
...     dataset.set_epoch(epoch)
...     for i, batch in enumerate(tqdm(dataloader, total=5)):
...         if i == 5:
...             break
...         batch = {k: v.to(device) for k, v in batch.items()}
...         outputs = model(**batch)
...         loss = outputs[0]
...         loss.backward()
...         optimizer.step()
...         optimizer.zero_grad()
...         if i % 10 == 0:
...             print(f"loss: {loss}")

Bir veri seti kontrol noktası kaydet ve yinelemeyi sürdür

Eğitim döngünüz durursa, eğitimden kaldığınız yerden devam etmek isteyebilirsiniz. Bunu yapmak için modelinizin ve optimizatörlerinizin bir kontrol noktasını (checkpoint) yanı sıra veri yükleyicinizi de kaydedebilirsiniz.

Iterable veri kümeleri, kaldığı yerden devam etmek için belirli bir örnek dizinine rastgele erişim sağlamaz; ancak modeller ve optimizörler için yapabildiğiniz gibi, bir kontrol noktasından devam etmek için IterableDataset.state_dict() ve IterableDataset.load_state_dict() kullanabilirsiniz:

>>> iterable_dataset = Dataset.from_dict({"a": range(6)}).to_iterable_dataset(num_shards=3)
>>> for idx, example in enumerate(iterable_dataset):
...     print(example)
...     if idx == 2:
...         state_dict = iterable_dataset.state_dict()
...         print("checkpoint")
...         break
>>> iterable_dataset.load_state_dict(state_dict)
>>> print(f"restart from checkpoint")
>>> for example in iterable_dataset:
...     print(example)

Dönüş:

{'a': 0}
{'a': 1}
{'a': 2}
checkpoint
restart from checkpoint
{'a': 3}
{'a': 4}
{'a': 5}

Arka planda, yinelebilir veri seti, okunan mevcut shard'i ve mevcut shard içindeki örnek dizinini takip eder ve bu bilgiyi state_dict içinde saklar.

Kontrol noktasından devam etmek için veri seti, önceki okunan tüm parçaları atlayarak mevcut parçadan yeniden başlar. Ardından parçayı okur ve kontrol noktasındaki tam örneğe ulaşana kadar örnekleri atlar.

Dolayısıyla bir veri setinin yeniden başlatılması oldukça hızlıdır, çünkü zaten üzerinde gezinilmiş olan parçaları yeniden okumaz. Yine de, bir veri setinin devam ettirilmesi genellikle anlık değildir; çünkü mevcut parçanın başından okumayı yeniden başlatıp, kontrol noktası konumuna ulaşana kadar örnekleri atlaması gerekir.

Bu, torchdata'daki StatefulDataLoader ile kullanılabilir:

>>> from torchdata.stateful_dataloader import StatefulDataLoader
>>> iterable_dataset = load_dataset("deepmind/code_contests", streaming=True, split="train")
>>> dataloader = StatefulDataLoader(iterable_dataset, batch_size=32, num_workers=4)
>>> # checkpoint
>>> state_dict = dataloader.state_dict()  # uses iterable_dataset.state_dict() under the hood
>>> # resume from checkpoint
>>> dataloader.load_state_dict(state_dict)  # uses iterable_dataset.load_state_dict() under the hood

Devam etme, .shuffle() kullanılmadığı sürece kontrol noktasının kaydedildiği tam noktadan başlar: devam ederken karıştırma tamponlarındaki örnekler kaybolur ve tamponlar yeni verilerle doldurulur.

Kaydet

Yinelebilir veri setiniz hazır olduğunda, onu Parquet biçiminde bir Hugging Face Dataset olarak kaydedebilir ve daha sonra load_dataset() ile yeniden kullanabilirsiniz.

Veri setinizi, Hugging Face'te kaydetmek istediğiniz veri seti deposunun adını push_to_hub() argümanı olarak sağlayarak kaydedin. Bu işlem, veri setinin üzerinden iterasyon yaparak verileri Hugging Face'e kademeli olarak yükler:

dataset.push_to_hub("username/my_dataset")

Varsayılan olarak IterableDataset.push_to_hub(), dataset.num_shards dosya yazar. Farklı bir sayı seçmek için num_shards değerini ayarlayın. dataset.num_shards değerinden daha fazla çıktı shard'ı varsa, her giriş shard'ı, örnekleri tek bir geçişte round-robin yöntemiyle kendi çıktı shard'ları grubuna yazılarak bu shard'lara dağıtılır. İstenen shard sayısından daha az örnek varsa, kalan shard'lar boş Parquet dosyalarıdır.

Veri kümesi birden çok parçadan (dataset.num_shards > 1) oluşuyorsa, onu paralel olarak yüklemek için birden çok süreç kullanabilirsiniz. Bu, özellikle map() veya filter() adımlarını uyguladıysanız çok faydalıdır, çünkü bu adımlar paralel çalıştırıldığında daha hızlı çalışır:

dataset.push_to_hub("username/my_dataset", num_proc=8)

Veri setini yeniden yüklemek için load_dataset() fonksiyonunu kullanın:

from datasets import load_dataset
reloaded_dataset = load_dataset("username/my_dataset")

Dışa Aktar

🤗 Datasets, veri setinizi diğer uygulamalarda çalışabilmeniz için dışa aktarmayı da destekler. Aşağıdaki tablo, dışa aktarabileceğiniz şu anda desteklenen dosya biçimlerini gösterir:

Dosya türüDışa aktarma yöntemi
CSVIterableDataset.to_csv()
JSONIterableDataset.to_json()
ParquetIterableDataset.to_parquet()
SQLIterableDataset.to_sql()
Bellek içi Python nesnesiIterableDataset.to_pandas(), IterableDataset.to_polars() or IterableDataset.to_dict()

Örneğin, veri setinizi bir CSV dosyasına şu şekilde dışa aktarın:

>>> dataset.to_csv("path/of/my/dataset.csv")

Büyük bir veri setiniz varsa, örneğin her shard için bir dosya kaydedebilirsiniz:

>>> num_shards = dataset.num_shards
>>> for index in range(num_shards):
...     shard = dataset.shard(index, num_shards)
...     shard.to_parquet(f"path/of/my/dataset/data-{index:05d}.parquet")
Update on GitHub