

# Conceitos básicos
<a name="nova-sagemaker-inference-getting-started"></a>

Este guia mostra como implantar modelos personalizados do Amazon Nova nos endpoints em tempo real do SageMaker, configurar parâmetros de inferência e invocar seus modelos para testes.

## Pré-requisitos
<a name="nova-sagemaker-inference-prerequisites"></a>

Confira abaixo os pré-requisitos para implantar modelos do Amazon Nova na inferência do SageMaker:
+ Crie uma Conta da AWS: se você ainda não tiver uma, consulte [Criar uma conta da AWS](https://docs.aws.amazon.com//sagemaker/latest/dg/gs-set-up.html#sign-up-for-aws).
+ Permissões necessárias do IAM - certifique-se de que seu usuário ou perfil do IAM tenha as seguintes políticas gerenciadas:
  + `AmazonSageMakerFullAccess`
  + `AmazonS3FullAccess`
+ Versões obrigatórias de SDKs/CLI - as seguintes versões de SDK foram testadas e validadas com modelos do Amazon Nova na inferência do SageMaker:
  + SageMaker Python SDK v3.0.0\$1 (`sagemaker>=3.0.0`) para abordagem de API baseada em recursos.
  + Boto3 versão 1.35.0\$1 (`boto3>=1.35.0`) para chamadas diretas de API. Os exemplos neste guia usam essa abordagem.
+ Aumento da cota de serviço: solicite um aumento da cota de serviço do Amazon SageMaker para o tipo de instância de ML que você planeja usar para seu endpoint da Inferência do SageMaker (por exemplo, `ml.p5.48xlarge for endpoint usage`). Para obter uma lista dos tipos de instâncias compatíveis, consulte [Modelos e instâncias compatíveis](nova-model-sagemaker-inference.md#nova-sagemaker-inference-supported). Para solicitar um aumento, consulte [Solicitar um aumento de cota](https://docs.aws.amazon.com//servicequotas/latest/userguide/request-quota-increase.html). Para obter mais informações sobre cotas de instâncias do SageMaker, consulte [Endpoints e cotas do SageMaker](https://docs.aws.amazon.com//general/latest/gr/sagemaker.html).

## Etapa 1: configurar as credenciais da AWS
<a name="nova-sagemaker-inference-step1"></a>

Configure suas credenciais da AWS usando um dos seguintes métodos:

**Opção 1: AWS CLI (recomendado)**

```
aws configure
```

Insira o ID da chave de acesso da AWS, a chave secreta e nome da região padrão quando solicitado.

**Opção 2: arquivo de credenciais da AWS**

Crie ou edite `~/.aws/credentials`:

```
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
```

**Opção 3: variáveis de ambiente**

```
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
```

**nota**  
Para obter mais informações sobre as credenciais da AWS, consulte [Definições do arquivo de credenciais e configurações](https://docs.aws.amazon.com//cli/latest/userguide/cli-configure-files.html).

**Inicializar clientes da AWS**

Crie um script ou caderno Python com o código abaixo para inicializar o AWS SDK e verificar suas credenciais:

```
import boto3

# AWS Configuration - Update these for your environment
REGION = "us-east-1"  # Supported regions: us-east-1, us-west-2
AWS_ACCOUNT_ID = "YOUR_ACCOUNT_ID"  # Replace with your AWS account ID

# Initialize AWS clients using default credential chain
sagemaker = boto3.client('sagemaker', region_name=REGION)
sts = boto3.client('sts')

# Verify credentials
try:
    identity = sts.get_caller_identity()
    print(f"Successfully authenticated to AWS Account: {identity['Account']}")
    
    if identity['Account'] != AWS_ACCOUNT_ID:
        print(f"Warning: Connected to account {identity['Account']}, expected {AWS_ACCOUNT_ID}")

except Exception as e:
    print(f"Failed to authenticate: {e}")
    print("Please verify your credentials are configured correctly.")
```

Se a autenticação tiver êxito, você deverá ver um resultado confirmando o ID da sua conta da AWS.

## Etapa 2: criar um perfil de execução do SageMaker
<a name="nova-sagemaker-inference-step2"></a>

Um perfil de execução do SageMaker é um perfil do IAM que concede ao SageMaker permissões para acessar recursos da AWS em seu nome, como buckets do Amazon S3 para artefatos de modelos e o CloudWatch para registro em log.

**Criação do perfil de execução**

**nota**  
A criação de perfis do IAM requer as permissões `iam:CreateRole` e `iam:AttachRolePolicy`. Antes de continuar, certifique-se de que seu usuário ou perfil do IAM tenha essas permissões.

O código abaixo cria um perfil do IAM com as permissões necessárias para implantar modelos personalizados do Amazon Nova:

```
import json

# Create SageMaker Execution Role
role_name = f"SageMakerInference-ExecutionRole-{AWS_ACCOUNT_ID}"

trust_policy = {
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {"Service": "sagemaker.amazonaws.com"},
            "Action": "sts:AssumeRole"
        }
    ]
}

iam = boto3.client('iam', region_name=REGION)

# Create the role
role_response = iam.create_role(
    RoleName=role_name,
    AssumeRolePolicyDocument=json.dumps(trust_policy),
    Description='SageMaker execution role with S3 and SageMaker access'
)

# Attach required policies
iam.attach_role_policy(
    RoleName=role_name,
    PolicyArn='arn:aws:iam::aws:policy/AmazonSageMakerFullAccess'
)

iam.attach_role_policy(
    RoleName=role_name,
    PolicyArn='arn:aws:iam::aws:policy/AmazonS3FullAccess'
)

SAGEMAKER_EXECUTION_ROLE_ARN = role_response['Role']['Arn']
print(f"Created SageMaker execution role: {SAGEMAKER_EXECUTION_ROLE_ARN}")
```

**Uso de um perfil de execução existente (opcional)**

Se já tiver um perfil de execução do SageMaker, você poderá usá-lo:

```
# Replace with your existing role ARN
SAGEMAKER_EXECUTION_ROLE_ARN = "arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_EXISTING_ROLE_NAME"
```

Para encontrar perfis existentes do SageMaker em sua conta:

```
iam = boto3.client('iam', region_name=REGION)
response = iam.list_roles()
sagemaker_roles = [role for role in response['Roles'] if 'SageMaker' in role['RoleName']]
for role in sagemaker_roles:
    print(f"{role['RoleName']}: {role['Arn']}")
```

**Importante**  
O perfil de execução deve ter uma relação de confiança com `sagemaker.amazonaws.com` e permissões para acessar os recursos do Amazon S3 e do SageMaker.

Para obter mais informações sobre perfis de execução do SageMaker, consulte [Perfis do SageMaker](https://docs.aws.amazon.com//sagemaker/latest/dg/sagemaker-roles.html).

## Etapa 3: configurar parâmetros de modelos
<a name="nova-sagemaker-inference-step3"></a>

Configure os parâmetros de implantação para seu modelo do Amazon Nova. Essas configurações controlam o comportamento do modelo, a alocação de recursos e as características de inferência. Para ver uma lista dos tipos de instâncias compatíveis e dos valores de CONTEXT\$1LENGTH e MAX\$1CONCURRENCY compatíveis para cada um, consulte [Modelos e instâncias compatíveis](nova-model-sagemaker-inference.md#nova-sagemaker-inference-supported).

**Parâmetros obrigatórios**
+ `IMAGE`: o URI da imagem do contêiner do Docker para o contêiner de inferência do Amazon Nova. Será fornecido pela AWS.
+ `CONTEXT_LENGTH`: tamanho do contexto do modelo.
+ `MAX_CONCURRENCY`: número máximo de sequências por iteração; define o limite de quantas solicitações (prompts) de usuários individuais podem ser processadas simultaneamente em um único lote na GPU. Intervalo: inteiro maior que 0.

**Parâmetros opcionais de geração**
+ `DEFAULT_TEMPERATURE`: controla a randomização na geração. Intervalo: de 0,0 a 2,0 (0,0 = determinístico, maior = mais randomizado).
+ `DEFAULT_TOP_P`: limite de amostragem de núcleo para a seleção de tokens. Intervalo: de 1e-10 a 1,0.
+ `DEFAULT_TOP_K`: limita a seleção de tokens aos K tokens mais prováveis. Intervalo: inteiro -1 ou maior (-1 = sem limite).
+ `DEFAULT_MAX_NEW_TOKENS`: número máximo de tokens a serem gerados na resposta (ou seja, máximo de tokens de saída). Intervalo: inteiro 1 ou maior.
+ `DEFAULT_LOGPROBS`: número de probabilidades logarítmicas a serem retornadas por token. Intervalo: inteiro de 1 a 20.

**Configure sua implantação**

```
# AWS Configuration
REGION = "us-east-1"  # Must match region from Step 1

# ECR Account mapping by region
ECR_ACCOUNT_MAP = {
    "us-east-1": "708977205387",
    "us-west-2": "176779409107"
}

# Container Image
IMAGE = f"{ECR_ACCOUNT_MAP[REGION]}.dkr.ecr.{REGION}.amazonaws.com/nova-inference-repo:SM-Inference-latest"
print(f"IMAGE = {IMAGE}")

# Model Parameters
CONTEXT_LENGTH = "16000"       # Maximum total context length
MAX_CONCURRENCY = "2"          # Maximum concurrent sequences

# Optional: Default generation parameters (uncomment to use)
DEFAULT_TEMPERATURE = "0.0"   # Deterministic output
DEFAULT_TOP_P = "1.0"         # Consider all tokens
# DEFAULT_TOP_K = "50"        # Uncomment to limit to top 50 tokens
# DEFAULT_MAX_NEW_TOKENS = "2048"  # Uncomment to set max output tokens
# DEFAULT_LOGPROBS = "1"      # Uncomment to enable log probabilities

# Build environment variables for the container
environment = {
    'CONTEXT_LENGTH': CONTEXT_LENGTH,
    'MAX_CONCURRENCY': MAX_CONCURRENCY,
}

# Add optional parameters if defined
if 'DEFAULT_TEMPERATURE' in globals():
    environment['DEFAULT_TEMPERATURE'] = DEFAULT_TEMPERATURE
if 'DEFAULT_TOP_P' in globals():
    environment['DEFAULT_TOP_P'] = DEFAULT_TOP_P
if 'DEFAULT_TOP_K' in globals():
    environment['DEFAULT_TOP_K'] = DEFAULT_TOP_K
if 'DEFAULT_MAX_NEW_TOKENS' in globals():
    environment['DEFAULT_MAX_NEW_TOKENS'] = DEFAULT_MAX_NEW_TOKENS
if 'DEFAULT_LOGPROBS' in globals():
    environment['DEFAULT_LOGPROBS'] = DEFAULT_LOGPROBS

print("Environment configuration:")
for key, value in environment.items():
    print(f"  {key}: {value}")
```

**Configurar parâmetros específicos da implantação**

Agora configure os parâmetros específicos para a implantação de modelos do Amazon Nova, incluindo o local dos artefatos do modelo e a seleção do tipo de instância.

**Definir identificador de implantação**

```
# Deployment identifier - use a descriptive name for your use case
JOB_NAME = "my-nova-deployment"
```

**Especificar o local dos artefatos dos modelos**

Forneça o URI do Amazon S3 em que os artefatos treinados dos modelos do Amazon Nova foram armazenados. Deve ser o local da saída da tarefa de treinamento de modelo ou de ajuste fino.

```
# S3 location of your trained Nova model artifacts
# Replace with your model's S3 URI - must end with /
MODEL_S3_LOCATION = "s3://your-bucket-name/path/to/model/artifacts/"
```

**Selecionar a variante do modelo e o tipo de instância**

```
# Configure model variant and instance type
TESTCASE = {
    "model": "lite2",              # Options: micro, lite, lite2
    "instance": "ml.p5.48xlarge"   # Refer to "Supported models and instances" section
}

# Generate resource names
INSTANCE_TYPE = TESTCASE["instance"]
MODEL_NAME = JOB_NAME + "-" + TESTCASE["model"] + "-" + INSTANCE_TYPE.replace(".", "-")
ENDPOINT_CONFIG_NAME = MODEL_NAME + "-Config"
ENDPOINT_NAME = MODEL_NAME + "-Endpoint"

print(f"Model Name: {MODEL_NAME}")
print(f"Endpoint Config: {ENDPOINT_CONFIG_NAME}")
print(f"Endpoint Name: {ENDPOINT_NAME}")
```

**Convenções de nomenclatura**

O código gera automaticamente nomes consistentes para os recursos da AWS:
+ Nome do modelo: .: `{JOB_NAME}-{model}-{instance-type}`
+ Configuração de endpoint: `{MODEL_NAME}-Config`
+ Nome do endpoint: `{MODEL_NAME}-Endpoint`

## Etapa 4: criar a configuração do modelo e endpoint do SageMaker
<a name="nova-sagemaker-inference-step4"></a>

Nesta etapa, você criará dois recursos essenciais: um objeto de modelo do SageMaker que faz referência aos artefatos dos modelos do Amazon Nova e uma configuração do endpoint que define como o modelo será implantado.

**Modelo do SageMaker**: um objeto de modelo que empacota a imagem do contêiner de inferência, o local dos artefatos do modelo e a configuração do ambiente. Este é um recurso reutilizável que pode ser implantado em vários endpoints.

**Configuração do endpoint**: define as configurações de infraestrutura para implantação, incluindo tipo de instância, contagem de instâncias e variantes do modelo. Isso permite que você gerencie as configurações de implantação separadamente do próprio modelo.

**Criar o modelo do SageMaker**

O código abaixo cria um modelo do SageMaker que faz referência aos artefatos do seu modelo do Amazon Nova:

```
try:
    model_response = sagemaker.create_model(
        ModelName=MODEL_NAME,
        PrimaryContainer={
            'Image': IMAGE,
            'ModelDataSource': {
                'S3DataSource': {
                    'S3Uri': MODEL_S3_LOCATION,
                    'S3DataType': 'S3Prefix',
                    'CompressionType': 'None'
                }
            },
            'Environment': environment
        },
        ExecutionRoleArn=SAGEMAKER_EXECUTION_ROLE_ARN,
        EnableNetworkIsolation=True
    )
    print("Model created successfully!")
    print(f"Model ARN: {model_response['ModelArn']}")
    
except sagemaker.exceptions.ClientError as e:
    print(f"Error creating model: {e}")
```

Principais parâmetros:
+ `ModelName`: identificador exclusivo do seu modelo
+ `Image`: URI de imagem de contêiner do Docker para inferência do Amazon Nova
+ `ModelDataSource`: local do Amazon S3 dos seus artefatos de modelos
+ `Environment`: variáveis de ambiente configuradas na Etapa 3
+ `ExecutionRoleArn`: perfil do IAM da Etapa 2
+ `EnableNetworkIsolation`: defina como True para aumentar a segurança (impede que o contêiner faça chamadas de rede de saída)

**Criar a configuração do endpoint**

Em seguida, crie uma configuração do endpoint que defina sua infraestrutura de implantação:

```
# Create Endpoint Configuration
try:
    production_variant = {
        'VariantName': 'primary',
        'ModelName': MODEL_NAME,
        'InitialInstanceCount': 1,
        'InstanceType': INSTANCE_TYPE,
    }
    
    config_response = sagemaker.create_endpoint_config(
        EndpointConfigName=ENDPOINT_CONFIG_NAME,
        ProductionVariants=[production_variant]
    )
    print("Endpoint configuration created successfully!")
    print(f"Config ARN: {config_response['EndpointConfigArn']}")
    
except sagemaker.exceptions.ClientError as e:
    print(f"Error creating endpoint configuration: {e}")
```

Principais parâmetros:
+ `VariantName`: identificador para essa variante de modelo (use “primary” para implantações de modelo único)
+ `ModelName`: faz referência ao modelo criado acima
+ `InitialInstanceCount`: número de instâncias a serem implantadas (comece com 1 e escale posteriormente, se necessário)
+ `InstanceType`: tipo de instância de ML selecionado na Etapa 3

**Verificar a criação de recursos**

Você pode verificar se os recursos foram criados com êxito:

```
# Describe the model
model_info = sagemaker.describe_model(ModelName=MODEL_NAME)
print(f"Model Status: {model_info['ModelName']} created")

# Describe the endpoint configuration
config_info = sagemaker.describe_endpoint_config(EndpointConfigName=ENDPOINT_CONFIG_NAME)
print(f"Endpoint Config Status: {config_info['EndpointConfigName']} created")
```

## Etapa 5: implantar o endpoint
<a name="nova-sagemaker-inference-step5"></a>

A próxima etapa é implantar seu modelo do Amazon Nova criando um endpoint em tempo real do SageMaker. Esse endpoint hospedará seu modelo e fornecerá um endpoint HTTPS seguro para fazer solicitações de inferência.

A criação do endpoint normalmente leva de 15 a 30 minutos, pois a AWS provisiona a infraestrutura, faz o download dos artefatos do modelo e inicializa o contêiner de inferência.

**Criar o endpoint**

```
import time

try:
    endpoint_response = sagemaker.create_endpoint(
        EndpointName=ENDPOINT_NAME,
        EndpointConfigName=ENDPOINT_CONFIG_NAME
    )
    print("Endpoint creation initiated successfully!")
    print(f"Endpoint ARN: {endpoint_response['EndpointArn']}")
except Exception as e:
    print(f"Error creating endpoint: {e}")
```

**Monitorar a criação do endpoint**

O código abaixo pesquisa o status do endpoint até a conclusão da implantação:

```
# Monitor endpoint creation progress
print("Waiting for endpoint creation to complete...")
print("This typically takes 15-30 minutes...\n")

while True:
    try:
        response = sagemaker.describe_endpoint(EndpointName=ENDPOINT_NAME)
        status = response['EndpointStatus']
        
        if status == 'Creating':
            print(f"⏳ Status: {status} - Provisioning infrastructure and loading model...")
        elif status == 'InService':
            print(f"✅ Status: {status}")
            print("\nEndpoint creation completed successfully!")
            print(f"Endpoint Name: {ENDPOINT_NAME}")
            print(f"Endpoint ARN: {response['EndpointArn']}")
            break
        elif status == 'Failed':
            print(f"❌ Status: {status}")
            print(f"Failure Reason: {response.get('FailureReason', 'Unknown')}")
            print("\nFull response:")
            print(response)
            break
        else:
            print(f"Status: {status}")
        
    except Exception as e:
        print(f"Error checking endpoint status: {e}")
        break
    
    time.sleep(30)  # Check every 30 seconds
```

**Verificar se o endpoint está pronto**

Quando o endpoint estiver InService, você poderá verificar sua configuração:

```
# Get detailed endpoint information
endpoint_info = sagemaker.describe_endpoint(EndpointName=ENDPOINT_NAME)

print("\n=== Endpoint Details ===")
print(f"Endpoint Name: {endpoint_info['EndpointName']}")
print(f"Endpoint ARN: {endpoint_info['EndpointArn']}")
print(f"Status: {endpoint_info['EndpointStatus']}")
print(f"Creation Time: {endpoint_info['CreationTime']}")
print(f"Last Modified: {endpoint_info['LastModifiedTime']}")

# Get endpoint config for instance type details
endpoint_config_name = endpoint_info['EndpointConfigName']
endpoint_config = sagemaker.describe_endpoint_config(EndpointConfigName=endpoint_config_name)

# Display production variant details
for variant in endpoint_info['ProductionVariants']:
    print(f"\nProduction Variant: {variant['VariantName']}")
    print(f"  Current Instance Count: {variant['CurrentInstanceCount']}")
    print(f"  Desired Instance Count: {variant['DesiredInstanceCount']}")
    # Get instance type from endpoint config
    for config_variant in endpoint_config['ProductionVariants']:
        if config_variant['VariantName'] == variant['VariantName']:
            print(f"  Instance Type: {config_variant['InstanceType']}")
            break
```

**Solução de problemas de falhas na criação de endpoints**

Motivos de falha comuns:
+ **Capacidade insuficiente**: o tipo de instância solicitada não está disponível na sua região.
  + Solução: tente um tipo de instância diferente ou solicite um aumento da cota
+ **Permissões do IAM**: o perfil de execução não tem as permissões necessárias
  + Solução: verifique se o perfil tem acesso aos artefatos dos modelos do Amazon S3 e às permissões necessárias do SageMaker
+ **Artefatos do modelo não encontrados**: o URI do Amazon S3 está incorreto ou inacessível
  + Solução: verifique o URI do Amazon S3, as permissões do bucket e se você está na região correta
+ **Limites de recursos**: limites da conta excedidos para endpoints ou instâncias
  + Solução: solicite um aumento de cota de serviço por meio do Service Quotas ou do AWS Support

**nota**  
Se você precisar excluir um endpoint com falha e começar de novo:  

```
sagemaker.delete_endpoint(EndpointName=ENDPOINT_NAME)
```

## Etapa 6: invocar o endpoint
<a name="nova-sagemaker-inference-step6"></a>

Quando seu endpoint estiver InService, você poderá enviar solicitações de inferência para gerar predições do seu modelo do Amazon Nova. O SageMaker oferece suporte a endpoints síncronos (em tempo real com os modos de streaming/não streaming) e endpoints assíncronos (baseados no Amazon S3 para processamento em lote).

**Configurar o cliente de runtime**

Crie um cliente de runtime do SageMaker com as configurações de tempo limite apropriadas:

```
import json
import boto3
import botocore
from botocore.exceptions import ClientError

# Configure client with appropriate timeouts
config = botocore.config.Config(
    read_timeout=120,      # Maximum time to wait for response
    connect_timeout=10,    # Maximum time to establish connection
    retries={'max_attempts': 3}  # Number of retry attempts
)

# Create SageMaker Runtime client
runtime_client = boto3.client('sagemaker-runtime', config=config, region_name=REGION)
```

**Criar uma função de inferência universal**

A função abaixo processa solicitações com ou sem streaming:

```
def invoke_nova_endpoint(request_body):
    """
    Invoke Nova endpoint with automatic streaming detection.
    
    Args:
        request_body (dict): Request payload containing prompt and parameters
    
    Returns:
        dict: Response from the model (for non-streaming requests)
        None: For streaming requests (prints output directly)
    """
    body = json.dumps(request_body)
    is_streaming = request_body.get("stream", False)
    
    try:
        print(f"Invoking endpoint ({'streaming' if is_streaming else 'non-streaming'})...")
        
        if is_streaming:
            response = runtime_client.invoke_endpoint_with_response_stream(
                EndpointName=ENDPOINT_NAME,
                ContentType='application/json',
                Body=body
            )
            
            event_stream = response['Body']
            for event in event_stream:
                if 'PayloadPart' in event:
                    chunk = event['PayloadPart']
                    if 'Bytes' in chunk:
                        data = chunk['Bytes'].decode()
                        print("Chunk:", data)
        else:
            # Non-streaming inference
            response = runtime_client.invoke_endpoint(
                EndpointName=ENDPOINT_NAME,
                ContentType='application/json',
                Accept='application/json',
                Body=body
            )
            
            response_body = response['Body'].read().decode('utf-8')
            result = json.loads(response_body)
            print("✅ Response received successfully")
            return result
    
    except ClientError as e:
        error_code = e.response['Error']['Code']
        error_message = e.response['Error']['Message']
        print(f"❌ AWS Error: {error_code} - {error_message}")
    except Exception as e:
        print(f"❌ Unexpected error: {str(e)}")
```

**Exemplo 1: conclusão de chat sem streaming**

Use o formato de chat para interações conversacionais:

```
# Non-streaming chat request
chat_request = {
    "messages": [
        {"role": "user", "content": "Hello! How are you?"}
    ],
    "max_tokens": 100,
    "max_completion_tokens": 100,  # Alternative to max_tokens
    "stream": False,
    "temperature": 0.7,
    "top_p": 0.9,
    "top_k": 50,
    "logprobs": True,
    "top_logprobs": 3,
    "reasoning_effort": "low",  # Options: "low", "high"
    "allowed_token_ids": None,  # List of allowed token IDs
    "truncate_prompt_tokens": None,  # Truncate prompt to this many tokens
    "stream_options": None
}

response = invoke_nova_endpoint(chat_request)
```

**Resposta de exemplo:**

```
{
    "id": "chatcmpl-123456",
    "object": "chat.completion",
    "created": 1234567890,
    "model": "default",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Hello! I'm doing well, thank you for asking. I'm here and ready to help you with any questions or tasks you might have. How can I assist you today?"
            },
            "logprobs": {
                "content": [
                    {
                        "token": "Hello",
                        "logprob": -0.123,
                        "top_logprobs": [
                            {"token": "Hello", "logprob": -0.123},
                            {"token": "Hi", "logprob": -2.456},
                            {"token": "Hey", "logprob": -3.789}
                        ]
                    }
                    # Additional tokens...
                ]
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 12,
        "completion_tokens": 28,
        "total_tokens": 40
    }
}
```

**Exemplo 2: conclusão de texto simples**

Use o formato de conclusão para geração de texto simples:

```
# Simple completion request
completion_request = {
    "prompt": "The capital of France is",
    "max_tokens": 50,
    "stream": False,
    "temperature": 0.0,
    "top_p": 1.0,
    "top_k": -1,  # -1 means no limit
    "logprobs": 3,  # Number of log probabilities to return
    "allowed_token_ids": None,  # List of allowed token IDs
    "truncate_prompt_tokens": None,  # Truncate prompt to this many tokens
    "stream_options": None
}

response = invoke_nova_endpoint(completion_request)
```

**Resposta de exemplo:**

```
{
    "id": "cmpl-789012",
    "object": "text_completion",
    "created": 1234567890,
    "model": "default",
    "choices": [
        {
            "text": " Paris.",
            "index": 0,
            "logprobs": {
                "tokens": [" Paris", "."],
                "token_logprobs": [-0.001, -0.002],
                "top_logprobs": [
                    {" Paris": -0.001, " London": -5.234, " Rome": -6.789},
                    {".": -0.002, ",": -4.567, "!": -7.890}
                ]
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 6,
        "completion_tokens": 2,
        "total_tokens": 8
    }
}
```

**Exemplo 3: conclusão de chat com streaming**

```
# Streaming chat request
streaming_request = {
    "messages": [
        {"role": "user", "content": "Tell me a short story about a robot"}
    ],
    "max_tokens": 200,
    "stream": True,
    "temperature": 0.7,
    "top_p": 0.95,
    "top_k": 40,
    "logprobs": True,
    "top_logprobs": 2,
    "reasoning_effort": "high",  # For more detailed reasoning
    "stream_options": {"include_usage": True}
}

invoke_nova_endpoint(streaming_request)
```

**Exemplo de saída de streaming:**

```
Chunk: data: {"id":"chatcmpl-029ca032-fa01-4868-80b7-c4cb1af90fb9","object":"chat.completion.chunk","created":1772060532,"model":"default","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":null},"logprobs":null,"finish_reason":null}],"prompt_token_ids":null}
Chunk: data: {"id":"chatcmpl-029ca032-fa01-4868-80b7-c4cb1af90fb9","object":"chat.completion.chunk","created":1772060532,"model":"default","choices":[{"index":0,"delta":{"content":" Once","reasoning_content":null},"logprobs":{"content":[{"token":"\u2581Once","logprob":-0.6078429222106934,"bytes":[226,150,129,79,110,99,101],"top_logprobs":[{"token":"\u2581Once","logprob":-0.6078429222106934,"bytes":[226,150,129,79,110,99,101]},{"token":"\u2581In","logprob":-0.7864127159118652,"bytes":[226,150,129,73,110]}]}]},"finish_reason":null,"token_ids":null}]}
Chunk: data: {"id":"chatcmpl-029ca032-fa01-4868-80b7-c4cb1af90fb9","object":"chat.completion.chunk","created":1772060532,"model":"default","choices":[{"index":0,"delta":{"content":" upon","reasoning_content":null},"logprobs":{"content":[{"token":"\u2581upon","logprob":-0.0012345,"bytes":[226,150,129,117,112,111,110],"top_logprobs":[{"token":"\u2581upon","logprob":-0.0012345,"bytes":[226,150,129,117,112,111,110]},{"token":"\u2581a","logprob":-6.789,"bytes":[226,150,129,97]}]}]},"finish_reason":null,"token_ids":null}]}
Chunk: data: {"id":"chatcmpl-029ca032-fa01-4868-80b7-c4cb1af90fb9","object":"chat.completion.chunk","created":1772060532,"model":"default","choices":[{"index":0,"delta":{"content":" a","reasoning_content":null},"logprobs":{"content":[{"token":"\u2581a","logprob":-0.0001234,"bytes":[226,150,129,97],"top_logprobs":[{"token":"\u2581a","logprob":-0.0001234,"bytes":[226,150,129,97]},{"token":"\u2581time","logprob":-9.123,"bytes":[226,150,129,116,105,109,101]}]}]},"finish_reason":null,"token_ids":null}]}
Chunk: data: {"id":"chatcmpl-029ca032-fa01-4868-80b7-c4cb1af90fb9","object":"chat.completion.chunk","created":1772060532,"model":"default","choices":[{"index":0,"delta":{"content":" time","reasoning_content":null},"logprobs":{"content":[{"token":"\u2581time","logprob":-0.0023456,"bytes":[226,150,129,116,105,109,101],"top_logprobs":[{"token":"\u2581time","logprob":-0.0023456,"bytes":[226,150,129,116,105,109,101]},{"token":",","logprob":-6.012,"bytes":[44]}]}]},"finish_reason":null,"token_ids":null}]}

# Additional chunks...

Chunk: data: {"id":"chatcmpl-029ca032-fa01-4868-80b7-c4cb1af90fb9","object":"chat.completion.chunk","created":1772060532,"model":"default","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":15,"completion_tokens":87,"total_tokens":102}}
Chunk: data: [DONE]
```

**Exemplo 4: conclusão do chat multimodal**

Use o formato multimodal para entradas de imagem e texto:

```
# Multimodal chat request (if supported by your model)
multimodal_request = {
    "messages": [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What's in this image?"},
                {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}
            ]
        }
    ],
    "max_tokens": 150,
    "temperature": 0.3,
    "top_p": 0.8,
    "stream": False
}

response = invoke_nova_endpoint(multimodal_request)
```

**Resposta de exemplo:**

```
{
    "id": "chatcmpl-345678",
    "object": "chat.completion",
    "created": 1234567890,
    "model": "default",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "The image shows..."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 1250,
        "completion_tokens": 45,
        "total_tokens": 1295
    }
}
```

## Etapa 7: limpar os recursos (opcional)
<a name="nova-sagemaker-inference-step7"></a>

Para evitar cobranças desnecessárias, exclua os recursos da AWS que você criou durante este tutorial. Os endpoints do SageMaker são cobrados enquanto estão em execução, mesmo que você não esteja ativamente fazendo solicitações de inferência.

**Importante**  
A exclusão de recursos é permanente e não poderá ser desfeita. Antes de continuar, certifique-se de que não precisará mais desses recursos.

**Excluir o endpoint**

```
import boto3

# Initialize SageMaker client
sagemaker = boto3.client('sagemaker', region_name=REGION)

try:
    print("Deleting endpoint...")
    sagemaker.delete_endpoint(EndpointName=ENDPOINT_NAME)
    print(f"✅ Endpoint '{ENDPOINT_NAME}' deletion initiated")
    print("Charges will stop once deletion completes (typically 2-5 minutes)")
except Exception as e:
    print(f"❌ Error deleting endpoint: {e}")
```

**nota**  
A exclusão do endpoint é assíncrona. Você pode monitorar o status da exclusão:  

```
import time

print("Monitoring endpoint deletion...")
while True:
    try:
        response = sagemaker.describe_endpoint(EndpointName=ENDPOINT_NAME)
        status = response['EndpointStatus']
        print(f"Status: {status}")
        time.sleep(10)
    except sagemaker.exceptions.ClientError as e:
        if e.response['Error']['Code'] == 'ValidationException':
            print("✅ Endpoint successfully deleted")
            break
        else:
            print(f"Error: {e}")
            break
```

**Excluir a configuração do endpoint**

Depois que o endpoint for excluído, remova a configuração dele:

```
try:
    print("Deleting endpoint configuration...")
    sagemaker.delete_endpoint_config(EndpointConfigName=ENDPOINT_CONFIG_NAME)
    print(f"✅ Endpoint configuration '{ENDPOINT_CONFIG_NAME}' deleted")
except Exception as e:
    print(f"❌ Error deleting endpoint configuration: {e}")
```

**Excluir o modelo**

Remova o objeto do modelo do SageMaker:

```
try:
    print("Deleting model...")
    sagemaker.delete_model(ModelName=MODEL_NAME)
    print(f"✅ Model '{MODEL_NAME}' deleted")
except Exception as e:
    print(f"❌ Error deleting model: {e}")
```