Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / data / tools / read_indexed_dataset.py: 0%
54 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
1# Copyright 2026 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""
16Inspect token sequences stored in an indexed dataset.
18python -m hyper_parallel.data.tools.read_indexed_dataset \
19 --path outputs/training_demo/tiny_llama_wikitext2/data_no_pack/wikitext2_real_text_document.idx \
20 --tokenizer outputs/training_demo/tiny_llama_wikitext2/tokenizer \
21 --num-samples 5
22"""
24import argparse
25import logging
26from collections.abc import Sequence
28from transformers import AutoTokenizer
30from hyper_parallel.data.dataset_logging import get_dataset_logger
31from hyper_parallel.data.indexed.indexed_data_reader import IndexedDataReader
33logger = get_dataset_logger(__name__)
36def _path_prefix(path: str) -> str:
37 """Remove an optional indexed Dataset file suffix from a path."""
38 return path[:-4] if path.endswith((".bin", ".idx")) else path
41def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
42 """Parse indexed Dataset inspection arguments."""
43 parser = argparse.ArgumentParser(description="Inspect an indexed dataset")
44 parser.add_argument("--path", required=True, help="Dataset prefix or its .bin/.idx path")
45 parser.add_argument("--tokenizer", help="Local Hugging Face tokenizer path or repository")
46 parser.add_argument(
47 "--tokenizer-type", choices=("huggingface", "pretokenized"), default="huggingface",
48 help="Use pretokenized when only vocabulary metadata is available",
49 )
50 parser.add_argument("--vocab-size", type=int, help="Vocabulary size for pretokenized data")
51 parser.add_argument("--eod-token-id", type=int, help="EOD token ID for pretokenized data")
52 parser.add_argument("--start-index", type=int, default=0, help="First sequence index to read")
53 parser.add_argument("--num-samples", type=int, default=5, help="Number of sequences to read")
54 parser.add_argument("--max-token-ids", type=int, default=80, help="Maximum token IDs printed per sequence")
55 parser.add_argument("--max-text-chars", type=int, default=1000, help="Maximum decoded characters per sequence")
56 parser.add_argument("--skip-special-tokens", action="store_true", help="Remove special tokens when decoding")
57 return parser.parse_args(argv)
60def main(argv: Sequence[str] | None = None) -> None:
61 """Print indexed Dataset metadata and selected token sequences."""
62 args = _parse_args(argv)
63 if args.start_index < 0 or args.num_samples < 0:
64 raise ValueError("start-index and num-samples must be non-negative")
66 if args.max_token_ids < 0 or args.max_text_chars < 0:
67 raise ValueError("max-token-ids and max-text-chars must be non-negative")
69 reader = IndexedDataReader(_path_prefix(args.path))
70 tokenizer = None
71 if args.tokenizer_type == "huggingface" and args.tokenizer:
72 tokenizer = AutoTokenizer.from_pretrained(args.tokenizer)
74 if args.tokenizer_type == "pretokenized":
75 if args.vocab_size is None or args.eod_token_id is None:
76 raise ValueError("pretokenized mode requires vocab-size and eod-token-id")
77 logger.info(
78 "Pretokenized metadata: vocab_size=%d, eod_token_id=%d; decoded text is unavailable",
79 args.vocab_size, args.eod_token_id,
80 )
81 sequence_lengths = reader.sequence_lengths
82 logger.info(
83 "Dataset: sequences=%d, documents=%d, min_length=%d, max_length=%d, mean_length=%.2f",
84 len(reader), len(reader.document_indices) - 1, int(sequence_lengths.min()), int(sequence_lengths.max()),
85 float(sequence_lengths.mean()),
86 )
88 stop_index = min(args.start_index + args.num_samples, len(reader))
89 for index in range(args.start_index, stop_index):
90 token_ids = reader[index].tolist()
91 displayed_ids = token_ids[:args.max_token_ids]
92 suffix = " ..." if len(displayed_ids) < len(token_ids) else ""
93 logger.info("[%d] length=%d\ntoken_ids=%s%s", index, len(token_ids), displayed_ids, suffix)
95 if args.tokenizer_type == "pretokenized":
96 eod_positions = [position for position, token_id in enumerate(token_ids) if token_id == args.eod_token_id]
97 logger.info("eod_positions=%s", eod_positions)
99 if tokenizer is not None:
100 text = tokenizer.decode(token_ids, skip_special_tokens=args.skip_special_tokens)
101 text_suffix = " ..." if len(text) > args.max_text_chars else ""
102 logger.info("text=%r%s", text[:args.max_text_chars], text_suffix)
105if __name__ == "__main__":
106 logging.basicConfig(level=logging.INFO, format="%(message)s")
107 main()