Files
startrail-org--pixelrag/train/package_hf_image_shards.py
wehub-resource-sync 542cfa195c
CI / Frontend build (push) Failing after 9m6s
CI / Plugin validate (push) Failing after 9m27s
CI / Python lint (push) Failing after 16m1s
CI / Tests (push) Successful in 18m0s
Deploy / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:27 +08:00

130 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""Pack a prepared HF dataset export into tar shards for faster Hub uploads."""
from __future__ import annotations
import argparse
import json
import shutil
import tarfile
from pathlib import Path
DEFAULT_SOURCE_DIR = Path(
"/home/user/wiki-screenshot-training/hf_dataset_export/screenshot-training"
)
DEFAULT_OUTPUT_DIR = Path(
"/home/user/wiki-screenshot-training/hf_dataset_export_sharded/screenshot-training"
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--source-dir", type=Path, default=DEFAULT_SOURCE_DIR)
parser.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT_DIR)
parser.add_argument(
"--overwrite",
action="store_true",
help="Remove existing shard tar if it already exists.",
)
return parser.parse_args()
def copy_metadata(source_dir: Path, output_dir: Path) -> None:
output_dir.mkdir(parents=True, exist_ok=True)
for src in sorted(source_dir.iterdir()):
if src.name == "images":
continue
if src.is_file():
shutil.copy2(src, output_dir / src.name)
def pack_one_shard(shard_dir: Path, tar_path: Path, output_root: Path) -> int:
file_count = 0
tar_path.parent.mkdir(parents=True, exist_ok=True)
with tarfile.open(tar_path, mode="w") as tar:
for path in sorted(shard_dir.rglob("*")):
if not path.is_file():
continue
arcname = path.relative_to(output_root).as_posix()
tar.add(path, arcname=arcname, recursive=False)
file_count += 1
return file_count
def build_readme(output_dir: Path, shard_count: int) -> None:
readme_path = output_dir / "README.md"
if not readme_path.exists():
return
original = readme_path.read_text()
extra = f"""
## Image Storage
The images are stored as `{shard_count}` tar shards under `image_shards/` to keep
the repository file count low and make uploads/downloads more reliable.
To materialize the images locally after download:
```bash
python extract_hf_image_shards.py --dataset-dir .
```
"""
if "## Image Storage" not in original:
readme_path.write_text(original.rstrip() + "\n" + extra)
def main() -> int:
args = parse_args()
source_dir = args.source_dir
output_dir = args.output_dir
source_images = source_dir / "images"
shard_output_dir = output_dir / "image_shards"
output_dir.mkdir(parents=True, exist_ok=True)
shard_output_dir.mkdir(parents=True, exist_ok=True)
copy_metadata(source_dir, output_dir)
shard_dirs = sorted(p for p in source_images.iterdir() if p.is_dir())
summary = {
"source_dir": str(source_dir),
"output_dir": str(output_dir),
"shard_count": 0,
"shards": {},
}
for shard_dir in shard_dirs:
tar_path = shard_output_dir / f"{shard_dir.name}.tar"
if tar_path.exists() and not args.overwrite:
continue
if tar_path.exists():
tar_path.unlink()
file_count = pack_one_shard(shard_dir, tar_path, source_images)
summary["shards"][shard_dir.name] = {
"tar_path": str(tar_path),
"file_count": file_count,
"size_bytes": tar_path.stat().st_size,
}
summary["shard_count"] = len(list(shard_output_dir.glob("*.tar")))
summary["total_size_bytes"] = sum(
info["size_bytes"] for info in summary["shards"].values()
)
(output_dir / "image_shards_summary.json").write_text(
json.dumps(summary, indent=2, sort_keys=True)
)
extract_script_src = Path(
"/home/user/wiki-screenshot-training/extract_hf_image_shards.py"
)
if extract_script_src.exists():
shutil.copy2(extract_script_src, output_dir / "extract_hf_image_shards.py")
build_readme(output_dir, summary["shard_count"])
print(json.dumps(summary, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())