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

feat: Adding RestrictedFeatures Support to the Python Frontend Bindings #7775

Open
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

KrishnanPrash
Copy link
Contributor

@KrishnanPrash KrishnanPrash commented Nov 8, 2024

What does the PR do?

This PR provides Restricted Features support to the python frontend bindings, a.k.a tritonfrontend.
This PR introduces 3 new classes to the tritonfrontend package:

  1. Feature: 1-to-1 mapping of RestrictedCategory Enum
  2. FeatureGroup: Pydantic @dataclass that stores (key, value, features) information while performing type validation.
  3. RestrictedFeatures: Store collections of FeatureGroup instances, apply an additional layer of validation to check for collisions (ensuring that each feature belongs to only one group), and serialize the data into a JSON string.

With these changes, we can pass a RestrictedFeatures to the KServeHttp and KServeGrpc frontends, which looks along the lines of:

>>> import tritonserver
>>> from tritonfrontend import KServeHttp, KServeGrpc
>>> from tritonfrontend import RestrictedFeatures
>>> server = tritonserver.Server(...).start(wait_until_ready=True)

>>> rf = RestrictedFeatures(...)

>>> http_options = KServeHttp.Options(restricted_features=rf)
>>> http_service = KServeHttp(server, http_options)
>>> http_service.start()

>>> grpc_options = KServeGrpc.Options(restricted_features=rf)
>>> grpc_service = KServeGrpc(server, grpc_options)
>>> grpc_service.start()

A RestrictedFeatures instance can be created with:

>>> from tritonfrontend import Feature, FeatureGroup, RestrictedFeatures
>>> admin_group = FeatureGroup(key="admin-key", value="admin-value", features=[Feature.HEALTH, Feature.METADATA])
>>> infer_group = FeatureGroup("infer-key", "infer-value", [Feature.INFERENCE])

>>> rf = RestrictedFeatures([admin_group, infer_group])

>>> model_group = FeatureGroup("model-key", "model-value", [Feature.MODEL_REPOSITORY])
>>> rf.add_feature_group(model_group)

>>> rf.create_feature_group("stat-key", "stat-value", [Feature.STATISTICS])
>>> rf
[  
   {"key": "admin-key", "value": "admin-value", "features": ["health", "metadata"]}, 
   {"key": "infer-key", "value": "infer-value", "features": ["inference"]}, 
   {"key": "model-key", "value": "model-value", "features": ["model-repository"]}, 
   {"key": "stat-key", "value": "stat-value", "features": ["statistics"]}
]

Where should the reviewer start?

Take a look at api/_restricted_features.py and tritonfrontend.h

Test plan:

In L0_python_api/test_kserve.py added:

  • test_correct_rf_parameters() and test_wrong_rf_parameters(): Tests for valid/invalid arguments passed/selected for Feature, FeatureGroup and RestrictedFeature
    To test if restricted features are working correctly with the frontends:
  • test_restricted_features(): Restricts inference. Then, sends an inference request with a correct and incorrect header to verify proper functionality.

CI Pipeline ID: 20189649

Background

For more information about restricted features support in Triton, please take a look at this: [Link]

Additonal Changes Made in this PR

  • Cleaned up includes in tritonfrontend.h and tritonfrontend_pybind.cc.
  • Added support to @handle_triton_error for non-void functions.
  • Added support to pass headers in send_and_test_inference_identity() so that we can re-use utility function for restricted features testing.

@KrishnanPrash KrishnanPrash self-assigned this Nov 8, 2024
def validate_features(features: List[Feature]) -> List[Feature]:
invalid_features = [item for item in features if not isinstance(item, Feature)]
if invalid_features:
raise tritonserver.InvalidArgumentError(
Copy link
Contributor Author

@KrishnanPrash KrishnanPrash Nov 8, 2024

Choose a reason for hiding this comment

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

Investigating why @field_validator is incompatible with @handle_triton_server nested underneath. To unblock, directly raised tritonserver equivalent error.

HTTP_ARGS = (KServeHttp, httpclient, "localhost:8000") # Default HTTP args
GRPC_ARGS = (KServeGrpc, grpcclient, "localhost:8001") # Default GRPC args
METRICS_ARGS = (Metrics, "localhost:8002") # Default Metrics args
RESTRICTED_FEATURE_ARG = RestrictedFeatures()
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the pytest way to set test suit level parameters? Can you point me to the guide on that?

src/python/tritonfrontend/_api/_error_mapping.py Outdated Show resolved Hide resolved

utils.teardown_service(service)
utils.teardown_server(server)

Copy link
Contributor

Choose a reason for hiding this comment

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

test for:

  1. multiple feature groups
  2. overwrite feature groups
  3. remove feature groups
  4. duplicate feature in different groups

self.add_feature_group(group)

@handle_triton_error
def _gather_rest_data(self) -> dict:
Copy link
Contributor

Choose a reason for hiding this comment

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

what is rest_data?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants