Personalizando Modelos Nova: Um Guia Prático com o SDK Nova Forge

Democratizando a Customização de Modelos de Linguagem

A personalização de modelos grandes de linguagem (LLMs) sempre foi uma tarefa desafiadora. Tradicionalmente, equipes enfrentam obstáculos significativos: necessidade de expertise técnica profunda, configuração complexa de infraestrutura e investimento considerável de tempo. A AWS anunciou o SDK Nova Forge precisamente para resolver esse cenário.

O Nova Forge SDK transforma a customização em um processo acessível e estruturado. Em vez de lidar com dependências complicadas, seleção de imagens e configuração de receitas, os times podem agora focar no que realmente importa: adaptar modelos para seus contextos específicos. A SDK suporta todo o espectro de customização, desde ajustes baseados no Amazon SageMaker até personalizações profundas aproveitando as capacidades completas do Nova Forge.

Um Caso Prático: Classificando Qualidade de Perguntas

Para ilustrar como o SDK Nova Forge funciona na prática, a AWS apresenta um cenário real extraído do Stack Overflow. O objetivo é automático: classificar perguntas em três categorias bem definidas (HQ — alta qualidade; LQ_EDIT — qualidade baixa com edições; LQ_CLOSE — qualidade baixa e fechada).

Moderadores do Stack Overflow enfrentam milhares de perguntas variadas. Uma ferramenta que classifique automaticamente a qualidade libera seus esforços, permitindo priorizar ações e guiar usuários. A solução utiliza o conjunto de dados Stack Overflow Question Quality, com 60 mil perguntas de 2016-2020 distribuídas nas três categorias mencionadas.

Para os experimentos, a AWS selecionou aleatoriamente 4.700 perguntas, organizadas assim:

  • Treinamento (Ajuste Fino Supervisionado): 3.500 amostras (~75%)
  • Avaliação: 500 amostras (~10%)
  • Ajuste por Reforço: 700 amostras (~15%), combinadas com as 3.500 do treinamento anterior para evitar esquecimento catastrófico

O experimento segue quatro estágios: avaliação de desempenho base, ajuste fino supervisionado, ajuste por reforço e, finalmente, implantação no Amazon SageMaker Inference.

Etapa 1: Estabelecendo o Desempenho de Linha de Base

Antes de qualquer ajuste fino, é essencial medir como o modelo pré-treinado Nova 2.0 se comporta naturalmente. Essa avaliação inicial fornece um ponto de referência concreto para quantificar melhorias futuras. Compreender capacidades do modelo sem refinamento, identificar lacunas de desempenho e validar se ajuste fino é necessário são passos críticos.

O SDK Nova Forge oferece utilitários poderosos para carregamento de dados que lidam automaticamente com validação e transformação. Usando a classe CSVDatasetLoader, os dados são carregados e transformados para o formato esperado pelos modelos Nova:

from amzn_nova_forge import (
    NovaModelCustomizer,
    SMTJRuntimeManager,
    TrainingMethod,
    EvaluationTask,
    CSVDatasetLoader,
    Model,
)

# Configuração geral
MODEL = Model.NOVA_LITE_2
INSTANCE_TYPE = 'ml.p5.48xlarge'
EXECUTION_ROLE = '<YOUR_EXECUTION_ROLE_ARN>'
S3_BUCKET = '<YOUR_S3_BUCKET>'
S3_PREFIX = 'stack-overflow'
EVAL_DATA = './eval.csv'

# Carregar dados
loader = CSVDatasetLoader(
    query='Body',
    response='Y',
    system='system'
)
loader.load(EVAL_DATA)
loader.transform(method=TrainingMethod.EVALUATION, model=MODEL)
loader.validate(method=TrainingMethod.EVALUATION, model=MODEL)

# Salvar no S3
eval_s3_uri = loader.save_data(f"s3://{S3_BUCKET}/{S3_PREFIX}/data/eval.jsonl")

Com os dados preparados, inicializa-se o gerenciador de runtime e executa-se a avaliação:

runtime_manager = SMTJRuntimeManager(
    instance_type=INSTANCE_TYPE,
    instance_count=1,
    execution_role=EXECUTION_ROLE
)

baseline_customizer = NovaModelCustomizer(
    model=MODEL,
    method=TrainingMethod.EVALUATION,
    infra=runtime_manager,
    data_s3_path=eval_s3_uri,
    output_s3_path=f"s3://{S3_BUCKET}/{S3_PREFIX}/baseline-eval"
)

baseline_result = baseline_customizer.evaluate(
    job_name="blogpost-baseline",
    eval_task=EvaluationTask.GEN_QA
)

Os resultados da linha de base revelaram um desempenho inicial de apenas 13,0% de precisão em coincidência exata (EM). Para uma tarefa de classificação em três categorias, adivinhar aleatoriamente resultaria em 33,3%, indicando que o modelo não está seguindo as instruções de formato apropriadamente. A distribuição de respostas mostrava verbosidade excessiva, com explicações longas quando a instrução pedia apenas o nome da categoria.

Imagem original — fonte: Aws

Etapa 2: Ajuste Fino Supervisionado para Aprender o Padrão

Com a linha de base estabelecida, o próximo passo é aplicar Ajuste Fino Supervisionado (SFT — Supervised Fine-Tuning). Essa técnica ensina ao modelo os padrões específicos do domínio e o formato de saída esperado.

A preparação de dados para SFT segue um processo similar, mas utiliza uma estrutura diferente — o formato de API Converse:

loader = CSVDatasetLoader(
    question='Body',
    answer='Y',
    system='system'
)
loader.load('sft.csv')
loader.transform(method=TrainingMethod.SFT_LORA, model=Model.NOVA_LITE_2)
loader.validate(method=TrainingMethod.SFT_LORA, model=Model.NOVA_LITE_2)

train_path = loader.save_data(f"s3://{S3_BUCKET}/{S3_PREFIX}/data/train.jsonl")

O treinamento é configurado com infraestrutura específica e hiperparâmetros controlados:

runtime = SMTJRuntimeManager(
    instance_type=INSTANCE_TYPE,
    instance_count=4,
    execution_role=EXECUTION_ROLE
)

customizer = NovaModelCustomizer(
    model=MODEL,
    method=TrainingMethod.SFT_LORA,
    infra=runtime,
    data_s3_path=train_path,
    output_s3_path=f"s3://{S3_BUCKET}/{S3_PREFIX}/sft-output"
)

training_config = {
    "lr": 5e-6,
    "warmup_steps": 17,
    "max_steps": 100,
    "global_batch_size": 64,
    "max_length": 8192,
}

result = customizer.train(
    job_name="blogpost-sft",
    overrides=training_config
)

Após o treinamento, a avaliação sobre o mesmo conjunto de dados de teste revelou melhorias expressivas. A precisão em coincidência exata saltou para 77,2%, e a métrica de precisão de classificação extraída chegou a 79,0%. A distribuição de respostas agora mostra 100% de respostas concisas, eliminando a verbosidade problemática.

Imagem original — fonte: Aws

Etapa 3: Ajuste por Reforço para Otimizar Precisão

Embora o SFT tenha ensinado o formato correto, há ainda espaço para melhorar a precisão real das classificações. O Ajuste por Reforço (RFT — Reinforcement Fine-Tuning) usa uma função de recompensa para guiar o modelo em direção a decisões mais precisas.

A função de recompensa para essa tarefa é binária: +1,0 para predições corretas e -1,0 para incorretas. Uma função Lambda AWS implementa essa lógica, lidando com variações menores no formato de saída:

def calculate_reward(prediction: str, ground_truth: str) -> float:
    """Calcula recompensa binária"""
    extracted = extract_category(prediction)
    truth_norm = normalize_text(ground_truth)
    
    if extracted and extracted == truth_norm:
        return 1.0
    return -1.0

def lambda_handler(event, context):
    """Handler Lambda com recompensas binárias"""
    scores = []
    for sample in event:
        idx = sample.get("id", "no_id")
        ground_truth = sample.get("reference_answer", "")
        prediction = sample.get("content", "")
        reward = calculate_reward(prediction, ground_truth)
        scores.append({"id": idx, "aggregate_reward_score": reward})
    return scores

O treinamento RFT é então iniciado a partir do checkpoint SFT anterior:

REWARD_LAMBDA_ARN = "arn:aws:lambda:us-east-1:ACCOUNT:function:classification-reward"

rft_runtime = SMTJRuntimeManager(
    instance_type=INSTANCE_TYPE,
    instance_count=2,
    execution_role=EXECUTION_ROLE
)

rft_customizer = NovaModelCustomizer(
    model=MODEL,
    method=TrainingMethod.RFT_LORA,
    infra=rft_runtime,
    data_s3_path=rft_s3_uri,
    output_s3_path=f"s3://{S3_BUCKET}/{S3_PREFIX}/rft-output",
    model_path=sft_checkpoint
)

rft_overrides = {
    "lr": 0.00001,
    "number_generation": 4,
    "max_new_tokens": 50,
    "kl_loss_coef": 0.02,
    "temperature": 1,
    "ent_coeff": 0.01,
    "max_steps": 40,
    "save_steps": 30,
    "top_k": 5,
    "global_batch_size": 64,
}

rft_result = rft_customizer.train(
    job_name="stack-overflow-rft",
    rft_lambda_arn=REWARD_LAMBDA_ARN,
    overrides=rft_overrides
)

O RFT trouxe melhorias adicionais incrementais. A precisão em coincidência exata aumentou para 78,8%, com a métrica Quasi-EM chegando a 80,6%. Embora o ganho seja menor que o do SFT, indica que o ajuste por reforço refina padrões diferentes, calibrando as decisões do modelo além da simples conformidade de formato.

Imagem original — fonte: Aws

Resultados Consolidados

Comparando todas as três fases — linha de base, pós-SFT e pós-RFT — observam-se ganhos consistentes em praticamente todas as métricas:

  • ROUGE-1: 0,158 → 0,829 → 0,84 (ganho total: +0,682)
  • Precisão em Coincidência Exata (EM): 0,13 → 0,772 → 0,788 (ganho total: +0,658)
  • F1 Score: 0,138 → 0,772 → 0,788 (ganho total: +0,65)

O SFT proporcionou o maior salto, com ganhos expressivos no aprendizado de padrões específicos do domínio. O RFT refinou a tomada de decisão através de sinais baseados em recompensa, consolidando e otimizando o comportamento do modelo.

Etapa 4: Implantação no Amazon SageMaker Inference

Com o modelo final ajustado e testado, chega o momento da implantação para servir predições em produção. O Nova Forge SDK simplifica esse processo oferecendo duas opções: Amazon Bedrock para uma experiência totalmente gerenciada, ou Amazon SageMaker Inference para maior controle sobre a infraestrutura.

ENDPOINT_NAME = "blogpost-sdkg6"

deployment_result = rft_customizer.deploy(
    job_result=rft_result,
    deploy_platform=DeployPlatform.SAGEMAKER,
    unit_count=1,
    endpoint_name=ENDPOINT_NAME,
    execution_role_name="blogpost-sagemaker",
    sagemaker_instance_type="ml.p5.48xlarge",
    sagemaker_environment_variables={
        "CONTEXT_LENGTH": "12000",
        "MAX_CONCURRENCY": "16"
    }
)

# Invocar o endpoint
streaming_chat_request = {
    "messages": [{"role": "user", "content": "sua pergunta aqui"}],
    "max_tokens": 200,
    "stream": True,
}

inference_result = rft_customizer.invoke_inference(
    request_body=streaming_chat_request,
    endpoint_arn=ENDPOINT_NAME
)

Conclusão: Da Complexidade à Acessibilidade

O SDK Nova Forge transforma a customização de modelos — tradicionalmente um processo complexo e demorado — em um fluxo estruturado e acessível. O caso de estudo do Stack Overflow demonstra isso concretamente: começando em 13% de precisão, o modelo alcançou 79% após ajuste supervisionado e 80,6% após ajuste por reforço.

A SDK elimina barreiras históricas: não é mais necessário expertise profunda em configuração de infraestrutura, gerenciamento de dependências ou orquestração de pipelines complexos. Organizações podem agora construir modelos especializados e inteligentes, sensíveis ao contexto empresarial específico, sem perder as capacidades gerais que tornam os modelos de fundação tão valiosos.

Para começar a customizar modelos Nova, a AWS convida a comunidade a explorar o SDK Nova Forge no GitHub e consultar a documentação completa para construir modelos adaptados às necessidades empresariais específicas.

Fonte

Kick off Nova customization experiments using Nova Forge SDK (https://aws.amazon.com/blogs/machine-learning/kick-off-nova-customization-experiments-using-nova-forge-sdk/)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *