kylinfires's picture
Sync main: low-VRAM live test results (624x360)
b9fc164 verified
Raw History Blame Contribute Delete
5.33 kB
"""WebDataset decoding and local shard resolution."""
import json
import os
from itertools import islice
from typing import Any, Optional
import datasets
import pyarrow as pa
from datasets.data_files import (
_get_origin_metadata,
DataFilesList as DataFilesListBase,
DownloadConfig,
SingleOriginMetadata,
)
from datasets.features.features import cast_to_python_objects
from datasets.packaged_modules.webdataset.webdataset import WebDataset as WebDatasetBase
class WebDataset(WebDatasetBase):
def _split_generators(self, dl_manager: Any) -> list[datasets.SplitGenerator]:
"""Handle string/list/dict data files and infer features from one sample stream."""
if not self.config.data_files:
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
data_files = dl_manager.download(self.config.data_files)
splits: list[datasets.SplitGenerator] = []
first_tar_path: str | None = None
first_tar_iterator: Any | None = None
for split_name, tar_paths in data_files.items():
if isinstance(tar_paths, str):
tar_paths = [tar_paths]
tar_iterators = [dl_manager.iter_archive(tar_path) for tar_path in tar_paths]
if first_tar_path is None:
first_tar_path = tar_paths[0]
first_tar_iterator = tar_iterators[0]
splits.append(
datasets.SplitGenerator(
name=split_name, gen_kwargs={"tar_paths": tar_paths, "tar_iterators": tar_iterators}
)
)
if not self.info.features:
if first_tar_path is None or first_tar_iterator is None:
raise ValueError("No TAR files were resolved from data_files.")
pipeline = self._get_pipeline_from_tar(first_tar_path, first_tar_iterator)
first_examples = list(islice(pipeline, self.NUM_EXAMPLES_FOR_FEATURES_INFERENCE))
if not first_examples:
raise ValueError("Unable to infer features: no examples found in TAR pipeline.")
if any(example.keys() != first_examples[0].keys() for example in first_examples):
raise ValueError(
"The TAR archives of the dataset should be in WebDataset format, "
"but the files in the archive don't share the same prefix or the same types."
)
pa_tables = [
pa.Table.from_pylist(cast_to_python_objects([example], only_1d_for_numpy=True))
for example in first_examples
]
inferred_arrow_schema = pa.concat_tables(pa_tables, promote_options="default").schema
features = datasets.Features.from_arrow_schema(inferred_arrow_schema)
for field_name in first_examples[0]:
extension = field_name.rsplit(".", 1)[-1]
if extension in self.IMAGE_EXTENSIONS:
features[field_name] = datasets.Image()
for field_name in first_examples[0]:
extension = field_name.rsplit(".", 1)[-1]
if extension in self.VIDEO_EXTENSIONS:
features[field_name] = datasets.Video(decode=False)
for field_name in first_examples[0]:
extension = field_name.rsplit(".", 1)[-1]
if extension in ["json"]:
features[field_name] = datasets.Value("string")
self.info.features = features
return splits
def json_loads(data: str | bytes | bytearray) -> str:
"""Parse JSON payload and normalize it back to a string value."""
data_obj = json.loads(data)
json_str = json.dumps(data_obj)
return json_str
DECODERS = {
"json": json_loads,
}
WebDataset.DECODERS = DECODERS
def _get_single_origin_metadata(
data_file: str,
download_config: Optional[DownloadConfig] = None,
) -> SingleOriginMetadata:
_ = data_file, download_config
return ()
class DataFilesList(DataFilesListBase):
@classmethod
def from_patterns(
cls,
patterns: list[str],
base_path: Optional[str] = None,
allowed_extensions: Optional[list[str]] = None,
download_config: Optional[DownloadConfig] = None,
) -> "DataFilesList":
_ = base_path, allowed_extensions
data_files = patterns
if not data_files:
raise ValueError("`patterns` must contain at least one path.")
if any("://" in str(path) for path in data_files):
raise ValueError("Dataset manifests must list local TAR files, not remote URLs.")
missing_files = [path for path in data_files if not os.path.exists(path)]
if missing_files:
preview = ", ".join(missing_files[:3])
if len(missing_files) > 3:
preview += f" ... (+{len(missing_files) - 3} more)"
raise FileNotFoundError(f"Missing data file(s): {preview}")
origin_metadata = _get_origin_metadata(data_files, download_config=download_config)
return cls(data_files, origin_metadata)
datasets.data_files._get_single_origin_metadata = _get_single_origin_metadata
datasets.data_files.DataFilesList = DataFilesList
datasets.packaged_modules.webdataset.WebDataset = WebDataset