def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        model_artefacts_path = './bert_model_artefacts'
        bucket_name = 'sagemaker-endpoint-artefacts'
        file_name = 'bert_model_artefacts/model.tar.gz'
        aws_region = 'eu-west-1'

        create_model_artefacts(model_artefacts_path, bucket_name, file_name,
                               aws_region)

        sagemaker_role = aws_iam.Role(
            self,
            id='SageMaker-BERT-Endpoint-Role',
            assumed_by=aws_iam.ServicePrincipal('sagemaker.amazonaws.com'))

        sagemaker_role.add_managed_policy(
            aws_iam.ManagedPolicy.from_aws_managed_policy_name(
                'AmazonSageMakerFullAccess'))

        sagemaker_model = aws_sagemaker.CfnModel(
            self,
            id='SageMaker-BERT-Model',
            execution_role_arn=sagemaker_role.role_arn,
            primary_container=aws_sagemaker.CfnModel.
            ContainerDefinitionProperty(
                image=
                '763104351884.dkr.ecr.eu-west-1.amazonaws.com/pytorch-inference:1.4.0-cpu-py36-ubuntu16.04',
                model_data_url='s3://' + bucket_name + '/' + file_name,
                environment={'SAGEMAKER_PROGRAM': 'predictor.py'}),
            model_name='bert-model')

        sagemaker_endpoint_config = aws_sagemaker.CfnEndpointConfig(
            self,
            id='SageMaker-BERT-Endpoint-Config',
            production_variants=[
                aws_sagemaker.CfnEndpointConfig.ProductionVariantProperty(
                    initial_instance_count=1,
                    initial_variant_weight=1.0,
                    instance_type='ml.t2.xlarge',
                    model_name=sagemaker_model.model_name,
                    variant_name='bert-model')
            ],
            endpoint_config_name='bert-model-endpoint-config')

        sagemaker_endpoint_config.add_depends_on(sagemaker_model)

        sagemaker_model_endpoint = aws_sagemaker.CfnEndpoint(
            self,
            id='SageMaker-BERT-Endpoint',
            endpoint_config_name='bert-model-endpoint-config',
            endpoint_name='bert-model-endpoint')

        sagemaker_model_endpoint.add_depends_on(sagemaker_endpoint_config)
Beispiel #2
0
def create_sagemaker_endpoint(scope, id, endpoint_config_name, model_name,
                              **kwargs):
    # create Sagemaker endpoint
    sagemaker_endpoint = sagemaker.CfnEndpoint(
        scope,
        id,
        endpoint_config_name=endpoint_config_name,
        tags=[{
            "key": "endpoint-name",
            "value": f"{model_name}-endpoint"
        }],
        **kwargs,
    )

    return sagemaker_endpoint
Beispiel #3
0
    def __init__(self, app: core.App, id: str, **kwargs) -> None:
        timestamp = '-' + time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())
        super().__init__(app, id, **kwargs)

        model = sagemaker.CfnModel(
            scope=self,
            id="my_model",
            execution_role_arn=self.node.try_get_context("role_arn"),
            containers=[{
                "image":
                self.node.try_get_context("image"),
                "modelDataUrl":
                self.node.try_get_context("model_data_url")
            }],
            model_name=self.node.try_get_context("model_name") + timestamp)

        epc = sagemaker.CfnEndpointConfig(
            scope=self,
            id="my_epc",
            production_variants=[{
                "modelName":
                model.model_name,
                "variantName":
                "variant-1",
                "initialVariantWeight":
                1.0,
                "initialInstanceCount":
                1,
                "instanceType":
                self.node.try_get_context("instance_type")
            }],
            endpoint_config_name=self.node.try_get_context("epc_name") +
            timestamp)

        epc.add_depends_on(model)

        ep = sagemaker.CfnEndpoint(
            scope=self,
            id="my_ep",
            endpoint_config_name=epc.endpoint_config_name,
            endpoint_name=self.node.try_get_context("ep_name") + timestamp)

        ep.add_depends_on(epc)
    def __init__(
        self,
        scope: core.Construct,
        construct_id: str,
        deployment_config: DeploymentConfig,
        project_name: str,
        endpoint_name: str,
        tags: list,
        **kwargs,
    ) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define the package group names for champion and challenger
        champion_package_group = f"{project_name}-champion"
        challenger_package_group = f"{project_name}-challenger"

        # Get the approved packages for the project
        registry = ModelRegistry()
        challenger_creation_time: datetime = None

        # If we don't have a specific champion variant defined, get the latest approved
        if deployment_config.champion_variant_config is None:
            logger.info("Selecting top champion variant")
            p = registry.get_latest_approved_packages(champion_package_group,
                                                      max_results=1)[0]
            deployment_config.champion_variant_config = VariantConfig(
                model_package_version=p["ModelPackageVersion"],
                model_package_arn=p["ModelPackageArn"],
                initial_variant_weight=1,
                instance_count=deployment_config.instance_count,
                instance_type=deployment_config.instance_type,
            )
            challenger_creation_time = p["CreationTime"]
        else:
            # Get the versioned package and update ARN
            version = deployment_config.champion_variant_config.model_package_version
            logger.info(f"Selecting champion version {version}")
            p = registry.get_versioned_approved_packages(
                champion_package_group,
                model_package_versions=[version],
            )[0]
            deployment_config.champion_variant_config.model_package_arn = p[
                "ModelPackageArn"]

        # If we don't have challenger variant config, get the latest after challenger creation time
        if deployment_config.challenger_variant_config is None:
            logger.info(
                f"Selecting top {deployment_config.challenger_variant_count} challenger variants created after {challenger_creation_time}"
            )
            deployment_config.challenger_variant_config = [
                VariantConfig(
                    model_package_version=p["ModelPackageVersion"],
                    model_package_arn=p["ModelPackageArn"],
                    initial_variant_weight=1,
                    instance_count=deployment_config.instance_count,
                    instance_type=deployment_config.instance_type,
                ) for p in registry.get_latest_approved_packages(
                    challenger_package_group,
                    max_results=deployment_config.challenger_variant_count,
                    creation_time_after=challenger_creation_time,
                )
            ]
        else:
            # Get the versioned packages and update ARN
            versions = [
                c.model_package_version
                for c in deployment_config.challenger_variant_config
            ]
            logger.info(f"Selecting challenger versions {versions}")
            ps = registry.get_versioned_approved_packages(
                challenger_package_group,
                model_package_versions=versions,
            )
            for i, vc in enumerate(
                    deployment_config.challenger_variant_config):
                vc.model_package_arn = ps[i]["ModelPackageArn"]

        # Get the service catalog role
        service_catalog_role = aws_iam.Role.from_role_arn(
            self,
            "SageMakerRole",
            f"arn:aws:iam::{self.account}:role/service-role/AmazonSageMakerServiceCatalogProductsUseRole",
        )

        # Add the challenger variant
        model_configs = [deployment_config.champion_variant_config
                         ] + deployment_config.challenger_variant_config

        model_variants = []
        for i, variant_config in enumerate(model_configs):
            # If variant name not in config use "Champion" for the latest approved and "Challenge{N}" for next N pending
            variant_name = variant_config.variant_name or (
                f"Champion{variant_config.model_package_version}" if i == 0
                else f"Challenger{variant_config.model_package_version}")

            # Do not use a custom named resource for models as these get replaced
            model = aws_sagemaker.CfnModel(
                self,
                variant_name,
                execution_role_arn=service_catalog_role.role_arn,
                primary_container=aws_sagemaker.CfnModel.
                ContainerDefinitionProperty(
                    model_package_name=variant_config.model_package_arn, ),
            )

            # Create the production variant
            model_variant = aws_sagemaker.CfnEndpointConfig.ProductionVariantProperty(
                initial_instance_count=variant_config.instance_count,
                initial_variant_weight=variant_config.initial_variant_weight,
                instance_type=variant_config.instance_type,
                model_name=model.attr_model_name,
                variant_name=variant_name,
            )
            model_variants.append(model_variant)

        if len(model_variants) == 0:
            raise Exception("No model variants matching configuration")

        endpoint_config = aws_sagemaker.CfnEndpointConfig(
            self,
            "EndpointConfig",
            production_variants=model_variants,
        )

        self.endpoint = aws_sagemaker.CfnEndpoint(
            self,
            "Endpoint",
            endpoint_config_name=endpoint_config.attr_endpoint_config_name,
            endpoint_name=endpoint_name,
            tags=tags,
        )