Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: configurable plugins #711

Merged
merged 30 commits into from
Jun 6, 2024

Conversation

jmartin-tech
Copy link
Collaborator

@jmartin-tech jmartin-tech commented May 31, 2024

Fix #589
Fix #595

Buckle up lots of adjustments to review. Many of the generator/probe/detector/buff/harness plugins are refactored in some way or another.

The goal of this change is to offer configuration of instance variables on plugins on a per "type" basis.

Summary of changes:

  • all plugins implementing Configurable and accept a named config_root parameter that defaults to the global _config
  • shift all configurable class variables into DEFAULT_PARAMS to avoid leaking instance specific values
  • inject all default params as instance attributes
  • provide exmaple for _supported_params in class definitions
  • propagate keys in the plugin yaml dictionalry as attributed on plugin instantiation
  • mechanism based on ENV_VAR class constant to obtain api_key during instantiation
  • plugin provides defining a class level _supported_params only apply supported params from configuration files, a warning is logged for unknown items
  • refactor inline configuration yaml refactored for readability
  • rasa.RasaRestGenerator is implements an extension of rest.RestGenerator with embedded defaults and updated module config docs to increase code reuse
  • garak.generators.load_generator() and other generator loading code is removed in favor of _plugin.load_plugin() accounting for DEFAULT_CLASS
  • remove plugin configuration method in favor of Configurable

Configuration files apply in a hierarchal fashion and allow configuration of parameters not exposed in the class initializer.

Final values for configured attributes as instance variables are applied in with precedence to programatic input with a nuance that a constructor default value can be overwritten by a configuration file value if the provided value is the same as the default.

value from named parameter in constructor 
  else: 
    value from config passed to constructor
    else:
      default provided or inherited in class

The changes introduce breaking changes to the expected structure of configuration wether provided as yaml or json.
The primary breaking change is the expectation that configuration of a class will be nested inside configuration for all classes of a module holding more specific resolutions as the maintained values. This format change is currently left in a partially compatible state to provide time for consumers to update configuration formats.
Here is an example of a how configuration of the rest.Generator class is expected to change.

        {"rest.RestGenerator":
            {
                "name": "example service",
                "uri": "https://example.ai/llm",
                "method": "post",
                "headers":{
                    "X-Authorization": "$KEY",
                },
                "req_template_json_object":{
                    "text":"$INPUT"
                },
                "response_json": true,
                "response_json_field": "text"
            }
        }

Becomes:

      {
          "rest": {
              "RestGenerator": {
                  "name": "example service",
                  "uri": "https://example.ai/llm",
                  "method": "post",
                  "headers": {
                      "X-Authorization": "$KEY",
                  },
                  "req_template_json_object": {
                      "text": "$INPUT"
                  },
                  "response_json": true,
                  "response_json_field": "text"
              }
          }
      }

If provided the previous format a warning is logged in garak.log about used of deprecated formatting.

Signed-off-by: Jeffrey Martin <[email protected]>
Signed-off-by: Jeffrey Martin <[email protected]>
* consitent api_key attribute name

Signed-off-by: Jeffrey Martin <[email protected]>
RasaRestGenerator implementation was a copy of RestGenerator with
some modified defaults. Lift defaults to class constants and override.

This is a breaking change to Rasa as the implementation was still expecting
the `rest` namespace in configuration files.

Signed-off-by: Jeffrey Martin <[email protected]>
When a plugin provides `_supported_params` only the supported
params should be applied from configuration files or cli options.

Signed-off-by: Jeffrey Martin <[email protected]>
* cleaner plugin eval
* add DEFAULT_PARAMS for instance values

Signed-off-by: Jeffrey Martin <[email protected]>
* shift all configurable class variables into DEFAULT_PARAMS
* inject all default params as instance attributes
* provide exmaple for `_supported_params` in class definitions
* propogate keys in the plugin yaml dictionalry as attributed on plugin instantiation
* mechanism based on ENV_VAR class constant to obtain `api_key` during instantiation
* remove plugin configuration methods in favor of `Configurable`
* update buff configuration test

Signed-off-by: Jeffrey Martin <[email protected]>
@jmartin-tech jmartin-tech changed the title Feature/configurable plugins Feature: configurable plugins May 31, 2024
@jmartin-tech jmartin-tech added the enhancement Architectural upgrades label May 31, 2024
Copy link
Collaborator

@leondz leondz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. Few questions, many around precendence/parent class.

garak/configurable.py Outdated Show resolved Hide resolved
garak/configurable.py Show resolved Hide resolved
garak/configurable.py Outdated Show resolved Hide resolved
garak/configurable.py Show resolved Hide resolved
garak/configurable.py Outdated Show resolved Hide resolved
tests/generators/test_generators.py Show resolved Hide resolved
tests/generators/test_rest.py Show resolved Hide resolved
tests/plugins/test_plugin_load.py Outdated Show resolved Hide resolved
tests/plugins/test_plugin_load.py Outdated Show resolved Hide resolved
tests/test_config.py Show resolved Hide resolved
@leondz
Copy link
Collaborator

leondz commented May 31, 2024 via email

Copy link
Collaborator

@erickgalinkin erickgalinkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good. Left a handful of comments throughout.

garak/_plugins.py Show resolved Hide resolved
garak/_plugins.py Show resolved Hide resolved
garak/_plugins.py Outdated Show resolved Hide resolved
garak/_plugins.py Outdated Show resolved Hide resolved
garak/_plugins.py Outdated Show resolved Hide resolved
garak/generators/huggingface.py Show resolved Hide resolved
garak/generators/huggingface.py Show resolved Hide resolved
garak/generators/rasa.py Outdated Show resolved Hide resolved
garak/resources/tap/generator_utils.py Outdated Show resolved Hide resolved
garak/resources/tap/generator_utils.py Outdated Show resolved Hide resolved
@jmartin-tech
Copy link
Collaborator Author

Thanks for all the feedback, I will work thru it all and post updated code soon.

* provides a more reabable and better guarded path parser
* avoids mutation of received `path` argument
* test plugin __init__ for config_root
* remove unused values in `generators/__init__.py`
* refactor method name typo

Signed-off-by: Jeffrey Martin <[email protected]>
Signed-off-by: Jeffrey Martin <[email protected]>
Signed-off-by: Jeffrey Martin <[email protected]>
* more clear configurable `_instance_configured`
* ensure `_supported_params` always exists for Configurable
* test `_supported_params` is a list before attemping to search
* additional tests of configurable behavior

Signed-off-by: Jeffrey Martin <[email protected]>
erickgalinkin
erickgalinkin previously approved these changes Jun 3, 2024
Copy link
Collaborator

@erickgalinkin erickgalinkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Definitely some work to be done refactoring TAP and AutoDAN but that's a problem for me to get into next week.

EDIT: Looks like some tests are failing, so clearly I've missed something.

garak/detectors/base.py Show resolved Hide resolved
garak/generators/huggingface.py Show resolved Hide resolved
@erickgalinkin erickgalinkin dismissed their stale review June 3, 2024 20:44

Failing tests

@erickgalinkin erickgalinkin self-requested a review June 3, 2024 20:44
Signed-off-by: Jeffrey Martin <[email protected]>
Copy link
Collaborator

@erickgalinkin erickgalinkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

garak/probes/visual_jailbreak.py Outdated Show resolved Hide resolved
garak/probes/visual_jailbreak.py Outdated Show resolved Hide resolved
garak/probes/visual_jailbreak.py Show resolved Hide resolved
garak/generators/nemo.py Outdated Show resolved Hide resolved
* handle `org_id` from env variable in `_validate_env_var()`
* pass params to parent `super().__init__()` for Pipeline

Signed-off-by: Jeffrey Martin <[email protected]>
* add detector usage of `_validate_env_var()`
* adjust `detector` load_plugins test to provide `api_key`
* generalize package name if not key is not for `generator` config
* defer validation to `Configurable` for more `Generators`

Signed-off-by: Jeffrey Martin <[email protected]>
garak/probes/base.py Outdated Show resolved Hide resolved
* Consolidates all `ENV_VAR` configuration as required at load of config
* changes `buff` behavior to error when instantiated without required ENV_VAR
* update load_plugin tests to mock `api_key` provided for all types

Signed-off-by: Jeffrey Martin <[email protected]>
Once `_load_config()` is called either in `super().__init__()` or in the
plugin constructor, only access values that have been passed in as `self.*`

Signed-off-by: Jeffrey Martin <[email protected]>
Previous to config updates `self.name` was initialized then reset by call
to `super().__init__()` using the original constructor values. This side-effect
was relied upon for pipeline creation.

* remove set of fullname from huggingface generators
* allow config to set `deprefix_prompt` (_config.run.deprefix will still force)

Signed-off-by: Jeffrey Martin <[email protected]>
@jmartin-tech jmartin-tech merged commit 1f3863f into NVIDIA:main Jun 6, 2024
4 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Jun 6, 2024
@jmartin-tech jmartin-tech deleted the feature/configurable-plugins branch June 6, 2024 13:54
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Architectural upgrades
Projects
None yet
Development

Successfully merging this pull request may close these issues.

update the configuration machinery to take class-level info Configurable Generator parameters
3 participants