Spaces:
Running on Zero
Running on Zero
Download utils/processed_pai.py from hugging-apps/lidarverse: direct link, hf CLI and curl.
- Browser
- Download file 4.06 kB
-
https://huggingface.co/spaces/hugging-apps/lidarverse/resolve/main/utils/processed_pai.py
- Command line
-
hf download hf://spaces/hugging-apps/lidarverse/utils/processed_pai.py
-
curl -L -o processed_pai.py https://huggingface.co/spaces/hugging-apps/lidarverse/resolve/main/utils/processed_pai.py
4.06 kB
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| """Small NPZ training adapter using the same PAI contract as the quickstarts.""" | |
| import os | |
| from pathlib import Path | |
| import numpy as np | |
| import torch | |
| from torch.utils.data import DataLoader, Dataset, DistributedSampler, default_collate | |
| from utils.pai_batch import make_pai_batch | |
| class ProcessedPAI(Dataset): | |
| def __init__(self, root, frames, tokenizer=False): | |
| self.paths = sorted(Path(root).rglob("*.npz")) | |
| if not self.paths: | |
| raise FileNotFoundError(f"No processed samples under {root}; run prepare_pai_bidir.py first") | |
| self.frames = frames | |
| self.tokenizer = tokenizer | |
| def __len__(self): | |
| return len(self.paths) | |
| def __getitem__(self, index): | |
| path = self.paths[index] | |
| with np.load(path, allow_pickle=False) as data: | |
| sample = {key: data[key] for key in data.files} | |
| ranges = sample["range_m"] | |
| if ranges.shape[1:] != (128, 1024) or len(ranges) < self.frames: | |
| raise ValueError(f"{path}: need {self.frames} real 128x1024 sweeps") | |
| if (str(sample["dataset"]) != "pandar" or int(sample["sensor_dataset_id"]) != 0 | |
| or float(sample["min_range_m"]) != 2.5 or float(sample["max_range_m"]) != 100 | |
| or float(sample["fps"]) != 10 or bool(sample["has_prepend"])): | |
| raise ValueError(f"{path}: sample does not match the PAI release contract") | |
| start = int(torch.randint(len(ranges) - self.frames + 1, ()).item()) | |
| temporal = ("range_m", "valid_mask", "hdmap", "pose_sensor_start_end", | |
| "box_valid", "box_object_to_world", "box_lwh", "box_track_id", "box_is_moving") | |
| for key in temporal: | |
| if key in sample: | |
| sample[key] = sample[key][start:start + self.frames] | |
| if self.tokenizer: | |
| ranges = sample["range_m"] | |
| valid = sample["valid_mask"] & np.isfinite(ranges) & (ranges >= 2.5) & (ranges <= 100) | |
| video = np.where(valid, 2 * (ranges - 2.5) / 97.5 - 1, -1).astype(np.float32) | |
| # Match tokenizer training's repeated first sweep, not the DiT layout. | |
| video = torch.from_numpy(np.concatenate((video[:1], video)))[None] | |
| mask = torch.from_numpy(np.concatenate((valid[:1], valid)))[None].float() | |
| batch = dict(video=video, recon_target=video.clone(), loss_mask=mask, | |
| loss_mask_is_validity=True, sensor_dataset_id=torch.tensor(0), | |
| sensor_ray_directions=torch.from_numpy(sample["ray_directions"]).float(), | |
| sensor_depth_bounds=torch.tensor([2.5, 100.])) | |
| else: | |
| batch = make_pai_batch(sample, self.frames) | |
| batch = {key: value[0] if torch.is_tensor(value) else value for key, value in batch.items()} | |
| batch.update(clip_name=path.stem, data_type="lidar", __key__=path.stem) | |
| return batch | |
| def _collate(samples): | |
| batch = default_collate(samples) | |
| for key in ("is_preprocessed", "loss_mask_is_validity"): | |
| if key in batch: | |
| batch[key] = True | |
| return batch | |
| def build_loader(root, frames=21, tokenizer=False, validation=False, num_workers=2, batch_size=1): | |
| dataset = ProcessedPAI(root, frames, tokenizer) | |
| sampler = DistributedSampler(dataset, shuffle=not validation) | |
| return DataLoader(dataset, batch_size=batch_size, sampler=sampler, num_workers=num_workers, | |
| pin_memory=True, drop_last=False, collate_fn=_collate) | |
| def loader_config(*, tokenizer=False, validation=False): | |
| from utils.lazy_config import LazyCall as L | |
| root = os.environ.get("LIDARVERSE_PAI_VAL_DATA" if validation else "LIDARVERSE_PAI_TRAIN_DATA", | |
| "data/bidir_quick_start/nvidia_pai") | |
| return L(build_loader)(root=root, frames=8 if tokenizer else 21, tokenizer=tokenizer, | |
| validation=validation, num_workers=2, batch_size=1) | |