Download code/src/preprocessing/build_preprocessed_shards.py from savastakan/hitit-cuneiform-ocr: direct link, hf CLI and curl.
- Browser
- Download file 5 kB
-
https://huggingface.co/savastakan/hitit-cuneiform-ocr/resolve/main/code/src/preprocessing/build_preprocessed_shards.py
- Command line
-
hf download hf://savastakan/hitit-cuneiform-ocr/code/src/preprocessing/build_preprocessed_shards.py
-
curl -L -o build_preprocessed_shards.py https://huggingface.co/savastakan/hitit-cuneiform-ocr/resolve/main/code/src/preprocessing/build_preprocessed_shards.py
5 kB
| #!/usr/bin/env python3 | |
| """Letterbox 224 preprocessed crop'ları WebDataset shard'larına yaz. | |
| Config-driven preprocessing.yaml'dan okur. | |
| Pipeline: read → CLAHE (conditional) → gamma → letterbox 224 → JPEG | |
| MSII proxy optional 2. shard olarak. | |
| """ | |
| import json, os, io, time, argparse | |
| from pathlib import Path | |
| from concurrent.futures import ProcessPoolExecutor | |
| import sys | |
| ROOT = Path("/arf/scratch/stakan/hitit-proje") | |
| SOURCES = ROOT / "datasets" / "sources" | |
| sys.path.insert(0, str(ROOT / "hitit_ocr" / "src")) | |
| def process_one(item): | |
| """Tek image: preprocess et, JPEG bytes döndür.""" | |
| rid, path, label, source, fold = item | |
| try: | |
| import numpy as np | |
| from PIL import Image | |
| import cv2 | |
| from preprocessing.pipeline import load_config, apply_clahe, apply_gamma, letterbox, is_low_quality, msii_proxy | |
| cfg = load_config() | |
| img = np.array(Image.open(path).convert('RGB')) | |
| enh = cfg.get('enhancement', {}) | |
| if enh.get('clahe', {}).get('enabled') and (not enh['clahe'].get('conditional') or is_low_quality(img)): | |
| img = apply_clahe(img, clip_limit=enh['clahe'].get('clip_limit', 2.5)) | |
| if enh.get('gamma_correction', {}).get('enabled') and (not enh['gamma_correction'].get('conditional') or is_low_quality(img)): | |
| img = apply_gamma(img, gamma=enh['gamma_correction'].get('gamma', 1.2)) | |
| lb = cfg.get('geometric', {}).get('letterbox', {}) | |
| img = letterbox(img, target=lb.get('target_size', 224), margin_ratio=lb.get('margin_ratio', 0.1)) | |
| # Encode JPEG | |
| buf = io.BytesIO() | |
| Image.fromarray(img).save(buf, format='JPEG', quality=90) | |
| jpeg_bytes = buf.getvalue() | |
| return (rid, jpeg_bytes, label, source, fold) | |
| except Exception as e: | |
| return (rid, None, None, None, None) | |
| def main(): | |
| import webdataset as wds | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument('--subset', default='curated', help='curated|all|hitit') | |
| ap.add_argument('--workers', type=int, default=64) | |
| ap.add_argument('--shard-size', type=int, default=2000) | |
| ap.add_argument('--out', default=str(ROOT / "datasets" / "streaming" / "preprocessed_224")) | |
| args = ap.parse_args() | |
| # Topla | |
| items = [] | |
| for d in sorted(SOURCES.iterdir()): | |
| if not d.is_dir(): continue | |
| mp = d / "manifest_classification.jsonl" | |
| if not mp.exists(): continue | |
| with open(mp) as f: | |
| for line in f: | |
| r = json.loads(line) | |
| if r.get('storage') != 'fs' or not r.get('path') or not os.path.exists(r['path']): continue | |
| if r.get('quality_gate_pass') is False: continue | |
| if args.subset == 'curated' and not r.get('in_curated_pretrain'): continue | |
| if args.subset == 'hitit' and r.get('source') != 'hitit': continue | |
| items.append((r['id'], r['path'], r.get('unified_label',''), r.get('source',''), r.get('fold', 0))) | |
| print(f"İşlenecek: {len(items):,}", flush=True) | |
| out_dir = Path(args.out) | |
| out_dir.mkdir(parents=True, exist_ok=True) | |
| pattern = str(out_dir / "preprocessed-%06d.tar") | |
| sink = wds.ShardWriter(pattern, maxcount=args.shard_size, encoder=False) | |
| t0 = time.time() | |
| done = 0 | |
| try: | |
| with ProcessPoolExecutor(max_workers=args.workers) as ex: | |
| for res in ex.map(process_one, items, chunksize=50): | |
| rid, jpeg_bytes, label, source, fold = res | |
| if jpeg_bytes: | |
| sink.write({ | |
| '__key__': rid, | |
| 'jpeg': jpeg_bytes, | |
| 'json': json.dumps({ | |
| 'id': rid, 'unified_label': label, | |
| 'source': source, 'fold': fold, | |
| }, ensure_ascii=False).encode('utf-8'), | |
| }) | |
| done += 1 | |
| if done % 5000 == 0 and done > 0: | |
| rate = done / max(time.time() - t0, 1) | |
| print(f" {done:,}/{len(items):,} ({rate:.0f} img/s)", flush=True) | |
| finally: | |
| sink.close() | |
| # Summary | |
| shards = sorted(out_dir.glob("preprocessed-*.tar")) | |
| total_size = sum(s.stat().st_size for s in shards) | |
| print(f"\n{len(shards)} shard, {done:,} kayıt, {total_size/1024/1024:.1f} MB") | |
| meta = { | |
| "format": "WebDataset (preprocessed letterbox 224, CLAHE+gamma conditional)", | |
| "n_shards": len(shards), | |
| "n_records": done, | |
| "total_size_mb": round(total_size/1024/1024, 1), | |
| "pattern": f"preprocessed-{{000000..{len(shards)-1:06d}}}.tar", | |
| "config_version": "1.0", | |
| "preprocessing_steps": ["CLAHE (conditional)", "Gamma (conditional)", "Letterbox 224 median-fill"], | |
| } | |
| with open(out_dir / "shards.json", 'w') as f: | |
| json.dump(meta, f, indent=2, ensure_ascii=False) | |
| if __name__ == '__main__': | |
| main() | |