Skip to main content

Sanitize text containing PII attributes while mainting high utility with cryptographic guarantees

Project description

preempt

Prϵϵmpt is a security framework designed to protect personally identifiable information (PII) in text by applying encryption or other privacy-preserving techniques before that data is sent to third-party large language model (LLM) APIs.

Prϵϵmpt achieves high utility for a diverse range of tasks while maintaining cryptographic guarantees. For the experiments and results found in Prϵϵmpt: Sanitizing Sensitive Prompts for LLMs, please refer to this repo.

This is a modular version of Prϵϵmpt, meant to be used as part of other projects.

Setup

  1. Install uv following the instructions here.
  2. Create a virtual environment with Python 3.11, activate it and add preempt:
uv venv --python 3.11
. ./.venv/bin/activate
uv init
uv add preempt
  1. Import Prϵϵmpt methods and classes with from preempt.utils import * to use in your code. See the usage examples below and in demo.ipynb.

If you would like to work with repo, clone the repo, navigate to the base folder (preempt) and use the following:

uv venv --python 3.11
. ./.venv/bin/activate
uv sync

If you already have a project in which you would like to use Prϵϵmpt, use either pip install preempt or uv add preempt, depending on the set up.

Usage

Additional usage examples can be found in demo.ipynb.

We will add support for generalized NER and sanitization in the near future.

Complete Usage Example

This is a complete usage example where we sanitize names and currency values. Make sure you either have Universal NER or Llama-3 8B Instruct available.

  1. Import all utilities:
# Import utils
from preempt.utils import *
  1. Initialize a NER and Sanitizer object:
# Load NER object
# ner_model = NER("/path/to/UniNER-7B-all", device="cuda:1")
ner_model = NER("/path/to/Meta-Llama-3-8B-Instruct/", device="cuda:1")

# Load Sanitizer object
sanitizer_name = Sanitizer(ner_model, key = "EF4359D8D580AA4F7F036D6F04FC6A94", tweak = "D8E7920AFA330A73")
sanitizer_money = Sanitizer(ner_model, key = "FF4359D8D580AA4F7F036D6F04FC6A94", tweak = "E8E7920AFA330A73")

# Sentences
sentences = ["Ben Parker and John Doe went to the bank and withdrew $200.", "Adam won $20 in the lottery."]
  1. Sanitize names in sentences:
# Sanitizing names
sanitized_sentences, _ = sanitizer_name.encrypt(sentences, entity='Name', epsilon=1)
print("Sanitized sentences:")
print(sanitized_sentences)
"""
Prints:

Sanitized sentences:
['Jay Francois and Lamine Franklin went to the bank and withdrew $200.', 'Elie Vinod won $20 in the lottery.']
"""
  1. Sanitize currency values in sanitized_sentences:
# Sanitizing currency values
sanitized_sentences, _ = sanitizer_money.encrypt(sanitized_sentences, entity='Money', epsilon=1)
print("Sanitized sentences:")
print(sanitized_sentences)
"""
Prints:

Sanitized sentences:
['Jay Francois and Lamine Franklin went to the bank and withdrew $769451698.', 'Elie Vinod won $37083668 in the lottery.']
"""
  1. Desanitize encrypted names in sanitized_sentences:
# Desanitizing names
desanitized_sentences = sanitizer_name.decrypt(sanitized_sentences, entity='Name', use_cache=True)
print("Desanitized sentences:")
print(desanitized_sentences)
"""
Prints:

Desanitized sentences:
['Ben Parker and John Doe went to the bank and withdrew $769451698.', 'Adam won $37083668 in the lottery.']
"""
  1. Desanitize encrypted currency values in desanitized_sentences:
# Desanitizing currency values
desanitized_sentences = sanitizer_money.decrypt(desanitized_sentences, entity='Money', use_cache=True)
print("Desanitized sentences:")
print(desanitized_sentences)
"""
Prints:

Desanitized sentences:
['Ben Parker and John Doe went to the bank and withdrew $200.', 'Adam won $20 in the lottery.']
"""

Extraction

We currently support Universal NER and Llama-3 8B Instruct for NER. We will add support for including your own NER models in the near future.

Initialize a NER class object by passing the path to one of the supported NER models mentioned above:

ner_model = NER("/path/to/Meta-Llama-3-8B-Instruct/", device="cuda:0")

Extract PII values found in a list of target strings using ner_model.extract():

sentences = ["Ben Parker and John Doe went to the bank.", "Who was late today? Adam."]
extracted = ner_model.extract(sentences, entity_type='{Name/Money/Age}')

Sanitization

We currently only support sanitization for names, currency values and age, using either FPE or m-LDP.

Initialize a Sanitizer class object by passing the previously initialized ner_model, a key and tweak parameter (required for the FF3 cipher used for FPE).

sanitizer = Sanitizer(ner_model, key = "EF4359D8D580AA4F7F036D6F04FC6A94", tweak = "D8E7920AFA330A73")

Sanitize a list of target strings using sanitizer.encrypt():

sanitized_sentences, _ = sanitizer.encrypt(sentences, entity='Name', epsilon=1, use_fpe=True, use_mdp=False)

PII values found during NER are stored under sanitizer.new_entities as a nested list.

The mappings between plain text and cipher text PII values are stored under sanitizer.entity_mapping. FPE will typically extract PII values from the sanitized sentences before decryption.

Sanitized sentences can be desanitized using sanitizer.decrypt():

desanitized_sentences = sanitizer.decrypt(sanitized_sentences, entity='Name')

If your NER model can't reliably pick up sanitized attributes, consider setting use_cache=True, to decrypt using stored NER values.

desanitized_sentences = sanitizer.decrypt(sanitized_sentences, entity='Name', use_cache=True)

Sanitizing multiple PII attributes

If you want to sanitize multiple sensitive attributes, create a sanitizer for each category separately.

For more examples, check out demo.ipynb

Usage tips

NER typically works better when the inputs are smaller. Consider breaking a large chunk of text into smaller sentences when using the sanitizer.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

preempt-0.1.15.tar.gz (82.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

preempt-0.1.15-py3-none-any.whl (48.7 kB view details)

Uploaded Python 3

File details

Details for the file preempt-0.1.15.tar.gz.

File metadata

  • Download URL: preempt-0.1.15.tar.gz
  • Upload date:
  • Size: 82.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.4

File hashes

Hashes for preempt-0.1.15.tar.gz
Algorithm Hash digest
SHA256 49c02ea6dcfe1065c1c1b95f4d08eed2bac4f07b2dc7e655a9e7cc515d513e9e
MD5 b94fe457ba7a3286a57a9108304c5ad9
BLAKE2b-256 836f647512a78f97c739f7c9f56bf72b5c3aed8489050a2edc8ab7b4ced83505

See more details on using hashes here.

File details

Details for the file preempt-0.1.15-py3-none-any.whl.

File metadata

  • Download URL: preempt-0.1.15-py3-none-any.whl
  • Upload date:
  • Size: 48.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.4

File hashes

Hashes for preempt-0.1.15-py3-none-any.whl
Algorithm Hash digest
SHA256 428d6f27a4f03abfc47b64c5369451b8e70a35dae89d2468ce1de79755438d56
MD5 c472c8317f5dd6b33fe5941caa6b0ad5
BLAKE2b-256 3f61d28ac33c1887fd3099ac6c4469a78eca6cd4470043c87647874b77413305

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page