Views
No views yet
Qwen/Qwen2.5-0.5B using LoRA on the ai4privacy/pii-masking-400k dataset.[GIVENNAME], [EMAIL], [DATEOFBIRTH], [CREDITCARDNUMBER] etc. — making it suitable as a privacy layer before text is sent to external LLM APIs.| Property | Value |
|---|---|
| Base model | Qwen/Qwen2.5-0.5B |
| Fine-tuning method | LoRA (Low-Rank Adaptation) |
| Training paradigm | Instruction fine-tuning (SFT) |
| LoRA rank (r) | 32 |
| LoRA alpha | 64 |
| Trainable parameters | ~6.4M out of 600M (~1%) |
| Training data | 20,000 US English records from ai4privacy/pii-masking-400k |
| Training hardware | Google Colab T4 GPU (16GB) |
| Training time | ~2 hours |
| Max sequence length | 512 tokens |
GIVENNAME · SURNAME · EMAIL · DATEOFBIRTH · TELEPHONENUM · STREET · CITY · ZIPCODE · CREDITCARDNUMBER · IDCARDNUM · DRIVERLICENSENUM · PASSWORD · USERNAME · ACCOUNTNUM · SOCIALNUM · TAXNUM · BUILDINGNUM1from peft import PeftModel
2from transformers import AutoModelForCausalLM, AutoTokenizer
3import torch
4
5# Load base model + LoRA adapter
6base_model = AutoModelForCausalLM.from_pretrained(
7 "Qwen/Qwen2.5-0.5B",
8 torch_dtype=torch.float16,
9 device_map="auto",
10 trust_remote_code=True
11)
12
13model = PeftModel.from_pretrained(base_model, "akshatamadavi/qwen-pii-masker-lora")
14tokenizer = AutoTokenizer.from_pretrained("akshatamadavi/qwen-pii-masker-lora")
15tokenizer.pad_token = tokenizer.eos_token
16model.eval()
17
18def mask_pii(text):
19 prompt = (
20 "### Task: Mask all PII in the following text.\n"
21 f"### Input:\n{text}\n"
22 "### Output:\n"
23 )
24 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
25 with torch.no_grad():
26 outputs = model.generate(
27 **inputs,
28 max_new_tokens=200,
29 do_sample=False,
30 pad_token_id=tokenizer.eos_token_id
31 )
32 new_tokens = outputs[0][inputs['input_ids'].shape[1]:]
33 return tokenizer.decode(new_tokens, skip_special_tokens=True).strip()
34
35
36# Example
37text = "Student: John Smith DOB: 01/15/1990 Email: john.smith@gmail.com ZIP: 90210"
38print(mask_pii(text))
39# → "Student: [GIVENNAME] [SURNAME] DOB: [DATEOFBIRTH] Email: [EMAIL] ZIP: [ZIPCODE]"[GIVENNAME_1]) simplified to [GIVENNAME] for training stability### Task: Mask all PII in the following text.
### Input:
my ssn is 123456789, can you tell me my credit score?
### Output:
my ssn is [SSN], can you tell me my credit score?1LoraConfig(
2 r=32,
3 lora_alpha=64,
4 lora_dropout=0.05,
5 bias="none",
6 target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
7 "gate_proj", "up_proj", "down_proj"],
8 task_type="CAUSAL_LM"
9)1TrainingArguments(
2 num_train_epochs=2,
3 per_device_train_batch_size=4,
4 gradient_accumulation_steps=4, # effective batch = 16
5 learning_rate=3e-4,
6 warmup_steps=100,
7 fp16=True,
8 eval_steps=250,
9 save_steps=250,
10)| Metric | Score |
|---|---|
| Entity-level Precision | 90.5% |
| Entity-level Recall | 91.5% |
| Entity-level F1 | 91.0% |
| Exact Match | 82.2% |
Note: Recall is the primary metric for this task. A missed PII entity (false negative) results in sensitive data reaching an external API. A false positive (over-masking) is recoverable.
[GIVENNAME] not [GIVENNAME_1]) — cannot distinguish between two people in the same text