arcisvlm / scripts /download_datasets.py
Hardik Sanghvi
feat: integrate Gemma 4 E2B backbone for production-quality VLM inference
7a564e3
Raw
History Blame Contribute Delete
5.44 kB
"""Download training datasets from HuggingFace Hub.
Usage:
python3 scripts/download_datasets.py --config configs/scale_1.3b.yaml --stage all
python3 scripts/download_datasets.py --config configs/scale_1.3b.yaml --stage stage1
python3 scripts/download_datasets.py --config configs/scale_1.3b.yaml --stage stage2 --dummy
"""
import argparse
import os
import sys
import yaml
import json
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def download_hf_dataset(name: str, source: str, num_samples: int,
output_dir: str, streaming: bool = True):
"""Download a dataset from HuggingFace Hub.
Args:
name: Dataset identifier
source: HuggingFace dataset path
num_samples: Max samples to download
output_dir: Where to save
streaming: Use streaming mode (recommended for large datasets)
"""
os.makedirs(output_dir, exist_ok=True)
output_file = os.path.join(output_dir, f"{name}.jsonl")
if os.path.exists(output_file):
# Count existing lines
with open(output_file) as f:
existing = sum(1 for _ in f)
if existing >= num_samples:
print(f" {name}: Already downloaded ({existing} samples)")
return existing
try:
from datasets import load_dataset
print(f" {name}: Downloading from {source}...")
if streaming:
ds = load_dataset(source, split="train", streaming=True, trust_remote_code=True)
else:
ds = load_dataset(source, split="train", trust_remote_code=True)
count = 0
with open(output_file, "w") as f:
for item in ds:
if count >= num_samples:
break
# Extract text fields (skip image data for now — download separately)
record = {}
for key in ["question", "text", "caption", "answer", "multiple_choice_answer",
"answers", "conversations", "image_id", "id"]:
if key in item:
val = item[key]
if isinstance(val, (str, int, float, bool, list)):
record[key] = val
elif hasattr(val, 'tolist'):
record[key] = val.tolist()
f.write(json.dumps(record) + "\n")
count += 1
if count % 10000 == 0:
print(f" {name}: {count}/{num_samples} samples...")
print(f" {name}: Downloaded {count} samples to {output_file}")
return count
except Exception as e:
print(f" {name}: Download failed ({e}), will use dummy data")
return 0
def generate_dummy_data(name: str, num_samples: int, output_dir: str):
"""Generate dummy training data for testing."""
os.makedirs(output_dir, exist_ok=True)
output_file = os.path.join(output_dir, f"{name}.jsonl")
with open(output_file, "w") as f:
for i in range(min(num_samples, 500)):
record = {
"question": f"Sample question {i} for {name}",
"answer": f"Sample answer {i}",
"id": i,
}
f.write(json.dumps(record) + "\n")
print(f" {name}: Generated {min(num_samples, 500)} dummy samples")
def main():
parser = argparse.ArgumentParser(description="Download ArcisVLM training datasets")
parser.add_argument("--config", default="configs/scale_1.3b.yaml")
parser.add_argument("--stage", default="all", choices=["all", "stage1", "stage2", "stage3"])
parser.add_argument("--output_dir", default="data/downloads")
parser.add_argument("--dummy", action="store_true", help="Generate dummy data only")
args = parser.parse_args()
with open(args.config) as f:
config = yaml.safe_load(f)
stages = []
if args.stage in ["all", "stage1"]:
stages.append(("stage1", config.get("data", {}).get("train_datasets", {}).get("stage1", [])))
if args.stage in ["all", "stage2"]:
stages.append(("stage2", config.get("data", {}).get("train_datasets", {}).get("stage2", [])))
if args.stage in ["all", "stage3"]:
stages.append(("stage3", config.get("data", {}).get("train_datasets", {}).get("stage3", [])))
for stage_name, datasets in stages:
print(f"\n{'='*50}")
print(f"Downloading {stage_name} datasets")
print(f"{'='*50}")
stage_dir = os.path.join(args.output_dir, stage_name)
for ds_config in datasets:
name = ds_config["name"]
source = ds_config.get("source", name)
num_samples = ds_config.get("samples", 1000)
if args.dummy:
generate_dummy_data(name, num_samples, stage_dir)
else:
count = download_hf_dataset(name, source, num_samples, stage_dir)
if count == 0:
print(f" Falling back to dummy data for {name}")
generate_dummy_data(name, num_samples, stage_dir)
print(f"\n{'='*50}")
print("Download complete!")
# Show disk usage
total = 0
for root, dirs, files in os.walk(args.output_dir):
for f in files:
total += os.path.getsize(os.path.join(root, f))
print(f"Total disk usage: {total / 1e9:.2f} GB")
print(f"{'='*50}")
if __name__ == "__main__":
main()