def dpo_pair_aligner_cleaned(response_field: str = "response",
                             id_field: str = "id",
                             do_sample: bool = False, ):
    """
    This aligner only accepts the cleaned file, which has removing all empty responses and combined with original data.
    :return: Callable
    """

    def func(data: List[Dict]):
        outputs = []
        for item in data:
            pos_resp = []
            neg_resp = []
            for i, (resp, pred) in enumerate(zip(item[response_field], item["pred"])):
                assert resp
                # assert pred
                if isinstance(resp, list):
                    assert isinstance(resp[0], str)
                    # assert "The answer is" in resp[-1], resp
                    resp = "".join(resp)

                if isinstance(item["label"], str):
                    if pred == item["label"]:
                        pos_resp.append((i, resp))
                    else:
                        neg_resp.append((i, resp))
                elif isinstance(item["label"], int):
                    if pred and ord(pred) - ord("A") == item["label"]:
                        pos_resp.append((i, resp))
                    else:
                        neg_resp.append((i, resp))
                else:
                    raise ValueError(f"Unknown type of label: {type(item['label'])}")

            if not (len(pos_resp) and len(neg_resp)):
                continue

            if do_sample:
                pos = random.choice(pos_resp)
                neg = random.choice(neg_resp)
                pos_resp = [pos]
                neg_resp = [neg]

            for pos in pos_resp:
                for neg in neg_resp:
                    new_item = copy.deepcopy(item)
                    new_item["pos"] = pos[1]
                    new_item["neg"] = neg[1]
                    new_item["pos_id"] = f"{item[id_field]}_{pos[0]}"
                    new_item["neg_id"] = f"{item[id_field]}_{neg[0]}"
                    outputs.append(new_item)

        logger.info(f"Counted {len(outputs)} DPO contrastive pairs.")
        return outputs

    return func

    This aligner only accepts the cleaned file, which has removing all empty responses and combined with original data.
    :return: Callable
    
PFPO/data/input_aligner.py