Partilhar via


Finetune Llama-3.2-3B com Unsloth

Este caderno demonstra como afinar finamente o modelo de linguagem grande Llama-3.2-3B usando a biblioteca Unsloth . Unsloth oferece implementações otimizadas para técnicas de afinação de parâmetros eficiente (PEFT), como LoRA (Low-Rank Adaptation), permitindo um treino mais rápido com menor consumo de memória.

O caderno cobre:

  • Carregamento e configuração do modelo base Llama-3.2-3B
  • Criação de um modelo PEFT com adaptadores LoRA
  • Processamento de dados de treino do conjunto de dados FineTome-100k
  • Treinamento com afinação supervisionada (SFT)
  • Registo de experiências com MLflow
  • Registo do modelo finamente ajustado no Catálogo Unity

Requisitos: Computação GPU sem servidor

Este portátil requer processamento por GPU com um acelerador A10.

  1. Selecione A10 como acelerador na opção de Hardware no painel de ambiente
  2. Seleciona AI v4 na opção de ambiente base no painel de ambientes
  3. Clique em Aplicar.

Nota: O provisionamento de computação pode demorar até 8 minutos.

Instalar as bibliotecas necessárias

Instalar a biblioteca Unsloth com suporte para CUDA 12.4 e PyTorch 2.6.0, juntamente com o accelerate para treino distribuído e o MLflow para rastreamento de experiências. O runtime em Python reinicia após a instalação para carregar os novos pacotes.

%pip install "unsloth[cu126-torch270]==2025.9.6" --no-deps
%pip install "unsloth_zoo==2025.9.8" --no-deps
%pip install "bitsandbytes==0.46.0" --no-deps
%pip install "trl==0.12.2" --no-deps
%pip install "xformers==0.0.31.post1" --index-url https://download.pytorch.org/whl/cu126 --no-deps
%pip install "mlflow==3.7.0" --no-deps
%restart_python

Configurar o Catálogo Unity e as definições do modelo

Defina as localizações do Catálogo Unity para armazenar os pontos de verificação do modelo e a versão final do modelo registado. A configuração inclui:

  • Espaço de nomes do Catálogo Unity (catálogo, esquema, nome do modelo, volume)
  • Seleção do modelo base (Llama-3.2-3B-Instruct da Unsloth)
  • Diretório de saída para guardar pontos de verificação
  • Conjunto de dados de treino (FineTome-100k)
dbutils.widgets.text("uc_catalog", "main")
dbutils.widgets.text("uc_schema", "default")
dbutils.widgets.text("uc_model_name", "llama-3.2-3b")
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}")

# Model selection - Choose based on your compute constraints
MODEL_NAME = "unsloth/Llama-3.2-3B-Instruct" # or choose "unsloth/Llama-3.2-1B-Instruct"
OUTPUT_DIR = f"/Volumes/{UC_CATALOG}/{UC_SCHEMA}/{UC_VOLUME}/{UC_MODEL_NAME}"
DATASET_NAME = "mlabonne/FineTome-100k"

print(f"MODEL_NAME: {MODEL_NAME}")
print(f"OUTPUT_DIR: {OUTPUT_DIR}")
print(f"DAASET_NAME: {DATASET_NAME}")

Carregar o modelo base e o tokenizador

Carregue o modelo Llama-3.2-3B-Instruct usando o FastLanguageModel do Unsloth. Isto configura o modelo com um comprimento máximo de sequência de 2048 tokens e deteção automática de dtype para um desempenho ótimo na GPU disponível.

from unsloth import FastLanguageModel
import torch
max_seq_length = 2048 # Choose any!
dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
load_in_4bit = False # Use 4bit quantization to reduce memory usage. Can be False.

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = MODEL_NAME,
    max_seq_length = max_seq_length,
    dtype = dtype,
    load_in_4bit = load_in_4bit,
    # token = "hf_...", # use one if using gated models like meta-llama/Llama-2-7b-hf
)

Aplicar adaptadores LoRA para um ajuste fino eficiente

Converta o modelo base para um modelo PEFT ao adicionar adaptadores LoRA (Adaptação de Baixa Ordem) às camadas de atenção e feed-forward. Este utiliza adaptadores rank 16, que adicionam apenas uma pequena fração dos parâmetros treináveis, mantendo o modelo base congelado, reduzindo significativamente os requisitos de memória e o tempo de treino.

model = FastLanguageModel.get_peft_model(
    model,
    r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj",],
    lora_alpha = 16,
    lora_dropout = 0, # Supports any, but = 0 is optimized
    bias = "none",    # Supports any, but = "none" is optimized
    # [NEW] "unsloth" uses 30% less VRAM, fits 2x larger batch sizes!
    use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
    random_state = 3407,
    use_rslora = False,  # We support rank stabilized LoRA
    loftq_config = None, # And LoftQ
)

Carregar e formatar o conjunto de dados de treino

Carregue o conjunto de dados FineTome-100k e prepare-o para treino. O processamento de dados aplica o modelo de chat Llama-3.1 para formatar conversas, padroniza o formato ShareGPT e converte cada conversa em sequências de texto tokenizadas adequadas para ajuste fino supervisionado.

from unsloth.chat_templates import get_chat_template

tokenizer = get_chat_template(
    tokenizer,
    chat_template = "llama-3.1",
)

def formatting_prompts_func(examples):
    convos = examples["conversations"]
    texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos]
    return { "text" : texts, }
pass

from datasets import load_dataset
dataset = load_dataset(DATASET_NAME, split = "train")
from unsloth.chat_templates import standardize_sharegpt
dataset = standardize_sharegpt(dataset)
dataset = dataset.map(formatting_prompts_func, batched = True,)

Configurar o treinador supervisionado de afinação fina

Configure o SFTTrainer com hiperparâmetros de treino, incluindo tamanho do lote, taxa de aprendizado e configurações do otimizador. O treinador está configurado para funcionar em 25 passos com o rastreamento MLflow ativado. O treino apenas de resposta garante que o modelo aprende apenas a partir de respostas de assistentes, e não de prompts do utilizador, melhorando a eficiência do treino.

from trl import SFTTrainer
from transformers import TrainingArguments, DataCollatorForSeq2Seq
from unsloth import is_bfloat16_supported
from transformers.integrations import MLflowCallback
from unsloth.chat_templates import train_on_responses_only
import mlflow
from unsloth import FastLanguageModel
import torch

trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    dataset_text_field = "text",
    max_seq_length = max_seq_length,
    data_collator = DataCollatorForSeq2Seq(tokenizer = tokenizer),
    dataset_num_proc = 6,
    packing = False, # Can make training 5x faster for short sequences.
    args = TrainingArguments(
        per_device_train_batch_size = 2,
        gradient_accumulation_steps = 4,
        warmup_steps = 5,
        # num_train_epochs = 1, # Set this for 1 full training run.
        max_steps = 25,
        learning_rate = 2e-4,
        fp16 = not is_bfloat16_supported(),
        bf16 = is_bfloat16_supported(),
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 3407,
        output_dir = OUTPUT_DIR,
        report_to = "mlflow", # Use MLflow to track model metrics
    ),
)


trainer = train_on_responses_only(
    trainer,
    instruction_part = "<|start_header_id|>user<|end_header_id|>\n\n",
    response_part = "<|start_header_id|>assistant<|end_header_id|>\n\n",
    num_proc=1)


Executar o ciclo de treino

Execute o processo de ajuste fino dentro de uma execução MLflow para acompanhar automaticamente métricas de treino (perda, taxa de aprendizagem, etc.) e métricas do sistema (utilização da GPU, uso de memória). A formação decorre durante 25 etapas conforme configurado no treinador, com checkpoints guardados no volume do Unity Catalog.

import mlflow
with mlflow.start_run(
    run_name='finetune-llama-3.2-3b-unsloth',
    log_system_metrics=True
):
    trainer.train()

Funde adaptadores LoRA e regista-os no Unity Catalog

Combine os pesos dos adaptadores LoRA treinados com o modelo base para criar um único modelo pronto para implantação. O modelo fundido é então registado no MLflow e registado no Unity Catalog com o tipo de tarefa de chat, tornando-o pronto para ser implementado nos endpoints de serviço do modelo.

mlflow_run_id = mlflow.last_active_run().info.run_id
merged_model = model.merge_and_unload()
# Create Unity Catalog model name
full_model_name = f"{UC_CATALOG}.{UC_SCHEMA}.{UC_MODEL_NAME}"

try:
    with mlflow.start_run(run_id = mlflow_run_id):
        model_info = mlflow.transformers.log_model(
            transformers_model={'model': merged_model, 'tokenizer': tokenizer},
            name='model',
            registered_model_name=full_model_name, # TODO: Replace with your own model name!
            await_registration_for=3600,
            task='llm/v1/chat',
        )
    print(f"✓ Model successfully registered in Unity Catalog: {full_model_name}")
    print(f"✓ MLflow model URI: {model_info.model_uri}")
    print(f"✓ Model version: {model_info.version}")
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: {OUTPUT_DIR}")

Passos seguintes

O modelo afinado está agora registado no Catálogo Unity e pronto a servir. Saiba mais sobre a implementação e utilização do modelo:

Exemplo de bloco de notas

Finetune Llama-3.2-3B com Unsloth

Obter bloco de notas