Ajuster Llama-3.2-3B avec Unsloth
Affiner le Llama-3.2-3B grand modèle de langage utilisant la bibliothèque Unsloth. Unsloth fournit des implémentations optimisées pour les techniques d'affinement (PEFT) à parameter efficace, comme LoRA (Low-Rank Adaptation), permettant un entraînement plus rapide avec une utilisation réduite de la mémoire.
Le notebook couvre :
- Chargement et configuration du Llama-3.2-3B de base. modèle
- Création d'un modèle PEFT avec des adaptateurs LoRA
- Traitement des données d'entraînement du dataset FineTome-100k
- Entraînement avec affinement supervisé (AS)
- Enregistrement des expériences avec MLflow
- L'enregistrement du modèle affiné dans Unity Catalog
Exigences : compute GPU serverless
Ce notebook nécessite un compute GPU avec un accélérateur A10.
- Sélectionnez A10 comme accélérateur à partir de l'option Matériel dans le panneau d'environnement.
- Sélectionnez **AI v5** dans l'option Environnement de base du panneau d'environnement.
- Cliquez sur Appliquer .
Remarque : Le provisionnement du Compute peut prendre jusqu'à 8 minutes.
Bibliothèques requises
L'environnement Databricks AI v5 inclut Unsloth et ses dépendances (unsloth, unsloth_zoo, bitsandbytes, trl, xformers, et mlflow), donc aucune installation supplémentaire n'est nécessaire.
Configurer Unity Catalog et les paramètres du modèle
Définissez les emplacements Unity Catalog pour stocker les points de contrôle du modèle et le modèle enregistré final. La configuration comprend :
- Espace de noms Unity Catalog (catalogue, schéma, nom de modèle, volume)
- Sélection du modèle de base (Llama-3.2-3B-Instruct de Unsloth)
- Répertoire de sortie pour l’enregistrement des points de contrôle
- Dataset d'entraînement (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}")
Chargez le modèle de base et le tokenizer
Charger le Llama-3.2-3B-Instruct modèle utilisant le FastLanguageModel d’Unsloth. Ceci configure le modèle avec une longueur de séquence maximale de 2048 jetons et une détection automatique du type de données pour des performances optimales sur le GPU disponible.
from unsloth import FastLanguageModel
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
)
Appliquer les adaptateurs LoRA pour un affinement efficace
Convertissez le modèle de base en modèle PEFT en ajoutant des adaptateurs LoRA (Low-Rank Adaptation) aux couches d'attention et de propagation avant. Ceci utilise 16 adaptateurs, ce qui ajoute seulement une petite fraction de paramètres entraînables tout en gardant le modèle de base figé, réduisant considérablement les exigences de mémoire et le temps d'entraînement.
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
)
Chargez et formatez le dataset d'entraînement
Chargez le dataset FineTome-100k et préparez-le pour l'entraînement. Le traitement des données applique le template de chat Llama-3.1 pour formater les conversations, standardise le format ShareGPT et convertit chaque conversation en séquences de texte tokenisées adaptées à l'affinement supervisé.
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,)
Configurer le formateur d'affinement supervisé
Configurez le SFTTrainer avec les hyperparamètres d'entraînement, y compris la taille du batch, le taux d'apprentissage et les paramètres de l'optimiseur. L'entraîneur est configuré pour exécuter 25 étapes avec le suivi MLflow activé. L'entraînement basé uniquement sur les réponses garantit que le modèle apprend uniquement des réponses de l'assistant et non des invites de l'utilisateur, améliorant ainsi l'efficacité de l'entraînement.
from trl import SFTTrainer
from transformers import TrainingArguments, DataCollatorForSeq2Seq
from unsloth import is_bfloat16_supported
from unsloth.chat_templates import train_on_responses_only
import mlflow
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)
Exécutez la boucle d'entraînement
Exécutez le processus d'affinement dans une exécution MLflow pour suivre automatiquement les métriques d'entraînement (perte, taux d'apprentissage, etc.) et les métriques système (utilisation du GPU, utilisation de la mémoire). L'entraînement s'exécute en 25 étapes, tel que configuré dans l'entraîneur, avec des points de contrôle enregistrés dans le volume Unity Catalog.
import mlflow
with mlflow.start_run(
run_name='finetune-llama-3.2-3b-unsloth',
log_system_metrics=True
):
trainer.train()
Merge les adaptateurs LoRA et enregistrez-les dans Unity Catalog
Combinez les poids de l’adaptateur LoRA entraîné avec le modèle de base pour créer un modèle unique et déployable. Le modèle fusionné est ensuite journalisé dans MLflow et enregistré dans Unity Catalog avec le type de tâche de discussion, le rendant prêt pour le déploiement sur les endpoints de service de modèle.
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}")
Étapes suivantes
Le modèle affiné est maintenant enregistré dans Unity Catalog et prêt à être servi. En savoir plus sur le déploiement et l’utilisation du modèle :
- Déployer des modèles pour l’inférence par batch ou en temps réel
- Créer et gérer les Endpoint de service de modèles
- Documentation Unsloth