def prepare_sessions(
        model_path: str,
        execution_provider: str,
        device: str,
        device_id: int,
        adapter_info: dict[str, Any],
        adapter_mode: AdapterMode,
    ) -> tuple[dict[str, InferenceSession], dict[str, dict[str, Any]]]:
        """Prepare the sessions and adapters for the model.

        :param model_path: Path to the model.
        :param execution_provider: The execution provider to use.
        :param device: The device to use.
        :param device_id: The device id to use.
        :param adapter_info: Dictionary of adapter information. Each key is the adapter name and the value is a
            dictionary with the following keys
            - "weights": Path to the weights file or dictionary of weights.
            - "template": The template to use for the adapter.
        :param adapter_mode: The mode to use for the adapters. Can be "inputs" or "initializers".
        :return: Tuple of sessions and adapters.
            Sessions is a dictionary of session names to InferenceSession objects.
            Adapters is a dictionary of adapter names to dictionaries with the following keys
            - "session": The session name to use for the adapter.
            - "template": The template to use for the adapter.
            - "numpy_inputs": The numpy inputs for the adapter if adapter_mode is "inputs".
            - "ortvalue_inputs": The OrtValue inputs for the adapter if adapter_mode is "inputs".
        """
        sessions = {}
        adapters = {}
        providers = [execution_provider]
        provider_options = [{"device_id": device_id}] if device in {"cuda", "dml"} else None
        if adapter_mode == AdapterMode.inputs:
            # there is only one session
            # TODO(jambayk): test and enable graph for cuda and dml
            sessions["default"] = InferenceSession(model_path, providers=providers, provider_options=provider_options)
            for name, info in adapter_info.items():
                adapters[name] = {
                    "session": "default",
                    "template": info.get("template"),
                }
                if info.get("weights") is not None:
                    np_weights = load_weights(info["weights"]) if isinstance(info["weights"], str) else info["weights"]
                    # TODO(jambayk): provide an option to lazy load the ortvalues if needed
                    # for example, there is not enough memory to load all adapters at once
                    if execution_provider != "QNNExecutionProvider":
                        ort_values = {
                            k: OrtValue.ortvalue_from_numpy(v, device, device_id) for k, v in np_weights.items()
                        }
                    else:
                        ort_values = None
                    adapters[name].update({"numpy_inputs": np_weights, "ortvalue_inputs": ort_values})
        else:
            # create a session for each adapter
            for name, info in adapter_info.items():
                # load the initializers and create the session
                initializer_names = []
                initializer_values = []
                if info.get("weights") is not None:
                    np_weights = load_weights(info["weights"]) if isinstance(info["weights"], str) else info["weights"]
                    for i_name, value in np_weights.items():
                        initializer_names.append(i_name)
                        initializer_values.append(OrtValue.ortvalue_from_numpy(value))

                session_options = SessionOptions()
                session_options.add_external_initializers(initializer_names, initializer_values)

                sessions[name] = InferenceSession(
                    model_path, providers=providers, provider_options=provider_options, sess_options=session_options
                )
                adapters[name] = {
                    "session": name,
                    "template": info.get("template"),
                }
        return sessions, adapters
Prepare the sessions and adapters for the model.

        :param model_path: Path to the model.
        :param execution_provider: The execution provider to use.
        :param device: The device to use.
        :param device_id: The device id to use.
        :param adapter_info: Dictionary of adapter information. Each key is the adapter name and the value is a
            dictionary with the following keys
            - "weights": Path to the weights file or dictionary of weights.
            - "template": The template to use for the adapter.
        :param adapter_mode: The mode to use for the adapters. Can be "inputs" or "initializers".
        :return: Tuple of sessions and adapters.
            Sessions is a dictionary of session names to InferenceSession objects.
            Adapters is a dictionary of adapter names to dictionaries with the following keys
            - "session": The session name to use for the adapter.
            - "template": The template to use for the adapter.
            - "numpy_inputs": The numpy inputs for the adapter if adapter_mode is "inputs".
            - "ortvalue_inputs": The OrtValue inputs for the adapter if adapter_mode is "inputs".
        
examples/utils/generator.py