Pular para o conteúdo principal

Ajuste fino completo do Qwen3-4B

Open in Databricks

Realize o ajuste fino completo do modelo de linguagem grande Qwen3-4B em uma única GPU H100. Este passo a passo mostra como:

  • Realize a execução do ajuste fino completo , que atualiza cada parâmetro do modelo para adaptação máxima aos seus dados
  • Use o ambiente Databricks AI v5 sem instalar nenhuma biblioteca adicional
  • Aproveite TRL (Transformer Reinforcement Learning) para ajuste fino supervisionado
  • Registre o modelo ajustado no Unity Catalog para governança e implantação

key conceitos:

  • Ajuste fino completo : Atualiza todos os pesos do modelo, dando ao modelo a maior capacidade de aprender com seu dataset ao custo de maior memória e compute do que os métodos eficientes em parâmetros
  • TRL: Uma biblioteca para treinamento de modelos de linguagem com aprendizado por reforço e ajuste fino supervisionado
  • Treinamento com eficiência de memória : Usa precisão mista BF16 e checkpointing de gradiente para ajustar um ajuste fino completo de 4 bilhões de parâmetros em uma única GPU H100

Matriz de decisão de ajuste fino completo vs LoRA

Este Notebook usa ajuste fino completo , que atualiza todos os parâmetros do modelo. A alternativa, LoRA (Low-Rank Adaptation), congela o modelo base e ensina apenas pequenas camadas adaptadoras.

Cenário

Recomendação

Motivo

Grande mudança no comportamento do modelo

Ajuste fino completo

Atualiza todos os parâmetros para mudanças fundamentais no comportamento do modelo

A mais alta qualidade possível em uma única tarefa

Ajuste fino completo

Sem aproximação de baixa classificação, para que o modelo tenha capacidade total de adaptação

Memória da GPU limitada

LoRA

Acomoda modelos maiores na memória com o treinamento de apenas aproximadamente 1% dos parâmetros

Vários adaptadores específicos para tarefas

LoRA

Fazer swap de diferentes adaptadores no mesmo modelo base

O ajuste fino completo de um modelo de 4 bilhões de parâmetros requer significativamente mais memória de GPU do que LoRA porque o estado do otimizador e os gradientes são mantidos para cada parâmetro. Este Notebook usa precisão mista BF16 e checkpointing de gradiente para que o treinamento caiba em uma única GPU H100 (80 GB).

Conectar-se ao compute de GPU serverless

Para se conectar ao compute de GPU serverless:

  1. Clique no menu suspenso Conectar no Notebook e selecione GPU Serverless .
  2. Escolha uma GPU H100 de 1x como acelerador.
  3. Abra o painel Ambiente e escolha AI v5 como o ambiente base.
  4. Clique em Aplicar .

Para mais informações, consulte a documentação de compute de GPU.

Importar bibliotecas

O ambiente Databricks AI v5 já inclui todas as bibliotecas necessárias para este exemplo (como trl, transformers, datasets e mlflow), portanto, nenhuma instalação adicional é necessária.

A próxima célula importa as bibliotecas necessárias para treinamento de modelo, manipulação de dataset e acompanhamento do MLflow.

Python
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import (
SFTConfig,
SFTTrainer,
setup_chat_format
)
import torch
import mlflow

Configuração

Integração com o Unity Catalog

A próxima célula configura onde seu modelo ajustado será armazenado e registrado:

  • Catálogo e esquema : Organize modelos no seu espaço de nomes do Unity Catalog (default: main.default)
  • Nome do Modelo : O nome do modelo registrado no Unity Catalog para governança e implantação
  • Volume : Volume do Unity Catalog para armazenar checkpoints do modelo durante o treinamento

Esses widgets permitem personalizar o local de armazenamento sem editar o código. O modelo será registrado como {catalog}.{schema}.{model_name} para fácil acesso e controle de versão.

Hiperparâmetros de treinamento

A célula também define os key parâmetros de treinamento:

  • Modelo & Dataset : Qwen3-4B com o dataset conversacional Capybara
  • Tamanho do lote (1) : número de exemplos por GPU por o passo de treinamento, mantido pequeno para caber um ajuste fino completo na memória
  • Acúmulo de Gradientes (8) : Acumula gradientes em 8 lotes para um tamanho de lote efetivo de 8
  • Taxa de Aprendizado (2e-5) : Taxa conservadora apropriada para ajuste fino completo
  • Máximo de os passos (50) : Limita o treinamento a 50 os passos para uma execução de demonstração rápida
  • Registro & Checkpoint : Salva o progresso a cada 25 os passos, log métricas a cada 10 os passos
Python
dbutils.widgets.text("uc_catalog", "main")
dbutils.widgets.text("uc_schema", "default")
dbutils.widgets.text("uc_model_name", "qwen3_4b_assistant")
dbutils.widgets.text("uc_volume", "checkpoints")

UC_CATALOG = dbutils.widgets.get("uc_catalog")
UC_SCHEMA = dbutils.widgets.get("uc_schema")
UC_MODEL_NAME = dbutils.widgets.get("uc_model_name")
UC_VOLUME = dbutils.widgets.get("uc_volume")

print(f"UC_CATALOG: {UC_CATALOG}")
print(f"UC_SCHEMA: {UC_SCHEMA}")
print(f"UC_MODEL_NAME: {UC_MODEL_NAME}")
print(f"UC_VOLUME: {UC_VOLUME}")

# MLflow and Unity Catalog configuration

# Model selection
MODEL_NAME = "Qwen/Qwen3-4B"
DATASET_NAME = "trl-lib/Capybara"
OUTPUT_DIR = f"/Volumes/{UC_CATALOG}/{UC_SCHEMA}/{UC_VOLUME}/{UC_MODEL_NAME}"

# Training hyperparameters
BATCH_SIZE = 1
GRADIENT_ACCUMULATION_STEPS = 8
LEARNING_RATE = 2e-5
MAX_STEPS = 50
EVAL_STEPS = 25
LOGGING_STEPS = 10
SAVE_STEPS = 25

Carregar e preparar o dataset

A próxima célula carrega o dataset de treinamento e o prepara para o ajuste fino:

  • Dataset : trl-lib/Capybara - dados conversacionais de alta qualidade otimizados para seguir instruções
  • Divisão de ensinar/validação : cria uma divisão de 90/10 se nenhum conjunto de teste existir
  • Validação de dados : garante a formatação adequada para ajuste fino conversacional
Python
dataset = load_dataset(DATASET_NAME)
print(f"✓ Dataset loaded: {dataset}")

if "test" not in dataset:
print("Creating validation split from training data...")
dataset = dataset["train"].train_test_split(test_size=0.1, seed=42)
print("✓ Data split: 90% train, 10% validation")

Inicializar modelo e tokenizador

A próxima célula carrega o modelo base e o tokenizador, e então os configura para o ajuste fino conversacional:

  • Carregamento do modelo : Faz o download de Qwen3-4B do Hugging Face em precisão BF16
  • Configuração do tokenizador : Configura o tokenizador rápido com preenchimento adequado
  • Formatação de chat : Aplica um padrão de chat para conversas estruturadas se o tokenizador ainda não definir um
  • Configuração de tokens : define o tokens de preenchimento como token EOS para o tratamento adequado da sequência
Python
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
torch_dtype=torch.bfloat16,
trust_remote_code=True,
)

tokenizer = AutoTokenizer.from_pretrained(
MODEL_NAME,
trust_remote_code=True,
use_fast=True
)

# Chat template formatting for conversational fine-tuning
if tokenizer.chat_template is None:
print("Adding chat template for proper conversation formatting...")
model, tokenizer = setup_chat_format(model, tokenizer, format="chatml")
print("✓ ChatML format applied for structured conversations")

if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
print("✓ Padding token set to EOS token")

print("✓ Model and tokenizer loaded successfully")

Ensinar o modelo

A próxima célula configura e executa o processo de ajuste fino completo:

Configuração de treinamento

  • Configuração de lotes : 1 amostra por dispositivo com 8 os passos de acumulação de gradiente (tamanho de lote efetivo: 8)
  • Otimização : os passos de aquecimento, decaimento de peso e seleção do melhor modelo com base na perda de avaliação
  • Registro : Relata métricas ao MLflow para o acompanhamento de experimentos

key otimizações ativadas

  • Precisão mista BF16 : Computação mais rápida com menor consumo de memória, bem adequada para GPUs H100
  • Checkpointing de gradiente : troca compute extra por uma grande redução na memória de ativação, o que permite que um ajuste fino completo de 4B caiba em um único H100
  • Acumulação de gradiente : simula tamanhos de lote maiores para treinamento estável
  • Pontos de verificação : Salva o modelo a cada 25 os passos com um limite de 2 pontos de verificação

O loop de treinamento log o progresso a cada 10 os passos e avalia a cada 25 os passos.

Python
with mlflow.start_run(run_name=f"{MODEL_NAME}_full-fine-tuning", log_system_metrics=True):
try:
print(f"Learning rate: {LEARNING_RATE}")

training_args_dict = {
"output_dir": OUTPUT_DIR,
"per_device_train_batch_size": BATCH_SIZE,
"per_device_eval_batch_size": BATCH_SIZE,
"gradient_accumulation_steps": GRADIENT_ACCUMULATION_STEPS,
"learning_rate": LEARNING_RATE,
"max_steps": MAX_STEPS,
"eval_steps": EVAL_STEPS,
"logging_steps": LOGGING_STEPS,
"save_steps": SAVE_STEPS,
"save_total_limit": 2,
"report_to": "mlflow", # Log to MLflow
"warmup_steps": 10,
"weight_decay": 0.01,
"metric_for_best_model": "eval_loss",
"greater_is_better": False,
"eval_strategy": "steps", # Run evaluation every eval_steps
"save_strategy": "steps", # Checkpoint on the same cadence as eval
"load_best_model_at_end": True, # Register the best-eval checkpoint, not the last
"dataloader_pin_memory": False,
"remove_unused_columns": False,
"bf16": True, # Mixed precision training
"gradient_checkpointing": True, # Reduce activation memory for full fine-tuning
"gradient_checkpointing_kwargs": {"use_reentrant": False},
}

training_args = SFTConfig(**training_args_dict)

trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
processing_class=tokenizer,
)

print("\n" + "="*50)
print("STARTING TRAINING")
print("="*50)

print("🚀 Full fine-tuning Qwen3-4B on a single H100 GPU")

trainer.train()
print("\n✓ Training completed successfully!")

except Exception as e:
print(f"✗ Training failed: {e}")
raise

Salvar artefatos do modelo

A próxima célula salva o modelo treinado e o tokenizador no volume do Unity Catalog:

  • Pesos completos do modelo : Salva o modelo ajustado completo, pronto para carregar diretamente para inferência
  • Tokenizer : Salva a configuração do tokenizer para inferência
  • Localização de armazenamento : Salva em /Volumes/{catalog}/{schema}/{volume}/{model_name}
Python
try:
print("\nSaving trained model...")

trainer.save_model(training_args.output_dir)
print("✓ Full model weights saved")

tokenizer.save_pretrained(training_args.output_dir)
print("✓ Tokenizer saved with model")
print(f"\n🎉 All artifacts saved to: {training_args.output_dir}")

except Exception as e:
print(f"✗ Model saving failed: {e}")
raise

Faça o registro do modelo no Unity Catalog

A próxima célula registra o modelo ajustado no Unity Catalog para governança e implantação:

Fluxo de trabalho de registro de modelo

  1. Carregar modelo treinado : Carrega o modelo de peso completo salvo e o tokenizador
  2. Preparar para registro : cria um dicionário de modelo transformers com o modelo e o tokenizador
  3. Registro no Unity Catalog : faz log no MLflow e registro no Unity Catalog
  4. Adicionar metadados : Inclui o tipo de tarefa, a família do modelo e as informações de tamanho

Benefícios do registro do Unity Catalog

  • Governança : Registro de modelo centralizado com controle de acesso e acompanhamento da linhagem
  • Versionamento : Gerenciamento automático de versões para o ciclo de vida do modelo
  • Implantação : Implantação fácil para endpoint de servindo modelo
  • Capacidade de descoberta : Os modelos são pesquisáveis e documentados no Unity Catalog
Python
mlflow_run_id = mlflow.last_active_run().info.run_id
print("\nRegistering model with MLflow and Unity Catalog...")

with mlflow.start_run(run_id=mlflow_run_id):
try:
# Load the trained full-weight model for registration
print("Loading fine-tuned model for registration...")
trained_model = AutoModelForCausalLM.from_pretrained(
training_args.output_dir,
torch_dtype=torch.bfloat16,
trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(training_args.output_dir)
model_type = "Full fine-tuning"
size_params = "4b"

# Prepare transformers model dictionary
transformers_model = {
"model": trained_model,
"tokenizer": tokenizer
}

# Create Unity Catalog model name
full_model_name = f"{UC_CATALOG}.{UC_SCHEMA}.{UC_MODEL_NAME}"

print(f"Registering model as: {full_model_name}")

# Start MLflow run and log model
task = "llm/v1/chat"
model_info = mlflow.transformers.log_model(
transformers_model=transformers_model,
task=task,
registered_model_name=full_model_name,
metadata={
"task": task,
"pretrained_model_name": MODEL_NAME,
"databricks_model_family": "Qwen3ForCausalLM",
"databricks_model_size_parameters": size_params,
},
repo_type="local", # Fix: specify repo_type for local path
)

print(f"✓ Model successfully registered in Unity Catalog: {full_model_name}")
print(f"✓ MLflow model URI: {model_info.model_uri}")

# Print deployment information
print(f"\n📦 Model Registration Complete!")
print(f"Unity Catalog Path: {full_model_name}")
print(f"Model Type: {model_type}")

except Exception as e:
print(f"✗ Model registration failed: {e}")
print("Model is still saved locally and can be registered manually")
print(f"Local model path: {training_args.output_dir}")
raise

Próximos os passos

Seu modelo Qwen3-4B foi ajustado com sucesso com ajuste fino de peso completo e registrado no Unity Catalog. Em seguida, você pode:

Notebook de exemplo

Ajuste fino completo do Qwen3-4B