Files
2026-07-13 13:16:54 +08:00

91 lines
3.1 KiB
Python

# Copyright (c) 2025 ByteDance Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# coding: utf-8
"""
Generic parquet/data file helpers that do not depend on cluster-specific settings.
"""
import os
import logging
from typing import Iterable, List, Optional
import pyarrow.fs as pf
import torch.distributed as dist
logger = logging.getLogger(__name__)
SUPPORTED_DATA_EXTENSIONS = (".parquet", ".json", ".jsonl")
def select_supported_files(file_paths: Iterable[str]) -> List[str]:
file_paths = list(file_paths)
parquet_files = [path for path in file_paths if path.endswith(".parquet")]
if parquet_files:
return parquet_files
return [path for path in file_paths if path.endswith((".json", ".jsonl"))]
def list_local_supported_data_files(data_dir: str) -> List[str]:
if os.path.isfile(data_dir):
if not data_dir.endswith(SUPPORTED_DATA_EXTENSIONS):
raise ValueError(f"Unsupported data file: {data_dir}")
return [data_dir]
if not os.path.isdir(data_dir):
raise FileNotFoundError(f"Data path does not exist: {data_dir}")
files = [
os.path.join(data_dir, name)
for name in os.listdir(data_dir)
if name.endswith(SUPPORTED_DATA_EXTENSIONS)
]
return select_supported_files(files)
def init_arrow_fs(parquet_file_path: str) -> pf.FileSystem:
if parquet_file_path.startswith("hdfs://"):
raise ValueError(f"Only local parquet files are supported, got remote path: {parquet_file_path}")
return pf.LocalFileSystem()
def init_arrow_pf_fs(parquet_file_path: str) -> pf.FileSystem:
return init_arrow_fs(parquet_file_path)
def get_parquet_data_paths_balanced(data_dir_list, rank=0, world_size=1, num_repeat=1):
all_data_paths = []
if rank == 0:
logger.info("Rank 0 is gathering local data file paths...")
for data_dir in data_dir_list:
all_data_paths.extend(sorted(list_local_supported_data_files(data_dir)))
logger.info(f"Total local data files found: {len(all_data_paths)}")
if num_repeat > 1:
original_len = len(all_data_paths)
all_data_paths = all_data_paths * num_repeat
logger.info(f"Repeating dataset {num_repeat} times, from {original_len} to {len(all_data_paths)} files.")
if world_size > 1 and dist.is_available() and dist.is_initialized():
object_list = [all_data_paths]
dist.broadcast_object_list(object_list, src=0)
return object_list[0]
return all_data_paths
def read_parquet_rows(parquet_file, row_group_id: int, columns: Optional[List[str]] = None):
return parquet_file.read_row_group(row_group_id, columns=columns).to_pylist()