def merge_lora(pipeline, lora_state_dict, multiplier=1, device="cpu", dtype=torch.float32):
    """Merge state_dict in LoRANetwork to the pipeline in diffusers.

    Reference:
    1. https://github.com/huggingface/diffusers/issues/3064#issuecomment-1512429695.
    """
    LORA_PREFIX_UNET = "lora_unet"
    LORA_PREFIX_TEXT_ENCODER = "lora_te"
    updates = defaultdict(dict)
    for key, value in lora_state_dict.items():
        layer, elem = key.split(".", 1)
        updates[layer][elem] = value
    for layer, elems in updates.items():
        if "text" in layer:
            layer_infos = layer.split(LORA_PREFIX_TEXT_ENCODER + "_")[-1].split("_")
            curr_layer = pipeline.text_encoder
        else:
            layer_infos = layer.split(LORA_PREFIX_UNET + "_")[-1].split("_")
            curr_layer = pipeline.unet
        temp_name = layer_infos.pop(0)
        while len(layer_infos) > -1:
            try:
                curr_layer = curr_layer.__getattr__(temp_name)
                if len(layer_infos) > 0:
                    temp_name = layer_infos.pop(0)
                elif len(layer_infos) == 0:
                    break
            except Exception:
                if len(layer_infos) == 0:
                    print("Error loading layer")
                if len(temp_name) > 0:
                    temp_name += "_" + layer_infos.pop(0)
                else:
                    temp_name = layer_infos.pop(0)
        weight_up = elems["lora_up.weight"].to(dtype)
        weight_down = elems["lora_down.weight"].to(dtype)
        if "alpha" in elems.keys():
            alpha = elems["alpha"].item() / weight_up.shape[1]
        else:
            alpha = 1.0
        curr_layer.weight.data = curr_layer.weight.data.to(device)
        if len(weight_up.shape) == 4:
            curr_layer.weight.data += (
                multiplier * alpha * torch.mm(weight_up.squeeze(3).squeeze(2), weight_down.squeeze(3).squeeze(2)).unsqueeze(2).unsqueeze(3)
            )
        else:
            curr_layer.weight.data += multiplier * alpha * torch.mm(weight_up, weight_down)
    return pipeline
Merge state_dict in LoRANetwork to the pipeline in diffusers.

    Reference:
    1. https://github.com/huggingface/diffusers/issues/3064#issuecomment-1512429695.
    
scripts/train_kohya/utils/lora_utils.py