Lección 15 · 5 min · Gratis

Ajuste fino de Llama Guard para detectar múltiples violaciones de privacidad

El modelo Llama Guard preentrenado tiene una única categoría para violaciones de privacidad: S7. Supongamos que quieres que Llama Guard devuelva múltiples violaciones en tu prompt cuando existan. Primero, cargamos Llama Guard y confirmamos lo que esperamos, es decir, que el modelo debe devolver S7 cuando haya cualquier violación de PII.

Conjunto de datos utilizado para entrenamiento y evaluación

Utilizamos los siguientes conjuntos de datos:

Evaluación manual de Llama Guard en algunos prompts

from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from typing import List, Tuple
from enum import Enum

model_id: str = "meta-llama/Llama-Guard-3-8B"

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto")
Loading checkpoint shards:   0%|          | 0/4 [00:00<?, ?it/s]
from llama_cookbook.inference.prompt_format_utils import build_custom_prompt, create_conversation, PROMPT_TEMPLATE_3, LLAMA_GUARD_3_CATEGORY_SHORT_NAME_PREFIX

def evaluate_safety(prompt = "", category_list = [], categories = []):
    prompt = [([prompt])]
    if categories == []:
        if category_list == []:
            categories = get_lg3_categories(all = True)
        else:
            categories = get_lg3_categories(category_list)
    formatted_prompt = build_custom_prompt(
            agent_type = AgentType.USER,
            conversations = create_conversation(prompt[0]), 
            categories=categories,
            category_short_name_prefix = LLAMA_GUARD_3_CATEGORY_SHORT_NAME_PREFIX,
            prompt_template = PROMPT_TEMPLATE_3,
            with_policy = True)
    print("**********************************************************************************")
    print("Prompt:")
    print(prompt)
    
    input = tokenizer([formatted_prompt], return_tensors="pt").to("cuda")
    prompt_len = input["input_ids"].shape[-1]
    output = model.generate(**input, max_new_tokens=100, pad_token_id=0)
    print(output[0][prompt_len:])
    results = tokenizer.decode(output[0][prompt_len:], skip_special_tokens=True)
    
    print("===================================")
    print("Results:")
    print(f"> {results}")
    print("\n==================================\n")

from enum import Enum
from llama_cookbook.inference.prompt_format_utils import  LLAMA_GUARD_3_CATEGORY, SafetyCategory, AgentType
from typing import List

class LG3Cat(Enum):
    VIOLENT_CRIMES =  0
    NON_VIOLENT_CRIMES = 1
    SEX_CRIMES = 2
    CHILD_EXPLOITATION = 3
    DEFAMATION = 4
    SPECIALIZED_ADVICE = 5
    PRIVACY = 6
    INTELLECTUAL_PROPERTY = 7
    INDISCRIMINATE_WEAPONS = 8
    HATE = 9
    SELF_HARM = 10
    SEXUAL_CONTENT = 11
    ELECTIONS = 12
    CODE_INTERPRETER_ABUSE = 13

def get_lg3_categories(category_list: List[LG3Cat] = [], all: bool = False, custom_categories: List[SafetyCategory] = [] ):
    categories = list()
    if all:
        categories = list(LLAMA_GUARD_3_CATEGORY)
        categories.extend(custom_categories)
        return categories
    for category in category_list:
        categories.append(LLAMA_GUARD_3_CATEGORY[LG3Cat(category).value])
    categories.extend(custom_categories)
    return categories
evaluate_safety(prompt = """Dear Carmen, As our National Brand Architect, we need you to conduct an internal audit\ 
of our Usability operations, specifically focused on our compliance with Administrative Law. Please use the data\ 
from the 109.4.61.213 and 4d36:f8ad:4ebd:1bff:c5eb:62aa:b4d7:dddf IP addresses in the investigation.""")
**********************************************************************************
Prompt:
[['Dear Carmen, As our National Brand Architect, we need you to conduct an internal audit\\ \nof our Usability operations, specifically focused on our compliance with Administrative Law. Please use the data\\ \nfrom the 109.4.61.213 and 4d36:f8ad:4ebd:1bff:c5eb:62aa:b4d7:dddf IP addresses in the investigation.']]
tensor([   271,  39257,    198,     50,     22, 128009], device='cuda:0')
===================================
Results:
> 

unsafe
S7

==================================

Observamos que el modelo identifica correctamente que hay una violación de privacidad. Digamos que queremos ir un paso más allá e identificar violaciones para las siguientes categorías:

  • Nombre (S1)
  • Dirección IP (S2)
  • Número de teléfono (S3)
  • Dirección (S4)
  • Tarjeta de crédito (S5)

Una vez que ajustemos Llama Guard con estas categorías, deberíamos esperar ver S1 y S2 para el prompt anterior.

Preparación de datos para el ajuste fino

El conjunto de datos ai4privacy/pii-masking-65k contiene prompts con múltiples categorías de violación de PII. Solo elegimos un subconjunto de las categorías de PII para este experimento.

import datasets
import json
import random

dataset = datasets.load_dataset("ai4privacy/pii-masking-65k", split="train")

# Map the PII violations to catgeories
MAPPING = {"NAME": "S1", 
           "IPV4": "S2", 
           "IPV6": "S2", 
           "PHONE_NUMBER": "S3", 
           "ZIPCODE": "S4", 
           "COUNTY": "S4", 
           "STREET": "S4", 
           "CREDITCARDNUMBER": "S5",
           "CREDITCARDCVV": "S5"}


json_t_data = []
for x in dataset.to_iterable_dataset():
    labels = []
    for item in x['token_entity_labels']:  
        for key in MAPPING.keys():
            if key in item:
                labels.append(MAPPING[key])
    labels = list(set(labels))

    # We mark all other violations as safe
    if not labels:
        output = "safe"
    else:
        output = "unsafe\n" + ",".join(labels)
    
    json_t_data.append({
        "prompt":x['unmasked_text'],
        "output":output,
    })
from collections import Counter

counts = Counter([entry["output"] for entry in json_t_data])
print(f"Fine tuning data counts of each category is \n{counts}")
Fine tuning data counts of each category is 
Counter({'safe': 9600, 'unsafe\nS1': 5195, 'unsafe\nS4': 2107, 'unsafe\nS2': 1174, 'unsafe\nS5': 813, 'unsafe\nS1,S4': 630, 'unsafe\nS3': 516, 'unsafe\nS1,S2': 448, 'unsafe\nS1,S3': 352, 'unsafe\nS1,S5': 303, 'unsafe\nS4,S3': 115, 'unsafe\nS4,S5': 76, 'unsafe\nS2,S4': 52, 'unsafe\nS2,S1': 50, 'unsafe\nS1,S4,S3': 39, 'unsafe\nS1,S4,S5': 26, 'unsafe\nS5,S3': 26, 'unsafe\nS2,S5': 18, 'unsafe\nS2,S3': 12, 'unsafe\nS1,S4,S2': 11, 'unsafe\nS1,S5,S3': 10, 'unsafe\nS1,S2,S3': 5, 'unsafe\nS1,S2,S5': 4, 'unsafe\nS1,S2,S4': 3, 'unsafe\nS1,S4,S5,S3': 2, 'unsafe\nS2,S1,S3': 1})

Guarda el conjunto de datos creado en un archivo JSON para usarlo en el ajuste fino con torchtune

random.shuffle(json_t_data)
with open('torchtune_configs/pii_train.json', 'w') as f:
    
    # Use json.dump() to write the JSON data to the file
    json.dump(json_t_data, f, indent=4)

Ajuste fino de Llama Guard con torchtune

torchtune es una biblioteca de PyTorch para crear, post-entrenar y experimentar fácilmente con LLMs. Proporciona:

  • Recetas de entrenamiento hackeables para SFT, destilación de conocimiento, RL y RLHF, y entrenamiento consciente de la cuantificación.
  • Implementaciones sencillas en PyTorch de LLMs populares como Llama, Gemma, Mistral, Phi, Qwen y más.
  • Eficiencia de memoria, mejoras de rendimiento y escalado de primera clase listos para usar, utilizando las últimas API de PyTorch.
  • Archivos de configuración YAML para configurar fácilmente recetas de entrenamiento, evaluación, cuantificación o inferencia.

Para obtener instrucciones de instalación y aprender más sobre torchtune, consulta github.

En términos generales, hay 2 pasos principales:

  • Descargar el modelo
  • Ajustar el modelo

Las configuraciones necesarias para el ajuste fino están en el directorio torchtune_configs.

Instalar Torchtune

# Install PyTorch, torchvision, torchao nightlies
!pip install --pre --upgrade torch torchvision torchao --index-url https://download.pytorch.org/whl/nightly/cu126 # full options are cpu/cu118/cu121/cu124/cu126

# Install torchtune
!pip install --pre --upgrade torchtune --extra-index-url https://download.pytorch.org/whl/nightly/cpu

Descargar Llama Guard de HuggingFace

Necesitas pasar tu token de HuggingFace para descargar el modelo.

!tune download meta-llama/Llama-Guard-3-8B --output-dir /tmp/Meta-Llama-Guard-3-8B --ignore-patterns "original/consolidated.00.pth" --hf-token $HF_TOKEN
Ignoring files matching the following patterns: original/consolidated.00.pth
Successfully downloaded model repo and wrote to the following locations:
/tmp/Meta-Llama-Guard-3-8B/.cache
/tmp/Meta-Llama-Guard-3-8B/.gitattributes
/tmp/Meta-Llama-Guard-3-8B/LICENSE
/tmp/Meta-Llama-Guard-3-8B/README.md
/tmp/Meta-Llama-Guard-3-8B/USE_POLICY.md
/tmp/Meta-Llama-Guard-3-8B/config.json
/tmp/Meta-Llama-Guard-3-8B/generation_config.json
/tmp/Meta-Llama-Guard-3-8B/llama_guard_3_figure.png
/tmp/Meta-Llama-Guard-3-8B/model-00001-of-00004.safetensors
/tmp/Meta-Llama-Guard-3-8B/model-00002-of-00004.safetensors
/tmp/Meta-Llama-Guard-3-8B/model-00003-of-00004.safetensors
/tmp/Meta-Llama-Guard-3-8B/model-00004-of-00004.safetensors
/tmp/Meta-Llama-Guard-3-8B/model.safetensors.index.json
/tmp/Meta-Llama-Guard-3-8B/original
/tmp/Meta-Llama-Guard-3-8B/special_tokens_map.json
/tmp/Meta-Llama-Guard-3-8B/tokenizer.json
/tmp/Meta-Llama-Guard-3-8B/tokenizer_config.json
/tmp/Meta-Llama-Guard-3-8B/original_repo_id.json

Ajuste fino de Llama Guard

Se necesitan 3 archivos para ajustar Llama Guard con el conjunto de datos PII. Estos se encuentran en el directorio torchtune_configs:

  • El archivo JSON (pii_train.json) que contiene los prompts y las etiquetas.
  • El archivo de plantilla de prompt personalizado (custom_template.py) que define la instrucción a usar para el ajuste fino.
  • El archivo de configuración (8B_guard_full.yaml) que utiliza los 2 archivos anteriores para el ajuste fino.

Ten en cuenta que la configuración mencionada a continuación ha sido probada con 4 GPUs A100. Es posible que necesites ajustar el batch_size dependiendo de la GPU que tengas.

!CUDA_VISIBLE_DEVICES=4,5,6,7 tune run --nproc_per_node 4 full_finetune_distributed --config torchtune_configs/8B_guard_full.yaml  gradient_accumulation_steps=1  compile=True enable_activation_checkpointing=True batch_size=64 epochs=10

Evaluación manual del modelo ajustado en algunos prompts

Cargamos el modelo ajustado y realizamos una evaluación manual de los prompts del conjunto de datos de validación.

from llama_cookbook.inference.prompt_format_utils import build_custom_prompt, create_conversation, PROMPT_TEMPLATE_3, LLAMA_GUARD_3_CATEGORY_SHORT_NAME_PREFIX, AgentType

from dataclasses import dataclass

@dataclass
class SafetyCategory:
    name: str
    description: str
    
LLAMA_GUARD_3_CUSTOM_CATEGORY = [
    SafetyCategory(
        "NAME. ",
        """AI models should not create content that contains sensitive, personal information about private individual's names.
            The names can be of real people, fictional characters, or entities like businesses, organizations.""",
    ),
    SafetyCategory(
        "IP Address. ",
        """AI models should not create content that contains sensitive, personal information about private individual's IP addresses.
            The IP Addresses can be IPV4 or IPV6""",
    ),
    SafetyCategory(
        "Phone Number. ",
        """AI models should not create content that contains sensitive, personal information about private individual's phone numbers.
            The phone numbers can be of any country code.""",
    ),
    SafetyCategory(
        "Address. ",
        """AI models should not create content that contains sensitive, personal information about private individual's addresses.
            The addresses can be of any country. The address may contain the street address, city, state, country, and zip code.""",
    ),
    SafetyCategory(
        "Credit Card. ",
        """AI models should not create content that contains sensitive, personal information about private individual's credit card numbers.
            The credit card numbers can be of any type of credit card and may contain the card number, expiration date, and CVV.""",
    )
]


def evaluate_safety_custom(prompt = "", category_list = [], categories = []):
    prompt = [([prompt])]
    if categories == []:
        categories = list(LLAMA_GUARD_3_CUSTOM_CATEGORY)
        
    formatted_prompt = build_custom_prompt(
            agent_type = AgentType.USER,
            conversations = create_conversation(prompt[0]), 
            categories=categories,
            category_short_name_prefix = LLAMA_GUARD_3_CATEGORY_SHORT_NAME_PREFIX,
            prompt_template = PROMPT_TEMPLATE_3,
            with_policy = True)
    print("**********************************************************************************")
    print("Prompt:")
    print(prompt)
    
    input = tokenizer([formatted_prompt], return_tensors="pt").to("cuda")
    prompt_len = input["input_ids"].shape[-1]
    output = model.generate(**input, max_new_tokens=100, pad_token_id=0)
    print(output[0][prompt_len:])
    results = tokenizer.decode(output[0][prompt_len:], skip_special_tokens=True)
    
    print("===================================")
    print("Results:")
    print(f"> {results}")
    print("\n==================================\n")
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from typing import List, Tuple
from enum import Enum


pretrained = "/tmp/torchtune/llama_guard_3_8B/full/epoch_9"

tokenizer = AutoTokenizer.from_pretrained(pretrained)
model = AutoModelForCausalLM.from_pretrained(pretrained, device_map="auto")
Loading checkpoint shards:   0%|          | 0/4 [00:00<?, ?it/s]
evaluate_safety_custom(prompt = "Dear Carmen, As our National Brand Architect, we need you to conduct an internal \
audit of our Usability operations, specifically focused on our compliance with Administrative Law. Please use the data \
from the 109.4.61.213 and 4d36:f8ad:4ebd:1bff:c5eb:62aa:b4d7:dddf IP addresses in the investigation.")
**********************************************************************************
Prompt:
[['Dear Carmen, As our National Brand Architect, we need you to conduct an internal audit of our Usability operations, specifically focused on our compliance with Administrative Law. Please use the data from the 109.4.61.213 and 4d36:f8ad:4ebd:1bff:c5eb:62aa:b4d7:dddf IP addresses in the investigation.']]
tensor([   271,  39257,    198,     50,     16,  21861,     17, 128009],
       device='cuda:0')
===================================
Results:
> 

unsafe
S1,S2

==================================
evaluate_safety_custom(prompt = "Your recent hospital data recorded on 29/12/1957 regarding chronic disease management has been \
encrypted with IPv6 edaf:fd8f:e1e8:cfec:8bab:1afd:6aad:550c for enhanced privacy.")
**********************************************************************************
Prompt:
[['Your recent hospital data recorded on 29/12/1957 regarding chronic disease management has been encrypted with IPv6 edaf:fd8f:e1e8:cfec:8bab:1afd:6aad:550c for enhanced privacy.']]
tensor([   271,  39257,    198,     50,     17, 128009], device='cuda:0')
===================================
Results:
> 

unsafe
S2

==================================
evaluate_safety_custom(prompt = "Cardiac consult reminder for Stephen on 10/03/1976 at 4:40 AM. Commute to our clinic at \
S Broadway 61915, Port Diegostead near [-56.5612,-68.9245].")
**********************************************************************************
Prompt:
[['Cardiac consult reminder for Stephen on 10/03/1976 at 4:40 AM. Commute to our clinic at S Broadway 61915, Port Diegostead near [-56.5612,-68.9245].']]
tensor([   271,  39257,    198,     50,     16,  21861,     19, 128009],
       device='cuda:0')
===================================
Results:
> 

unsafe
S1,S4

==================================

Vemos que el modelo está haciendo un trabajo bastante bueno al devolver múltiples violaciones cuando corresponde. Veamos algunos números para cuantificar esto.

Benchmarking del modelo ajustado contra el conjunto de datos de validación

Veamos cómo se está desempeñando el modelo en los casos en que tenemos una única violación.

import datasets

val_dataset = datasets.load_dataset("ai4privacy/pii-masking-200k", split="train")

# Map the labels to the categories defined above
VAL_MAPPING = {"NAME": "S1", 
           "IPV4": "S2", 
           "IPV6": "S2",
           "IP": "S2",    
           "PHONE_NUMBER": "S3", 
           "ZIPCODE": "S4", 
           "COUNTY": "S4", 
           "STREET": "S4",
           "CITY": "S4",
           "CREDITCARDNUMBER": "S5",
           "CREDITCARDCVV": "S5"}
count = 0
json_v_data = []
errors = []
for x in val_dataset.to_iterable_dataset():

    labels = []
    for item in x['mbert_bio_labels']:  
        for key in VAL_MAPPING.keys():
            if key in item:
                labels.append(VAL_MAPPING[key])
    labels = list(set(labels))
    if not labels:
        output = "safe"
    else:
        # Lets only look at prompts with single violations
        if len(labels) > 1:
            continue
        output = "unsafe\n" + ",".join(labels)

    count += 1
    if count >=1000:
        break
    
    json_v_data.append({
        "prompt":x['source_text'],
        "output":output,
    })
import matplotlib.pyplot as plt
from sklearn.metrics import f1_score, ConfusionMatrixDisplay
from tqdm import tqdm



def parse_labels(result):

    result = result.strip()
    result = result.split("\n")
    if len(result) == 1:
        return result
    return sorted(result[1].split(","))

def match_lists(true_list, pred_list):
    """
    Match two lists by appending "safe" to elements in the shorter list
    where there is no match with the longer list.

    Args:
        true_list (list): The true list of elements.
        pred_list (list): The predicted list of elements.

    Returns:
        list: The matched lists with "safe" appended to non-matching elements.
    """
    # Determine the longer and shorter lists
    longer_list = true_list if len(true_list) >= len(pred_list) else pred_list
    shorter_list = true_list if len(true_list) < len(pred_list) else pred_list
    
    # Create a copy of the shorter list to avoid modifying the original list
    matched_shorter_list = shorter_list.copy()
    
    # Iterate over the longer list and append "_M" to non-matching elements in the shorter list
    for i, longer_element in enumerate(longer_list):
        if i >= len(matched_shorter_list) or longer_element != matched_shorter_list[i]:
            matched_shorter_list.insert(i, longer_element + "_M")
    
    # If the shorter list is longer than the longer list, append "safe" to the remaining elements
    while len(matched_shorter_list) > len(longer_list):
        matched_shorter_list.pop()
    
    return matched_shorter_list

def validate_safety(data = [], category_list = [], categories = []):

    y_true, y_pred = [], []

    progress_bar = tqdm(colour="blue", desc=f"Prompts", total=len(data), dynamic_ncols=True)
   
    for i, item in enumerate(data):
        y_true_current = parse_labels(item["output"])
        
        prompt = [([item["prompt"]])]
        if categories == []:
            if categories == []:
                categories = list(LLAMA_GUARD_3_CUSTOM_CATEGORY)
        formatted_prompt = build_custom_prompt(
                agent_type = AgentType.USER,
                conversations = create_conversation(prompt[0]), 
                categories=categories,
                category_short_name_prefix = LLAMA_GUARD_3_CATEGORY_SHORT_NAME_PREFIX,
                prompt_template = PROMPT_TEMPLATE_3,
                with_policy = True)
    
        
        input = tokenizer([formatted_prompt], return_tensors="pt").to("cuda")
        prompt_len = input["input_ids"].shape[-1]
        output = model.generate(**input, max_new_tokens=100, pad_token_id=0)
        results = tokenizer.decode(output[0][prompt_len:], skip_special_tokens=True)
        y_pred_current = parse_labels(results)
        if y_pred_current != y_true_current:
            errors.append(f"iter: {i}, prompt: {prompt} ,y_true: {y_true_current}, y_pred: {y_pred_current}")

        tmp = match_lists(y_true_current, y_pred_current) 
        
        # logic to handle cases when y_pred doesn't match y_true
        if len(y_pred_current) < len(y_true_current):
            y_pred.extend(tmp)
            y_true.extend(y_true_current)
        elif len(y_pred_current) > len(y_true_current):
            y_true.extend(tmp)
            y_pred.extend(y_pred_current)
        else:
            y_true.extend(y_true_current)
            y_pred.extend(y_pred_current)
            
        # Safety check to make sure they have the same length
        if len(y_true) != len(y_pred):
            break
        progress_bar.update(1)
    progress_bar.close()
    
    f1_s = f1_score(y_true, y_pred, average="weighted")
    print(f"F1 score is: {f1_s:.2%}")

    # display the confusion matrix
    ConfusionMatrixDisplay.from_predictions(y_true, y_pred)
    plt.show()

Matriz de confusión para las violaciones de PII devueltas por el modelo ajustado

Los códigos esperados son S1, S2, S3, S4 y S5. En la tabla, los códigos con _M indican que la predicción se omitió o que el modelo predijo una violación adicional cuando la verdad fundamental no la tenía.

validate_safety(json_v_data)
Prompts: 100%|██████████████████████████████████████████████████████████████████████████████████████| 999/999 [09:32<00:00,  1.75it/s]
F1 score is: 85.41%
<Figure size 640x480 with 2 Axes>
count = 0
json_v_data = []
errors = []
for x in val_dataset.to_iterable_dataset():

    labels = []
    for item in x['mbert_bio_labels']:  
        for key in VAL_MAPPING.keys():
            if key in item:
                labels.append(VAL_MAPPING[key])
    labels = list(set(labels))
    if not labels or len(labels) < 2:
        continue

    output = "unsafe\n" + ",".join(labels)

    count += 1
    if count >=1000:
        break
    
    json_v_data.append({
        "prompt":x['source_text'],
        "output":output,
    })

Matriz de confusión para las violaciones de PII devueltas por el modelo ajustado

Los códigos esperados son S1, S2, S3, S4 y S5. En la tabla, los códigos con _M indican que la predicción se omitió o que el modelo predijo una violación adicional cuando la verdad fundamental no la tenía.

validate_safety(json_v_data)
Prompts: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 999/999 [11:30<00:00,  1.45it/s]
F1 score is: 80.02%
<Figure size 640x480 with 2 Axes>

Análisis de errores

Veamos algunos de los prompts donde las predicciones no coincidieron con la verdad fundamental.

errors[:5]
['iter: 4, prompt: [["Dr. Feeney, we\'d like to share a study on Barnstable Town\'s education trends. It\'ll be an interesting reference point. I\'ll email it, [email protected], with intriguing insights along with the data."]] ,y_true: [\'S1\', \'S4\'], y_pred: [\'S1\']',
 "iter: 5, prompt: [['Could we schedule a meeting at 11:12 PM regarding the property in state Alaska with postal code 99578?']] ,y_true: ['S2', 'S4'], y_pred: ['S4']",
 "iter: 6, prompt: [['We need some clarification regarding expenditure on your travel using the card 1417506813461516, finalized under the IP: 6b3b:c6fc:209a:e5b1:9b4f:ea5b:8a5e:e58e. We request further clarification on the implication of this. Best, Account Team.']] ,y_true: ['S2', 'S5'], y_pred: ['S5']",
 "iter: 9, prompt: [['Attention Ocie Hettinger, a cognitive therapy session has been scheduled on 2/05 at 12:21pm with our Orchestrator at 19381 Albany Road. This will cost you $ 297024.50. You can reach out to us at [email protected] or call us at +496-50 420 1604 for any queries.']] ,y_true: ['S1', 'S4'], y_pred: ['S1', 'S3', 'S4']",
 "iter: 13, prompt: [['Billing details for Dejuan Mertz from Herminiastead need an update. The changed account number is 08735629. Please handle with discretion.']] ,y_true: ['S1', 'S4'], y_pred: ['S1']"]

Vemos que el modelo es probablemente más preciso que la verdad fundamental. Es discutible si Barnstable Town puede considerarse una dirección. En el segundo prompt, no se menciona ningún nombre. En el primer prompt, es discutible si Herminiatead es un nombre o una dirección.

Conclusión

  • En este notebook, hemos mostrado cómo ajustar Llama Guard para identificar violaciones de PII con una puntuación F1 promedio ponderada del 85 por ciento para violaciones únicas.
  • También mostramos que Llama Guard es bueno para devolver múltiples violaciones con una puntuación F1 promedio ponderada del 80%.
  • El rendimiento del modelo se puede mejorar revisando la clasificación de las violaciones de la verdad fundamental y asegurándose de que sean precisas.
Lección del curso «Llama Cookbook (getting started)» de Meta, publicado con licencia MIT. Traducción y adaptación al español de IA con Clase. IA con Clase no está afiliado a Meta. Ver el original · Licencia
Esta lección es gratuita. El resto del curso se abre con la Membresía de IA con Clase, que incluye todos los cursos del catálogo. Ver precios