def demo_postprocess(outputs: ndarray, img_size: Tuple[int, int], p6: bool = False) -> ndarray:
    """yolox post processing function
        formats the raw outputs into scores and bounding boxes
    Args:
        outputs (ndarray): the outputs from the yolox model inference
        img_size (Tuple[int, int]): the size of the input image
        p6 (bool, optional): model architecture parameter. marqo-yolo v1 and v2 should be False.
                            check the model architecture for anything else. Defaults to False.

    Returns:
        ndarray: _description_
    """
    grids = []
    expanded_strides = []

    if not p6:
        strides = [8, 16, 32]
    else:
        strides = [8, 16, 32, 64]

    hsizes = [img_size[0] // stride for stride in strides]
    wsizes = [img_size[1] // stride for stride in strides]

    for hsize, wsize, stride in zip(hsizes, wsizes, strides):
        xv, yv = np.meshgrid(np.arange(wsize), np.arange(hsize))
        grid = np.stack((xv, yv), 2).reshape(1, -1, 2)
        grids.append(grid)
        shape = grid.shape[:2]
        expanded_strides.append(np.full((*shape, 1), stride))

    grids = np.concatenate(grids, 1)
    expanded_strides = np.concatenate(expanded_strides, 1)
    outputs[..., :2] = (outputs[..., :2] + grids) * expanded_strides
    outputs[..., 2:4] = np.exp(outputs[..., 2:4]) * expanded_strides

    return outputs
yolox post processing function
        formats the raw outputs into scores and bounding boxes
    Args:
        outputs (ndarray): the outputs from the yolox model inference
        img_size (Tuple[int, int]): the size of the input image
        p6 (bool, optional): model architecture parameter. marqo-yolo v1 and v2 should be False.
                            check the model architecture for anything else. Defaults to False.

    Returns:
        ndarray: _description_
    
src/marqo/s2_inference/processing/yolox_utils.py