def validate_config(
    config: Union[dict[str, Any], ConfigBase, None],
    instance_class: type[T],
    warn_unused_keys: bool = True,
) -> T:
    """Validate a config dictionary or object against a base class and instance class.

    instance class is a subclass of base class.
    """
    config = config or {}

    if isinstance(config, dict):
        user_keys = set(config.keys())
        config = instance_class(**config)
        # check for unused keys
        config_dict = config.dict()
        config_keys = set(config_dict.keys())
        unused_keys = user_keys - config_keys
        if isinstance(config, NestedConfig):
            unused_keys -= set((config_dict.get(config._nested_field_name) or {}).keys())  # pylint: disable=W0212
        if unused_keys and warn_unused_keys:
            logger.warning("Keys %s are not part of %s. Ignoring them.", unused_keys, instance_class.__name__)
    # for dynamically created class by Pydantic create_model, the classes are different even if the class names are same
    elif (
        isinstance(config, ConfigBase)
        and config.__class__.__module__ == instance_class.__module__
        and config.__class__.__name__ == instance_class.__name__
    ):
        pass
    else:
        raise ValueError(
            f"Invalid config class. Expected {instance_class.__name__} but got {config.__class__.__name__}"
        )
    return config
Validate a config dictionary or object against a base class and instance class.

    instance class is a subclass of base class.
    
olive/common/config_utils.py