LoRA: Low-Rank Adaptation of Large Language Models
Paper
β’
2106.09685
β’
Published
β’
56
A lightweight 3B parameter PII (Personally Identifiable Information) classifier, distilled from the Roblox PII Classifier (560M XLM-RoBERTa) using teacher-student distillation with Fireworks AI's LoRA fine-tuning.
| Attribute | Value |
|---|---|
| Base Model | Llama-3.2-3B-Instruct |
| Teacher Model | Roblox/roblox-pii-classifier |
| Training Method | LoRA (Low-Rank Adaptation) via Fireworks AI SFT |
| LoRA Rank | 16 |
| Training Examples | 4,000 (5,000 generated, 80/10/10 split) |
| Test Accuracy | 87.4% on held-out test set |
| Labels | none, asking, giving |
This model uses a novel "LLM Head as Classifier" approach inspired by Fireworks AI's blog post:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TEACHER-STUDENT DISTILLATION β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββ Labels ββββββββββββββββββββββββ β
β β DeepSeek API β βββββββββββββββΊ β Synthetic Dataset β β
β β (Data Generator) β β 5,000 examples β β
β ββββββββββββββββββββ ββββββββββββ¬ββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β ROBLOX PII CLASSIFIER (Teacher) β β
β β XLM-RoBERTa-Large (560M) β β
β β β β
β β Thresholds: β β
β β β’ asking >= 0.2 β "asking" β β
β β β’ giving >= 0.3 β "giving" β β
β β β’ max >= 0.2691 β most confident class β β
β β β’ else β "none" β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β β Soft Labels β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β LLAMA 3.2 3B + LoRA (Student) β β
β β β β
β β System: "Classify if this message involves PII. β β
β β Reply with: none, asking, or giving." β β
β β β β
β β User: Message: "whats ur snap?" β β
β β Assistant: asking β β
β β β β
β β LoRA Config: β β
β β β’ Rank: 16, Alpha: 32 β β
β β β’ Target: q,k,v,o,gate,up,down_proj β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Metric | Value |
|---|---|
| Accuracy | 87.4% |
| None F1 | 0.93 |
| Asking F1 | 0.70 |
| Giving F1 | 0.80 |
| Pred: none | Pred: asking | Pred: giving | |
|---|---|---|---|
| Actual: none | 316 | 16 | 8 |
| Actual: asking | 15 | 57 | 15 |
| Actual: giving | 6 | 3 | 64 |
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
import torch
# Load base model
base_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-3B-Instruct",
torch_dtype=torch.bfloat16,
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")
# Load LoRA adapter
model = PeftModel.from_pretrained(base_model, "sugiv/sugiv-pii-classifier")
def classify_pii(message: str) -> str:
"""Classify a message for PII content."""
messages = [
{"role": "system", "content": 'Classify if this chat message involves PII (personal info). Reply with exactly one word: "none", "asking", or "giving".'},
{"role": "user", "content": f'Message: "{message}"'}
]
inputs = tokenizer.apply_chat_template(messages, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(inputs, max_new_tokens=10, temperature=0, do_sample=False)
response = tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True)
return response.strip().lower().split()[0]
# Examples
print(classify_pii("whats ur snap?")) # β asking
print(classify_pii("my email is [email protected]")) # β giving
print(classify_pii("this game is so fun")) # β none
import requests
API_KEY = "your-fireworks-api-key"
MODEL = "accounts/sugi205-8d1850/models/pii-classifier-llama3b-5k"
def classify_pii(message: str) -> str:
response = requests.post(
"https://api.fireworks.ai/inference/v1/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": MODEL,
"messages": [
{"role": "system", "content": 'Classify if this message involves PII. Reply: none, asking, or giving.'},
{"role": "user", "content": f'Message: "{message}"'}
],
"max_tokens": 10,
"temperature": 0
}
)
return response.json()["choices"][0]["message"]["content"].strip().lower()
| Label | Description | Examples |
|---|---|---|
| none | No PII request or disclosure | "this game is fun", "lol nice shot" |
| asking | Requesting personal information | "what's your phone number?", "where do you live?" |
| giving | Sharing personal information | "my email is [email protected]", "I live at 123 Main St" |
privacy_asking_for_pii >= 0.2 β "asking"privacy_giving_pii >= 0.3 β "giving" max(asking, giving) >= 0.2691 β most confidentApache 2.0
Created by @sugiv
Base model
meta-llama/Llama-3.2-3B-Instruct