def process(self, inputs, outputs):
        """
        Process the pair of inputs and outputs.
        If they contain batches, the pairs can be consumed one-by-one using `zip`:

        .. code-block:: python

            for input_, output in zip(inputs, outputs):
                # do evaluation on single input/output pair
                ...

        Args:
            inputs (list): the inputs that's used to call the model.
            outputs (list): the return value of `model(inputs)`
        """
        sample_tokens = [x['sample_token'] for x in inputs]
        idx_to_token = get_group_idxs(sample_tokens, NUM_IMAGES_PER_SAMPLE, inverse=True)

        # This handles samples with no detections.
        for token in set(sample_tokens):
            self._nusc_sample_results[token]  # pylint: disable=pointless-statement

        for image_idx, (input_per_image, pred_per_image) in enumerate(zip(inputs, outputs)):
            pred_classes = pred_per_image['instances'].pred_classes
            pred_boxes = pred_per_image['instances'].pred_boxes.tensor
            pred_boxes3d = pred_per_image['instances'].pred_boxes3d
            # pred_boxes3d = pred_per_image['instances'].pred_box3d_as_vec
            scores = pred_per_image['instances'].scores
            scores_3d = pred_per_image['instances'].scores_3d

            pred_attributes = pred_per_image['instances'].pred_attributes
            pred_speeds = pred_per_image['instances'].pred_speeds

            file_name = input_per_image['file_name']
            image_id = input_per_image['image_id']

            pred_boxes3d_global = pred_per_image['instances'].pred_boxes3d_global

            sample_token = idx_to_token[image_idx]

            for class_id, box3d, box3d_global, score_3d, box2d, attr, speed, score in zip(
                pred_classes, pred_boxes3d, pred_boxes3d_global, scores_3d, pred_boxes, pred_attributes, pred_speeds,
                scores
            ):
                # class_name = self._metadata.thing_classes[class_id]
                class_name = NUSCENES_DETECTION_CATEGORIES[class_id]

                # attribute
                attr = attr.item()
                if class_name in VEH_ATTR_CLASSES:
                    attr_name = VEH_ATTR_ID_TO_NAME[attr % len(VEH_ATTR_ID_TO_NAME)]
                elif class_name in PED_ATTR_CLASSES:
                    attr_name = PED_ATTR_ID_TO_NAME[attr % len(PED_ATTR_ID_TO_NAME)]
                elif class_name in CYC_ATTR_CLASSES:
                    attr_name = CYC_ATTR_ID_TO_NAME[attr % len(CYC_ATTR_ID_TO_NAME)]
                else:
                    attr_name = ""

                # velocity
                vel_global = speed.cpu().numpy() * Quaternion(box3d_global.quat.tolist()[0]).rotation_matrix.T[0]
                vx, vy = vel_global[:2].tolist()
                # speed * Quaternion(ann['rotation']).rotation_matrix.T[0] ~= vel_global

                box3d_as_vec = box3d.vectorize()[0].cpu().numpy()

                pred = OrderedDict(
                    category_id=int(class_id),  # COCO instances
                    category=class_name,
                    bbox3d=box3d_as_vec.tolist(),
                    # COCO instances uses "XYWH". Aligning with it as much as possible
                    bbox=BoxMode.convert(box2d.tolist(), from_mode=BoxMode.XYXY_ABS, to_mode=BoxMode.XYWH_ABS),
                    score=float(score),
                    score_3d=float(score_3d),
                    file_name=file_name,
                    image_id=image_id  # COCO instances
                )
                self._predictions_as_json.append(pred)

                nusc_det = self.build_nusc_detection(
                    sample_token, box3d_global, class_name, score_3d, attribute=attr_name, velocity=[vx, vy]
                )
                self._nusc_sample_results[sample_token].append(nusc_det)

        Process the pair of inputs and outputs.
        If they contain batches, the pairs can be consumed one-by-one using `zip`:

        .. code-block:: python

            for input_, output in zip(inputs, outputs):
                # do evaluation on single input/output pair
                ...

        Args:
            inputs (list): the inputs that's used to call the model.
            outputs (list): the return value of `model(inputs)`
        
tridet/evaluators/nuscenes_evaluator.py