def get_quant_model(
        self, model: HfModelHandler, config: type[BasePassConfig], output_model_path: str
    ) -> tuple[HfModelHandler, "PreTrainedModel", dict, list[str]]:
        """Get the model handler, LoRA model for QLoRA fine-tuning.

        :param model: The input model handler.
        :param config: The config for the pass run.
        :param output_model_path: The path to save the output model to.
        :return: The new model handler, LoRA model, quantization config and list of quantized modules.
        """
        import bitsandbytes as bnb

        # get new model
        bnb_quant_config = {
            "quantization_method": "bitsandbytes",
            "quantization_config": {
                "load_in_4bit": True,
                "bnb_4bit_compute_dtype": self.get_torch_dtype(config.compute_dtype or config.torch_dtype),
                "bnb_4bit_use_double_quant": config.double_quant,
                "bnb_4bit_quant_type": config.quant_type,
            },
        }
        pytorch_model = self.load_base_pytorch_model(model, config, **bnb_quant_config)

        # find the quantized modules, only linears
        quantized_modules = find_submodules(pytorch_model, bnb.nn.Linear4bit)
        logger.debug("Quantized modules: %s", quantized_modules)

        # enable lora fine-tuning with new lora modules
        config.target_modules = quantized_modules
        pytorch_model = self.enable_lora(pytorch_model, config, model.task)

        return deepcopy(model), pytorch_model, bnb_quant_config, quantized_modules
Get the model handler, LoRA model for QLoRA fine-tuning.

        :param model: The input model handler.
        :param config: The config for the pass run.
        :param output_model_path: The path to save the output model to.
        :return: The new model handler, LoRA model, quantization config and list of quantized modules.
        
olive/passes/pytorch/lora.py